Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ Cargo.lock
.DS_Store
Thumbs.db

# Local environment overrides
.env

# Debug files
debug/
*.pdb
Expand Down
63 changes: 63 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
## Default goal
.DEFAULT_GOAL := help

SHELL := /bin/bash

ROOT_DIR := $(abspath $(CURDIR))
EX_DIR := examples
SELECT_PROBE_SCRIPT := $(ROOT_DIR)/scripts/select-probe.sh

EXAMPLES := stm32g0-charging stm32g0-otg stm32g0-sc8815-sw2303 stm32g4

.PHONY: help select-probe

help:
@echo 'Usage:'
@echo ' 1. eval "$$(make -s select-probe)"'
@echo ' 2. make <target>'
@echo
@echo 'Targets by example (release build + probe-rs tooling):'
@for ex in $(EXAMPLES); do \
echo " $$ex: help run build attach reset reset-attach select-probe"; \
done
@echo
@echo 'Shortcuts:'
@echo ' run-<example> -> make -C examples/<example> run'
@echo ' build-<example> -> make -C examples/<example> build'
@echo ' attach-<example> -> make -C examples/<example> attach'
@echo ' reset-<example> -> make -C examples/<example> reset'
@echo ' reset-attach-<example> -> make -C examples/<example> reset-attach'
@echo ' help-<example> -> make -C examples/<example> help'
@echo
@echo 'Examples:'
@echo ' make run-stm32g0-otg'
@echo ' make -C examples/stm32g0-otg help'
@echo ' eval "$$(make -s select-probe)"'

select-probe:
@$(SELECT_PROBE_SCRIPT)

define MAKE_DELEGATES
.PHONY: run-$(1) build-$(1) attach-$(1) reset-$(1) reset-attach-$(1) help-$(1)

run-$(1):
$(MAKE) -C $(EX_DIR)/$(1) run

build-$(1):
$(MAKE) -C $(EX_DIR)/$(1) build

attach-$(1):
$(MAKE) -C $(EX_DIR)/$(1) attach

reset-$(1):
$(MAKE) -C $(EX_DIR)/$(1) reset

reset-attach-$(1):
$(MAKE) -C $(EX_DIR)/$(1) reset-attach

help-$(1):
$(MAKE) -C $(EX_DIR)/$(1) help

endef

$(foreach ex,$(EXAMPLES),$(eval $(call MAKE_DELEGATES,$(ex))))
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ where I2C::Error: core::fmt::Debug

The SC8815 provides a GPO pin for external MOSFET control and power path management.

Note on semantics: writing `1` (true) enables the internal open-drain transistor and PULLS THE PIN LOW via ~6kΩ. Writing `0` (false) turns it OFF and leaves the pin HIGH-Z.
Semantics: writing `true` enables the internal open-drain transistor and pulls the pin LOW via ~6kΩ. Writing `false` turns it off and leaves the pin high-impedance.

