Merge pull request 'fix: remap CAN from CAN2/PB12-13 to CAN1/PB8-9 (Issue #676)' (#677) from sl-firmware/issue-597-can-driver into main

This commit is contained in:
sl-jetson 2026-03-17 21:39:29 -04:00
commit 7f67fc6abe
4 changed files with 23 additions and 17 deletions

View File

@ -5,7 +5,7 @@
#include <stdbool.h> #include <stdbool.h>
/* CAN bus driver for BLDC motor controllers (Issue #597) /* 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 * APB1 = 54 MHz: PSC=6, BS1=13tq, BS2=4tq, SJW=1tq 18 tq/bit = 500 kbps
*/ */

View File

@ -257,8 +257,9 @@
#define GIMBAL_PAN_LIMIT_DEG 180.0f // pan soft limit (deg each side) #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) #define GIMBAL_TILT_LIMIT_DEG 90.0f // tilt soft limit (deg each side)
// --- CAN Bus Driver (Issue #597) --- // --- CAN Bus Driver (Issue #597, remapped Issue #676) ---
// CAN2 on PB12 (RX, AF9) / PB13 (TX, AF9) — repurposes SPI2/OSD pins (unused on balance bot) // 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_RPM_SCALE 10 // motor_cmd to RPM: 1 cmd count = 10 RPM
#define CAN_TLM_HZ 1u // JLINK_TLM_CAN_STATS transmit rate (Hz) #define CAN_TLM_HZ 1u // JLINK_TLM_CAN_STATS transmit rate (Hz)

View File

@ -1,6 +1,11 @@
/* CAN bus driver for BLDC motor controllers (Issue #597) /* 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)
* Filter bank 14 (first CAN2 bank; SlaveStartFilterBank=14) * 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" #include "can_driver.h"
@ -13,24 +18,22 @@ static volatile can_stats_t s_stats;
void can_driver_init(void) void can_driver_init(void)
{ {
/* CAN2 requires CAN1 master clock for shared filter RAM */
__HAL_RCC_CAN1_CLK_ENABLE(); __HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_CAN2_CLK_ENABLE();
__HAL_RCC_GPIOB_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_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.Mode = GPIO_MODE_AF_PP;
gpio.Pull = GPIO_NOPULL; gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_HIGH; gpio.Speed = GPIO_SPEED_FREQ_HIGH;
gpio.Alternate = GPIO_AF9_CAN2; gpio.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOB, &gpio); HAL_GPIO_Init(GPIOB, &gpio);
/* 500 kbps @ APB1=54 MHz: PSC=6, BS1=13tq, BS2=4tq, SJW=1tq /* 500 kbps @ APB1=54 MHz: PSC=6, BS1=13tq, BS2=4tq, SJW=1tq
* bit_time = 6 × (1+13+4) / 54000000 = 2 µs 500 kbps * bit_time = 6 × (1+13+4) / 54000000 = 2 µs 500 kbps
* sample point = (1+13)/18 = 77.8% */ * sample point = (1+13)/18 = 77.8% */
s_can.Instance = CAN2; s_can.Instance = CAN1;
s_can.Init.Prescaler = CAN_PRESCALER; s_can.Init.Prescaler = CAN_PRESCALER;
s_can.Init.Mode = CAN_MODE_NORMAL; s_can.Init.Mode = CAN_MODE_NORMAL;
s_can.Init.SyncJumpWidth = CAN_SJW_1TQ; s_can.Init.SyncJumpWidth = CAN_SJW_1TQ;
@ -48,11 +51,13 @@ void can_driver_init(void)
return; return;
} }
/* Filter bank 14: 32-bit mask, FIFO0, accept std IDs 0x2000x21F /* Filter bank 0: 32-bit mask, FIFO0, accept std IDs 0x2000x21F
* 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]) * FilterIdHigh = 0x200 << 5 = 0x4000 (base ID shifted to bit[15:5])
* FilterMaskHigh = 0x7E0 << 5 = 0xFC00 (mask: top 6 bits must match) */ * FilterMaskHigh = 0x7E0 << 5 = 0xFC00 (mask: top 6 bits must match) */
CAN_FilterTypeDef flt = {0}; CAN_FilterTypeDef flt = {0};
flt.FilterBank = 14u; flt.FilterBank = 0u;
flt.FilterMode = CAN_FILTERMODE_IDMASK; flt.FilterMode = CAN_FILTERMODE_IDMASK;
flt.FilterScale = CAN_FILTERSCALE_32BIT; flt.FilterScale = CAN_FILTERSCALE_32BIT;
flt.FilterIdHigh = (uint16_t)(CAN_FILTER_STDID << 5u); flt.FilterIdHigh = (uint16_t)(CAN_FILTER_STDID << 5u);

View File

@ -195,7 +195,7 @@ int main(void) {
/* Init Jetson serial binary protocol on USART1 (PB6/PB7) at 921600 baud */ /* Init Jetson serial binary protocol on USART1 (PB6/PB7) at 921600 baud */
jlink_init(); 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(); can_driver_init();
/* Send fault log summary on boot if a prior fault was recorded (Issue #565) */ /* Send fault log summary on boot if a prior fault was recorded (Issue #565) */
@ -388,7 +388,7 @@ int main(void) {
jlink_state.arm_req = 0u; jlink_state.arm_req = 0u;
if (!safety_remote_estop_active() && if (!safety_remote_estop_active() &&
mpu6000_is_calibrated() && 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); safety_arm_start(now);
} }
} }
@ -556,7 +556,7 @@ int main(void) {
/* Rising edge: start arm hold (motors enable after ARMING_HOLD_MS) */ /* Rising edge: start arm hold (motors enable after ARMING_HOLD_MS) */
if (!safety_remote_estop_active() && if (!safety_remote_estop_active() &&
mpu6000_is_calibrated() && 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); safety_arm_start(now);
} }
} }
@ -576,7 +576,7 @@ int main(void) {
cdc_arm_request = 0; cdc_arm_request = 0;
if (!safety_remote_estop_active() && if (!safety_remote_estop_active() &&
mpu6000_is_calibrated() && 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); safety_arm_start(now);
} }
} }