Skip to content

Commit c2055f8

Browse files
tridgeclaude
andcommitted
bootloader: consume per-board CAN pins, RGB LED and RAM limit
Wire the bootloader source to the per-board macros set by Inc/targets.h: - sys_can_stm32_CANFD.c: map the main-firmware-style CAN_RX/TX_PORT/_PIN names onto the bootloader's FDCAN_* names (AF still defaults to AF9), so a board can route FDCAN to non-default pins (ARK uses TX on PB9). - Mcu/g431/Inc/blutil.h: add RGB LED support keyed on RED/GREEN/BLUE_PORT/_PIN (open drain, active low) with a small per-port clock enable. No debug UART. - main.c: re-add the LED hooks (no-op stubs when !USE_RGB_LED, plus a blink state machine that shows error/normal while stuck in the bootloader), and generalize the jump() RAM check to RAM_LIMIT_KB (default 64) so the ARK's 112KB lets the bootloader accept an app whose stack sits above 64KB. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 876b7aa commit c2055f8

3 files changed

Lines changed: 127 additions & 1 deletion

File tree

Mcu/g431/Inc/blutil.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,69 @@ static inline void bl_gpio_init(void)
175175
LL_GPIO_Init(input_port, &GPIO_InitStruct);
176176
}
177177

178+
/*
179+
RGB LED support, driven by per-board RED/GREEN/BLUE_PORT/_PIN from
180+
Inc/targets.h (active low, open drain). Pins are LL_GPIO_PIN_x masks.
181+
*/
182+
#ifdef USE_RGB_LED
183+
static inline void bl_led_port_clock(GPIO_TypeDef *port)
184+
{
185+
#ifdef GPIOA
186+
if (port == GPIOA) { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); return; }
187+
#endif
188+
#ifdef GPIOB
189+
if (port == GPIOB) { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); return; }
190+
#endif
191+
#ifdef GPIOC
192+
if (port == GPIOC) { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); return; }
193+
#endif
194+
#ifdef GPIOD
195+
if (port == GPIOD) { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); return; }
196+
#endif
197+
#ifdef GPIOF
198+
if (port == GPIOF) { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOF); return; }
199+
#endif
200+
}
201+
202+
static inline void bl_led_init(void)
203+
{
204+
bl_led_port_clock(RED_PORT);
205+
bl_led_port_clock(GREEN_PORT);
206+
bl_led_port_clock(BLUE_PORT);
207+
LL_GPIO_SetPinMode(RED_PORT, RED_PIN, LL_GPIO_MODE_OUTPUT);
208+
LL_GPIO_SetPinOutputType(RED_PORT, RED_PIN, LL_GPIO_OUTPUT_OPENDRAIN);
209+
LL_GPIO_SetPinMode(GREEN_PORT, GREEN_PIN, LL_GPIO_MODE_OUTPUT);
210+
LL_GPIO_SetPinOutputType(GREEN_PORT, GREEN_PIN, LL_GPIO_OUTPUT_OPENDRAIN);
211+
LL_GPIO_SetPinMode(BLUE_PORT, BLUE_PIN, LL_GPIO_MODE_OUTPUT);
212+
LL_GPIO_SetPinOutputType(BLUE_PORT, BLUE_PIN, LL_GPIO_OUTPUT_OPENDRAIN);
213+
// LEDs off (open drain high = hi-Z = off)
214+
LL_GPIO_SetOutputPin(RED_PORT, RED_PIN);
215+
LL_GPIO_SetOutputPin(GREEN_PORT, GREEN_PIN);
216+
LL_GPIO_SetOutputPin(BLUE_PORT, BLUE_PIN);
217+
}
218+
219+
static inline void bl_led_on(void)
220+
{
221+
LL_GPIO_ResetOutputPin(RED_PORT, RED_PIN);
222+
LL_GPIO_ResetOutputPin(GREEN_PORT, GREEN_PIN);
223+
LL_GPIO_ResetOutputPin(BLUE_PORT, BLUE_PIN);
224+
}
225+
226+
static inline void bl_led_off(void)
227+
{
228+
LL_GPIO_SetOutputPin(RED_PORT, RED_PIN);
229+
LL_GPIO_SetOutputPin(GREEN_PORT, GREEN_PIN);
230+
LL_GPIO_SetOutputPin(BLUE_PORT, BLUE_PIN);
231+
}
232+
233+
static inline void bl_led_red_on(void)
234+
{
235+
LL_GPIO_ResetOutputPin(RED_PORT, RED_PIN);
236+
LL_GPIO_SetOutputPin(GREEN_PORT, GREEN_PIN);
237+
LL_GPIO_SetOutputPin(BLUE_PORT, BLUE_PIN);
238+
}
239+
#endif // USE_RGB_LED
240+
178241
/*
179242
return true if the MCU booted under a software reset
180243
*/