```rust,ignore
use sc8815::{SC8815, PowerPathStatus, registers::constants::DEFAULT_ADDRESS};
Expand Down Expand Up @@ -168,11 +168,7 @@ where I2C::Error: core::fmt::Debug
**GPO Pin Behavior:**

- `true` (1): GPO pin pulls LOW (6kΩ internal pull-down active, open-drain ON)
- `false` (0): GPO pin is HIGH-Z (open drain)

API 变更(更清晰的语义):
- 替换 `set_gpo_control(true/false)` 为 `set_gpo_pull_low(true/false)`(true=拉低)
- 替换 `get_gpo_status()` 为 `is_gpo_pulled_low()`
- `false` (0): GPO pin is high-impedance (open-drain OFF)

## Feature Flags

Expand Down
51 changes: 51 additions & 0 deletions examples/stm32g0-charging/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
SHELL := /bin/bash

CARGO ?= cargo
PROBE_RS ?= probe-rs

ROOT_DIR := $(abspath $(CURDIR)/../..)
TARGET_TRIPLE := thumbv6m-none-eabi
CHIP := STM32G031C8Ux
BINARY := sc8815_stm32g031c8u6_charging_example
ELF := target/$(TARGET_TRIPLE)/release/$(BINARY)
SELECT_PROBE_SCRIPT := $(ROOT_DIR)/scripts/select-probe.sh

.PHONY: help select-probe build run attach reset reset-attach require-probe

help:
@echo 'stm32g0-charging example targets:'
@echo ' help - Show this message'
@echo ' select-probe - Interactively choose a debug probe (prints export command)'
@echo ' build - cargo build --release --target $(TARGET_TRIPLE)'
@echo ' run - Build + probe-rs run --release'
@echo ' attach - Build + probe-rs attach'
@echo ' reset - probe-rs reset'
@echo ' reset-attach - Build + probe-rs reset + attach (software reset)'
@echo
@echo 'Before run/attach/reset targets, set PROBE_ID:'
@echo ' eval "$$(make -s select-probe)"'

select-probe:
@$(SELECT_PROBE_SCRIPT)

require-probe:
@if [ -z "$(PROBE_ID)" ]; then \
echo 'PROBE_ID is not set. Run: eval "$$(make -s select-probe)"' >&2; \
exit 1; \
fi

build:
$(CARGO) build --release --target $(TARGET_TRIPLE)

run: require-probe build
$(PROBE_RS) run --probe $(PROBE_ID) --chip $(CHIP) $(ELF)

attach: require-probe build
$(PROBE_RS) attach --probe $(PROBE_ID) --chip $(CHIP) $(ELF)

reset: require-probe
$(PROBE_RS) reset --probe $(PROBE_ID) --chip $(CHIP)

reset-attach: require-probe build
$(PROBE_RS) reset --probe $(PROBE_ID) --chip $(CHIP)
$(PROBE_RS) attach --probe $(PROBE_ID) --chip $(CHIP) $(ELF)
3 changes: 2 additions & 1 deletion examples/stm32g0-otg/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-rs run --chip STM32G031G8" # to list chips, run `probe-rs chip list.`
linker = "rust-lld"

rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
"-C", "link-arg=-Tlink.x",
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
"-C", "link-arg=--nmagic",
Expand Down
51 changes: 51 additions & 0 deletions examples/stm32g0-otg/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
SHELL := /bin/bash

CARGO ?= cargo
PROBE_RS ?= probe-rs

ROOT_DIR := $(abspath $(CURDIR)/../..)
TARGET_TRIPLE := thumbv6m-none-eabi
CHIP := STM32G031G8
BINARY := sc8815_stm32g031g8_otg_example
ELF := target/$(TARGET_TRIPLE)/release/$(BINARY)
SELECT_PROBE_SCRIPT := $(ROOT_DIR)/scripts/select-probe.sh

.PHONY: help select-probe build run attach reset reset-attach require-probe

help:
@echo 'stm32g0-otg example targets:'
@echo ' help - Show this message'
@echo ' select-probe - Interactively choose a debug probe (prints export command)'
@echo ' build - cargo build --release --target $(TARGET_TRIPLE)'
@echo ' run - Build + probe-rs run --release'
@echo ' attach - Build + probe-rs attach'
@echo ' reset - probe-rs reset'
@echo ' reset-attach - Build + probe-rs reset + attach (software reset)'
@echo
@echo 'Before run/attach/reset targets, set PROBE_ID:'
@echo ' eval "$$(make -s select-probe)"'

select-probe:
@$(SELECT_PROBE_SCRIPT)

require-probe:
@if [ -z "$(PROBE_ID)" ]; then \
echo 'PROBE_ID is not set. Run: eval "$$(make -s select-probe)"' >&2; \
exit 1; \
fi

build:
$(CARGO) build --release --target $(TARGET_TRIPLE)

run: require-probe build
$(PROBE_RS) run --probe $(PROBE_ID) --chip $(CHIP) $(ELF)

attach: require-probe build
$(PROBE_RS) attach --probe $(PROBE_ID) --chip $(CHIP) $(ELF)

reset: require-probe
$(PROBE_RS) reset --probe $(PROBE_ID) --chip $(CHIP)

reset-attach: require-probe build
$(PROBE_RS) reset --probe $(PROBE_ID) --chip $(CHIP)
$(PROBE_RS) attach --probe $(PROBE_ID) --chip $(CHIP) $(ELF)
15 changes: 15 additions & 0 deletions examples/stm32g0-sc8815-sw2303/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "probe-rs run --chip STM32G031G8"
linker = "rust-lld"

rustflags = [
"-C", "link-arg=-Tdefmt.x",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=--nmagic",
]

[build]
target = "thumbv6m-none-eabi"

[env]
DEFMT_LOG = "info"
72 changes: 72 additions & 0 deletions examples/stm32g0-sc8815-sw2303/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
[package]
name = "sc8815_sw2303_fb_example"
version = "0.1.0"
edition = "2024"

[dependencies]
embassy-stm32 = { git = "https://github.com/embassy-rs/embassy.git", rev = "94f9b2707486ca3eade5bf4b237edf3d6aa90f35", features = [
"defmt",
"time-driver-any",
"stm32g031g8",
"memory-x",
"unstable-pac",
"exti",
] }
embassy-embedded-hal = { git = "https://github.com/embassy-rs/embassy.git", rev = "94f9b2707486ca3eade5bf4b237edf3d6aa90f35" }
embassy-executor = { git = "https://github.com/embassy-rs/embassy.git", rev = "94f9b2707486ca3eade5bf4b237edf3d6aa90f35", features = [
"arch-cortex-m",
"executor-thread",
"defmt",
] }
embassy-time = { git = "https://github.com/embassy-rs/embassy.git", rev = "94f9b2707486ca3eade5bf4b237edf3d6aa90f35", features = [
"defmt",
"defmt-timestamp-uptime",
"tick-hz-32_768",
] }
embassy-sync = { git = "https://github.com/embassy-rs/embassy.git", rev = "94f9b2707486ca3eade5bf4b237edf3d6aa90f35", features = [
"defmt",
] }

defmt = "1.0.1"
defmt-rtt = "1.0.0"

cortex-m = { version = "0.7.7", features = [
"inline-asm",
"critical-section-single-core",
] }
cortex-m-rt = "0.7.5"
panic-probe = { version = "1.0.0", features = ["print-defmt"] }
heapless = { version = "0.8", default-features = false }
portable-atomic = { version = "1.11.0", features = ["critical-section"] }
static_cell = "2.1.0"
libm = "0.2.8"

sc8815 = { version = "*", path = "../../", features = ["async", "defmt"] }
sw2303 = { version = "*", path = "../../../sw2303-rs", features = ["async", "defmt"] }

[profile.dev]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 3
overflow-checks = true

[profile.release]
codegen-units = 1
debug = 2
strip = "none"
debug-assertions = false
incremental = false
lto = "thin"
opt-level = 2
overflow-checks = false

[profile.bench]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = "fat"
opt-level = 3
overflow-checks = false
51 changes: 51 additions & 0 deletions examples/stm32g0-sc8815-sw2303/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
SHELL := /bin/bash

CARGO ?= cargo
PROBE_RS ?= probe-rs

ROOT_DIR := $(abspath $(CURDIR)/../..)
TARGET_TRIPLE := thumbv6m-none-eabi
CHIP := STM32G031G8
BINARY := sc8815_sw2303_fb_example
ELF := target/$(TARGET_TRIPLE)/release/$(BINARY)
SELECT_PROBE_SCRIPT := $(ROOT_DIR)/scripts/select-probe.sh

.PHONY: help select-probe build run attach reset reset-attach require-probe

help:
@echo 'stm32g0-sc8815-sw2303 example targets:'
@echo ' help - Show this message'
@echo ' select-probe - Interactively choose a debug probe (prints export command)'
@echo ' build - cargo build --release --target $(TARGET_TRIPLE)'
@echo ' run - Build + probe-rs run --release'
@echo ' attach - Build + probe-rs attach'
@echo ' reset - probe-rs reset'
@echo ' reset-attach - Build + probe-rs reset + attach (software reset)'
@echo
@echo 'Before run/attach/reset targets, set PROBE_ID:'
@echo ' eval "$$(make -s select-probe)"'

select-probe:
@$(SELECT_PROBE_SCRIPT)

require-probe:
@if [ -z "$(PROBE_ID)" ]; then \
echo 'PROBE_ID is not set. Run: eval "$$(make -s select-probe)"' >&2; \
exit 1; \
fi

build:
$(CARGO) build --release --target $(TARGET_TRIPLE)

run: require-probe build
$(PROBE_RS) run --probe $(PROBE_ID) --chip $(CHIP) $(ELF)

attach: require-probe build
$(PROBE_RS) attach --probe $(PROBE_ID) --chip $(CHIP) $(ELF)

reset: require-probe
$(PROBE_RS) reset --probe $(PROBE_ID) --chip $(CHIP)

reset-attach: require-probe build
$(PROBE_RS) reset --probe $(PROBE_ID) --chip $(CHIP)
$(PROBE_RS) attach --probe $(PROBE_ID) --chip $(CHIP) $(ELF)
45 changes: 45 additions & 0 deletions examples/stm32g0-sc8815-sw2303/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# SC8815 + SW2303 FB Regulation Demo (STM32G031G8U6)

This example configures an SC8815 power-management IC and an SW2303 USB-PD controller on an STM32G031G8U6 platform. VBUS is regulated through the SC8815 FB network using an internal 1.2 V reference and external resistors, while the SW2303 negotiates charging protocols and provides telemetry.

## Hardware Overview

- **MCU**: STM32G031G8U6 (PB6 = I²C1 SCL, PB7 = I²C1 SDA, PB5 = SC8815 PSTOP, PB8 = status LED)
- **SC8815**:
- Operating mode: OTG (discharge)
- External FB divider: Rp = 100 kΩ, Rd = 31.6 kΩ → ≈5 V output with 1.2 V reference
- Sense resistors: RS1 = RS2 = 5 mΩ
- Current limits: IBUS = 3.5 A, IBAT = 2 A
- VBUS/VBAT sensing: **internal VBAT monitoring (VBATS tied to VBAT)** with driver defaults targeting a 4S pack
- Switching frequency: 450 kHz, dead time: 80 ns
- **SW2303**:
- Default protocol set, monitoring of negotiated fast-charging mode
- 12-bit ADC readings for VBUS and output current (ICH)

## Firmware Behavior

1. Hold `PSTOP` high to keep SC8815 in standby.
2. Configure SC8815 (OTG mode, FB network, ADC).
3. Set `PSTOP` low and wait 500 ms for stabilization.
4. Initialize SW2303 on the same I²C bus.
5. Every 500 ms log:
- SC8815 VBAT / IBAT / VBUS / IBUS
- SW2303 VBUS / IBUS (ICH)
- Active SW2303 protocol (if any)

Any configuration failure triggers a repeating LED blink fault loop.

## Building & Running

```bash
# From this example directory
make build # Cross-builds for thumbv6m-none-eabi (release profile)
eval "$(make -s select-probe)" # Optional helper to choose a probe
make run # Flash + run via probe-rs
```

Debug output is available via `defmt-rtt`. To keep the control loop stable:

- Keep `VBATS` hard-wired to `VBAT` so the SC8815 uses its internal VBAT monitor.
- Use the bundled configuration (4S battery defaults) unless you also redesign the resistor network and ADC ratios.
- Verify the external FB network (Rp/Rd) is wired exactly as shown to avoid hardware damage.
Loading