# Custom Firmware Development Custom firmware development is intended for users who want to program CAN, CAN FD, RS485, and device-control logic directly on the STM32G0B1RCT6. The examples already configure the V8 MCU, external 8 MHz crystal, pins, and basic peripherals and can be imported directly into STM32CubeIDE. These examples do not retain the USB/SPI conversion, SocketCAN, management-port protocol, transparent mode, or offline batch-command functions of the V82 release firmware. If you need to retain these functions and only add I2C, ADC, USART3, sensors, or application logic, use [Official Firmware Extension Development](official_firmware_development). ## Choose an Example | Development requirement | Recommended project | | --- | --- | | Custom classic CAN with an 11-bit standard ID | [CAN Standard-Frame Direct-Development Project](#can-standard-frame-direct-development-project) | | Custom classic CAN with a 29-bit extended ID | [CAN Extended-Frame Direct-Development Project](#can-extended-frame-direct-development-project) | | Custom CAN FD with an 11-bit standard ID | [CAN FD Standard-Frame Direct-Development Project](#can-fd-standard-frame-direct-development-project) | | Custom CAN FD with a 29-bit extended ID | [CAN FD Extended-Frame Direct-Development Project](#can-fd-extended-frame-direct-development-project) | | Custom RS485 device control | [RS485 Direct-Development Project](#rs485-direct-development-project) | | Retain V82 communication functions and only add peripherals or application logic | [Official Firmware Extension Development](official_firmware_development) | Example download: [V8 custom firmware examples](https://gitcode.com/sanpo/robot/tree/main/products/spine/v8/firmware-examples/direct-development) ## Use the Same Project for Both MCUs The two STM32G0B1RCT6 MCUs on the board have identical models and pin assignments. The same build can be programmed into either MCU or into both MCUs. | Programming connector | Project interfaces | Board interfaces | | --- | --- | --- | | MCU (1) SWD | FDCAN1/FDCAN2 and RS485-A/RS485-B | CAN/CAN FD-1, CAN/CAN FD-2, RS485-1, and RS485-2 | | MCU (2) SWD | FDCAN1/FDCAN2 and RS485-A/RS485-B | CAN/CAN FD-3, CAN/CAN FD-4, RS485-3, and RS485-4 | See [Interfaces and Pin Definitions](board_schematic) for the complete pin assignment. ## STM32CubeIDE Environment All five examples use the same environment: - STM32CubeIDE; the examples have been build-tested with version 2.2.0; - STM32G0B1RCT6; - external 8 MHz crystal, with a 60 MHz system clock and FDCAN kernel clock; - ST-LINK debugger. Use `File > Import > Existing Projects into Workspace` to import the selected project, then build the `Release` or `Debug` configuration. Program through the SWD connector for the target MCU. Do not perform a full-chip erase, because it may delete data stored by the board. Every direct-development project includes an `.ioc` file and can be adjusted in STM32CubeMX. Back up the project before generating code. After generation, recheck the clock tree, V8 pin assignment, CAN/CAN FD bit timing, RS485 direction control, and customer logic in `Core/Src/main.c`. ## CAN Standard-Frame Direct-Development Project Download: [CAN standard-frame project](https://gitcode.com/sanpo/robot/tree/main/products/spine/v8/firmware-examples/direct-development/can-standard) This project configures the MCU's two FDCAN peripherals for 1 Mbit/s classic CAN. By default, it only receives standard and extended frames, rejects remote frames, and does not transmit automatically. Receive counters and the latest frames are stored in: ```text g_can1_rx_count / g_can1_last_header / g_can1_last_data g_can2_rx_count / g_can2_last_header / g_can2_last_data ``` `DirectCan_SendStandard()` in `Core/Src/main.c` provides an explicit transmit entry point for an 11-bit standard ID and an 8-byte data frame. Before connecting a device, confirm the CAN ID, payload, and bit rate from the device protocol, then call this function explicitly. ## CAN Extended-Frame Direct-Development Project Download: [CAN extended-frame project](https://gitcode.com/sanpo/robot/tree/main/products/spine/v8/firmware-examples/direct-development/can-extended) This project configures both FDCAN peripherals for 1 Mbit/s classic CAN and is receive-only by default. `DirectCan_SendExtended()` provides an explicit transmit entry point for a 29-bit extended ID and an 8-byte data frame. The project does not automatically send Cybergear or other motor-control commands. Before using an extended-frame device, implement the ID encoding, data scaling, state machine, and safety protection required by the device protocol. ## CAN FD Standard-Frame Direct-Development Project Download: [CAN FD standard-frame project](https://gitcode.com/sanpo/robot/tree/main/products/spine/v8/firmware-examples/direct-development/fdcan-standard) The default settings are: | Item | Default | | --- | --- | | Arbitration bit rate | 1 Mbit/s | | Data-phase bit rate | 5 Mbit/s | | BRS | Enabled | | Transmit format | 11-bit standard ID with a 16-byte CAN FD data frame | | Default behavior | Both channels receive only and do not transmit automatically | `DirectCanFd_SendStandard16()` provides the transmit entry point. If you change the data length, use a valid CAN FD DLC and ensure that the transmit and receive buffers are large enough. ## CAN FD Extended-Frame Direct-Development Project Download: [CAN FD extended-frame project](https://gitcode.com/sanpo/robot/tree/main/products/spine/v8/firmware-examples/direct-development/fdcan-extended) This project also uses a 1 Mbit/s arbitration phase, a 5 Mbit/s data phase, and BRS. `DirectCanFd_SendExtended16()` provides a transmit entry point for a 29-bit extended ID and a 16-byte CAN FD data frame. The main loop is receive-only by default and does not transmit automatically. Before adding a device protocol, confirm that the target device supports CAN FD, BRS, 29-bit extended IDs, and the configured bit timing. ## RS485 Direct-Development Project Download: [RS485 project](https://gitcode.com/sanpo/robot/tree/main/products/spine/v8/firmware-examples/direct-development/rs485) This project directly controls the two half-duplex RS485 channels of the MCU: | Item | RS485-A | RS485-B | | --- | --- | --- | | UART | USART1 | USART2 | | Pins | TX=PC4, RX=PB7, RE=PD2 | TX=PD5, RX=PD6, RE=PC9 | | Default settings | 4 Mbit/s, 8-N-1 | 4 Mbit/s, 8-N-1 | | Default behavior | Receive only | Receive only | Received data is stored in two 256-byte ring buffers. `DirectRs485_Transmit()` switches the transceiver direction and performs a blocking transmit, but the main loop does not call it automatically. A production application must add protocol framing, checksums, timeouts, and error recovery, and evaluate interrupt or DMA operation according to its real-time requirements. ## USB and Official Protocols The USB initialization code in the direct-development projects is only a basic project resource. It is not the V82 management port, SocketCAN interface, USB-to-CAN/CAN FD interface, or USB-to-RS485 interface. If you need these functions, you must implement the complete USB descriptors, protocol, buffering, flow control, and host support, or use [Official Firmware Extension Development](official_firmware_development). ## Validation After Development At minimum, complete the following checks: 1. the Release configuration builds without errors; 2. the MCU, external crystal, system clock, and pin configuration match the V8 hardware; 3. CAN/CAN FD arbitration timing, data timing, BRS, and ID type match the device; 4. RS485 bit rate, data bits, parity, stop bits, and direction control are correct; 5. channel mapping is correct when the two MCUs are programmed separately; 6. verify wiring, termination, and bus operation in the default receive-only state before enabling transmission; 7. motor or actuator ranges, state machines, and protection parameters are safe; 8. long-duration operation shows no unexpected reset, communication interruption, buffer overflow, or significant frame loss.