bootloader/DroneCAN/sys_can_stm32_CANFD.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,15 @@ static void can_init(void)
382382
void sys_can_init(void)
383383
{
384384
// Setup CAN RX and TX pins
385+
// map main-firmware-style CAN pin names (from Inc/targets.h) onto FDCAN_*
386+
#if defined(CAN_RX_PORT) && !defined(FDCAN_RX_PORT)
387+
#define FDCAN_RX_PORT CAN_RX_PORT
388+
#define FDCAN_RX_PIN CAN_RX_PIN
389+
#endif
390+
#if defined(CAN_TX_PORT) && !defined(FDCAN_TX_PORT)
391+
#define FDCAN_TX_PORT CAN_TX_PORT
392+
#define FDCAN_TX_PIN CAN_TX_PIN
393+
#endif
385394
#ifndef FDCAN_RX_PORT
386395
#define FDCAN_RX_PORT GPIOA
387396
#define FDCAN_RX_PIN LL_GPIO_PIN_11

bootloader/main.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,49 @@ static uint16_t invalid_command;
113113

114114
#include <blutil.h>
115115

116+
// default no-op LED functions if not provided by blutil.h (USE_RGB_LED)
117+
#ifndef USE_RGB_LED
118+
static inline void bl_led_init(void) {}
119+
static inline void bl_led_on(void) {}
120+
static inline void bl_led_off(void) {}
121+
static inline void bl_led_red_on(void) {}
122+
#endif
123+
124+
#ifdef USE_RGB_LED
125+
/*
126+
blink RGB LEDs while stuck in the bootloader
127+
- normal: blink all LEDs at ~2.5Hz
128+
- error: blink red only
129+
*/
130+
static uint16_t led_timer_start;
131+
static uint8_t led_blink_counter;
132+
static bool led_error_mode;
133+
134+
static void __attribute__((unused)) bl_led_set_error(bool error)
135+
{
136+
led_error_mode = error;
137+
}
138+
139+
static void bl_led_update(void)
140+
{
141+
const uint16_t now = bl_timer_us();
142+
if ((uint16_t)(now - led_timer_start) < 25000U) {
143+
return;
144+
}
145+
led_timer_start = now;
146+
led_blink_counter++;
147+
if (led_blink_counter & 0x08) {
148+
if (led_error_mode) {
149+
bl_led_red_on();
150+
} else {
151+
bl_led_on();
152+
}
153+
} else {
154+
bl_led_off();
155+
}
156+
}
157+
#endif // USE_RGB_LED
158+
116159
#if DRONECAN_SUPPORT
117160
#include "DroneCAN/DroneCAN.h"
118161
#include "DroneCAN/sys_can.h"
@@ -348,7 +391,10 @@ static void jump()
348391
*/
349392
const uint32_t *app = (uint32_t*)(MCU_FLASH_START + FIRMWARE_RELATIVE_START);
350393
const uint32_t ram_start = 0x20000000;
351-
const uint32_t ram_limit_kb = 64;
394+
#ifndef RAM_LIMIT_KB
395+
#define RAM_LIMIT_KB 64
396+
#endif
397+
const uint32_t ram_limit_kb = RAM_LIMIT_KB;
352398
const uint32_t ram_end = ram_start+ram_limit_kb*1024;
353399
if (app[0] < ram_start || app[0] > ram_end) {
354400
invalid_command = 0;
@@ -369,12 +415,16 @@ static void jump()
369415
#if DRONECAN_SUPPORT
370416
if (!DroneCAN_boot_ok()) {
371417
invalid_command = 0;
418+
#ifdef USE_RGB_LED
419+
bl_led_set_error(true);
420+
#endif
372421
return;
373422
}
374423

375424
sys_can_disable_IRQ();
376425
#endif
377426

427+
bl_led_off();
378428
jump_to_application();
379429
#endif
380430
}
@@ -769,6 +819,9 @@ static bool serialreadChar()
769819
}
770820
bl_timer_reset();
771821
}
822+
#endif
823+
#ifdef USE_RGB_LED
824+
bl_led_update();
772825
#endif
773826
}
774827

@@ -1094,6 +1147,7 @@ int main(void)
10941147
bl_clock_config();
10951148
bl_timer_init();
10961149
bl_gpio_init();
1150+
bl_led_init();
10971151

10981152
#ifdef BOOTLOADER_TEST_CLOCK
10991153
test_clock();

0 commit comments

Comments
 (0)