From 14c80dc33ccbf07fe4b7f2817a7aba8a81d3e002 Mon Sep 17 00:00:00 2001 From: sl-firmware Date: Tue, 17 Mar 2026 20:31:59 -0400 Subject: [PATCH 1/2] fix: remap CAN from CAN2/PB12-13 to CAN1/PB8-9 (Issue #676) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mamba F722S MK2 does not expose PB12/PB13 externally. Waveshare CAN module is wired to the SCL (PB8) and SDA (PB9) header pads. Changes in can_driver_init(): - Drop __HAL_RCC_CAN2_CLK_ENABLE() — CAN1 needs no slave clock - GPIO: GPIO_PIN_12/13 → GPIO_PIN_8/9, GPIO_AF9_CAN2 → GPIO_AF9_CAN1 - Instance: CAN2 → CAN1 - Filter bank: 14 → 0 (CAN1 master banks start at 0; bank 14 is the CAN2 slave-start boundary, unused here) I2C1 is free: BME280 has been moved to I2C2 (PB10/PB11), so PB8/PB9 are available for CAN1 without any peripheral conflict. Co-Authored-By: Claude Sonnet 4.6 --- include/can_driver.h | 2 +- include/config.h | 5 +++-- src/can_driver.c | 25 +++++++++++++++---------- src/main.c | 2 +- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/can_driver.h b/include/can_driver.h index 15f067d..d52f945 100644 --- a/include/can_driver.h +++ b/include/can_driver.h @@ -5,7 +5,7 @@ #include /* CAN bus driver for BLDC motor controllers (Issue #597) - * CAN2 on PB12 (RX, AF9) / PB13 (TX, AF9) at 500 kbps + * CAN1 on PB8 (RX, AF9) / PB9 (TX, AF9) at 500 kbps (Issue #676 remap) * APB1 = 54 MHz: PSC=6, BS1=13tq, BS2=4tq, SJW=1tq → 18 tq/bit = 500 kbps */ diff --git a/include/config.h b/include/config.h index dba294c..8ab7191 100644 --- a/include/config.h +++ b/include/config.h @@ -257,8 +257,9 @@ #define GIMBAL_PAN_LIMIT_DEG 180.0f // pan soft limit (deg each side) #define GIMBAL_TILT_LIMIT_DEG 90.0f // tilt soft limit (deg each side) -// --- CAN Bus Driver (Issue #597) --- -// CAN2 on PB12 (RX, AF9) / PB13 (TX, AF9) — repurposes SPI2/OSD pins (unused on balance bot) +// --- CAN Bus Driver (Issue #597, remapped Issue #676) --- +// CAN1 on PB8 (RX, AF9) / PB9 (TX, AF9) — SCL/SDA pads on Mamba F722S MK2 +// I2C1 freed: BME280 moved to I2C2 (PB10/PB11); PB8/PB9 repurposed for CAN1 #define CAN_RPM_SCALE 10 // motor_cmd to RPM: 1 cmd count = 10 RPM #define CAN_TLM_HZ 1u // JLINK_TLM_CAN_STATS transmit rate (Hz) diff --git a/src/can_driver.c b/src/can_driver.c index fbdc73d..1f09716 100644 --- a/src/can_driver.c +++ b/src/can_driver.c @@ -1,6 +1,11 @@ /* CAN bus driver for BLDC motor controllers (Issue #597) - * CAN2 on PB12 (RX, AF9) / PB13 (TX, AF9) at 500 kbps - * Filter bank 14 (first CAN2 bank; SlaveStartFilterBank=14) + * CAN1 on PB8 (RX, AF9) / PB9 (TX, AF9) at 500 kbps (Issue #676 remap) + * Filter bank 0 (CAN1 master; SlaveStartFilterBank=14) + * + * NOTE: Mamba F722S MK2 does not expose PB12/PB13 externally. + * Waveshare CAN module wired to SCL pad (PB8 = CAN1_RX) and + * SDA pad (PB9 = CAN1_TX). I2C1 is free (BME280 moved to I2C2). + * CAN1 uses AF9 on PB8/PB9 — no conflict with other active peripherals. */ #include "can_driver.h" @@ -13,24 +18,22 @@ static volatile can_stats_t s_stats; void can_driver_init(void) { - /* CAN2 requires CAN1 master clock for shared filter RAM */ __HAL_RCC_CAN1_CLK_ENABLE(); - __HAL_RCC_CAN2_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); - /* PB12 = CAN2_RX, PB13 = CAN2_TX, AF9 */ + /* PB8 = CAN1_RX, PB9 = CAN1_TX, AF9 (Issue #676) */ GPIO_InitTypeDef gpio = {0}; - gpio.Pin = GPIO_PIN_12 | GPIO_PIN_13; + gpio.Pin = GPIO_PIN_8 | GPIO_PIN_9; gpio.Mode = GPIO_MODE_AF_PP; gpio.Pull = GPIO_NOPULL; gpio.Speed = GPIO_SPEED_FREQ_HIGH; - gpio.Alternate = GPIO_AF9_CAN2; + gpio.Alternate = GPIO_AF9_CAN1; HAL_GPIO_Init(GPIOB, &gpio); /* 500 kbps @ APB1=54 MHz: PSC=6, BS1=13tq, BS2=4tq, SJW=1tq * bit_time = 6 × (1+13+4) / 54000000 = 2 µs → 500 kbps * sample point = (1+13)/18 = 77.8% */ - s_can.Instance = CAN2; + s_can.Instance = CAN1; s_can.Init.Prescaler = CAN_PRESCALER; s_can.Init.Mode = CAN_MODE_NORMAL; s_can.Init.SyncJumpWidth = CAN_SJW_1TQ; @@ -48,11 +51,13 @@ void can_driver_init(void) return; } - /* Filter bank 14: 32-bit mask, FIFO0, accept std IDs 0x200–0x21F + /* Filter bank 0: 32-bit mask, FIFO0, accept std IDs 0x200–0x21F + * CAN1 is master; its filter banks start at 0 (SlaveStartFilterBank=14 + * reserves banks 14-27 for CAN2, but CAN2 is unused here). * FilterIdHigh = 0x200 << 5 = 0x4000 (base ID shifted to bit[15:5]) * FilterMaskHigh = 0x7E0 << 5 = 0xFC00 (mask: top 6 bits must match) */ CAN_FilterTypeDef flt = {0}; - flt.FilterBank = 14u; + flt.FilterBank = 0u; flt.FilterMode = CAN_FILTERMODE_IDMASK; flt.FilterScale = CAN_FILTERSCALE_32BIT; flt.FilterIdHigh = (uint16_t)(CAN_FILTER_STDID << 5u); diff --git a/src/main.c b/src/main.c index 1aefc79..6451f75 100644 --- a/src/main.c +++ b/src/main.c @@ -193,7 +193,7 @@ int main(void) { /* Init Jetson serial binary protocol on USART1 (PB6/PB7) at 921600 baud */ jlink_init(); - /* Init CAN2 BLDC motor controller bus — PB12/PB13, 500 kbps (Issue #597) */ + /* Init CAN1 BLDC motor controller bus — PB8/PB9, 500 kbps (Issue #597/#676) */ can_driver_init(); /* Send fault log summary on boot if a prior fault was recorded (Issue #565) */ From ea5203b67df26d0edb7b8d55d2771f94cb62a880 Mon Sep 17 00:00:00 2001 From: sl-firmware Date: Tue, 17 Mar 2026 21:38:02 -0400 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20bump=20arm=20pitch=20threshold=2010?= =?UTF-8?q?=C2=B0=E2=86=9220=C2=B0=20(Issue=20#678)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mamba is mounted at ~12° on the frame, causing all three arm-interlock checks to block arming. Raise fabsf(bal.pitch_deg) < 10.0f to 20.0f at lines 375, 512, 532 (JLink arm, RC arm rising-edge, CDC arm). Co-Authored-By: Claude Sonnet 4.6 --- src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 6451f75..a8a23d1 100644 --- a/src/main.c +++ b/src/main.c @@ -372,7 +372,7 @@ int main(void) { jlink_state.arm_req = 0u; if (!safety_remote_estop_active() && mpu6000_is_calibrated() && - bal.state == BALANCE_DISARMED && fabsf(bal.pitch_deg) < 10.0f) { + bal.state == BALANCE_DISARMED && fabsf(bal.pitch_deg) < 20.0f) { safety_arm_start(now); } } @@ -509,7 +509,7 @@ int main(void) { /* Rising edge: start arm hold (motors enable after ARMING_HOLD_MS) */ if (!safety_remote_estop_active() && mpu6000_is_calibrated() && - bal.state == BALANCE_DISARMED && fabsf(bal.pitch_deg) < 10.0f) { + bal.state == BALANCE_DISARMED && fabsf(bal.pitch_deg) < 20.0f) { safety_arm_start(now); } } @@ -529,7 +529,7 @@ int main(void) { cdc_arm_request = 0; if (!safety_remote_estop_active() && mpu6000_is_calibrated() && - bal.state == BALANCE_DISARMED && fabsf(bal.pitch_deg) < 10.0f) { + bal.state == BALANCE_DISARMED && fabsf(bal.pitch_deg) < 20.0f) { safety_arm_start(now); } }