shibosoftwaredev/f1c100s-linux-nema17-stepper-controller

A four-layer NEMA 17 motor-controller PCB combining an Allwinner F1C100S Linux computer, USB‑PD/buck power system, W5500 Ethernet, STM32 real-time motion control, DRV8825 stepper driver, protection/temperature/current telemetry, USB interfaces, and local LED/buzzer diagnostics.

Version
0.4.56
License
unset
Stars
0

firmware/stm32/README.md

# Experimental STM32G030F6P6 motion firmware

This is compilable firmware, not a hardware-qualified safety system. Host tests
exercise the portable state machine; they do not validate PCB pin multiplexing,
interrupt timing, ADC calibration, bootloader operation, thermal thresholds or
motor behaviour on a first article. Complete `hardware-validation.md` before use.

## Build

Use GNU Arm Embedded 13.3.Rel1 (tested on macOS arm64) and a host C compiler:

```sh
make all test
```

`ARM_PREFIX` can select a toolchain outside PATH. Outputs are `build/motion.elf`
and `build/motion.bin`; flash the binary at `0x08000000`. The linker reserves
32 KiB flash and 8 KiB RAM. The build uses `-Wall -Wextra -Werror`; host tests
use AddressSanitizer and UndefinedBehaviorSanitizer.

## Implemented behaviour

- Reset leaves the bridge disabled. Arming requires a recent heartbeat,
  healthy DRV8825 fault input, a working TMP102 below 70 °C, valid PD status
  and measured VBUS between 10.8 and 16.5 V.
- A hardware-timer ISR produces exactly the requested number of STEP edges,
  independently of Linux. Valid rates are 1–20,000 microsteps/s. There is one
  active relative move; a second request returns busy rather than overwriting it.
- At least three millisecond ticks separate arming and the first move, covering
  the DRV8825's 1.7 ms wake-up requirement. The host client waits 5 ms as well.
- Heartbeat expiry at 250 ms, driver fault, sensor failure, over-temperature,
  UART errors and malformed frames latch a fault and disable the bridge. A
  nominal 100 ms independent watchdog resets a stalled main loop (LSI tolerance
  affects the actual timeout). Disarm with healthy inputs before rearming.
- TMP102 is sampled every 100 ms; its alert input provides an additional fast
  trip. Thermal recovery requires a temperature no higher than 60 °C.
- PA1 measures the 1 MΩ / 100 kΩ VBUS divider using VREFINT calibration. PB3
  reads the BSS138-isolated PD-valid status. High-voltage GATE never touches
  an MCU pin. These checks supplement the existing hardware enable gate.
- PA13 drives the RGB status LED through timer-triggered DMA when idle
  (blue idle, green armed, red fault); PB9 drives the fault buzzer. LED updates
  do not mask STEP interrupts. Hardware LED/waveform validation remains required.

## Factory programming and later Linux updates

First programming is through the existing SWDIO, SWCLK, NRST and GND test pads.
Use a 3.3 V-referenced probe and connect under reset: PA13 becomes LED data after
startup. Keep Linux PE2/PE3 released while the probe owns reset/BOOT0.

The G030 factory default `nBOOT_SEL=1` ignores the BOOT0 pin. To enable the
board's later F1C100S-controlled ROM-UART update path, explicitly configure
`nBOOT_SEL=0`, `nBOOT1=1`, boot locking disabled and read protection level 0
with STM32CubeProgrammer. Review/read back the option bytes for this exact part;
do not copy an opaque option-byte word from another STM32. This repository does
not silently change option bytes. Verify normal flash boot afterwards.

For subsequent ROM updates: stop/disarm motion, hold reset low with PE3, drive
BOOT0 high with PE2, release reset, and use the supported STM32 ROM-UART protocol
on UART0 (bootloader framing is not the motion protocol). Finish with BOOT0 low
and another reset. Verify this procedure on hardware before relying on it.

## Vendor sources

`vendor/stm32g030xx.h`, `system_stm32g0xx.h` and `LICENSE-ST.md` are from ST's
[cmsis-device-g0](https://github.com/STMicroelectronics/cmsis-device-g0).
The CMSIS compiler/core headers and `LICENSE-CMSIS.txt` are from ARM's
[CMSIS 5.9.0](https://github.com/ARM-software/CMSIS_5/tree/5.9.0/CMSIS/Include).
The exact copied headers are included here so builds do not fetch changing
dependencies. TIM16's DMAMUX update request is `0x2e`, per ST's
`stm32g0xx_ll_dmamux.h`. Register definitions target STM32G030, not a generic G0.