From fdd5350b78651c05b0263b32ed6494ef73988672 Mon Sep 17 00:00:00 2001 From: mcgalliard Date: Sun, 18 Jan 2026 01:09:32 -0500 Subject: [PATCH 1/2] Confirming PHAL CAN TX --- common/phal_G4/fdcan/fdcan.h | 5 ++ source/g4_testing/g4_testing.h | 3 +- source/g4_testing/nucleo.c | 95 ++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 source/g4_testing/nucleo.c diff --git a/common/phal_G4/fdcan/fdcan.h b/common/phal_G4/fdcan/fdcan.h index 56ad8b4b2..ad624af05 100644 --- a/common/phal_G4/fdcan/fdcan.h +++ b/common/phal_G4/fdcan/fdcan.h @@ -21,8 +21,13 @@ void __attribute__((weak)) PHAL_FDCAN_rxCallback(CanMsgTypeDef_t* msg); #define MAX_NUM_XID_FILTER (8) #define MAX_NUM_SID_FILTER (28) +#define AF_NUM_FDCAN1 (9) #define AF_NUM_FDCAN2 (9) #define AF_NUM_FDCAN13 (11) + +#define GPIO_INIT_FDCAN1RX_PA11 GPIO_INIT_AF(GPIOA, 11, AF_NUM_FDCAN1, GPIO_OUTPUT_ULTRA_SPEED, GPIO_OUTPUT_OPEN_DRAIN, GPIO_INPUT_OPEN_DRAIN) +#define GPIO_INIT_FDCAN1TX_PA12 GPIO_INIT_AF(GPIOA, 12, AF_NUM_FDCAN1, GPIO_OUTPUT_ULTRA_SPEED, GPIO_OUTPUT_OPEN_DRAIN, GPIO_INPUT_OPEN_DRAIN) + #define GPIO_INIT_FDCAN2RX_PB12 GPIO_INIT_AF(GPIOB, 12, AF_NUM_FDCAN2, GPIO_OUTPUT_ULTRA_SPEED, GPIO_OUTPUT_OPEN_DRAIN, GPIO_INPUT_OPEN_DRAIN) #define GPIO_INIT_FDCAN2TX_PB13 GPIO_INIT_AF(GPIOB, 13, AF_NUM_FDCAN2, GPIO_OUTPUT_ULTRA_SPEED, GPIO_OUTPUT_PUSH_PULL, GPIO_INPUT_OPEN_DRAIN) diff --git a/source/g4_testing/g4_testing.h b/source/g4_testing/g4_testing.h index 9a7b22d8e..0a3629dca 100644 --- a/source/g4_testing/g4_testing.h +++ b/source/g4_testing/g4_testing.h @@ -6,8 +6,9 @@ #define TEST_FDCAN 1 #define TEST_USART 2 #define TEST_SPI 3 +#define TEST_NUCLEO 4 // Change this define to set the test compiled -#define G4_TESTING_CHOSEN TEST_SPI +#define G4_TESTING_CHOSEN TEST_NUCLEO #endif // __G4_TESTING__ diff --git a/source/g4_testing/nucleo.c b/source/g4_testing/nucleo.c new file mode 100644 index 000000000..d3e29b806 --- /dev/null +++ b/source/g4_testing/nucleo.c @@ -0,0 +1,95 @@ + +#include "g4_testing.h" +#if (G4_TESTING_CHOSEN == TEST_NUCLEO) + +#include "common/freertos/freertos.h" +#include "common/phal/gpio.h" +#include "common/phal/rcc.h" +#include "common/phal/can.h" +#include "main.h" +#include + +GPIOInitConfig_t gpio_config[] = { + GPIO_INIT_OUTPUT(GPIOA, 5, GPIO_OUTPUT_LOW_SPEED), // USER LED + GPIO_INIT_FDCAN1RX_PA11, // CANFD + GPIO_INIT_FDCAN1TX_PA12 +}; + +#define TargetCoreClockrateHz 16000000 +ClockRateConfig_t clock_config = { + .clock_source = CLOCK_SOURCE_HSI, + .use_pll = false, + .vco_output_rate_target_hz = 160000000, + .system_clock_target_hz = TargetCoreClockrateHz, + .ahb_clock_target_hz = (TargetCoreClockrateHz / 1), + .apb1_clock_target_hz = (TargetCoreClockrateHz / (1)), + .apb2_clock_target_hz = (TargetCoreClockrateHz / (1)), +}; + +extern uint32_t APB1ClockRateHz; +extern uint32_t APB2ClockRateHz; +extern uint32_t AHBClockRateHz; +extern uint32_t PLLClockRateHz; + +void HardFault_Handler(); + +static void ledblink1(void); +static void can_tx_100hz(void); + +defineThreadStack(ledblink1, 1000, osPriorityNormal, 64); +defineThreadStack(can_tx_100hz, 10, osPriorityHigh, 256); + +int main() { + osKernelInitialize(); + + if (PHAL_configureClockRates(&clock_config)) { + HardFault_Handler(); + } + + if (!PHAL_initGPIO(gpio_config, sizeof(gpio_config) / sizeof(GPIOInitConfig_t))) { + HardFault_Handler(); + } + + if (!PHAL_FDCAN_init(FDCAN1, false, 500000U)) { + HardFault_Handler(); + } + + // Create threads + createThread(ledblink1); + createThread(can_tx_100hz); + + osKernelStart(); // Go! + + return 0; +} + +static void ledblink1(void) { + PHAL_toggleGPIO(GPIOA, 5); +} + +uint8_t items[8] = {0}; + +static void PHAL_FDCAN_testStandard(void) { + CanMsgTypeDef_t msg; + msg.Bus = FDCAN1; + msg.IDE = 0; + msg.StdId = 0x300 + 4; + uint8_t payload[8] = {'S', 'T', 'D', 'I', 'D', '_', 'T', 'X'}; + items[0]++; + msg.DLC = sizeof(payload); + memcpy(msg.Data, items, sizeof(items)); + PHAL_FDCAN_send(&msg); +} + +static void can_tx_100hz(void) +{ + PHAL_FDCAN_testStandard(); +} + +void HardFault_Handler() { + while (1) { + __asm__("nop"); + } +} + +#endif // G4_TESTING_CHOSEN == TEST_NUCLEO From 40f584c8fcab199cd67e0ca53d50c57006dd886f Mon Sep 17 00:00:00 2001 From: mcgalliard Date: Sun, 18 Jan 2026 01:19:09 -0500 Subject: [PATCH 2/2] confirming RX works --- source/g4_testing/nucleo.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/source/g4_testing/nucleo.c b/source/g4_testing/nucleo.c index d3e29b806..8ea42c5b2 100644 --- a/source/g4_testing/nucleo.c +++ b/source/g4_testing/nucleo.c @@ -35,9 +35,13 @@ void HardFault_Handler(); static void ledblink1(void); static void can_tx_100hz(void); +static void can_rx_1khz(void); defineThreadStack(ledblink1, 1000, osPriorityNormal, 64); defineThreadStack(can_tx_100hz, 10, osPriorityHigh, 256); +defineThreadStack(can_rx_1khz, 1, osPriorityHigh, 256); + +defineStaticQueue(q_can_rx, CanMsgTypeDef_t, 256); int main() { osKernelInitialize(); @@ -54,9 +58,20 @@ int main() { HardFault_Handler(); } + uint32_t sids[8] = {0x300, 0x301}; + uint32_t xids[8] = {0x1ABCDE1, 0x1ABCDE2, 0x1ABCDE3}; + PHAL_FDCAN_setFilters(FDCAN1, sids, 2, xids, 3); + // Create threads createThread(ledblink1); createThread(can_tx_100hz); + createThread(can_rx_1khz); + + q_can_rx = createStaticQueue(q_can_rx, CanMsgTypeDef_t, 256); + + // NVIC + NVIC_SetPriority(FDCAN1_IT0_IRQn, 6); + NVIC_EnableIRQ(FDCAN1_IT0_IRQn); osKernelStart(); // Go! @@ -86,6 +101,24 @@ static void can_tx_100hz(void) PHAL_FDCAN_testStandard(); } +void PHAL_FDCAN_rxCallback(CanMsgTypeDef_t* msg) { + if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) { + BaseType_t xHigherPriorityTaskWoken = 0; + xQueueSendFromISR(q_can_rx, msg, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } +} + +volatile CanMsgTypeDef_t rx_frame_0; +static void can_rx_1khz(void) { + CanMsgTypeDef_t rx_frame; + while (xQueueReceive(q_can_rx, &rx_frame, (TickType_t)0) == pdTRUE) { + rx_frame_0 = rx_frame; + ; + } +} + + void HardFault_Handler() { while (1) { __asm__("nop");