From ac1ca1f11998b52250396775310b6fbf60ef90f8 Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Wed, 7 Jan 2026 04:18:18 -0800 Subject: [PATCH 01/18] Structure for STM32G4, can_init mostly done --- Lib/Peripherals/CAN/Test/can_test_init.c | 5 + Lib/Peripherals/CAN/Test/readme.md | 12 ++ Lib/Peripherals/CAN/can.c | 210 +++++++++++++++++++++++ Lib/Peripherals/CAN/can.h | 68 ++++++++ Lib/Peripherals/CAN/can_platform_deps.h | 18 ++ Lib/Peripherals/CAN/common.cmake | 15 ++ Lib/Peripherals/CAN/features.md | 7 + 7 files changed, 335 insertions(+) create mode 100644 Lib/Peripherals/CAN/Test/can_test_init.c create mode 100644 Lib/Peripherals/CAN/Test/readme.md create mode 100644 Lib/Peripherals/CAN/can.c create mode 100644 Lib/Peripherals/CAN/can.h create mode 100644 Lib/Peripherals/CAN/can_platform_deps.h create mode 100644 Lib/Peripherals/CAN/common.cmake create mode 100644 Lib/Peripherals/CAN/features.md diff --git a/Lib/Peripherals/CAN/Test/can_test_init.c b/Lib/Peripherals/CAN/Test/can_test_init.c new file mode 100644 index 00000000..619ff6de --- /dev/null +++ b/Lib/Peripherals/CAN/Test/can_test_init.c @@ -0,0 +1,5 @@ +#include "can.h" + + + + diff --git a/Lib/Peripherals/CAN/Test/readme.md b/Lib/Peripherals/CAN/Test/readme.md new file mode 100644 index 00000000..0396e937 --- /dev/null +++ b/Lib/Peripherals/CAN/Test/readme.md @@ -0,0 +1,12 @@ +# Tests +1. Initialize FDCAN1, then try to initialize the same instance (should error) +2. Initialize, then release immediately. Check state of GPIOs and FDCAN. Then initialize the same peripheral again +3. Initialize, add some filters until you add too many (should do something interesting) + // + + +after releasing: +- State of FDCANx peripheral registers are back to reset. +- State of GPIOx ports registers are back to reset. +- turn off RCC clock if there are no other FDCAN peripherals. + diff --git a/Lib/Peripherals/CAN/can.c b/Lib/Peripherals/CAN/can.c new file mode 100644 index 00000000..be8cc10e --- /dev/null +++ b/Lib/Peripherals/CAN/can.c @@ -0,0 +1,210 @@ +#include "can.h" +#include "Logomatic.h" +#include + +//#ifdef STM32G474xx + +//HAL handles +FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; +FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; +FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; + +//Handle for circular buffer + HAL fdcan handle +CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; +CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; +CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; + +#define _GPIOx_CLK_ENABLE(GPIOX) \ + do { \ + switch ((uintptr_t)(GPIOX)) { \ + case (uintptr_t)GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break; \ + case (uintptr_t)GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break; \ + case (uintptr_t)GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break; \ + case (uintptr_t)GPIOE: __HAL_RCC_GPIOE_CLK_ENABLE(); break; \ + default: LOGOMATIC("CAN: Invalid GPIO Pins"); break; /* unknown port, do nothing */ \ + } \ + } while(0) +//#endif + +#define NVIC_ACTIVATE(FDCAN1) + # + HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); + +CANHandle* can_init(const CANConfig *config) { + //config validation? + //assert(config != 0) + + //#ifdef STM32G474xx + CANHandle * canHandle = 0; + if (config->fdcan_instance == FDCAN1 && ) { + if (CAN1->tx_buffer) {LOGOMATIC("CAN: FDCAN1 is already initialized"); return 0;} + else canHandle = &CAN1; + } else if (config->fdcan_instance == FDCAN2 && CAN2->tx_buffer) { + if (CAN2->tx_buffer) {LOGOMATIC("CAN: FDCAN2 is already initialized"); return 0;} + else canHandle = &CAN2; + } else if (config->fdcan_instance == FDCAN3 && CAN3->tx_buffer) { + if (CAN3->tx_buffer) {LOGOMATIC("CAN: FDCAN3 is already initialized"); return 0;} + else canHandle = &CAN3; + } + //#elif defined(STM32L476xx) + //#else + //#error "Unsupported STM32 family" + //#endif + else { + LOGOMATIC("CAN: Unrecognized FDCAN instance"); + return 0; + } + + (canHandle->hal_fdcanP).Init = config->hal_fdcan_init; //copy FDCAN parameters from user + canHandle->rx_gpio = config->rx_gpio; + canHandle->tx_gpio = config->tx_gpio; + canHandle->rx_callback = config->rx_callback; + canHandle->tx_buffer_length = config->tx_buffer_length; + + //FDCAN Clock Init + __HAL_RCC_FDCAN_CLK_ENABLE(); + //Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler + + //GPIOs init + HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio) ); + HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio) ); + + if (HAL_FDCAN_Init( config->hal_fdcanP ) != HAL_OK) + { + LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); + can_release(canHandle); + return 0; + //Error_Handler(); + } + + _GPIOx_CLK_ENABLE(config->rx_gpio); + _GPIOx_CLK_ENABLE(config->tx_gpio); + + //FDCAN peripheral init + if (HAL_FDCAN_Init( canHandle->hal_fdcanP ) != HAL_OK) + { + LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); + can_release(canHandle); + return 0; + //Error_Handler(); + } + + //Configure interrupts + //uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; + uint32 status = 0; + status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, FDCAN_INTERRUPT_0); + + //uint32_t txevents = FDCAN_IT_TX_COMPLETE; + uint32_t destinations = FDCAN_TX_BUFFER0; + + //not sure if need to be on separate interrupt lines or if HAL takes care of it + status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, FDCAN_IT_TX_COMPLETE, destinations); + status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, FDCAN_IT_TX_COMPLETE, FDCAN_INTERRUPT_1); + //Callbacks redefined later + //HAL_FDCAN_TxBufferCompleteCallback + //HAL_FDCAN_RxFifo0Callback + + //Enable Interrupts + HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); + + HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); + + if (status & HAL_ERROR) { + LOGOMATIC("CAN: Could not activate rx and tx interrupts"); + can_release(canHandle); + return 0; + } + + //Circular Buffer + canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); + if (!canHandle->tx_buffer ) { + LOGOMATIC("CAN: Could not allocate circular buffer"); + return 0; + } + + return canHandle; +} + +HAL_FDCAN_TxBufferCompleteCallback( canHandle->hal_fdcanP, ) { + +} +HAL_FDCAN_RxFifo0Callback() { + +} + + +CANHandle can_add_filter() { + //HAL_FDCAN_ConfigFilter() +} + +int can_start(CANHandle * canHandle) { + //Start the HAL function + //HAL_FDCAN_Start +} + +int can_stop(CANHandle * canHandle) { + //Add stopped state? + + //HAL_FDCAN_Stop +} + +int can_release(CANHandle * canHandle) { + if (canHandle == 0) { + LOGOMATIC("CAN: Tried to release a null handle"); + return -1; + + //free circular buffer contents + //turn off gpio clocks + + //clear filters + //HAL_FDCAN_DeInit(); + + //turn off fdcan clock if no other instances are remaining + //__HAL_RCC_FDCAN_CLK_ENABLE(); + + memset(canHandle, 0, sizeof(canHandle)); + + return 0; +} + +//tx callback should free memory of sending buffer +//block until enqueued on circular buffer +void can_send() { + // +} + + +//not needed, provide an rx callback instead +//void can_receive(); + +//HAL_FDCAN_Start +//HAL_FDCAN_Stop +//HAL_AddMessageToTXFifoQ + +//HAL_FDCAN_GetProtocolStatus +//HAL_FDCAN_GetErrorCounters + +//HAL_FDCAN_IsTXBufferMessagePending +//HAL_FDCAN_AbortTXRequest +//HAL_FDCAN_GetRXMessage +//HAL_FDCAN_GetTxEvent + +//HAL_FDCAN_GetRxFifoFillLevel +//HAL_FDCAN_GetTxFifoFreeLevel + +//HAL_FDCAN_ConfigFilter + +//HAL_FDCAN_ConfigRXFifoOverwrite + + +//HAL_FDCAN_Start +//HAL_FDCAN_Stop + +//HAL_FDCAN_TxEventFifoCallback + +//HAL_FDCAN_GetState + diff --git a/Lib/Peripherals/CAN/can.h b/Lib/Peripherals/CAN/can.h new file mode 100644 index 00000000..da08fc75 --- /dev/null +++ b/Lib/Peripherals/CAN/can.h @@ -0,0 +1,68 @@ +#include "can_platform_deps.h" +#include "circularBuffer.h" + +typedef void (*CAN_RXCallback) (void*, uint32_t size); +typedef struct { + //can baud rate is set by fdcan prescaler and RCC clock configurations + + FDCAN_GlobalTypeDef *fdcan_instance; //Base address of FDCAN peripheral in memory (FDCAN1, FDCAN2, FDCAN3 macros) + + FDCAN_InitTypeDef hal_fdcan_init; + CAN_RXCallback rx_callback; + uint32_t rx_interrupt_priority; + + //Circular Buffer + uint32_t tx_buffer_length; + + GPIO_TypeDef *rx_gpio; //Instance name, like GPIOA, GPIOB, etc. + GPIO_InitTypeDef init_rx_gpio; //GPIO Parameters - set correct Alternate Function, no pullup/pulldown, high frequency + GPIO_TypeDef *tx_gpio; + GPIO_InitTypeDef init_tx_gpio; + + //additional parameters???? + +} CANConfig; + + + +//FDCAN peripheral for STM32G4 +typedef struct { + FDCAN_HandleTypeDef *hal_fdcanP; + CircularBuffer* tx_buffer; + uint32_t tx_buffer_length; + + CAN_RXCallback rx_callback; + + //for release + GPIO_TypeDef * rx_gpio; + GPIO_TypeDef * tx_gpio; + + //Stopped state, will HAL throw an error if trying to user tries to add to queue when FDCAN is stopped? + + //NVIC exceptions +} CANHandle + +/* +FDCAN_FilterTypeDef +FDCAN_FilterTypeDef is defined in the stm32g4xx_hal_fdcan.h +Data Fields +• uint32_t IdType +• uint32_t FilterIndex +• uint32_t FilterType +• uint32_t FilterConfig +• uint32_t FilterID1 +• uint32_t FilterID2 +*/ + +CANHandle* can_init(CANConfig *config); //user must supply an rx callback function + +//tx callback should free memory of sending buffer +//block until enqueued on circular buffer +//void can_(); //enqueue onto circular +void can_enqueue(CANHandle* canHandle, char * message,); //engueue onto circular buffer +//remember to free all data in the circular buffer +void can_release(CANHandle* canHandle); //deinit circular buffer and turn off can peripheral and gpios + +void can_add_filter(HAL_FDCAN_FilterTypeDef * filter); + + diff --git a/Lib/Peripherals/CAN/can_platform_deps.h b/Lib/Peripherals/CAN/can_platform_deps.h new file mode 100644 index 00000000..f7105750 --- /dev/null +++ b/Lib/Peripherals/CAN/can_platform_deps.h @@ -0,0 +1,18 @@ +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_gpio.h" +#include "stm32g4xx_hal_gpio_ex.h" +#include "stm32g4xx_hal_fdcan.h" +#include "stm32g4xx_hal_rcc.h" +#include "stm32g4xx_ll_gpio.h" +#include "stm32g474xx.h" + + +#ifdef STM32L476xx + +#elif defined(STM32G474xx) + +#elif defined(STM32U5A9xx) +#else +#error "Unsupported STM32 family" +#endif + diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake new file mode 100644 index 00000000..44b04d8e --- /dev/null +++ b/Lib/Peripherals/CAN/common.cmake @@ -0,0 +1,15 @@ +add_library(PERIPHERAL_CAN_LIB INTERFACE) + +target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/can.c) + +target_link_libraries( + PERIPHERAL_CAN_LIB INTERFACE CircularBuffer_Lib +) + +# Make headers accessible as #include "Peripherals/USART/usart.h" +target_include_directories( + PERIPHERAL_CAN_LIB + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/../.. +) + diff --git a/Lib/Peripherals/CAN/features.md b/Lib/Peripherals/CAN/features.md new file mode 100644 index 00000000..a146064c --- /dev/null +++ b/Lib/Peripherals/CAN/features.md @@ -0,0 +1,7 @@ + + +- TX buffering policy, do we spread them out over multiple TX buffers +- + + +- Redefining interrupt handlers: \ No newline at end of file From 1d846ef1442787427743a21832a4896bfc897ba1 Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Thu, 8 Jan 2026 08:07:04 -0800 Subject: [PATCH 02/18] finished all minimal functions, now need to write HITL tests --- Lib/Peripherals/CAN/{ => Inc}/can.h | 46 +- .../CAN/{ => Inc}/can_platform_deps.h | 1 + Lib/Peripherals/CAN/Src/can.c | 433 ++++++++++++++++++ Lib/Peripherals/CAN/Test/can_test_init.c | 5 +- Lib/Peripherals/CAN/Test/readme.md | 12 +- Lib/Peripherals/CAN/additional_features.md | 14 + Lib/Peripherals/CAN/can.c | 210 --------- Lib/Peripherals/CAN/common.cmake | 19 +- Lib/Peripherals/CAN/features.md | 7 - 9 files changed, 506 insertions(+), 241 deletions(-) rename Lib/Peripherals/CAN/{ => Inc}/can.h (65%) rename Lib/Peripherals/CAN/{ => Inc}/can_platform_deps.h (99%) create mode 100644 Lib/Peripherals/CAN/Src/can.c create mode 100644 Lib/Peripherals/CAN/additional_features.md delete mode 100644 Lib/Peripherals/CAN/can.c delete mode 100644 Lib/Peripherals/CAN/features.md diff --git a/Lib/Peripherals/CAN/can.h b/Lib/Peripherals/CAN/Inc/can.h similarity index 65% rename from Lib/Peripherals/CAN/can.h rename to Lib/Peripherals/CAN/Inc/can.h index da08fc75..6c0edd3a 100644 --- a/Lib/Peripherals/CAN/can.h +++ b/Lib/Peripherals/CAN/Inc/can.h @@ -1,7 +1,10 @@ #include "can_platform_deps.h" #include "circularBuffer.h" -typedef void (*CAN_RXCallback) (void*, uint32_t size); + +//Must perform a deep copy of the data +typedef void (*CAN_RXCallback) (void* data, uint32_t size); + typedef struct { //can baud rate is set by fdcan prescaler and RCC clock configurations @@ -10,6 +13,7 @@ typedef struct { FDCAN_InitTypeDef hal_fdcan_init; CAN_RXCallback rx_callback; uint32_t rx_interrupt_priority; + uint32_t tx_interrupt_priority; //Circular Buffer uint32_t tx_buffer_length; @@ -19,8 +23,7 @@ typedef struct { GPIO_TypeDef *tx_gpio; GPIO_InitTypeDef init_tx_gpio; - //additional parameters???? - + //additional parameters } CANConfig; @@ -38,31 +41,36 @@ typedef struct { GPIO_TypeDef * tx_gpio; //Stopped state, will HAL throw an error if trying to user tries to add to queue when FDCAN is stopped? + bool init; + bool started; //NVIC exceptions -} CANHandle - -/* -FDCAN_FilterTypeDef -FDCAN_FilterTypeDef is defined in the stm32g4xx_hal_fdcan.h -Data Fields -• uint32_t IdType -• uint32_t FilterIndex -• uint32_t FilterType -• uint32_t FilterConfig -• uint32_t FilterID1 -• uint32_t FilterID2 -*/ +} CANHandle; + +#define FDCAN_MAX_DATA_BYTES 64 +typedef struct { + FDCAN_TxHeaderTypeDef tx_header; + uint8_t data[FDCAN_MAX_DATA_BYTES]; +} FDCANMessage; + CANHandle* can_init(CANConfig *config); //user must supply an rx callback function +int can_start(CANHandle*handle); +int can_stop(CANandle*handle); +int can_send(char* buffer, size_t send); +int can_release(CANHandle* canHandle); //deinit circular buffer and turn off can peripheral and gpios +int can_add_filter(CANHandle* canHandle, HAL_FDCAN_FilterTypeDef * filter); +//alternatively use +//HAL_FDCAN_ConfigGlobalFilter() +//HAL_FDCAN_ConfigFilter() + + + //tx callback should free memory of sending buffer //block until enqueued on circular buffer //void can_(); //enqueue onto circular -void can_enqueue(CANHandle* canHandle, char * message,); //engueue onto circular buffer //remember to free all data in the circular buffer -void can_release(CANHandle* canHandle); //deinit circular buffer and turn off can peripheral and gpios -void can_add_filter(HAL_FDCAN_FilterTypeDef * filter); diff --git a/Lib/Peripherals/CAN/can_platform_deps.h b/Lib/Peripherals/CAN/Inc/can_platform_deps.h similarity index 99% rename from Lib/Peripherals/CAN/can_platform_deps.h rename to Lib/Peripherals/CAN/Inc/can_platform_deps.h index f7105750..b8be2263 100644 --- a/Lib/Peripherals/CAN/can_platform_deps.h +++ b/Lib/Peripherals/CAN/Inc/can_platform_deps.h @@ -7,6 +7,7 @@ #include "stm32g474xx.h" + #ifdef STM32L476xx #elif defined(STM32G474xx) diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c new file mode 100644 index 00000000..79bb75d6 --- /dev/null +++ b/Lib/Peripherals/CAN/Src/can.c @@ -0,0 +1,433 @@ +#include "can.h" +#include "Logomatic.h" +#include + +//#ifdef STM32G474xx + +//HAL handles +//#ifdef USECAN1 +FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; +CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; +//#endif + +//#ifdef USECAN2 +FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; +CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; +//#endif + +//#ifdef USECAN3 +FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; +CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; +//#endif + +CANHandle * handleUtil; + +//macro lore +/* +#define CAT(a,b) a##b +#define CAT3(a, b, c) a##b##c +#define CAT4(a, b,c,d) a##b##c##d +#define CAT5(a, b,c,d,e) a##b##c##d##e + +#define ACTIVATE_FDCAN_HELPER(FDCANX, ITY, preirq, subirq) \ + do { \ + HAL_NVIC_SetPriority( CAT4(FDCANX##,_,ITY, _IRQn ) , preirq, subirq ); \ + HAL_NVIC_EnableIRQ( CAT4(FDCANX##,_,ITY, _IRQn ) ); \ + } while(0) + +#define HAL_NVIC_ACTIVATE_FDCAN(FDCANX, ITY, preirq, subirq) \ + do { \ + if (FDCANX == ##FDCAN1 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN1 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT1, preirq, subirq); } \ + else { LOGOMATIC("Unrecognized FDCAN and Interrupt Line combination"); } \ + } while(0) + +*/ + +#define GPIOx_CLK_ENABLE(GPIOX) \ + do {\ + switch ( (uintptr_t) GPIOX ){ \ + case (uintptr_t) GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break; \ + case (uintptr_t) GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break; \ + case (uintptr_t) GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break; \ + default: LOGOMATIC("BAD FDCAN GPIO Port") \ + } \ + } while(0) + + +#define GPIOx_CLK_DISABLE(GPIOX) \ + do {\ + switch ( (uintptr_t) GPIOX ){ \ + case (uintptr_t) GPIOA: __HAL_RCC_GPIOA_CLK_DISABLE(); break; \ + case (uintptr_t) GPIOB: __HAL_RCC_GPIOB_CLK_DISABLE(); break; \ + case (uintptr_t) GPIOD: __HAL_RCC_GPIOD_CLK_DISABLE(); break; \ + default: LOGOMATIC("BAD FDCAN GPIO Port") \ + } \ + } while(0) + + +static inline void gpio_clk_enable(GPIO_TypeDef *gpio) { + if (gpio == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE(); + else if (gpio == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE(); + else if (gpio == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE(); +} + +static inline void gpio_clk_disable(GPIO_TypeDef *gpio) { + if (gpio == GPIOA) __HAL_RCC_GPIOA_CLK_DISABLE(); + else if (gpio == GPIOB) __HAL_RCC_GPIOB_CLK_DISABLE(); + else if (gpio == GPIOD) __HAL_RCC_GPIOD_CLK_DISABLE(); +} + +static int can_get_irqs(FDCAN_GlobalTypeDef *instance, + IRQn_Type *it0, + IRQn_Type *it1); +static int can_msp_init(CANHandle* handle, const CANConfig*config); +CANHandle* can_init(const CANConfig *config) { + //config validation? + //assert(config != 0) + + //#ifdef STM32G474xx + CANHandle * canHandle = 0; + //#ifdef USECAN1 + if (config->fdcan_instance == FDCAN1) { + if (CAN1.tx_buffer) {LOGOMATIC("CAN: CAN1 is already initialized\n"); return 0;} + else canHandle = &CAN1; + } + //#endif + //#ifdef USECAN2 + else if (config->fdcan_instance == FDCAN2) { + if (CAN2.tx_buffer) {LOGOMATIC("CAN: CAN2 is already initialized\n"); return 0;} + else canHandle = &CAN2; + } + //#ifdef USECAN3 + else if (config->fdcan_instance == FDCAN3) { + if (CAN3.tx_buffer) {LOGOMATIC("CAN: CAN3 is already initialized\n"); return 0;} + else canHandle = &CAN3; + } + //#endif + //#elif defined(STM32L476xx) + //#else + //#error "Unsupported STM32 family" + //#endif + else { + LOGOMATIC("CAN: Unrecognized FDCAN instance"); + return 0; + } + canHandle->init = false; + canHandle->started = false; + + //Initialize handle + assert( config->hal_fdcan_init.TxFifoQueueMode == FDCAN_TX_FIFO_OPERATION ); + + (canHandle->hal_fdcanP).Init = config->hal_fdcan_init; //copy FDCAN parameters from user + //canHandle->hal_fdcanP->Instance = config->fdcan_instance //handles initialized with correct base instance addresses + + canHandle->rx_gpio = config->rx_gpio; + canHandle->tx_gpio = config->tx_gpio; + canHandle->rx_callback = config->rx_callback; + canHandle->tx_buffer_length = config->tx_buffer_length; + + + if (can_msp_init(canHandle, config)) { + LOGOMATIC("CAN_init: could not initialize MSP resources"); + can_release(canHandle); + } + + //Circular Buffer + canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); + if (!canHandle->tx_buffer ) { + LOGOMATIC("CAN: Could not allocate circular buffer\n"); + return 0; + } + + canHandle->init = true; + canHandle->started = false; + return canHandle; +} + +static int can_msp_init(CANHandle* canHandle, const CANConfig*config) { + //MSP Layers + //FDCAN Clock Init + __HAL_RCC_FDCAN_CLK_ENABLE(); + //Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler + + //GPIOs init + GPIOx_CLK_ENABLE(config->rx_gpio); + GPIOx_CLK_ENABLE(config->tx_gpio); + + HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio) ); + HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio) ); + + //FDCAN peripheral init + //This will not work, as I do not define HAL_MSP anywhere (usually created by CubeIDE) + //May have to manipulate the registers myself + if (HAL_FDCAN_Init( canHandle->hal_fdcanP ) != HAL_OK) + { + LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); + return -1; + //Error_Handler(); + } + + //Configure interrupts + //uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; + uint32 status = 0; + uint32 rx_events = FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL; + status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, rx_events, 0); + status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, rx_events, FDCAN_INTERRUPT_LINE0); + + //uint32_t txevents = FDCAN_IT_TX_COMPLETE; + uint32_t destinations = FDCAN_TX_BUFFER0; + uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; + status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, tx_events, destinations); + status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, tx_events, FDCAN_INTERRUPT_LINE1); + //Callbacks redefined later + //HAL_FDCAN_TxBufferCompleteCallback + //HAL_FDCAN_RxFifo0Callback + + uint32_t rxit, txit; + can_get_irqs(canHandle->hal_fdcanP->Instance, &rxit, &txit); + + //rxfifo0 + HAL_NVIC_SetPriority(rxit, config->rx_interrupt_priority, 0); + HAL_NVIC_EnableIRQ(rxit); + + //tx + HAL_NVIC_SetPriority(txit, config->tx_interrupt_priority,0); + HAL_NVIC_EnableIRQ(txit); + + if (status & HAL_ERROR) { + LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); + return -1; + } + + return 0; +} + + +static int can_get_irqs(FDCAN_GlobalTypeDef *instance, + IRQn_Type *it0, + IRQn_Type *it1) +{ + if (instance == FDCAN1) { + *it0 = FDCAN1_IT0_IRQn; + *it1 = FDCAN1_IT1_IRQn; + return 0; + } + if (instance == FDCAN2) { + *it0 = FDCAN2_IT0_IRQn; + *it1 = FDCAN2_IT1_IRQn; + return 0; + } + if (instance == FDCAN3) { + *it0 = FDCAN3_IT0_IRQn; + *it1 = FDCAN3_IT1_IRQn; + return 0; + } + + return -1; // invalid instance +} + +static const char* can_get_instance_name(FDCAN_GlobalTypeDef *instance) { + if (instance == FDCAN1) return "FDCAN1"; + else if (instance == FDCAN2) return "FDCAN2"; + else if (instance == FDCAN3) return "FDCAN3"; +} + +static CANHandle* can_get_buffer_handle(FDCAN_HandleTypeDef * hfdcan) { + + CANHandle* handle = 0; + //#ifdef STM32G474xx + if (hfdcan->Instance == FDCAN1) return &CAN1; + else if (hfdcan->Instance == FDCAN2) return &CAN2; + else if (hfdcan->Instance == FDCAN3) return &CAN3; + else { + LOGOMATIC("CAN_get_buffer_handle: was given invalid FDCAN instance\n"); + return 0; + } +} + + +static int can_tx_buffer_helper(CANHandle* handle) { + while (HAL_FDCAN_GetTxFifoFreeLevel(handle->hal_fdcanP) && !GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { + FDCANMessage* msg = GR_CircularBuffer_Pop(handle->tx_buffer); + + HAL_FDCAN_AddMessageToTxFifoQ(handle->hal_fdcanP, &msg->tx_header, &msg->data ); + + //not a good idea to free within an interrupt service routine + free(msg); + } +} + +void HAL_FDCAN_TxBufferCompleteCallback( FDCAN_HandleTypeDef * hfdcan, uint32_t BufferIndexes ) { + + //If circular buffer has elements, send to queue + //Otherwise do nothing + //#ifdef USECAN1 + CANHandle* handle = can_get_buffer_handle(hfdcan); + + if (!handle->tx_buffer) { + //LOGOMATIC("CAN: TX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); + return; + } + + if (GR_CircularBuffer_IsEmpty(handle->tx_buffer)) return; + + //see if you can pop any more from the buffer + can_tx_buffer_helper(handle); +} +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs) { + CANHandle * handle = can_get_buffer_handle(hfdcan); + + /*if (!handle->rx_buffer) { + LOGOMATIC("CAN: RX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); + return; + } */ // no rx buffer at the moment + + /*if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_MESSAGE_LOST) { + lost_rx++; + }*/ + + if ( !(RxFifo0ITs & ~FDCAN_IT_RX_FIFO0_MESSAGE_LOST)) return; + + if (GR_CircularBuffer_IsFull(handle->tx_buffer)) return; + + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; + + while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) { + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); + + //stack allocation should be fine? Callback needs to terminate first before stack is popped + //should switch this over to malloc at some point to avoid double copies? + handle->rx_callback(rx_data, rx_header.DataLength); + } + + /* whoopsie, don't need the rx buffer yet + while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) & !GR_CircularBuffer_IsFull(handle->rx_buffer)) { + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); + + if (GR_CircularBuffer_IsEmpty(handle->rx_buffer)) handle->rx_callback(rx_data, rx_header.DataLength); + else { + GR_CircularBuffer_Push(handle->rx_buffer, rx_data, rx_header.DataLength); + } + }*/ +} + +/* +void can_read_rx_buffer(CANHandle* canHandle) { + //User can call this at their leisure to pop the rx_buffer + + //read rx_buffer one element at a time? + //or read until empty +}*/ + +/*void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs) { + +}*/ + + +//Just alternatively just use the HAL_FDCAN_ConfigFilter directly with the canHandle->hal_fdcan +int can_add_filters(CANHandle* canHandle, FDCAN_FilterTypeDef *filter , size_t num){ + if (!canHandle) { + LOGOMATIC("CAN_add_filter: handle is null") + return -1; + } + + if ( !(canHandle->init && canHandle->started) ) { + LOGOMATIC("CAN_add_filter: can instance is not started and initialized") + return -1; + } + + if (HAL_FDCAN_ConfigFilter(canHandle->hal_fdcanP, filter) != HAL_OK ) { + LOGOMATIC("CAN_add_filter: failed to configure filter"); + return -1; + } + return 0; + //check that # of filters isn't exceeding max value +} + +int can_start(CANHandle * canHandle) { + //Start the HAL function + if (!canHandle || !canHandle->init) return -1; + + GPIOx_CLK_ENABLE(canHandle->rx_gpio); + GPIOx_CLK_ENABLE(canHandle->tx_gpio); + + HAL_FDCAN_Start(canHandle->hal_fdcanP); + canHandle->started = true; + + return 0; +} + +int can_stop(CANHandle * canHandle) { + //Add stopped state? + if (!canHandle) return -1; + + HAL_FDCAN_Stop(canHandle->hal_fdcanP); + + GPIOx_CLK_DISABLE(canHandle->rx_gpio); + GPIOx_CLK_DISABLE(canHandle->tx_gpio); + + canHandle->started = false; + + return 0; +} + +int can_release(CANHandle * canHandle) { + if (!canHandle) { + LOGOMATIC("CAN: Tried to release a null handle"); + return -1; + } + + if (!canHandle->init) { + LOGOMATIC("CAN_release: can instance is already deinitialized"); + return -1; + } + + //free circular buffer contents + GR_CircularBuffer_Free(&(canHandle->tx_buffer)); + + //turn off gpio clocks + GPIOx_CLK_DISABLE(canHandle->rx_gpio); + GPIOx_CLK_DISABLE(canHandle->tx_gpio); + + //clear filters and reset other parameters + HAL_FDCAN_DeInit(canHandle->hal_fdcanP); + + FDCAN_HandleTypeDef * temp = canHandle->hal_fdcanP; + memset(canHandle, 0, sizeof(*canHandle)); + canHandle->hal_fdcanP = temp; + + //turn off fdcan clock if no other FDCAN instances are running + if (!CAN1.tx_buffer && !CAN2.tx_buffer && !CAN3.tx_buffer) __HAL_RCC_FDCAN_CLK_DISABLE(); + + return 0; +} + +int can_send(CANHandle* canHandle, FDCANMessage* message) { + if (!message) { LOGOMATIC("CAN_send: received null pointer\n"); return -1; } + + #if (data_size > FDCAN_MAX_DATA_BYTES) { LOGOMATIC("CAN_send: cannot send more than %d data bytes\n",FDCAN_MAX_DATA_BYTES); return -1;} + + //IF TX Fifos are not full, send directly to them + //If TX Fifos are full, append to circular buffer + //If circular buffer is full, return an error code + if (HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP)) { + HAL_FDCAN_AddMessageToTxFifoQ(canHandle->hal_fdcanP, &(message->tx_header), &(message->data)); + } else if (!GR_CircularBuffer_IsFull(canHandle->tx_buffer)) { + + GR_CircularBuffer_Push(canHandle->tx_buffer, message, sizeof(FDCANMessage)); + } else { + LOGOMATIC("CAN_send: tx_buffer is full\n"); + return -1; + } + + return 0; +} + diff --git a/Lib/Peripherals/CAN/Test/can_test_init.c b/Lib/Peripherals/CAN/Test/can_test_init.c index 619ff6de..75edb193 100644 --- a/Lib/Peripherals/CAN/Test/can_test_init.c +++ b/Lib/Peripherals/CAN/Test/can_test_init.c @@ -1,5 +1,6 @@ #include "can.h" - - +int main() { + +} \ No newline at end of file diff --git a/Lib/Peripherals/CAN/Test/readme.md b/Lib/Peripherals/CAN/Test/readme.md index 0396e937..34dc581f 100644 --- a/Lib/Peripherals/CAN/Test/readme.md +++ b/Lib/Peripherals/CAN/Test/readme.md @@ -2,11 +2,19 @@ 1. Initialize FDCAN1, then try to initialize the same instance (should error) 2. Initialize, then release immediately. Check state of GPIOs and FDCAN. Then initialize the same peripheral again 3. Initialize, add some filters until you add too many (should do something interesting) - // +4. Send some data, but try to release buffer halfway through and see if it gets logged by the TX complete callback after releasing: - State of FDCANx peripheral registers are back to reset. - State of GPIOx ports registers are back to reset. -- turn off RCC clock if there are no other FDCAN peripherals. +- turn off RCC clock if there are no other FDCAN peripherals. + + +- State of circular buffer inside + +- can_send_helper, free a circular buffer + + +- discuss freeing within ISR, how to avoid. \ No newline at end of file diff --git a/Lib/Peripherals/CAN/additional_features.md b/Lib/Peripherals/CAN/additional_features.md new file mode 100644 index 00000000..1cc65a48 --- /dev/null +++ b/Lib/Peripherals/CAN/additional_features.md @@ -0,0 +1,14 @@ + + +- TX buffering policy, do we spread them out over multiple TX buffers +- + + +- Redefining interrupt handlers: +- FIFO vs Queue policy +- Add support for RXFifo1 +- can_read_rx_buffer, linked to RXFifo0 callback + +- Allow circular buffer of size 0 - right now, whether circular buffer is allocated is used to test whether CAN1 instance is running + +- Smaller can headers for tx (right now its just use the TXHeaderTypeDef) \ No newline at end of file diff --git a/Lib/Peripherals/CAN/can.c b/Lib/Peripherals/CAN/can.c deleted file mode 100644 index be8cc10e..00000000 --- a/Lib/Peripherals/CAN/can.c +++ /dev/null @@ -1,210 +0,0 @@ -#include "can.h" -#include "Logomatic.h" -#include - -//#ifdef STM32G474xx - -//HAL handles -FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; -FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; -FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; - -//Handle for circular buffer + HAL fdcan handle -CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; -CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; -CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; - -#define _GPIOx_CLK_ENABLE(GPIOX) \ - do { \ - switch ((uintptr_t)(GPIOX)) { \ - case (uintptr_t)GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break; \ - case (uintptr_t)GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break; \ - case (uintptr_t)GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break; \ - case (uintptr_t)GPIOE: __HAL_RCC_GPIOE_CLK_ENABLE(); break; \ - default: LOGOMATIC("CAN: Invalid GPIO Pins"); break; /* unknown port, do nothing */ \ - } \ - } while(0) -//#endif - -#define NVIC_ACTIVATE(FDCAN1) - # - HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); - -CANHandle* can_init(const CANConfig *config) { - //config validation? - //assert(config != 0) - - //#ifdef STM32G474xx - CANHandle * canHandle = 0; - if (config->fdcan_instance == FDCAN1 && ) { - if (CAN1->tx_buffer) {LOGOMATIC("CAN: FDCAN1 is already initialized"); return 0;} - else canHandle = &CAN1; - } else if (config->fdcan_instance == FDCAN2 && CAN2->tx_buffer) { - if (CAN2->tx_buffer) {LOGOMATIC("CAN: FDCAN2 is already initialized"); return 0;} - else canHandle = &CAN2; - } else if (config->fdcan_instance == FDCAN3 && CAN3->tx_buffer) { - if (CAN3->tx_buffer) {LOGOMATIC("CAN: FDCAN3 is already initialized"); return 0;} - else canHandle = &CAN3; - } - //#elif defined(STM32L476xx) - //#else - //#error "Unsupported STM32 family" - //#endif - else { - LOGOMATIC("CAN: Unrecognized FDCAN instance"); - return 0; - } - - (canHandle->hal_fdcanP).Init = config->hal_fdcan_init; //copy FDCAN parameters from user - canHandle->rx_gpio = config->rx_gpio; - canHandle->tx_gpio = config->tx_gpio; - canHandle->rx_callback = config->rx_callback; - canHandle->tx_buffer_length = config->tx_buffer_length; - - //FDCAN Clock Init - __HAL_RCC_FDCAN_CLK_ENABLE(); - //Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler - - //GPIOs init - HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio) ); - HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio) ); - - if (HAL_FDCAN_Init( config->hal_fdcanP ) != HAL_OK) - { - LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); - can_release(canHandle); - return 0; - //Error_Handler(); - } - - _GPIOx_CLK_ENABLE(config->rx_gpio); - _GPIOx_CLK_ENABLE(config->tx_gpio); - - //FDCAN peripheral init - if (HAL_FDCAN_Init( canHandle->hal_fdcanP ) != HAL_OK) - { - LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); - can_release(canHandle); - return 0; - //Error_Handler(); - } - - //Configure interrupts - //uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; - uint32 status = 0; - status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); - status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, FDCAN_INTERRUPT_0); - - //uint32_t txevents = FDCAN_IT_TX_COMPLETE; - uint32_t destinations = FDCAN_TX_BUFFER0; - - //not sure if need to be on separate interrupt lines or if HAL takes care of it - status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, FDCAN_IT_TX_COMPLETE, destinations); - status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, FDCAN_IT_TX_COMPLETE, FDCAN_INTERRUPT_1); - //Callbacks redefined later - //HAL_FDCAN_TxBufferCompleteCallback - //HAL_FDCAN_RxFifo0Callback - - //Enable Interrupts - HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); - - HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); - - if (status & HAL_ERROR) { - LOGOMATIC("CAN: Could not activate rx and tx interrupts"); - can_release(canHandle); - return 0; - } - - //Circular Buffer - canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); - if (!canHandle->tx_buffer ) { - LOGOMATIC("CAN: Could not allocate circular buffer"); - return 0; - } - - return canHandle; -} - -HAL_FDCAN_TxBufferCompleteCallback( canHandle->hal_fdcanP, ) { - -} -HAL_FDCAN_RxFifo0Callback() { - -} - - -CANHandle can_add_filter() { - //HAL_FDCAN_ConfigFilter() -} - -int can_start(CANHandle * canHandle) { - //Start the HAL function - //HAL_FDCAN_Start -} - -int can_stop(CANHandle * canHandle) { - //Add stopped state? - - //HAL_FDCAN_Stop -} - -int can_release(CANHandle * canHandle) { - if (canHandle == 0) { - LOGOMATIC("CAN: Tried to release a null handle"); - return -1; - - //free circular buffer contents - //turn off gpio clocks - - //clear filters - //HAL_FDCAN_DeInit(); - - //turn off fdcan clock if no other instances are remaining - //__HAL_RCC_FDCAN_CLK_ENABLE(); - - memset(canHandle, 0, sizeof(canHandle)); - - return 0; -} - -//tx callback should free memory of sending buffer -//block until enqueued on circular buffer -void can_send() { - // -} - - -//not needed, provide an rx callback instead -//void can_receive(); - -//HAL_FDCAN_Start -//HAL_FDCAN_Stop -//HAL_AddMessageToTXFifoQ - -//HAL_FDCAN_GetProtocolStatus -//HAL_FDCAN_GetErrorCounters - -//HAL_FDCAN_IsTXBufferMessagePending -//HAL_FDCAN_AbortTXRequest -//HAL_FDCAN_GetRXMessage -//HAL_FDCAN_GetTxEvent - -//HAL_FDCAN_GetRxFifoFillLevel -//HAL_FDCAN_GetTxFifoFreeLevel - -//HAL_FDCAN_ConfigFilter - -//HAL_FDCAN_ConfigRXFifoOverwrite - - -//HAL_FDCAN_Start -//HAL_FDCAN_Stop - -//HAL_FDCAN_TxEventFifoCallback - -//HAL_FDCAN_GetState - diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake index 44b04d8e..adc1cdfc 100644 --- a/Lib/Peripherals/CAN/common.cmake +++ b/Lib/Peripherals/CAN/common.cmake @@ -6,10 +6,27 @@ target_link_libraries( PERIPHERAL_CAN_LIB INTERFACE CircularBuffer_Lib ) -# Make headers accessible as #include "Peripherals/USART/usart.h" +# Make headers accessible as #include "Peripherals/CAN/can.h" target_include_directories( PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/../.. ) +# link test to this library +if(CMAKE_BUILD_TYPE STREQUAL "Test") +# Initialization + add_executable( + PERIPHERAL_CAN_LIB_init_test + ${CMAKE_CURRENT_LIST_DIR}/Test/can_test_init.c + ) + target_link_libraries( + PERIPHERAL_CAN_LIB_init_test + PERIPHERAL_CAN_LIB + ) + add_test( + CircularBuffer_Lib_Initialization + CircularBuffer_Lib_Initialization_test + ) + +endif() diff --git a/Lib/Peripherals/CAN/features.md b/Lib/Peripherals/CAN/features.md deleted file mode 100644 index a146064c..00000000 --- a/Lib/Peripherals/CAN/features.md +++ /dev/null @@ -1,7 +0,0 @@ - - -- TX buffering policy, do we spread them out over multiple TX buffers -- - - -- Redefining interrupt handlers: \ No newline at end of file From b4fc608ad637c0d4032d30645b90f43422346407 Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Thu, 8 Jan 2026 08:29:58 -0800 Subject: [PATCH 03/18] need to figure out cmake --- CMakeLists.txt | 2 ++ Lib/Peripherals/CAN/Inc/can_platform_deps.h | 13 +++++-------- Lib/Peripherals/CAN/Src/can.c | 2 -- Lib/Peripherals/CAN/common.cmake | 9 ++++----- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c33e8f9..3478a23b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ include("${lib_path}/cmake/gr-lib.cmake") # Peripherals include("${lib_path}/Peripherals/USART/common.cmake") +include("${lib_path}/Peripherals/CAN/common.cmake") message( STATUS @@ -56,5 +57,6 @@ add_gr_project(STM32L476xG BLINKY L4BLINKY) add_gr_project(STM32G474xE Onboarding W3_G4SPI_Receive) add_gr_project(STM32G474xE Onboarding W3_G4SPI_Transmit) + # Onboarding Projects # TODO Add onboarding projects here as needed diff --git a/Lib/Peripherals/CAN/Inc/can_platform_deps.h b/Lib/Peripherals/CAN/Inc/can_platform_deps.h index b8be2263..a7bd4f59 100644 --- a/Lib/Peripherals/CAN/Inc/can_platform_deps.h +++ b/Lib/Peripherals/CAN/Inc/can_platform_deps.h @@ -1,17 +1,14 @@ + +#define STM32G474xx +#ifdef STM32L476xx + +#elif defined(STM32G474xx) #include "stm32g4xx_hal.h" #include "stm32g4xx_hal_gpio.h" #include "stm32g4xx_hal_gpio_ex.h" #include "stm32g4xx_hal_fdcan.h" #include "stm32g4xx_hal_rcc.h" #include "stm32g4xx_ll_gpio.h" -#include "stm32g474xx.h" - - - -#ifdef STM32L476xx - -#elif defined(STM32G474xx) - #elif defined(STM32U5A9xx) #else #error "Unsupported STM32 family" diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 79bb75d6..ddb0dbe4 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -250,7 +250,6 @@ static CANHandle* can_get_buffer_handle(FDCAN_HandleTypeDef * hfdcan) { } } - static int can_tx_buffer_helper(CANHandle* handle) { while (HAL_FDCAN_GetTxFifoFreeLevel(handle->hal_fdcanP) && !GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { FDCANMessage* msg = GR_CircularBuffer_Pop(handle->tx_buffer); @@ -331,7 +330,6 @@ void can_read_rx_buffer(CANHandle* canHandle) { }*/ - //Just alternatively just use the HAL_FDCAN_ConfigFilter directly with the canHandle->hal_fdcan int can_add_filters(CANHandle* canHandle, FDCAN_FilterTypeDef *filter , size_t num){ if (!canHandle) { diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake index adc1cdfc..1d869bb3 100644 --- a/Lib/Peripherals/CAN/common.cmake +++ b/Lib/Peripherals/CAN/common.cmake @@ -1,6 +1,6 @@ add_library(PERIPHERAL_CAN_LIB INTERFACE) -target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/can.c) +target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/can.c) target_link_libraries( PERIPHERAL_CAN_LIB INTERFACE CircularBuffer_Lib @@ -10,7 +10,7 @@ target_link_libraries( target_include_directories( PERIPHERAL_CAN_LIB INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/../.. + ${CMAKE_CURRENT_LIST_DIR}/Inc/ ) # link test to this library @@ -25,8 +25,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Test") PERIPHERAL_CAN_LIB ) add_test( - CircularBuffer_Lib_Initialization - CircularBuffer_Lib_Initialization_test + PERIPHERAL_CAN_LIB_init + PERIPHERAL_CAN_LIB_init_test ) - endif() From 806104849247df6cf221a994bae4f8cadf29e6d0 Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Thu, 8 Jan 2026 23:47:28 -0800 Subject: [PATCH 04/18] compiles --- G4PERTESTING/CMakeLists.txt | 3 +- G4PERTESTING/Core/Src/fdcan.c | 262 +++++++-------- G4PERTESTING/Core/Src/main.c | 81 ++++- G4PERTESTING/Core/Src/stm32g4xx_it.c | 19 +- Lib/Peripherals/CAN/Inc/can.h | 29 +- Lib/Peripherals/CAN/Inc/can_platform_deps.h | 1 + Lib/Peripherals/CAN/README.md | 44 +++ Lib/Peripherals/CAN/Src/can.c | 345 ++++++++++++++------ Lib/Peripherals/CAN/Test/readme.md | 9 +- Lib/Peripherals/CAN/common.cmake | 8 +- 10 files changed, 539 insertions(+), 262 deletions(-) create mode 100644 Lib/Peripherals/CAN/README.md diff --git a/G4PERTESTING/CMakeLists.txt b/G4PERTESTING/CMakeLists.txt index fe543a8d..52ceee74 100644 --- a/G4PERTESTING/CMakeLists.txt +++ b/G4PERTESTING/CMakeLists.txt @@ -26,6 +26,7 @@ project(${CMAKE_PROJECT_NAME}) get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) add_library(${PROJECT_NAME}_USER_CODE INTERFACE) + target_sources( ${PROJECT_NAME}_USER_CODE INTERFACE @@ -46,6 +47,6 @@ target_sources( Core/Src/usart.c ) -target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE) +target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_LIB) target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) diff --git a/G4PERTESTING/Core/Src/fdcan.c b/G4PERTESTING/Core/Src/fdcan.c index f39dbfa2..3fa841e1 100644 --- a/G4PERTESTING/Core/Src/fdcan.c +++ b/G4PERTESTING/Core/Src/fdcan.c @@ -1,133 +1,133 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file fdcan.c - * @brief This file provides code for the configuration - * of the FDCAN instances. - ****************************************************************************** - * @attention - * - * Copyright (c) 2024 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Includes ------------------------------------------------------------------*/ -#include "fdcan.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -FDCAN_HandleTypeDef hfdcan2; - -/* FDCAN2 init function */ -void MX_FDCAN2_Init(void) -{ - - /* USER CODE BEGIN FDCAN2_Init 0 */ - - /* USER CODE END FDCAN2_Init 0 */ - - /* USER CODE BEGIN FDCAN2_Init 1 */ - - /* USER CODE END FDCAN2_Init 1 */ - hfdcan2.Instance = FDCAN2; - hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1; - hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; - hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; - hfdcan2.Init.AutoRetransmission = ENABLE; - hfdcan2.Init.TransmitPause = DISABLE; - hfdcan2.Init.ProtocolException = ENABLE; - hfdcan2.Init.NominalPrescaler = 1; - hfdcan2.Init.NominalSyncJumpWidth = 16; - hfdcan2.Init.NominalTimeSeg1 = 119; - hfdcan2.Init.NominalTimeSeg2 = 40; - hfdcan2.Init.DataPrescaler = 8; - hfdcan2.Init.DataSyncJumpWidth = 16; - hfdcan2.Init.DataTimeSeg1 = 14; - hfdcan2.Init.DataTimeSeg2 = 5; - hfdcan2.Init.StdFiltersNbr = 0; - hfdcan2.Init.ExtFiltersNbr = 2; - hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; - if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { - Error_Handler(); - } - /* USER CODE BEGIN FDCAN2_Init 2 */ - - /* USER CODE END FDCAN2_Init 2 */ -} - -void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcanHandle) -{ - - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if (fdcanHandle->Instance == FDCAN2) { - /* USER CODE BEGIN FDCAN2_MspInit 0 */ - - /* USER CODE END FDCAN2_MspInit 0 */ - LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); - - /* FDCAN2 clock enable */ - __HAL_RCC_FDCAN_CLK_ENABLE(); - - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**FDCAN2 GPIO Configuration - PB12 ------> FDCAN2_RX - PB13 ------> FDCAN2_TX - */ - GPIO_InitStruct.Pin = GPIO_PIN_12; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = GPIO_PIN_13; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* FDCAN2 interrupt Init */ - HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); - /* USER CODE BEGIN FDCAN2_MspInit 1 */ - - /* USER CODE END FDCAN2_MspInit 1 */ - } -} - -void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcanHandle) -{ - - if (fdcanHandle->Instance == FDCAN2) { - /* USER CODE BEGIN FDCAN2_MspDeInit 0 */ - - /* USER CODE END FDCAN2_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_FDCAN_CLK_DISABLE(); - - /**FDCAN2 GPIO Configuration - PB12 ------> FDCAN2_RX - PB13 ------> FDCAN2_TX - */ - HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13); - - /* FDCAN2 interrupt Deinit */ - HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); - /* USER CODE BEGIN FDCAN2_MspDeInit 1 */ - - /* USER CODE END FDCAN2_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ +// /* USER CODE BEGIN Header */ +// /** +// ****************************************************************************** +// * @file fdcan.c +// * @brief This file provides code for the configuration +// * of the FDCAN instances. +// ****************************************************************************** +// * @attention +// * +// * Copyright (c) 2024 STMicroelectronics. +// * All rights reserved. +// * +// * This software is licensed under terms that can be found in the LICENSE file +// * in the root directory of this software component. +// * If no LICENSE file comes with this software, it is provided AS-IS. +// * +// ****************************************************************************** +// */ +// /* USER CODE END Header */ +// /* Includes ------------------------------------------------------------------*/ +// #include "fdcan.h" + +// /* USER CODE BEGIN 0 */ + +// /* USER CODE END 0 */ + +// FDCAN_HandleTypeDef hfdcan2; + +// /* FDCAN2 init function */ +// void MX_FDCAN2_Init(void) +// { + +// /* USER CODE BEGIN FDCAN2_Init 0 */ + +// /* USER CODE END FDCAN2_Init 0 */ + +// /* USER CODE BEGIN FDCAN2_Init 1 */ + +// /* USER CODE END FDCAN2_Init 1 */ +// hfdcan2.Instance = FDCAN2; +// hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1; +// hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; +// hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; +// hfdcan2.Init.AutoRetransmission = ENABLE; +// hfdcan2.Init.TransmitPause = DISABLE; +// hfdcan2.Init.ProtocolException = ENABLE; +// hfdcan2.Init.NominalPrescaler = 1; +// hfdcan2.Init.NominalSyncJumpWidth = 16; +// hfdcan2.Init.NominalTimeSeg1 = 119; +// hfdcan2.Init.NominalTimeSeg2 = 40; +// hfdcan2.Init.DataPrescaler = 8; +// hfdcan2.Init.DataSyncJumpWidth = 16; +// hfdcan2.Init.DataTimeSeg1 = 14; +// hfdcan2.Init.DataTimeSeg2 = 5; +// hfdcan2.Init.StdFiltersNbr = 0; +// hfdcan2.Init.ExtFiltersNbr = 2; +// hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; +// if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { +// Error_Handler(); +// } +// /* USER CODE BEGIN FDCAN2_Init 2 */ + +// /* USER CODE END FDCAN2_Init 2 */ +// } + +// void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// GPIO_InitTypeDef GPIO_InitStruct = {0}; +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspInit 0 */ + +// /* USER CODE END FDCAN2_MspInit 0 */ +// LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + +// /* FDCAN2 clock enable */ +// __HAL_RCC_FDCAN_CLK_ENABLE(); + +// __HAL_RCC_GPIOB_CLK_ENABLE(); +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// GPIO_InitStruct.Pin = GPIO_PIN_12; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_PULLUP; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// GPIO_InitStruct.Pin = GPIO_PIN_13; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_NOPULL; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// /* FDCAN2 interrupt Init */ +// HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0); +// HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspInit 1 */ + +// /* USER CODE END FDCAN2_MspInit 1 */ +// } +// } + +// /*void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspDeInit 0 */ + +// /* USER CODE END FDCAN2_MspDeInit 0 */ +// /* Peripheral clock disable */ +// __HAL_RCC_FDCAN_CLK_DISABLE(); + +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13); + +// /* FDCAN2 interrupt Deinit */ +// HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspDeInit 1 */ + +// /* USER CODE END FDCAN2_MspDeInit 1 */ +// } +// } + +// /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/G4PERTESTING/Core/Src/main.c b/G4PERTESTING/Core/Src/main.c index 5267e175..92969307 100644 --- a/G4PERTESTING/Core/Src/main.c +++ b/G4PERTESTING/Core/Src/main.c @@ -27,6 +27,8 @@ #include "tim.h" #include "usart.h" +#include "can.h" // Assume this works + /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -60,6 +62,12 @@ void SystemClock_Config(void); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ +static int toggleze = 0; + +void DEBUG_callback (void* data, uint32_t size) { + toggleze = (*((char*) data) & 0x80); +} + /* USER CODE END 0 */ @@ -95,27 +103,90 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); - MX_FDCAN2_Init(); + // MX_FDCAN2_Init(); MX_ADC1_Init(); MX_LPUART1_UART_Init(); MX_I2C2_Init(); MX_USART1_UART_Init(); MX_SPI3_Init(); MX_TIM2_Init(); + + /* USER CODE BEGIN 2 */ + CANConfig canCfg; + + canCfg.fdcan_instance = FDCAN2; + + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_CLASSIC; + canCfg.hal_fdcan_init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; + canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; + canCfg.hal_fdcan_init.TransmitPause = DISABLE; + canCfg.hal_fdcan_init.ProtocolException = ENABLE; + canCfg.hal_fdcan_init.NominalPrescaler = 1; + canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; + canCfg.hal_fdcan_init.NominalTimeSeg1 = 119; + canCfg.hal_fdcan_init.NominalTimeSeg2 = 40; + canCfg.hal_fdcan_init.DataPrescaler = 8; + canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; + canCfg.hal_fdcan_init.DataTimeSeg1 = 14; + canCfg.hal_fdcan_init.DataTimeSeg2 = 5; + canCfg.hal_fdcan_init.StdFiltersNbr = 0; + canCfg.hal_fdcan_init.ExtFiltersNbr = 2; + + canCfg.rx_callback = NULL; // PLEASE SET + canCfg.rx_interrupt_priority = 0; // PLEASE SET + canCfg.tx_interrupt_priority = 0; // PLEASE SET + canCfg.tx_buffer_length = 20; // PLEASE SET + + canCfg.rx_gpio = GPIOB; + + canCfg.init_rx_gpio.Pin = GPIO_PIN_12; + canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_rx_gpio.Pull = GPIO_PULLUP; + canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + canCfg.tx_gpio = GPIOB; + + canCfg.init_tx_gpio.Pin = GPIO_PIN_13; + canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_tx_gpio.Pull = GPIO_NOPULL; + canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + + CANHandle *can2Handle = can_init(&canCfg); + + FDCAN_FilterTypeDef filter; + can_add_filter(can2Handle, &filter); + can_start(can2Handle); /* USER CODE END 2 */ + FDCAN_TxHeaderTypeDef TxHeader = { + .IdType = FDCAN_EXTENDED_ID, + .TxFrameType = FDCAN_DATA_FRAME, + .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node + // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors + .BitRateSwitch = FDCAN_BRS_OFF, + .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages + .MessageMarker = 0 // also change this to a real address if you change fifo control + }; + + FDCANTxMessage msg; + msg.data[0] = 0x80; + msg.tx_header = TxHeader; + /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ - // BLINKY - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); - HAL_Delay(1000); - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); + // INDICTIY + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_Delay(1000); + msg.data[0] = toggleze ? 0x00 : 0x80; + can_send(can2Handle, &msg); /* USER CODE BEGIN 3 */ } diff --git a/G4PERTESTING/Core/Src/stm32g4xx_it.c b/G4PERTESTING/Core/Src/stm32g4xx_it.c index 6b491ff5..1db87c69 100644 --- a/G4PERTESTING/Core/Src/stm32g4xx_it.c +++ b/G4PERTESTING/Core/Src/stm32g4xx_it.c @@ -55,7 +55,7 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ -extern FDCAN_HandleTypeDef hfdcan2; +//extern FDCAN_HandleTypeDef hfdcan2; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -196,16 +196,17 @@ void SysTick_Handler(void) /** * @brief This function handles FDCAN2 interrupt 0. */ -void FDCAN2_IT0_IRQHandler(void) -{ - /* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */ +/* +// void FDCAN2_IT0_IRQHandler(void) +// { +// /* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */ - /* USER CODE END FDCAN2_IT0_IRQn 0 */ - HAL_FDCAN_IRQHandler(&hfdcan2); - /* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */ +// /* USER CODE END FDCAN2_IT0_IRQn 0 */ +// HAL_FDCAN_IRQHandler(&hfdcan2); +// /* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */ - /* USER CODE END FDCAN2_IT0_IRQn 1 */ -} +// /* USER CODE END FDCAN2_IT0_IRQn 1 */ +// } /* USER CODE BEGIN 1 */ diff --git a/Lib/Peripherals/CAN/Inc/can.h b/Lib/Peripherals/CAN/Inc/can.h index 6c0edd3a..b365627b 100644 --- a/Lib/Peripherals/CAN/Inc/can.h +++ b/Lib/Peripherals/CAN/Inc/can.h @@ -19,7 +19,7 @@ typedef struct { uint32_t tx_buffer_length; GPIO_TypeDef *rx_gpio; //Instance name, like GPIOA, GPIOB, etc. - GPIO_InitTypeDef init_rx_gpio; //GPIO Parameters - set correct Alternate Function, no pullup/pulldown, high frequency + GPIO_InitTypeDef init_rx_gpio; //GPIO Parameters - set correct Alternate Function, no pullup/pulldown, high/very_high frequency GPIO_TypeDef *tx_gpio; GPIO_InitTypeDef init_tx_gpio; @@ -39,32 +39,41 @@ typedef struct { //for release GPIO_TypeDef * rx_gpio; GPIO_TypeDef * tx_gpio; + uint32_t Clock_Source; - //Stopped state, will HAL throw an error if trying to user tries to add to queue when FDCAN is stopped? + //state bool init; bool started; - //NVIC exceptions + + //error states } CANHandle; #define FDCAN_MAX_DATA_BYTES 64 typedef struct { FDCAN_TxHeaderTypeDef tx_header; uint8_t data[FDCAN_MAX_DATA_BYTES]; -} FDCANMessage; - +} FDCANTxMessage; +typedef struct { + FDCAN_RxHeaderTypeDef rx_header; + uint8_t data[FDCAN_MAX_DATA_BYTES]; +} FDCANRxMessage; -CANHandle* can_init(CANConfig *config); //user must supply an rx callback function +CANHandle* can_init(const CANConfig *config); //user must supply an rx callback function int can_start(CANHandle*handle); -int can_stop(CANandle*handle); -int can_send(char* buffer, size_t send); -int can_release(CANHandle* canHandle); //deinit circular buffer and turn off can peripheral and gpios -int can_add_filter(CANHandle* canHandle, HAL_FDCAN_FilterTypeDef * filter); +int can_stop(CANHandle*handle); +int can_send(CANHandle*handle, FDCANTxMessage* buffer); +int can_release(CANHandle* handle); //deinit circular buffer and turn off can peripheral and gpios +int can_add_filter(CANHandle* handle, FDCAN_FilterTypeDef * filter); //alternatively use //HAL_FDCAN_ConfigGlobalFilter() //HAL_FDCAN_ConfigFilter() +//doesn't need a handle, independent of any CAN instance +int can_set_clksource(uint32_t clksource); //LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE + + //tx callback should free memory of sending buffer diff --git a/Lib/Peripherals/CAN/Inc/can_platform_deps.h b/Lib/Peripherals/CAN/Inc/can_platform_deps.h index a7bd4f59..ad0fe5e7 100644 --- a/Lib/Peripherals/CAN/Inc/can_platform_deps.h +++ b/Lib/Peripherals/CAN/Inc/can_platform_deps.h @@ -8,6 +8,7 @@ #include "stm32g4xx_hal_gpio_ex.h" #include "stm32g4xx_hal_fdcan.h" #include "stm32g4xx_hal_rcc.h" +#include "stm32g4xx_ll_rcc.h" #include "stm32g4xx_ll_gpio.h" #elif defined(STM32U5A9xx) #else diff --git a/Lib/Peripherals/CAN/README.md b/Lib/Peripherals/CAN/README.md new file mode 100644 index 00000000..1e593912 --- /dev/null +++ b/Lib/Peripherals/CAN/README.md @@ -0,0 +1,44 @@ +- USAGE: + +CANHandle* can_init(CANConfig *config); //user must supply an rx callback function + +int can_set_clksource(uint32_t LL_RCC_FDCAN_CLKSOURCE); //ex LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE + +int can_start(CANHandle*handle); +int can_stop(CANHandle*handle); +int can_send(CANHandle*handle, FDCANMessage* buffer, size_t send); +int can_release(CANHandle* handle); //deinit circular buffer and turn off can peripheral and gpios +int can_add_filter(CANHandle* handle, HAL_FDCAN_FilterTypeDef * filter); +int can_add_global_filter(CANHandle* handle, HAL_FDCAN_FilterTypeDef* filter); + +//alternatively instead use the HAL libraries +//HAL_FDCAN_ConfigGlobalFilter(canHandle->hal_fdcanP, filterTypeDef) +//HAL_FDCAN_ConfigFilter(ca) + + + + +PROBLEMS: +Verify ISR safety, no race conditions, atomic read/writes + - Interrupts keep firing while trying to can_release() + - Could try to set the NVIC register to selectively disable interrupts (preferably using a bitmask) +- Need to discuss expected behaviour of API + - particularly can_start, can_stop + - can_release +- Freeing within ISRs whenever popping from CircularBuffer (yes its faster, than stack copies, but heap is getting fragmented) +- ISRS might take too long to resolve because popping and freeing circular buffer. +: + +IDEAS for other features: +- abstract to different STM families besides STM32G4 +- Rx Buffering +- TX Buffering policy, do we spread them out over multiple TX buffers +- DMA support for copying from circular buffer, circular buffer could then be stack allocated +- Smaller can headers for tx and rx (right now its just use the TXHeaderTypeDef) +- TX FIFO vs Queue policy (only allow FIFOS) +- Add support for RXFifo1 + +lot of work: +- Alternatively, rewrite without using HAL, just use CMSIS definitions. +- PROS: Would look good on your Github. +- CONS: Wouldn't help \ No newline at end of file diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index ddb0dbe4..1acb39d7 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -1,27 +1,28 @@ #include "can.h" #include "Logomatic.h" #include +#include +#include +#include //#ifdef STM32G474xx //HAL handles //#ifdef USECAN1 -FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; -CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; +static FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; +static CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; //#endif //#ifdef USECAN2 -FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; -CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; +static FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; +static CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; //#endif //#ifdef USECAN3 -FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; -CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; +static FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; +static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; //#endif -CANHandle * handleUtil; - //macro lore /* #define CAT(a,b) a##b @@ -50,26 +51,54 @@ CANHandle * handleUtil; #define GPIOx_CLK_ENABLE(GPIOX) \ do {\ - switch ( (uintptr_t) GPIOX ){ \ - case (uintptr_t) GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break; \ - case (uintptr_t) GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break; \ - case (uintptr_t) GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break; \ - default: LOGOMATIC("BAD FDCAN GPIO Port") \ + switch ( (uint32_t) GPIOX ) { \ + case (uint32_t) GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break; \ + case (uint32_t) GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break; \ + case (uint32_t) GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break; \ + default: LOGOMATIC("BAD FDCAN GPIO Port"); \ } \ } while(0) #define GPIOx_CLK_DISABLE(GPIOX) \ do {\ - switch ( (uintptr_t) GPIOX ){ \ - case (uintptr_t) GPIOA: __HAL_RCC_GPIOA_CLK_DISABLE(); break; \ - case (uintptr_t) GPIOB: __HAL_RCC_GPIOB_CLK_DISABLE(); break; \ - case (uintptr_t) GPIOD: __HAL_RCC_GPIOD_CLK_DISABLE(); break; \ - default: LOGOMATIC("BAD FDCAN GPIO Port") \ + switch ( (uint32_t) GPIOX ){ \ + case (uint32_t) GPIOA: __HAL_RCC_GPIOA_CLK_DISABLE(); break; \ + case (uint32_t) GPIOB: __HAL_RCC_GPIOB_CLK_DISABLE(); break; \ + case (uint32_t) GPIOD: __HAL_RCC_GPIOD_CLK_DISABLE(); break; \ + default: LOGOMATIC("BAD FDCAN GPIO Port"); \ } \ } while(0) + +static int fdcan_shared_clock_ref = 0; +static inline void fdcan_enable_shared_clock(void) { + uint32_t primask = __get_PRIMASK(); + __disable_irq(); + + if (fdcan_shared_clock_ref == 0) { + __HAL_RCC_FDCAN_CLK_ENABLE(); + } + fdcan_shared_clock_ref++; + + __set_PRIMASK(primask); +} + +static inline void fdcan_disable_shared_clock(void) { + uint32_t primask = __get_PRIMASK(); + __disable_irq(); + + if (fdcan_shared_clock_ref > 0) { + fdcan_shared_clock_ref--; + if (fdcan_shared_clock_ref == 0) { + __HAL_RCC_FDCAN_CLK_DISABLE(); + } + } + __set_PRIMASK(primask); +} + + static inline void gpio_clk_enable(GPIO_TypeDef *gpio) { if (gpio == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE(); else if (gpio == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE(); @@ -85,6 +114,7 @@ static inline void gpio_clk_disable(GPIO_TypeDef *gpio) { static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1); + static int can_msp_init(CANHandle* handle, const CANConfig*config); CANHandle* can_init(const CANConfig *config) { //config validation? @@ -94,18 +124,18 @@ CANHandle* can_init(const CANConfig *config) { CANHandle * canHandle = 0; //#ifdef USECAN1 if (config->fdcan_instance == FDCAN1) { - if (CAN1.tx_buffer) {LOGOMATIC("CAN: CAN1 is already initialized\n"); return 0;} + if (CAN1.init) {LOGOMATIC("CAN: CAN1 is already initialized\n"); return 0;} else canHandle = &CAN1; } //#endif //#ifdef USECAN2 else if (config->fdcan_instance == FDCAN2) { - if (CAN2.tx_buffer) {LOGOMATIC("CAN: CAN2 is already initialized\n"); return 0;} + if (CAN2.init) {LOGOMATIC("CAN: CAN2 is already initialized\n"); return 0;} else canHandle = &CAN2; } //#ifdef USECAN3 else if (config->fdcan_instance == FDCAN3) { - if (CAN3.tx_buffer) {LOGOMATIC("CAN: CAN3 is already initialized\n"); return 0;} + if (CAN3.init) {LOGOMATIC("CAN: CAN3 is already initialized\n"); return 0;} else canHandle = &CAN3; } //#endif @@ -123,19 +153,50 @@ CANHandle* can_init(const CANConfig *config) { //Initialize handle assert( config->hal_fdcan_init.TxFifoQueueMode == FDCAN_TX_FIFO_OPERATION ); - (canHandle->hal_fdcanP).Init = config->hal_fdcan_init; //copy FDCAN parameters from user + canHandle->hal_fdcanP->Init = config->hal_fdcan_init; //copy FDCAN parameters from user //canHandle->hal_fdcanP->Instance = config->fdcan_instance //handles initialized with correct base instance addresses canHandle->rx_gpio = config->rx_gpio; canHandle->tx_gpio = config->tx_gpio; canHandle->rx_callback = config->rx_callback; canHandle->tx_buffer_length = config->tx_buffer_length; - + //alternately -> have can_msp_init setup state for HAL_FDCAN_MspInit to work correctly + //have can_msp_deinit setup state for HAL_FDCAN_MspDeInit to work correctly + //Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() + + //Current idea, redefine HAL_FDCAN_MspInit and MspDeInit do nothing at all, do all the work in can_msp_init() if (can_msp_init(canHandle, config)) { LOGOMATIC("CAN_init: could not initialize MSP resources"); can_release(canHandle); } + + //PROBLEM: HAL_FDCAN_Init expects HAL_FDCAN_MspInit() to be defined + if (HAL_FDCAN_Init( canHandle->hal_fdcanP ) != HAL_OK) + { + LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); + return NULL; + //Error_Handler(); + } + + //Active FDCAN callbacks - rxcalback uses line0, txcallback uses line1 + //uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; + uint32_t status = 0; + uint32_t rx_events = FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL; + status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, rx_events, 0); + status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, rx_events, FDCAN_INTERRUPT_LINE0); + + //uint32_t txevents = FDCAN_IT_TX_COMPLETE; + uint32_t destinations = FDCAN_TX_BUFFER0; + uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; + status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, tx_events, destinations); + status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, tx_events, FDCAN_INTERRUPT_LINE1); + //Callbacks redefined later + + if (status & HAL_ERROR) { + LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); + return NULL; + } //Circular Buffer canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); @@ -146,49 +207,37 @@ CANHandle* can_init(const CANConfig *config) { canHandle->init = true; canHandle->started = false; + return canHandle; } +void FDCAN1_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } +void FDCAN1_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } -static int can_msp_init(CANHandle* canHandle, const CANConfig*config) { - //MSP Layers - //FDCAN Clock Init - __HAL_RCC_FDCAN_CLK_ENABLE(); +void FDCAN2_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } +void FDCAN2_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } + +void FDCAN3_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } +void FDCAN3_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } + +inline int can_set_clk_source(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } + + +//only valid for #STM32G474x, must redefine for each family +static int can_msp_init(CANHandle *canHandle, const CANConfig *config) { + //MSP Init ------- This could be inside HAL_FDCAN_MspInit() instead + //FDCAN Clock Select + + fdcan_enable_shared_clock(); //Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler //GPIOs init GPIOx_CLK_ENABLE(config->rx_gpio); GPIOx_CLK_ENABLE(config->tx_gpio); - HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio) ); - HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio) ); - - //FDCAN peripheral init - //This will not work, as I do not define HAL_MSP anywhere (usually created by CubeIDE) - //May have to manipulate the registers myself - if (HAL_FDCAN_Init( canHandle->hal_fdcanP ) != HAL_OK) - { - LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); - return -1; - //Error_Handler(); - } - - //Configure interrupts - //uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; - uint32 status = 0; - uint32 rx_events = FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL; - status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, rx_events, 0); - status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, rx_events, FDCAN_INTERRUPT_LINE0); - - //uint32_t txevents = FDCAN_IT_TX_COMPLETE; - uint32_t destinations = FDCAN_TX_BUFFER0; - uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; - status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, tx_events, destinations); - status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, tx_events, FDCAN_INTERRUPT_LINE1); - //Callbacks redefined later - //HAL_FDCAN_TxBufferCompleteCallback - //HAL_FDCAN_RxFifo0Callback + HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio)); + HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio)); - uint32_t rxit, txit; + IRQn_Type rxit, txit; can_get_irqs(canHandle->hal_fdcanP->Instance, &rxit, &txit); //rxfifo0 @@ -198,16 +247,19 @@ static int can_msp_init(CANHandle* canHandle, const CANConfig*config) { //tx HAL_NVIC_SetPriority(txit, config->tx_interrupt_priority,0); HAL_NVIC_EnableIRQ(txit); - - if (status & HAL_ERROR) { - LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); - return -1; - } + //End MSP Init -------------- return 0; } +void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcan) { return; } + //use can_msp_init() instead to initialize MSP before calling HAL_FDCAN_Init() + +void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcan) { return; } + //use can_msp_deinit() instead + +//valid only for STM32G4 static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1) @@ -231,14 +283,15 @@ static int can_get_irqs(FDCAN_GlobalTypeDef *instance, return -1; // invalid instance } +//valid only for STM32G4 static const char* can_get_instance_name(FDCAN_GlobalTypeDef *instance) { if (instance == FDCAN1) return "FDCAN1"; else if (instance == FDCAN2) return "FDCAN2"; else if (instance == FDCAN3) return "FDCAN3"; } +//valid only for STM32G4 static CANHandle* can_get_buffer_handle(FDCAN_HandleTypeDef * hfdcan) { - CANHandle* handle = 0; //#ifdef STM32G474xx if (hfdcan->Instance == FDCAN1) return &CAN1; @@ -250,14 +303,21 @@ static CANHandle* can_get_buffer_handle(FDCAN_HandleTypeDef * hfdcan) { } } -static int can_tx_buffer_helper(CANHandle* handle) { +static void can_tx_buffer_helper(CANHandle* handle) { while (HAL_FDCAN_GetTxFifoFreeLevel(handle->hal_fdcanP) && !GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { - FDCANMessage* msg = GR_CircularBuffer_Pop(handle->tx_buffer); + FDCANTxMessage* msg = GR_CircularBuffer_Pop(handle->tx_buffer); + + if (!msg) break; - HAL_FDCAN_AddMessageToTxFifoQ(handle->hal_fdcanP, &msg->tx_header, &msg->data ); + HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ(handle->hal_fdcanP, &msg->tx_header, msg->data ); - //not a good idea to free within an interrupt service routine - free(msg); + if (status != HAL_OK) { + LOGOMATIC("CAN_tx_helper: failed to add message to FIFO\n"); + free(msg); // Free the message we couldn't send + break; // Stop trying to send more + } + + free(msg); // Successfully sent, free the memory } } @@ -268,8 +328,7 @@ void HAL_FDCAN_TxBufferCompleteCallback( FDCAN_HandleTypeDef * hfdcan, uint32_t //#ifdef USECAN1 CANHandle* handle = can_get_buffer_handle(hfdcan); - if (!handle->tx_buffer) { - //LOGOMATIC("CAN: TX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); + if (!handle|| !handle->tx_buffer) { return; } @@ -281,6 +340,10 @@ void HAL_FDCAN_TxBufferCompleteCallback( FDCAN_HandleTypeDef * hfdcan, uint32_t void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs) { CANHandle * handle = can_get_buffer_handle(hfdcan); + if (!handle || !handle->init || !handle->rx_callback) { + return; + } + /*if (!handle->rx_buffer) { LOGOMATIC("CAN: RX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); return; @@ -292,13 +355,13 @@ void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs if ( !(RxFifo0ITs & ~FDCAN_IT_RX_FIFO0_MESSAGE_LOST)) return; - if (GR_CircularBuffer_IsFull(handle->tx_buffer)) return; + //if (GR_CircularBuffer_IsFull(handle->rx_buffer)) return; FDCAN_RxHeaderTypeDef rx_header; uint8_t rx_data[64] = {0}; while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) { - HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, rx_data); //stack allocation should be fine? Callback needs to terminate first before stack is popped //should switch this over to malloc at some point to avoid double copies? @@ -331,14 +394,14 @@ void can_read_rx_buffer(CANHandle* canHandle) { }*/ //Just alternatively just use the HAL_FDCAN_ConfigFilter directly with the canHandle->hal_fdcan -int can_add_filters(CANHandle* canHandle, FDCAN_FilterTypeDef *filter , size_t num){ +int can_add_filter(CANHandle* canHandle, FDCAN_FilterTypeDef *filter){ if (!canHandle) { - LOGOMATIC("CAN_add_filter: handle is null") + LOGOMATIC("CAN_add_filter: handle is null"); return -1; } if ( !(canHandle->init && canHandle->started) ) { - LOGOMATIC("CAN_add_filter: can instance is not started and initialized") + LOGOMATIC("CAN_add_filter: can instance is not started and initialized"); return -1; } @@ -350,8 +413,8 @@ int can_add_filters(CANHandle* canHandle, FDCAN_FilterTypeDef *filter , size_t n //check that # of filters isn't exceeding max value } +//Need to int can_start(CANHandle * canHandle) { - //Start the HAL function if (!canHandle || !canHandle->init) return -1; GPIOx_CLK_ENABLE(canHandle->rx_gpio); @@ -364,8 +427,8 @@ int can_start(CANHandle * canHandle) { } int can_stop(CANHandle * canHandle) { - //Add stopped state? - if (!canHandle) return -1; + if (!canHandle || !canHandle->init) return -1; + if (!canHandle->started) return 0; HAL_FDCAN_Stop(canHandle->hal_fdcanP); @@ -377,55 +440,141 @@ int can_stop(CANHandle * canHandle) { return 0; } +//Valid only for STM32G474xE +int can_msp_deinit(CANHandle* canHandle) { + //MSP DeInit + //turn off gpio clocks + GPIOx_CLK_DISABLE(canHandle->rx_gpio); + GPIOx_CLK_DISABLE(canHandle->tx_gpio); + + //turn off NVIC resources + IRQn_Type rx0it, txit; + can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); + HAL_NVIC_DisableIRQ(rx0it); + HAL_NVIC_DisableIRQ(txit); + + return 0; +} + + +//TODO: Make this less confusing to look +static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) +{ + // Enter INIT mode + hfdcan->Instance->CCCR |= FDCAN_CCCR_INIT; + while (!(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT)); + + // Clear filters + memset((void *) hfdcan->msgRam.StandardFilterSA, 0, 0x0070); + memset((void *) hfdcan->msgRam.ExtendedFilterSA, 0, 0x0050); + + // Optionally reset FIFOs / buffers + + // Disable interrupts + __HAL_FDCAN_DISABLE_IT(hfdcan, + FDCAN_IT_LIST_RX_FIFO0 | FDCAN_IT_LIST_RX_FIFO1 | + FDCAN_IT_LIST_SMSG | FDCAN_IT_LIST_TX_FIFO_ERROR | + FDCAN_IT_LIST_MISC | FDCAN_IT_LIST_BIT_LINE_ERROR | + FDCAN_IT_LIST_PROTOCOL_ERROR + ); + + + + // Exit INIT mode + hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT; + while (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT); + + // Update handle state + hfdcan->State = HAL_FDCAN_STATE_RESET; +} + int can_release(CANHandle * canHandle) { if (!canHandle) { LOGOMATIC("CAN: Tried to release a null handle"); return -1; } - + if (!canHandle->init) { LOGOMATIC("CAN_release: can instance is already deinitialized"); return -1; } + can_stop(canHandle); //try to prevent more interrupts from firing + + //must disable NVIC IRQs before freeing circular buffer + can_msp_deinit(canHandle); + + //reset FDCANx instance and message RAM and filters, clear interrupts + //HAL_FDCAN_DeInit(canHandle->hal_fdcanP); resets a little too hard + FDCAN_InstanceDeInit(canHandle->hal_fdcanP); + + __DSB(); // Data Synchronization Barrier + __ISB(); // Instruction Synchronization Barrier //free circular buffer contents GR_CircularBuffer_Free(&(canHandle->tx_buffer)); - //turn off gpio clocks - GPIOx_CLK_DISABLE(canHandle->rx_gpio); - GPIOx_CLK_DISABLE(canHandle->tx_gpio); - - //clear filters and reset other parameters - HAL_FDCAN_DeInit(canHandle->hal_fdcanP); - + //reset can instance FDCAN_HandleTypeDef * temp = canHandle->hal_fdcanP; memset(canHandle, 0, sizeof(*canHandle)); canHandle->hal_fdcanP = temp; - //turn off fdcan clock if no other FDCAN instances are running - if (!CAN1.tx_buffer && !CAN2.tx_buffer && !CAN3.tx_buffer) __HAL_RCC_FDCAN_CLK_DISABLE(); + fdcan_disable_shared_clock(); //only turns off clock if no other instances are running. return 0; } -int can_send(CANHandle* canHandle, FDCANMessage* message) { - if (!message) { LOGOMATIC("CAN_send: received null pointer\n"); return -1; } +int can_send(CANHandle* canHandle, FDCANTxMessage* message) { + if (!canHandle || !message) { + LOGOMATIC("CAN_send: received null pointer\n"); + return -1; + } - #if (data_size > FDCAN_MAX_DATA_BYTES) { LOGOMATIC("CAN_send: cannot send more than %d data bytes\n",FDCAN_MAX_DATA_BYTES); return -1;} + if (!canHandle->init || !canHandle->started) { + LOGOMATIC("CAN_send: CAN not initialized or started\n"); + return -1; + } + uint32_t primask = __get_PRIMASK(); + __disable_irq(); //IF TX Fifos are not full, send directly to them //If TX Fifos are full, append to circular buffer //If circular buffer is full, return an error code - if (HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP)) { - HAL_FDCAN_AddMessageToTxFifoQ(canHandle->hal_fdcanP, &(message->tx_header), &(message->data)); - } else if (!GR_CircularBuffer_IsFull(canHandle->tx_buffer)) { + if (HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP) > 0) { + HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ( + canHandle->hal_fdcanP, + &(message->tx_header), + message->data // Not &message->data if data is array + ); - GR_CircularBuffer_Push(canHandle->tx_buffer, message, sizeof(FDCANMessage)); - } else { - LOGOMATIC("CAN_send: tx_buffer is full\n"); - return -1; + __set_PRIMASK(primask); + + if (status != HAL_OK) { + LOGOMATIC("CAN_send: failed to add to HW FIFO\n"); + return -1; + } + return 0; } - return 0; + // Hardware FIFO full, try software buffer + if (!GR_CircularBuffer_IsFull(canHandle->tx_buffer)) { + int result = GR_CircularBuffer_Push( + canHandle->tx_buffer, + message, + sizeof(FDCANTxMessage) + ); + + __set_PRIMASK(primask); + + if (result != 0) { + LOGOMATIC("CAN_send: buffer push failed\n"); + return -1; + } + return 0; + } + + // Both buffers full + __set_PRIMASK(primask); + LOGOMATIC("CAN_send: all buffers full\n"); + return -1; } diff --git a/Lib/Peripherals/CAN/Test/readme.md b/Lib/Peripherals/CAN/Test/readme.md index 34dc581f..aba2e133 100644 --- a/Lib/Peripherals/CAN/Test/readme.md +++ b/Lib/Peripherals/CAN/Test/readme.md @@ -10,11 +10,12 @@ after releasing: - State of GPIOx ports registers are back to reset. - turn off RCC clock if there are no other FDCAN peripherals. +- can_send_helper, free a circular buffer +- discuss freeing within ISR, how to avoid. -- State of circular buffer inside - -- can_send_helper, free a circular buffer +- Critical Section when releasing: +- -- discuss freeing within ISR, how to avoid. \ No newline at end of file +- Add MACRO support to detect if FDCAN is a supported peripheral on the defined STM32 family \ No newline at end of file diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake index 1d869bb3..5b63c033 100644 --- a/Lib/Peripherals/CAN/common.cmake +++ b/Lib/Peripherals/CAN/common.cmake @@ -1,16 +1,16 @@ add_library(PERIPHERAL_CAN_LIB INTERFACE) -target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/can.c) - target_link_libraries( PERIPHERAL_CAN_LIB INTERFACE CircularBuffer_Lib ) +target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/can.c) + # Make headers accessible as #include "Peripherals/CAN/can.h" target_include_directories( PERIPHERAL_CAN_LIB INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/Inc/ + ${CMAKE_CURRENT_LIST_DIR}/Inc ) # link test to this library @@ -28,4 +28,4 @@ if(CMAKE_BUILD_TYPE STREQUAL "Test") PERIPHERAL_CAN_LIB_init PERIPHERAL_CAN_LIB_init_test ) -endif() +endif() \ No newline at end of file From 1811a54b70b424b8dfd9394579f438cc80ec3b92 Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Sat, 10 Jan 2026 13:55:23 -0800 Subject: [PATCH 05/18] RX callback is entered after sending TX message, using internal CAN loopback --- G4PERTESTING/CMakeLists.txt | 4 +- G4PERTESTING/Core/Src/main.c | 80 ++----------- Lib/Peripherals/CAN/Inc/can.h | 34 +++--- Lib/Peripherals/CAN/Inc/can_platform_deps.h | 11 +- Lib/Peripherals/CAN/README.md | 47 +++++++- Lib/Peripherals/CAN/Src/can.c | 48 ++++---- Lib/Peripherals/CAN/Test/can_test_init.c | 6 - Lib/Peripherals/CAN/Test/can_tests.c | 120 ++++++++++++++++++++ Lib/Peripherals/CAN/Test/can_tests.h | 19 ++++ Lib/Peripherals/CAN/additional_features.md | 14 --- Lib/Peripherals/CAN/common.cmake | 39 ++++--- 11 files changed, 267 insertions(+), 155 deletions(-) delete mode 100644 Lib/Peripherals/CAN/Test/can_test_init.c create mode 100644 Lib/Peripherals/CAN/Test/can_tests.c create mode 100644 Lib/Peripherals/CAN/Test/can_tests.h delete mode 100644 Lib/Peripherals/CAN/additional_features.md diff --git a/G4PERTESTING/CMakeLists.txt b/G4PERTESTING/CMakeLists.txt index 52ceee74..5f2a4524 100644 --- a/G4PERTESTING/CMakeLists.txt +++ b/G4PERTESTING/CMakeLists.txt @@ -48,5 +48,7 @@ target_sources( ) target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_LIB) +target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_TEST_LIB) -target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) + +target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) \ No newline at end of file diff --git a/G4PERTESTING/Core/Src/main.c b/G4PERTESTING/Core/Src/main.c index 92969307..7fa6ad6d 100644 --- a/G4PERTESTING/Core/Src/main.c +++ b/G4PERTESTING/Core/Src/main.c @@ -28,6 +28,7 @@ #include "usart.h" #include "can.h" // Assume this works +#include "can_tests.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -68,7 +69,6 @@ void DEBUG_callback (void* data, uint32_t size) { toggleze = (*((char*) data) & 0x80); } - /* USER CODE END 0 */ /** @@ -77,7 +77,6 @@ void DEBUG_callback (void* data, uint32_t size) { */ int main(void) { - /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ @@ -88,7 +87,6 @@ int main(void) /* Reset of all peripherals, Initializes the Flash interface and the * Systick. */ HAL_Init(); - /* USER CODE BEGIN Init */ /* USER CODE END Init */ @@ -111,83 +109,23 @@ int main(void) MX_SPI3_Init(); MX_TIM2_Init(); - /* USER CODE BEGIN 2 */ - CANConfig canCfg; - - canCfg.fdcan_instance = FDCAN2; - - canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; - canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_CLASSIC; - canCfg.hal_fdcan_init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; - canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; - canCfg.hal_fdcan_init.TransmitPause = DISABLE; - canCfg.hal_fdcan_init.ProtocolException = ENABLE; - canCfg.hal_fdcan_init.NominalPrescaler = 1; - canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; - canCfg.hal_fdcan_init.NominalTimeSeg1 = 119; - canCfg.hal_fdcan_init.NominalTimeSeg2 = 40; - canCfg.hal_fdcan_init.DataPrescaler = 8; - canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; - canCfg.hal_fdcan_init.DataTimeSeg1 = 14; - canCfg.hal_fdcan_init.DataTimeSeg2 = 5; - canCfg.hal_fdcan_init.StdFiltersNbr = 0; - canCfg.hal_fdcan_init.ExtFiltersNbr = 2; - - canCfg.rx_callback = NULL; // PLEASE SET - canCfg.rx_interrupt_priority = 0; // PLEASE SET - canCfg.tx_interrupt_priority = 0; // PLEASE SET - canCfg.tx_buffer_length = 20; // PLEASE SET - - canCfg.rx_gpio = GPIOB; - - canCfg.init_rx_gpio.Pin = GPIO_PIN_12; - canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; - canCfg.init_rx_gpio.Pull = GPIO_PULLUP; - canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; - - canCfg.tx_gpio = GPIOB; - - canCfg.init_tx_gpio.Pin = GPIO_PIN_13; - canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; - canCfg.init_tx_gpio.Pull = GPIO_NOPULL; - canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; - - CANHandle *can2Handle = can_init(&canCfg); - - FDCAN_FilterTypeDef filter; - can_add_filter(can2Handle, &filter); - can_start(can2Handle); - /* USER CODE END 2 */ - - FDCAN_TxHeaderTypeDef TxHeader = { - .IdType = FDCAN_EXTENDED_ID, - .TxFrameType = FDCAN_DATA_FRAME, - .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node - // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors - .BitRateSwitch = FDCAN_BRS_OFF, - .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages - .MessageMarker = 0 // also change this to a real address if you change fifo control - }; - - FDCANTxMessage msg; - msg.data[0] = 0x80; - msg.tx_header = TxHeader; + + can_test(); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ - // INDICTIY - HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET : GPIO_PIN_RESET); - HAL_Delay(1000); - msg.data[0] = toggleze ? 0x00 : 0x80; - can_send(can2Handle, &msg); + // Receive on GPIOs + //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET : GPIO_PIN_RESET); + //HAL_Delay(1000); + //msg.data[0] = toggleze ? 0x00 : 0x80; + //can_send(can2Handle, &msg); + //RCC->CFGR |= RCC_CFGR_SW; /* USER CODE BEGIN 3 */ } } diff --git a/Lib/Peripherals/CAN/Inc/can.h b/Lib/Peripherals/CAN/Inc/can.h index b365627b..194b8cc1 100644 --- a/Lib/Peripherals/CAN/Inc/can.h +++ b/Lib/Peripherals/CAN/Inc/can.h @@ -1,13 +1,24 @@ +#ifndef CAN_H +#define CAN_H + +//Supported STM32 Families +#ifdef STM32G4 +#elif defined(STM32L4) +#elif defined(STM32U5) +#error "Unsupported STM32 Family" +#endif + + + #include "can_platform_deps.h" #include "circularBuffer.h" -//Must perform a deep copy of the data +//RX Callback must perform a deep copy of the data +// typedef void (*CAN_RXCallback) (void* data, uint32_t size); - typedef struct { //can baud rate is set by fdcan prescaler and RCC clock configurations - FDCAN_GlobalTypeDef *fdcan_instance; //Base address of FDCAN peripheral in memory (FDCAN1, FDCAN2, FDCAN3 macros) FDCAN_InitTypeDef hal_fdcan_init; @@ -45,7 +56,6 @@ typedef struct { bool init; bool started; - //error states } CANHandle; @@ -67,19 +77,11 @@ int can_send(CANHandle*handle, FDCANTxMessage* buffer); int can_release(CANHandle* handle); //deinit circular buffer and turn off can peripheral and gpios int can_add_filter(CANHandle* handle, FDCAN_FilterTypeDef * filter); //alternatively use -//HAL_FDCAN_ConfigGlobalFilter() +//HAL_FDCAN_ConfigGlobalFilter() //important to accept nonmatching frames into //HAL_FDCAN_ConfigFilter() -//doesn't need a handle, independent of any CAN instance -int can_set_clksource(uint32_t clksource); //LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE - - - - -//tx callback should free memory of sending buffer -//block until enqueued on circular buffer -//void can_(); //enqueue onto circular -//remember to free all data in the circular buffer - +//doesn't need a handle, CAN cores share peripheral clock +int can_set_clksource(uint32_t clksource); //ex. LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE +#endif //End Header Guard diff --git a/Lib/Peripherals/CAN/Inc/can_platform_deps.h b/Lib/Peripherals/CAN/Inc/can_platform_deps.h index ad0fe5e7..885b6559 100644 --- a/Lib/Peripherals/CAN/Inc/can_platform_deps.h +++ b/Lib/Peripherals/CAN/Inc/can_platform_deps.h @@ -1,8 +1,8 @@ +#ifndef CAN_PLATFORM_DEPS_H +#define CAN_PLATFORM_DEPS_H -#define STM32G474xx -#ifdef STM32L476xx -#elif defined(STM32G474xx) +#if defined(STM32G4) #include "stm32g4xx_hal.h" #include "stm32g4xx_hal_gpio.h" #include "stm32g4xx_hal_gpio_ex.h" @@ -10,8 +10,11 @@ #include "stm32g4xx_hal_rcc.h" #include "stm32g4xx_ll_rcc.h" #include "stm32g4xx_ll_gpio.h" -#elif defined(STM32U5A9xx) +//#elif defined(STM32L4) +//#elif defined(STM32U5) #else #error "Unsupported STM32 family" #endif + +#endif //end header guard diff --git a/Lib/Peripherals/CAN/README.md b/Lib/Peripherals/CAN/README.md index 1e593912..f643b044 100644 --- a/Lib/Peripherals/CAN/README.md +++ b/Lib/Peripherals/CAN/README.md @@ -11,10 +11,13 @@ int can_release(CANHandle* handle); //deinit circular buffer and turn off can pe int can_add_filter(CANHandle* handle, HAL_FDCAN_FilterTypeDef * filter); int can_add_global_filter(CANHandle* handle, HAL_FDCAN_FilterTypeDef* filter); -//alternatively instead use the HAL libraries -//HAL_FDCAN_ConfigGlobalFilter(canHandle->hal_fdcanP, filterTypeDef) +//alternatively instead use the HAL filter functions +//HAL_FDCAN_ConfigGlobalFilter(canHandle->hal_fdcanP, filterTypeDef) //HAL_FDCAN_ConfigFilter(ca) +If no filters are set, the default behaviour is to accept all standard and extended frames into the RXFIFO0 + + @@ -27,7 +30,17 @@ Verify ISR safety, no race conditions, atomic read/writes - can_release - Freeing within ISRs whenever popping from CircularBuffer (yes its faster, than stack copies, but heap is getting fragmented) - ISRS might take too long to resolve because popping and freeing circular buffer. -: + +- HARDCODE Platform Usage Flag for compiler definitions +- CAN.H expects #STM32G4 to be defined, + + +- RX Callback must perform deep copy of data supplied to it - could also malloc, but not safe to do inside ISRs +- + + +-Shouldn't disable GPIOs in the MSP layers when releasing, might affect other peripherals + IDEAS for other features: - abstract to different STM families besides STM32G4 @@ -38,7 +51,33 @@ IDEAS for other features: - TX FIFO vs Queue policy (only allow FIFOS) - Add support for RXFifo1 -lot of work: + +TESTING- ---------------------------------------------- +USE LOGOMATIC for return status - +either returns through semihosting or debug cores +LOGOMATIC is defined platform by platform + +Testing framework +- Can operate on API states and behaviours, but API should work across platforms +- All API tests are defined in can_test.c +- All tests are run from the top level function in can_test.c + +- can_test.c should initialize everything properly. +- May have to create platform specific asserts when testing state +- use LOGOMATIC to return errors or throw asserts + +- Platform testing, such as in G4PERTESTING just needs include "can_test.h" and call top level function +in main. + +Two approaches: +Platform centric +- In G4PERTesting, include "can_tests.h" and call the top level function in can_test.c +- This approach is better because we can abstract the logging and debug method + +Library Centric Testing: +- Test the implementation in each library. + +HAL_Rewrite: - Alternatively, rewrite without using HAL, just use CMSIS definitions. - PROS: Would look good on your Github. - CONS: Wouldn't help \ No newline at end of file diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 1acb39d7..06b8ae7e 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -5,8 +5,6 @@ #include #include -//#ifdef STM32G474xx - //HAL handles //#ifdef USECAN1 static FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; @@ -210,14 +208,6 @@ CANHandle* can_init(const CANConfig *config) { return canHandle; } -void FDCAN1_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } -void FDCAN1_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } - -void FDCAN2_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } -void FDCAN2_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } - -void FDCAN3_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } -void FDCAN3_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } inline int can_set_clk_source(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } @@ -321,6 +311,15 @@ static void can_tx_buffer_helper(CANHandle* handle) { } } +void FDCAN1_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } +void FDCAN1_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } + +void FDCAN2_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } +void FDCAN2_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } + +void FDCAN3_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } +void FDCAN3_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } + void HAL_FDCAN_TxBufferCompleteCallback( FDCAN_HandleTypeDef * hfdcan, uint32_t BufferIndexes ) { //If circular buffer has elements, send to queue @@ -441,23 +440,14 @@ int can_stop(CANHandle * canHandle) { } //Valid only for STM32G474xE -int can_msp_deinit(CANHandle* canHandle) { +/*int can_msp_deinit(CANHandle* canHandle) { //MSP DeInit - //turn off gpio clocks - GPIOx_CLK_DISABLE(canHandle->rx_gpio); - GPIOx_CLK_DISABLE(canHandle->tx_gpio); + //turn off gpio clocks - can only turn off GPIOs if no other instances are using them - //turn off NVIC resources - IRQn_Type rx0it, txit; - can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); - HAL_NVIC_DisableIRQ(rx0it); - HAL_NVIC_DisableIRQ(txit); return 0; -} - +}*/ -//TODO: Make this less confusing to look static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) { // Enter INIT mode @@ -465,6 +455,7 @@ static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) while (!(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT)); // Clear filters + //TODO: fix magic numbers memset((void *) hfdcan->msgRam.StandardFilterSA, 0, 0x0070); memset((void *) hfdcan->msgRam.ExtendedFilterSA, 0, 0x0050); @@ -478,8 +469,6 @@ static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) FDCAN_IT_LIST_PROTOCOL_ERROR ); - - // Exit INIT mode hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT; while (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT); @@ -501,7 +490,16 @@ int can_release(CANHandle * canHandle) { can_stop(canHandle); //try to prevent more interrupts from firing //must disable NVIC IRQs before freeing circular buffer - can_msp_deinit(canHandle); + + //turn off NVIC resources + IRQn_Type rx0it, txit; + can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); + HAL_NVIC_DisableIRQ(rx0it); + HAL_NVIC_DisableIRQ(txit); + + //need to check if other pins are using before disabling - do this after mvp + //GPIOx_CLK_DISABLE(canHandle->rx_gpio); + //GPIOx_CLK_DISABLE(canHandle->tx_gpio); //reset FDCANx instance and message RAM and filters, clear interrupts //HAL_FDCAN_DeInit(canHandle->hal_fdcanP); resets a little too hard diff --git a/Lib/Peripherals/CAN/Test/can_test_init.c b/Lib/Peripherals/CAN/Test/can_test_init.c deleted file mode 100644 index 75edb193..00000000 --- a/Lib/Peripherals/CAN/Test/can_test_init.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "can.h" - - -int main() { - -} \ No newline at end of file diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c new file mode 100644 index 00000000..e612b87d --- /dev/null +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -0,0 +1,120 @@ +#include "can_tests.h" +#include "can.h" + +//each family has a constant number of CAN peripherals + + +int can_test_instance(FDCAN_HandleTypeDef) { + + return 0; +} + +void can_test_rx_callback(void*data, uint32_t size) { + //Is within an ISR, so needs to exit quickly + return; +} + +int can_test(void) { + + CANConfig canCfg; + //canCfg.fdcan_instance = FDCAN2; + + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; + canCfg.hal_fdcan_init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; + canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; + canCfg.hal_fdcan_init.TransmitPause = DISABLE; + canCfg.hal_fdcan_init.ProtocolException = ENABLE; + canCfg.hal_fdcan_init.NominalPrescaler = 1; + canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; + canCfg.hal_fdcan_init.NominalTimeSeg1 = 119; + canCfg.hal_fdcan_init.NominalTimeSeg2 = 40; + canCfg.hal_fdcan_init.DataPrescaler = 8; + canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; + canCfg.hal_fdcan_init.DataTimeSeg1 = 14; + canCfg.hal_fdcan_init.DataTimeSeg2 = 5; + canCfg.hal_fdcan_init.StdFiltersNbr = 1; + canCfg.hal_fdcan_init.ExtFiltersNbr = 0; + + canCfg.rx_callback = can_test_rx_callback; // PLEASE SET + canCfg.rx_interrupt_priority = 0; // PLEASE SET + canCfg.tx_interrupt_priority = 0; // PLEASE SET + canCfg.tx_buffer_length = 20; // PLEASE SET + + //canCfg.rx_gpio = GPIOB; + //canCfg.init_rx_gpio.Pin = GPIO_PIN_12; + canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_rx_gpio.Pull = GPIO_PULLUP; + canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + //canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + //canCfg.tx_gpio = GPIOB; + //canCfg.init_tx_gpio.Pin = GPIO_PIN_13; + canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_tx_gpio.Pull = GPIO_NOPULL; + canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + //canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + + + //Not testing filters at the moment + //FDCAN_FilterTypeDef filter; + + //can_add_filter(can2Handle, &filter); + /* USER CODE END 2 */ + + FDCAN_TxHeaderTypeDef TxHeader = { + .IdType = FDCAN_STANDARD_ID, + .TxFrameType = FDCAN_DATA_FRAME, + .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node + // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors + .BitRateSwitch = FDCAN_BRS_OFF, + .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages + .MessageMarker = 0 // also change this to a real address if you change fifo control + }; + + FDCANTxMessage msg; + msg.data[0] = 0x80; + msg.tx_header = TxHeader; + + + #ifdef FDCAN1 + + #endif + #ifdef FDCAN2 + + + canCfg.fdcan_instance = FDCAN2; + canCfg.rx_gpio = GPIOB; + canCfg.init_rx_gpio.Pin = GPIO_PIN_12; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + canCfg.tx_gpio = GPIOB; + canCfg.init_tx_gpio.Pin = GPIO_PIN_13; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + + CANHandle *can2Handle = can_init(&canCfg); + + //accept unmatched standard and extended frames into RXFIFO0 - default behaviour + HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, FDCAN_ACCEPT_IN_RX_FIFO0, 0, 0,0); + + //not accepting filters + //can_add_filter(can2Handle, &filter); + + //API Testing + can_init(&canCfg); + + can_start(can2Handle); + + can_send(can2Handle, &msg); + //can_release(can2Handle); + + #endif + #ifdef FDCAN3 + + #endif + + + return 0; + +} + diff --git a/Lib/Peripherals/CAN/Test/can_tests.h b/Lib/Peripherals/CAN/Test/can_tests.h new file mode 100644 index 00000000..052c27ce --- /dev/null +++ b/Lib/Peripherals/CAN/Test/can_tests.h @@ -0,0 +1,19 @@ +#ifndef CAN_TESTS_H +#define CAN_TESTS_H + +#include "can.h" +#include "can_platform_deps.h" +#include "Logomatic.h" + +//Tested STM32 Families +#ifdef STM32G4 +//#elif defined(STM32L4) +//#elif defined(STM32U5) +#else +#error "Untested STM32 Family" +#endif + +//Assume the LOGOMATIC is setup correctly +int can_test(void); //top-level function, just call this and check if the return status is correct + +#endif \ No newline at end of file diff --git a/Lib/Peripherals/CAN/additional_features.md b/Lib/Peripherals/CAN/additional_features.md deleted file mode 100644 index 1cc65a48..00000000 --- a/Lib/Peripherals/CAN/additional_features.md +++ /dev/null @@ -1,14 +0,0 @@ - - -- TX buffering policy, do we spread them out over multiple TX buffers -- - - -- Redefining interrupt handlers: -- FIFO vs Queue policy -- Add support for RXFifo1 -- can_read_rx_buffer, linked to RXFifo0 callback - -- Allow circular buffer of size 0 - right now, whether circular buffer is allocated is used to test whether CAN1 instance is running - -- Smaller can headers for tx (right now its just use the TXHeaderTypeDef) \ No newline at end of file diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake index 5b63c033..a7f8fd2a 100644 --- a/Lib/Peripherals/CAN/common.cmake +++ b/Lib/Peripherals/CAN/common.cmake @@ -6,6 +6,7 @@ target_link_libraries( target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/can.c) + # Make headers accessible as #include "Peripherals/CAN/can.h" target_include_directories( PERIPHERAL_CAN_LIB @@ -13,19 +14,29 @@ target_include_directories( ${CMAKE_CURRENT_LIST_DIR}/Inc ) + +#tests +add_library(PERIPHERAL_CAN_TEST_LIB INTERFACE) +target_sources(PERIPHERAL_CAN_TEST_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Test/can_tests.c) +target_include_directories( + PERIPHERAL_CAN_TEST_LIB + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/Test +) + # link test to this library -if(CMAKE_BUILD_TYPE STREQUAL "Test") +#if(CMAKE_BUILD_TYPE STREQUAL "Test") # Initialization - add_executable( - PERIPHERAL_CAN_LIB_init_test - ${CMAKE_CURRENT_LIST_DIR}/Test/can_test_init.c - ) - target_link_libraries( - PERIPHERAL_CAN_LIB_init_test - PERIPHERAL_CAN_LIB - ) - add_test( - PERIPHERAL_CAN_LIB_init - PERIPHERAL_CAN_LIB_init_test - ) -endif() \ No newline at end of file +# add_executable( +# PERIPHERAL_CAN_LIB_init_test +# ${CMAKE_CURRENT_LIST_DIR}/Test/can_test_init.c +# ) +# target_link_libraries( +# PERIPHERAL_CAN_LIB_init_test +# PERIPHERAL_CAN_LIB +# ) +# add_test( +# PERIPHERAL_CAN_LIB_init +# PERIPHERAL_CAN_LIB_init_test +# ) +#endif() \ No newline at end of file From 6ed53d0835de433f9da3b6a48d1c0b9b5b06e832 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Sun, 11 Jan 2026 23:32:58 -0800 Subject: [PATCH 06/18] Setup `G4PERTESTING` to have successful `LOGOMATIC` operations --- .vscode/launch.json | 17 +++++++++++++- .vscode/tasks.json | 9 ++++++++ G4PERTESTING/CMakeLists.txt | 2 +- G4PERTESTING/Core/Src/main.c | 45 ++++++++++++++++++++++-------------- 4 files changed, 54 insertions(+), 19 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ae080cf8..80838b74 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -157,7 +157,22 @@ "searchDir": [], "preLaunchTask": "CMake: configure and build G4PERTESTING", "showDevDebugOutput": "raw", - "svdPath": "${workspaceFolder}/Lib/Platform/STM32G474xE/CompileDependencies/STM32G474.svd" + "svdPath": "${workspaceFolder}/Lib/Platform/STM32G474xE/CompileDependencies/STM32G474.svd", + "swoConfig": { + "enabled": true, + "cpuFrequency": 170000000, + "swoFrequency": 2000000, + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "showOnStartup": true, + "port": 0, + "encoding": "ascii" + } + ] + } } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9e2423cc..7d069fb4 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -18,6 +18,15 @@ ], "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target ECU" }, + { + "label": "CMake: configure and build G4PERTESTING", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure" + ], + "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4PERTESTING" + }, { "label": "CMake: configure and build G4HELLO", "type": "shell", diff --git a/G4PERTESTING/CMakeLists.txt b/G4PERTESTING/CMakeLists.txt index 5f2a4524..0f9f978c 100644 --- a/G4PERTESTING/CMakeLists.txt +++ b/G4PERTESTING/CMakeLists.txt @@ -51,4 +51,4 @@ target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_LIB) target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_TEST_LIB) -target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) \ No newline at end of file +target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) diff --git a/G4PERTESTING/Core/Src/main.c b/G4PERTESTING/Core/Src/main.c index 7fa6ad6d..6072c968 100644 --- a/G4PERTESTING/Core/Src/main.c +++ b/G4PERTESTING/Core/Src/main.c @@ -32,7 +32,7 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ - +#include "Logomatic.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -63,10 +63,22 @@ void SystemClock_Config(void); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ -static int toggleze = 0; +/* Enable ITM for SWO output */ +static void ITM_Enable(void) +{ + /* Enable TRC (Trace) */ + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; -void DEBUG_callback (void* data, uint32_t size) { - toggleze = (*((char*) data) & 0x80); + /* Enable stimulus port 0 */ + ITM->TER |= (1UL << 0); + + /* Set trace control register */ + ITM->TCR |= ITM_TCR_ITMENA_Msk; +} +static int toggleze = 0; +void DEBUG_callback(void *data, uint32_t size) +{ + toggleze = (*((char *)data) & 0x80); } /* USER CODE END 0 */ @@ -88,7 +100,7 @@ int main(void) * Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ - + ITM_Enable(); /* USER CODE END Init */ /* Configure the system clock */ @@ -111,7 +123,7 @@ int main(void) /* USER CODE BEGIN 2 */ - + LOGOMATIC("Booted!\n"); can_test(); /* Infinite loop */ @@ -120,12 +132,11 @@ int main(void) /* USER CODE END WHILE */ // Receive on GPIOs - //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET : GPIO_PIN_RESET); - //HAL_Delay(1000); - //msg.data[0] = toggleze ? 0x00 : 0x80; - //can_send(can2Handle, &msg); + // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET + // : GPIO_PIN_RESET); HAL_Delay(1000); msg.data[0] = toggleze ? + // 0x00 : 0x80; can_send(can2Handle, &msg); - //RCC->CFGR |= RCC_CFGR_SW; + // RCC->CFGR |= RCC_CFGR_SW; /* USER CODE BEGIN 3 */ } } @@ -140,13 +151,13 @@ void SystemClock_Config(void) while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { } LL_PWR_EnableRange1BoostMode(); - LL_RCC_HSE_Enable(); - /* Wait till HSE is ready */ - while (LL_RCC_HSE_IsReady() != 1) { + LL_RCC_HSI_Enable(); + /* Wait till HSI is ready */ + while (LL_RCC_HSI_IsReady() != 1) { } - LL_RCC_HSE_EnableCSS(); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, + LL_RCC_HSI_SetCalibTrimming(64); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, LL_RCC_PLLR_DIV_2); LL_RCC_PLL_EnableDomain_SYS(); LL_RCC_PLL_Enable(); @@ -168,7 +179,7 @@ void SystemClock_Config(void) LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - LL_SetSystemCoreClock(160000000); + LL_SetSystemCoreClock(170000000); /* Update the time base */ if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { From 97afbc054b635b824841b9cfac78cceac386cc27 Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Mon, 12 Jan 2026 10:11:38 -0800 Subject: [PATCH 07/18] Add `canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;` to `can_tests.c` --- Lib/Peripherals/CAN/Test/can_tests.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index e612b87d..38ddce7c 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -22,6 +22,7 @@ int can_test(void) { canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; canCfg.hal_fdcan_init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; + canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; canCfg.hal_fdcan_init.TransmitPause = DISABLE; canCfg.hal_fdcan_init.ProtocolException = ENABLE; From 984649af1772cf31a8142a7d8882b87182cbfda6 Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Mon, 12 Jan 2026 21:17:04 -0800 Subject: [PATCH 08/18] FDCAN on PCLK1 --- G4PERTESTING/Core/Src/main.c | 55 +++++++++++++++++++++++++--- Lib/Peripherals/CAN/Src/can.c | 2 +- Lib/Peripherals/CAN/Test/can_tests.c | 6 ++- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/G4PERTESTING/Core/Src/main.c b/G4PERTESTING/Core/Src/main.c index 6072c968..850ff34f 100644 --- a/G4PERTESTING/Core/Src/main.c +++ b/G4PERTESTING/Core/Src/main.c @@ -151,14 +151,16 @@ void SystemClock_Config(void) while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { } LL_PWR_EnableRange1BoostMode(); - LL_RCC_HSI_Enable(); - /* Wait till HSI is ready */ - while (LL_RCC_HSI_IsReady() != 1) { + LL_RCC_HSE_Enable(); + + /* Wait till HSE is ready */ + while (LL_RCC_HSE_IsReady() != 1) { } - LL_RCC_HSI_SetCalibTrimming(64); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, + LL_RCC_HSE_EnableCSS(); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, LL_RCC_PLLR_DIV_2); + //LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, ); LL_RCC_PLL_EnableDomain_SYS(); LL_RCC_PLL_Enable(); /* Wait till PLL is ready */ @@ -179,13 +181,54 @@ void SystemClock_Config(void) LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - LL_SetSystemCoreClock(170000000); + LL_SetSystemCoreClock(160000000); /* Update the time base */ if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { Error_Handler(); } } +// void SystemClock_Config(void) +// { +// LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); +// while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { +// } +// LL_PWR_EnableRange1BoostMode(); +// LL_RCC_HSI_Enable(); +// /* Wait till HSI is ready */ +// while (LL_RCC_HSI_IsReady() != 1) { +// } + +// LL_RCC_HSI_SetCalibTrimming(64); +// LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, +// LL_RCC_PLLR_DIV_2); +// LL_RCC_PLL_EnableDomain_SYS(); +// LL_RCC_PLL_Enable(); +// /* Wait till PLL is ready */ +// while (LL_RCC_PLL_IsReady() != 1) { +// } + +// LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); +// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); +// /* Wait till System clock is ready */ +// while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { +// } + +// /* Insure 1us transition state at intermediate medium speed clock*/ +// for (__IO uint32_t i = (170 >> 1); i != 0; i--) +// ; + +// /* Set AHB prescaler*/ +// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); +// LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); +// LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); +// LL_SetSystemCoreClock(170000000); + +// /* Update the time base */ +// if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { +// Error_Handler(); +// } +// } /* USER CODE BEGIN 4 */ diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 06b8ae7e..24d59521 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -209,7 +209,7 @@ CANHandle* can_init(const CANConfig *config) { return canHandle; } -inline int can_set_clk_source(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } +inline int can_set_clksource(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } //only valid for #STM32G474x, must redefine for each family diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index 38ddce7c..6ca270db 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -11,7 +11,7 @@ int can_test_instance(FDCAN_HandleTypeDef) { void can_test_rx_callback(void*data, uint32_t size) { //Is within an ISR, so needs to exit quickly - return; + return;// } int can_test(void) { @@ -21,6 +21,7 @@ int can_test(void) { canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; + canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; canCfg.hal_fdcan_init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; @@ -68,6 +69,7 @@ int can_test(void) { .TxFrameType = FDCAN_DATA_FRAME, .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors + .DataLength = 1, .BitRateSwitch = FDCAN_BRS_OFF, .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages .MessageMarker = 0 // also change this to a real address if you change fifo control @@ -75,6 +77,7 @@ int can_test(void) { FDCANTxMessage msg; msg.data[0] = 0x80; + //memset(&(msg.data), 0, ); msg.tx_header = TxHeader; @@ -104,6 +107,7 @@ int can_test(void) { //API Testing can_init(&canCfg); + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); can_start(can2Handle); can_send(can2Handle, &msg); From b62eb92a98bb087b94b7bf8c6b7a367e610ae7fc Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Mon, 12 Jan 2026 21:50:07 -0800 Subject: [PATCH 09/18] single node success --- .vscode/launch.json | 2 +- G4PERTESTING/Core/Src/main.c | 99 ++++++++++++++++++----------------- Lib/Peripherals/CAN/README.md | 2 +- 3 files changed, 52 insertions(+), 51 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 80838b74..67c1ce84 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -160,7 +160,7 @@ "svdPath": "${workspaceFolder}/Lib/Platform/STM32G474xE/CompileDependencies/STM32G474.svd", "swoConfig": { "enabled": true, - "cpuFrequency": 170000000, + "cpuFrequency": 160000000, "swoFrequency": 2000000, "source": "probe", "decoders": [ diff --git a/G4PERTESTING/Core/Src/main.c b/G4PERTESTING/Core/Src/main.c index 850ff34f..2ba06976 100644 --- a/G4PERTESTING/Core/Src/main.c +++ b/G4PERTESTING/Core/Src/main.c @@ -145,63 +145,23 @@ int main(void) * @brief System Clock Configuration * @retval None */ -void SystemClock_Config(void) -{ - LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); - while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { - } - LL_PWR_EnableRange1BoostMode(); - LL_RCC_HSE_Enable(); - - /* Wait till HSE is ready */ - while (LL_RCC_HSE_IsReady() != 1) { - } - - LL_RCC_HSE_EnableCSS(); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, - LL_RCC_PLLR_DIV_2); - //LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, ); - LL_RCC_PLL_EnableDomain_SYS(); - LL_RCC_PLL_Enable(); - /* Wait till PLL is ready */ - while (LL_RCC_PLL_IsReady() != 1) { - } - - LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); - LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); - /* Wait till System clock is ready */ - while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { - } - - /* Insure 1us transition state at intermediate medium speed clock*/ - for (__IO uint32_t i = (170 >> 1); i != 0; i--) - ; - - /* Set AHB prescaler*/ - LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); - LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); - LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - LL_SetSystemCoreClock(160000000); - /* Update the time base */ - if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { - Error_Handler(); - } -} // void SystemClock_Config(void) // { // LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); // while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { // } // LL_PWR_EnableRange1BoostMode(); -// LL_RCC_HSI_Enable(); -// /* Wait till HSI is ready */ -// while (LL_RCC_HSI_IsReady() != 1) { +// LL_RCC_HSE_Enable(); + +// /* Wait till HSE is ready */ +// while (LL_RCC_HSE_IsReady() != 1) { // } -// LL_RCC_HSI_SetCalibTrimming(64); -// LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, +// LL_RCC_HSE_EnableCSS(); +// LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, // LL_RCC_PLLR_DIV_2); +// //LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, ); // LL_RCC_PLL_EnableDomain_SYS(); // LL_RCC_PLL_Enable(); // /* Wait till PLL is ready */ @@ -222,13 +182,54 @@ void SystemClock_Config(void) // LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); // LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); // LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); -// LL_SetSystemCoreClock(170000000); +// LL_SetSystemCoreClock(160000000); // /* Update the time base */ // if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { // Error_Handler(); // } -// } +// }*/ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); + while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { + } + LL_PWR_EnableRange1BoostMode(); + LL_RCC_HSI_Enable(); + /* Wait till HSI is ready */ + while (LL_RCC_HSI_IsReady() != 1) { + } + + LL_RCC_HSI_SetCalibTrimming(64); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_1, 10, + LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_EnableDomain_SYS(); + LL_RCC_PLL_Enable(); + /* Wait till PLL is ready */ + while (LL_RCC_PLL_IsReady() != 1) { + } + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + // LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + /* Wait till System clock is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { + } + + /* Insure 1us transition state at intermediate medium speed clock*/ + for (__IO uint32_t i = (170 >> 1); i != 0; i--) + ; + + /* Set AHB prescaler*/ + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + LL_SetSystemCoreClock(160000000); + + /* Update the time base */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { + Error_Handler(); + } +} /* USER CODE BEGIN 4 */ diff --git a/Lib/Peripherals/CAN/README.md b/Lib/Peripherals/CAN/README.md index f643b044..db96f9a3 100644 --- a/Lib/Peripherals/CAN/README.md +++ b/Lib/Peripherals/CAN/README.md @@ -80,4 +80,4 @@ Library Centric Testing: HAL_Rewrite: - Alternatively, rewrite without using HAL, just use CMSIS definitions. - PROS: Would look good on your Github. -- CONS: Wouldn't help \ No newline at end of file +- CONS: takes too long \ No newline at end of file From fe669d2f96d031d33d5ec1142e121839d2e65e94 Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Mon, 12 Jan 2026 22:25:02 -0800 Subject: [PATCH 10/18] Filter confirmed to work, need LOGOMATIC --- Lib/Peripherals/CAN/Src/can.c | 7 ++++--- Lib/Peripherals/CAN/Test/can_tests.c | 19 +++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 24d59521..bb87dbd5 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -399,8 +399,8 @@ int can_add_filter(CANHandle* canHandle, FDCAN_FilterTypeDef *filter){ return -1; } - if ( !(canHandle->init && canHandle->started) ) { - LOGOMATIC("CAN_add_filter: can instance is not started and initialized"); + if ( !canHandle->init || canHandle->started ) { + LOGOMATIC("CAN_add_filter: can instance is not initialized or already started"); return -1; } @@ -537,7 +537,8 @@ int can_send(CANHandle* canHandle, FDCANTxMessage* message) { //IF TX Fifos are not full, send directly to them //If TX Fifos are full, append to circular buffer //If circular buffer is full, return an error code - if (HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP) > 0) { + uint32_t free = HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP); + if (free > 0) { HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ( canHandle->hal_fdcanP, &(message->tx_header), diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index 6ca270db..6eaffdd3 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -1,5 +1,6 @@ #include "can_tests.h" #include "can.h" +#include //each family has a constant number of CAN peripherals @@ -65,6 +66,8 @@ int can_test(void) { /* USER CODE END 2 */ FDCAN_TxHeaderTypeDef TxHeader = { + .Identifier = 1, + .IdType = FDCAN_STANDARD_ID, .TxFrameType = FDCAN_DATA_FRAME, .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node @@ -77,7 +80,7 @@ int can_test(void) { FDCANTxMessage msg; msg.data[0] = 0x80; - //memset(&(msg.data), 0, ); + memset(&(msg.data), 0, sizeof(msg.data)); msg.tx_header = TxHeader; @@ -96,16 +99,24 @@ int can_test(void) { canCfg.init_tx_gpio.Pin = GPIO_PIN_13; canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + FDCAN_FilterTypeDef filter; + filter.IdType = FDCAN_STANDARD_ID; + filter.FilterIndex = 0; + filter.FilterType = FDCAN_FILTER_RANGE, + filter.FilterConfig = FDCAN_FILTER_REJECT; + filter.FilterID1 = 0x00; + filter.FilterID2 = 0x02; + CANHandle *can2Handle = can_init(&canCfg); //accept unmatched standard and extended frames into RXFIFO0 - default behaviour - HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, FDCAN_ACCEPT_IN_RX_FIFO0, 0, 0,0); + HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, 0, 0, 0,0); //not accepting filters - //can_add_filter(can2Handle, &filter); + can_add_filter(can2Handle, &filter); //API Testing - can_init(&canCfg); + //can_init(&canCfg); can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); can_start(can2Handle); From aeb1f054fe9f75e9518599a12cae3de55aee382d Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Tue, 13 Jan 2026 00:44:04 -0800 Subject: [PATCH 11/18] Ensure still 1 Mbps can nominal baud rate and such while supporting `LOGOMATIC` --- G4PERTESTING/Core/Src/main.c | 27 ++- G4PERTESTING/Core/Src/usart.c | 2 +- Lib/Peripherals/CAN/Src/can.c | 247 +++++++++++++-------------- Lib/Peripherals/CAN/Test/can_tests.c | 42 ++--- 4 files changed, 166 insertions(+), 152 deletions(-) diff --git a/G4PERTESTING/Core/Src/main.c b/G4PERTESTING/Core/Src/main.c index 2ba06976..03635c54 100644 --- a/G4PERTESTING/Core/Src/main.c +++ b/G4PERTESTING/Core/Src/main.c @@ -66,14 +66,27 @@ void SystemClock_Config(void); /* Enable ITM for SWO output */ static void ITM_Enable(void) { + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; + /* Enable TRC (Trace) */ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - /* Enable stimulus port 0 */ - ITM->TER |= (1UL << 0); + /* Configure TPI for SWO output (set prescaler for 2MHz SWO clock) */ + TPI->SPPR = 2U; /* 2 = Manchester/async UART mode */ + TPI->ACPR = 84U; /* Prescaler: (170 MHz / (84+1) / 2) ≈ 1MHz SWO */ - /* Set trace control register */ - ITM->TCR |= ITM_TCR_ITMENA_Msk; + ITM->TER |= (1UL << 0); + ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); } static int toggleze = 0; void DEBUG_callback(void *data, uint32_t size) @@ -130,6 +143,8 @@ int main(void) /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ + LOGOMATIC("Main Loop\n"); + LL_mDelay(1000); // Receive on GPIOs // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET @@ -201,7 +216,7 @@ void SystemClock_Config(void) } LL_RCC_HSI_SetCalibTrimming(64); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_1, 10, + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, LL_RCC_PLLR_DIV_2); LL_RCC_PLL_EnableDomain_SYS(); LL_RCC_PLL_Enable(); @@ -223,7 +238,7 @@ void SystemClock_Config(void) LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - LL_SetSystemCoreClock(160000000); + LL_SetSystemCoreClock(170000000); /* Update the time base */ if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { diff --git a/G4PERTESTING/Core/Src/usart.c b/G4PERTESTING/Core/Src/usart.c index 80a204e3..85df3b91 100644 --- a/G4PERTESTING/Core/Src/usart.c +++ b/G4PERTESTING/Core/Src/usart.c @@ -37,7 +37,7 @@ void MX_LPUART1_UART_Init(void) LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_HSI); /* Peripheral clock enable */ LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index bb87dbd5..be849a50 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -7,18 +7,18 @@ //HAL handles //#ifdef USECAN1 -static FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; +static FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; static CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; -//#endif +//#endif //#ifdef USECAN2 -static FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; +static FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; static CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; -//#endif +//#endif //#ifdef USECAN3 -static FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; -static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; +static FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; +static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; //#endif //macro lore @@ -31,18 +31,18 @@ static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; #define ACTIVATE_FDCAN_HELPER(FDCANX, ITY, preirq, subirq) \ do { \ HAL_NVIC_SetPriority( CAT4(FDCANX##,_,ITY, _IRQn ) , preirq, subirq ); \ - HAL_NVIC_EnableIRQ( CAT4(FDCANX##,_,ITY, _IRQn ) ); \ + HAL_NVIC_EnableIRQ( CAT4(FDCANX##,_,ITY, _IRQn ) ); \ } while(0) #define HAL_NVIC_ACTIVATE_FDCAN(FDCANX, ITY, preirq, subirq) \ do { \ if (FDCANX == ##FDCAN1 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT0, preirq, subirq); } \ - else if (FDCANX == FDCAN1 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT1, preirq, subirq); } \ - else if (FDCANX == FDCAN2 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT0, preirq, subirq); } \ - else if (FDCANX == FDCAN2 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT1, preirq, subirq); } \ - else if (FDCANX == FDCAN3 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT0, preirq, subirq); } \ - else if (FDCANX == FDCAN3 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT1, preirq, subirq); } \ - else { LOGOMATIC("Unrecognized FDCAN and Interrupt Line combination"); } \ + else if (FDCANX == FDCAN1 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT1, preirq, subirq); } \ + else { LOGOMATIC("Unrecognized FDCAN and Interrupt Line combination"); } \ } while(0) */ @@ -55,7 +55,7 @@ static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; case (uint32_t) GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break; \ default: LOGOMATIC("BAD FDCAN GPIO Port"); \ } \ - } while(0) + } while(0) #define GPIOx_CLK_DISABLE(GPIOX) \ @@ -66,11 +66,11 @@ static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; case (uint32_t) GPIOD: __HAL_RCC_GPIOD_CLK_DISABLE(); break; \ default: LOGOMATIC("BAD FDCAN GPIO Port"); \ } \ - } while(0) + } while(0) -static int fdcan_shared_clock_ref = 0; +static int fdcan_shared_clock_ref = 0; static inline void fdcan_enable_shared_clock(void) { uint32_t primask = __get_PRIMASK(); __disable_irq(); @@ -80,13 +80,13 @@ static inline void fdcan_enable_shared_clock(void) { } fdcan_shared_clock_ref++; - __set_PRIMASK(primask); + __set_PRIMASK(primask); } static inline void fdcan_disable_shared_clock(void) { uint32_t primask = __get_PRIMASK(); __disable_irq(); - + if (fdcan_shared_clock_ref > 0) { fdcan_shared_clock_ref--; if (fdcan_shared_clock_ref == 0) { @@ -113,8 +113,8 @@ static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1); -static int can_msp_init(CANHandle* handle, const CANConfig*config); -CANHandle* can_init(const CANConfig *config) { +static int can_msp_init(CANHandle* handle, const CANConfig*config); +CANHandle* can_init(const CANConfig *config) { //config validation? //assert(config != 0) @@ -123,30 +123,30 @@ CANHandle* can_init(const CANConfig *config) { //#ifdef USECAN1 if (config->fdcan_instance == FDCAN1) { if (CAN1.init) {LOGOMATIC("CAN: CAN1 is already initialized\n"); return 0;} - else canHandle = &CAN1; - } - //#endif + else canHandle = &CAN1; + } + //#endif //#ifdef USECAN2 else if (config->fdcan_instance == FDCAN2) { if (CAN2.init) {LOGOMATIC("CAN: CAN2 is already initialized\n"); return 0;} - else canHandle = &CAN2; + else canHandle = &CAN2; } //#ifdef USECAN3 else if (config->fdcan_instance == FDCAN3) { if (CAN3.init) {LOGOMATIC("CAN: CAN3 is already initialized\n"); return 0;} - else canHandle = &CAN3; + else canHandle = &CAN3; } //#endif //#elif defined(STM32L476xx) - //#else + //#else //#error "Unsupported STM32 family" //#endif else { LOGOMATIC("CAN: Unrecognized FDCAN instance"); - return 0; + return 0; } - canHandle->init = false; - canHandle->started = false; + canHandle->init = false; + canHandle->started = false; //Initialize handle assert( config->hal_fdcan_init.TxFifoQueueMode == FDCAN_TX_FIFO_OPERATION ); @@ -154,59 +154,59 @@ CANHandle* can_init(const CANConfig *config) { canHandle->hal_fdcanP->Init = config->hal_fdcan_init; //copy FDCAN parameters from user //canHandle->hal_fdcanP->Instance = config->fdcan_instance //handles initialized with correct base instance addresses - canHandle->rx_gpio = config->rx_gpio; - canHandle->tx_gpio = config->tx_gpio; - canHandle->rx_callback = config->rx_callback; - canHandle->tx_buffer_length = config->tx_buffer_length; + canHandle->rx_gpio = config->rx_gpio; + canHandle->tx_gpio = config->tx_gpio; + canHandle->rx_callback = config->rx_callback; + canHandle->tx_buffer_length = config->tx_buffer_length; //alternately -> have can_msp_init setup state for HAL_FDCAN_MspInit to work correctly //have can_msp_deinit setup state for HAL_FDCAN_MspDeInit to work correctly - //Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() + //Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() //Current idea, redefine HAL_FDCAN_MspInit and MspDeInit do nothing at all, do all the work in can_msp_init() if (can_msp_init(canHandle, config)) { LOGOMATIC("CAN_init: could not initialize MSP resources"); - can_release(canHandle); + can_release(canHandle); } //PROBLEM: HAL_FDCAN_Init expects HAL_FDCAN_MspInit() to be defined if (HAL_FDCAN_Init( canHandle->hal_fdcanP ) != HAL_OK) { LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); - return NULL; + return NULL; //Error_Handler(); } //Active FDCAN callbacks - rxcalback uses line0, txcallback uses line1 //uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; - uint32_t status = 0; + uint32_t status = 0; uint32_t rx_events = FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL; status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, rx_events, 0); status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, rx_events, FDCAN_INTERRUPT_LINE0); //uint32_t txevents = FDCAN_IT_TX_COMPLETE; - uint32_t destinations = FDCAN_TX_BUFFER0; - uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; + uint32_t destinations = FDCAN_TX_BUFFER0; + uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, tx_events, destinations); status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, tx_events, FDCAN_INTERRUPT_LINE1); //Callbacks redefined later if (status & HAL_ERROR) { - LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); - return NULL; + LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); + return NULL; } - + //Circular Buffer - canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); + canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); if (!canHandle->tx_buffer ) { - LOGOMATIC("CAN: Could not allocate circular buffer\n"); - return 0; + LOGOMATIC("CAN: Could not allocate circular buffer\n"); + return 0; } - canHandle->init = true; - canHandle->started = false; + canHandle->init = true; + canHandle->started = false; - return canHandle; + return canHandle; } inline int can_set_clksource(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } @@ -217,17 +217,17 @@ static int can_msp_init(CANHandle *canHandle, const CANConfig *config) { //MSP Init ------- This could be inside HAL_FDCAN_MspInit() instead //FDCAN Clock Select - fdcan_enable_shared_clock(); + fdcan_enable_shared_clock(); //Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler //GPIOs init - GPIOx_CLK_ENABLE(config->rx_gpio); - GPIOx_CLK_ENABLE(config->tx_gpio); + GPIOx_CLK_ENABLE(config->rx_gpio); + GPIOx_CLK_ENABLE(config->tx_gpio); HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio)); HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio)); - IRQn_Type rxit, txit; + IRQn_Type rxit, txit; can_get_irqs(canHandle->hal_fdcanP->Instance, &rxit, &txit); //rxfifo0 @@ -236,14 +236,14 @@ static int can_msp_init(CANHandle *canHandle, const CANConfig *config) { //tx HAL_NVIC_SetPriority(txit, config->tx_interrupt_priority,0); - HAL_NVIC_EnableIRQ(txit); + HAL_NVIC_EnableIRQ(txit); //End MSP Init -------------- return 0; } -void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcan) { return; } - //use can_msp_init() instead to initialize MSP before calling HAL_FDCAN_Init() +void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcan) { return; } + //use can_msp_init() instead to initialize MSP before calling HAL_FDCAN_Init() void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcan) { return; } //use can_msp_deinit() instead @@ -282,20 +282,20 @@ static const char* can_get_instance_name(FDCAN_GlobalTypeDef *instance) { //valid only for STM32G4 static CANHandle* can_get_buffer_handle(FDCAN_HandleTypeDef * hfdcan) { - CANHandle* handle = 0; + CANHandle* handle = 0; //#ifdef STM32G474xx if (hfdcan->Instance == FDCAN1) return &CAN1; else if (hfdcan->Instance == FDCAN2) return &CAN2; else if (hfdcan->Instance == FDCAN3) return &CAN3; else { - LOGOMATIC("CAN_get_buffer_handle: was given invalid FDCAN instance\n"); - return 0; + LOGOMATIC("CAN_get_buffer_handle: was given invalid FDCAN instance\n"); + return 0; } } static void can_tx_buffer_helper(CANHandle* handle) { while (HAL_FDCAN_GetTxFifoFreeLevel(handle->hal_fdcanP) && !GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { - FDCANTxMessage* msg = GR_CircularBuffer_Pop(handle->tx_buffer); + FDCANTxMessage* msg = GR_CircularBuffer_Pop(handle->tx_buffer); if (!msg) break; @@ -306,7 +306,7 @@ static void can_tx_buffer_helper(CANHandle* handle) { free(msg); // Free the message we couldn't send break; // Stop trying to send more } - + free(msg); // Successfully sent, free the memory } } @@ -326,7 +326,7 @@ void HAL_FDCAN_TxBufferCompleteCallback( FDCAN_HandleTypeDef * hfdcan, uint32_t //Otherwise do nothing //#ifdef USECAN1 CANHandle* handle = can_get_buffer_handle(hfdcan); - + if (!handle|| !handle->tx_buffer) { return; } @@ -334,48 +334,48 @@ void HAL_FDCAN_TxBufferCompleteCallback( FDCAN_HandleTypeDef * hfdcan, uint32_t if (GR_CircularBuffer_IsEmpty(handle->tx_buffer)) return; //see if you can pop any more from the buffer - can_tx_buffer_helper(handle); + can_tx_buffer_helper(handle); } void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs) { - CANHandle * handle = can_get_buffer_handle(hfdcan); + CANHandle * handle = can_get_buffer_handle(hfdcan); if (!handle || !handle->init || !handle->rx_callback) { return; } /*if (!handle->rx_buffer) { - LOGOMATIC("CAN: RX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); + LOGOMATIC("CAN: RX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); return; } */ // no rx buffer at the moment /*if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_MESSAGE_LOST) { - lost_rx++; + lost_rx++; }*/ - if ( !(RxFifo0ITs & ~FDCAN_IT_RX_FIFO0_MESSAGE_LOST)) return; + if ( !(RxFifo0ITs & ~FDCAN_IT_RX_FIFO0_MESSAGE_LOST)) return; //if (GR_CircularBuffer_IsFull(handle->rx_buffer)) return; - - FDCAN_RxHeaderTypeDef rx_header; - uint8_t rx_data[64] = {0}; + + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) { - HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, rx_data); + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, rx_data); //stack allocation should be fine? Callback needs to terminate first before stack is popped //should switch this over to malloc at some point to avoid double copies? handle->rx_callback(rx_data, rx_header.DataLength); - } + } /* whoopsie, don't need the rx buffer yet while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) & !GR_CircularBuffer_IsFull(handle->rx_buffer)) { - FDCAN_RxHeaderTypeDef rx_header; - uint8_t rx_data[64] = {0}; - HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); if (GR_CircularBuffer_IsEmpty(handle->rx_buffer)) handle->rx_callback(rx_data, rx_header.DataLength); else { - GR_CircularBuffer_Push(handle->rx_buffer, rx_data, rx_header.DataLength); + GR_CircularBuffer_Push(handle->rx_buffer, rx_data, rx_header.DataLength); } }*/ } @@ -396,33 +396,33 @@ void can_read_rx_buffer(CANHandle* canHandle) { int can_add_filter(CANHandle* canHandle, FDCAN_FilterTypeDef *filter){ if (!canHandle) { LOGOMATIC("CAN_add_filter: handle is null"); - return -1; + return -1; } if ( !canHandle->init || canHandle->started ) { LOGOMATIC("CAN_add_filter: can instance is not initialized or already started"); - return -1; + return -1; } if (HAL_FDCAN_ConfigFilter(canHandle->hal_fdcanP, filter) != HAL_OK ) { - LOGOMATIC("CAN_add_filter: failed to configure filter"); - return -1; + LOGOMATIC("CAN_add_filter: failed to configure filter"); + return -1; } - return 0; + return 0; //check that # of filters isn't exceeding max value } -//Need to +//Need to int can_start(CANHandle * canHandle) { if (!canHandle || !canHandle->init) return -1; - GPIOx_CLK_ENABLE(canHandle->rx_gpio); - GPIOx_CLK_ENABLE(canHandle->tx_gpio); + GPIOx_CLK_ENABLE(canHandle->rx_gpio); + GPIOx_CLK_ENABLE(canHandle->tx_gpio); HAL_FDCAN_Start(canHandle->hal_fdcanP); - canHandle->started = true; + canHandle->started = true; - return 0; + return 0; } int can_stop(CANHandle * canHandle) { @@ -431,21 +431,21 @@ int can_stop(CANHandle * canHandle) { HAL_FDCAN_Stop(canHandle->hal_fdcanP); - GPIOx_CLK_DISABLE(canHandle->rx_gpio); - GPIOx_CLK_DISABLE(canHandle->tx_gpio); + GPIOx_CLK_DISABLE(canHandle->rx_gpio); + GPIOx_CLK_DISABLE(canHandle->tx_gpio); - canHandle->started = false; + canHandle->started = false; - return 0; + return 0; } //Valid only for STM32G474xE /*int can_msp_deinit(CANHandle* canHandle) { //MSP DeInit //turn off gpio clocks - can only turn off GPIOs if no other instances are using them - - return 0; + + return 0; }*/ static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) @@ -456,16 +456,16 @@ static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) // Clear filters //TODO: fix magic numbers - memset((void *) hfdcan->msgRam.StandardFilterSA, 0, 0x0070); - memset((void *) hfdcan->msgRam.ExtendedFilterSA, 0, 0x0050); + memset((void *) hfdcan->msgRam.StandardFilterSA, 0, 0x0070); + memset((void *) hfdcan->msgRam.ExtendedFilterSA, 0, 0x0050); // Optionally reset FIFOs / buffers // Disable interrupts - __HAL_FDCAN_DISABLE_IT(hfdcan, - FDCAN_IT_LIST_RX_FIFO0 | FDCAN_IT_LIST_RX_FIFO1 | - FDCAN_IT_LIST_SMSG | FDCAN_IT_LIST_TX_FIFO_ERROR | - FDCAN_IT_LIST_MISC | FDCAN_IT_LIST_BIT_LINE_ERROR | + __HAL_FDCAN_DISABLE_IT(hfdcan, + FDCAN_IT_LIST_RX_FIFO0 | FDCAN_IT_LIST_RX_FIFO1 | + FDCAN_IT_LIST_SMSG | FDCAN_IT_LIST_TX_FIFO_ERROR | + FDCAN_IT_LIST_MISC | FDCAN_IT_LIST_BIT_LINE_ERROR | FDCAN_IT_LIST_PROTOCOL_ERROR ); @@ -479,27 +479,27 @@ static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) int can_release(CANHandle * canHandle) { if (!canHandle) { - LOGOMATIC("CAN: Tried to release a null handle"); - return -1; + LOGOMATIC("CAN: Tried to release a null handle"); + return -1; } - + if (!canHandle->init) { LOGOMATIC("CAN_release: can instance is already deinitialized"); - return -1; + return -1; } can_stop(canHandle); //try to prevent more interrupts from firing //must disable NVIC IRQs before freeing circular buffer - + //turn off NVIC resources - IRQn_Type rx0it, txit; + IRQn_Type rx0it, txit; can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); HAL_NVIC_DisableIRQ(rx0it); - HAL_NVIC_DisableIRQ(txit); + HAL_NVIC_DisableIRQ(txit); //need to check if other pins are using before disabling - do this after mvp - //GPIOx_CLK_DISABLE(canHandle->rx_gpio); - //GPIOx_CLK_DISABLE(canHandle->tx_gpio); + //GPIOx_CLK_DISABLE(canHandle->rx_gpio); + //GPIOx_CLK_DISABLE(canHandle->tx_gpio); //reset FDCANx instance and message RAM and filters, clear interrupts //HAL_FDCAN_DeInit(canHandle->hal_fdcanP); resets a little too hard @@ -512,21 +512,21 @@ int can_release(CANHandle * canHandle) { GR_CircularBuffer_Free(&(canHandle->tx_buffer)); //reset can instance - FDCAN_HandleTypeDef * temp = canHandle->hal_fdcanP; + FDCAN_HandleTypeDef * temp = canHandle->hal_fdcanP; memset(canHandle, 0, sizeof(*canHandle)); - canHandle->hal_fdcanP = temp; + canHandle->hal_fdcanP = temp; fdcan_disable_shared_clock(); //only turns off clock if no other instances are running. - return 0; + return 0; } int can_send(CANHandle* canHandle, FDCANTxMessage* message) { - if (!canHandle || !message) { - LOGOMATIC("CAN_send: received null pointer\n"); - return -1; + if (!canHandle || !message) { + LOGOMATIC("CAN_send: received null pointer\n"); + return -1; } - + if (!canHandle->init || !canHandle->started) { LOGOMATIC("CAN_send: CAN not initialized or started\n"); return -1; @@ -537,16 +537,16 @@ int can_send(CANHandle* canHandle, FDCANTxMessage* message) { //IF TX Fifos are not full, send directly to them //If TX Fifos are full, append to circular buffer //If circular buffer is full, return an error code - uint32_t free = HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP); + uint32_t free = HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP); if (free > 0) { HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ( - canHandle->hal_fdcanP, - &(message->tx_header), + canHandle->hal_fdcanP, + &(message->tx_header), message->data // Not &message->data if data is array ); - + __set_PRIMASK(primask); - + if (status != HAL_OK) { LOGOMATIC("CAN_send: failed to add to HW FIFO\n"); return -1; @@ -557,13 +557,13 @@ int can_send(CANHandle* canHandle, FDCANTxMessage* message) { // Hardware FIFO full, try software buffer if (!GR_CircularBuffer_IsFull(canHandle->tx_buffer)) { int result = GR_CircularBuffer_Push( - canHandle->tx_buffer, - message, + canHandle->tx_buffer, + message, sizeof(FDCANTxMessage) ); - + __set_PRIMASK(primask); - + if (result != 0) { LOGOMATIC("CAN_send: buffer push failed\n"); return -1; @@ -573,7 +573,6 @@ int can_send(CANHandle* canHandle, FDCANTxMessage* message) { // Both buffers full __set_PRIMASK(primask); - LOGOMATIC("CAN_send: all buffers full\n"); + LOGOMATIC("CAN_send: all buffers full\n"); return -1; } - diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index 6eaffdd3..9ac739e4 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -2,7 +2,7 @@ #include "can.h" #include -//each family has a constant number of CAN peripherals +//each family has a constant number of CAN peripherals int can_test_instance(FDCAN_HandleTypeDef) { @@ -11,8 +11,9 @@ int can_test_instance(FDCAN_HandleTypeDef) { } void can_test_rx_callback(void*data, uint32_t size) { - //Is within an ISR, so needs to exit quickly - return;// + LOGOMATIC("Got data!\n"); + // Is within an ISR, so needs to exit quickly + return; } int can_test(void) { @@ -20,7 +21,7 @@ int can_test(void) { CANConfig canCfg; //canCfg.fdcan_instance = FDCAN2; - canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; canCfg.hal_fdcan_init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; @@ -30,11 +31,11 @@ int can_test(void) { canCfg.hal_fdcan_init.ProtocolException = ENABLE; canCfg.hal_fdcan_init.NominalPrescaler = 1; canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; - canCfg.hal_fdcan_init.NominalTimeSeg1 = 119; - canCfg.hal_fdcan_init.NominalTimeSeg2 = 40; + canCfg.hal_fdcan_init.NominalTimeSeg1 = 127; // Updated for 170MHz: (1+127+42)*1 = 170 ticks -> 1 Mbps + canCfg.hal_fdcan_init.NominalTimeSeg2 = 42; canCfg.hal_fdcan_init.DataPrescaler = 8; canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; - canCfg.hal_fdcan_init.DataTimeSeg1 = 14; + canCfg.hal_fdcan_init.DataTimeSeg1 = 15; // Updated for 170MHz: (1+15+5)*8 = 168 ticks -> ~5 Mbps canCfg.hal_fdcan_init.DataTimeSeg2 = 5; canCfg.hal_fdcan_init.StdFiltersNbr = 1; canCfg.hal_fdcan_init.ExtFiltersNbr = 0; @@ -43,8 +44,8 @@ int can_test(void) { canCfg.rx_interrupt_priority = 0; // PLEASE SET canCfg.tx_interrupt_priority = 0; // PLEASE SET canCfg.tx_buffer_length = 20; // PLEASE SET - - //canCfg.rx_gpio = GPIOB; + + //canCfg.rx_gpio = GPIOB; //canCfg.init_rx_gpio.Pin = GPIO_PIN_12; canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; canCfg.init_rx_gpio.Pull = GPIO_PULLUP; @@ -58,7 +59,7 @@ int can_test(void) { canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; - + //Not testing filters at the moment //FDCAN_FilterTypeDef filter; @@ -66,13 +67,13 @@ int can_test(void) { /* USER CODE END 2 */ FDCAN_TxHeaderTypeDef TxHeader = { - .Identifier = 1, + .Identifier = 1, .IdType = FDCAN_STANDARD_ID, .TxFrameType = FDCAN_DATA_FRAME, .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors - .DataLength = 1, + .DataLength = 1, .BitRateSwitch = FDCAN_BRS_OFF, .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages .MessageMarker = 0 // also change this to a real address if you change fifo control @@ -80,18 +81,18 @@ int can_test(void) { FDCANTxMessage msg; msg.data[0] = 0x80; - memset(&(msg.data), 0, sizeof(msg.data)); + memset(&(msg.data), 0, sizeof(msg.data)); msg.tx_header = TxHeader; #ifdef FDCAN1 - #endif + #endif #ifdef FDCAN2 canCfg.fdcan_instance = FDCAN2; - canCfg.rx_gpio = GPIOB; + canCfg.rx_gpio = GPIOB; canCfg.init_rx_gpio.Pin = GPIO_PIN_12; canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; @@ -103,14 +104,14 @@ int can_test(void) { filter.IdType = FDCAN_STANDARD_ID; filter.FilterIndex = 0; filter.FilterType = FDCAN_FILTER_RANGE, - filter.FilterConfig = FDCAN_FILTER_REJECT; + filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; filter.FilterID1 = 0x00; filter.FilterID2 = 0x02; CANHandle *can2Handle = can_init(&canCfg); //accept unmatched standard and extended frames into RXFIFO0 - default behaviour - HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, 0, 0, 0,0); + HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, 0, 0, 0,0); //not accepting filters can_add_filter(can2Handle, &filter); @@ -118,19 +119,18 @@ int can_test(void) { //API Testing //can_init(&canCfg); - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); can_start(can2Handle); can_send(can2Handle, &msg); //can_release(can2Handle); - #endif + #endif #ifdef FDCAN3 - #endif + #endif return 0; } - From 61613498ebbfd1edfdbcea2f9f5960c2f8442f5c Mon Sep 17 00:00:00 2001 From: Daniel Hansen Date: Tue, 13 Jan 2026 01:31:31 -0800 Subject: [PATCH 12/18] Copy G4PERTESTING to G4CANTESTING and undo G4PERTESTING changes to hopefully make life easier for merge conflicts and continued dev of peripherals in parallel but incremental fixes --- .vscode/launch.json | 31 ++ .vscode/tasks.json | 9 + CMakeLists.txt | 5 +- G4CANTESTING/CMakeLists.txt | 54 +++ G4CANTESTING/Core/Inc/adc.h | 49 +++ G4CANTESTING/Core/Inc/crc.h | 51 +++ G4CANTESTING/Core/Inc/dma.h | 51 +++ G4CANTESTING/Core/Inc/fdcan.h | 51 +++ G4CANTESTING/Core/Inc/gpio.h | 48 +++ G4CANTESTING/Core/Inc/i2c.h | 49 +++ G4CANTESTING/Core/Inc/main.h | 116 ++++++ G4CANTESTING/Core/Inc/spi.h | 49 +++ G4CANTESTING/Core/Inc/stm32_assert.h | 53 +++ G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h | 394 +++++++++++++++++++++ G4CANTESTING/Core/Inc/stm32g4xx_it.h | 67 ++++ G4CANTESTING/Core/Inc/tim.h | 49 +++ G4CANTESTING/Core/Inc/usart.h | 50 +++ G4CANTESTING/Core/Src/adc.c | 209 +++++++++++ G4CANTESTING/Core/Src/crc.c | 86 +++++ G4CANTESTING/Core/Src/dma.c | 50 +++ G4CANTESTING/Core/Src/fdcan.c | 133 +++++++ G4CANTESTING/Core/Src/gpio.c | 261 ++++++++++++++ G4CANTESTING/Core/Src/i2c.c | 92 +++++ G4CANTESTING/Core/Src/main.c | 283 +++++++++++++++ G4CANTESTING/Core/Src/spi.c | 95 +++++ G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c | 86 +++++ G4CANTESTING/Core/Src/stm32g4xx_it.c | 213 +++++++++++ G4CANTESTING/Core/Src/syscalls.c | 166 +++++++++ G4CANTESTING/Core/Src/sysmem.c | 79 +++++ G4CANTESTING/Core/Src/system_stm32g4xx.c | 297 ++++++++++++++++ G4CANTESTING/Core/Src/tim.c | 79 +++++ G4CANTESTING/Core/Src/usart.c | 188 ++++++++++ G4CANTESTING/G4PERTESTING.ioc | 382 ++++++++++++++++++++ G4CANTESTING/README.md | 5 + G4PERTESTING/CMakeLists.txt | 5 +- G4PERTESTING/Core/Inc/main.h | 1 - G4PERTESTING/Core/Inc/stm32_assert.h | 3 +- G4PERTESTING/Core/Inc/stm32g4xx_hal_conf.h | 24 +- G4PERTESTING/Core/Src/adc.c | 67 ++-- G4PERTESTING/Core/Src/fdcan.c | 262 +++++++------- G4PERTESTING/Core/Src/gpio.c | 3 +- G4PERTESTING/Core/Src/main.c | 117 +----- G4PERTESTING/Core/Src/stm32g4xx_it.c | 20 +- G4PERTESTING/Core/Src/sysmem.c | 10 +- G4PERTESTING/Core/Src/system_stm32g4xx.c | 38 +- G4PERTESTING/Core/Src/usart.c | 8 +- G4PERTESTING/README.md | 4 +- 47 files changed, 4095 insertions(+), 347 deletions(-) create mode 100644 G4CANTESTING/CMakeLists.txt create mode 100644 G4CANTESTING/Core/Inc/adc.h create mode 100644 G4CANTESTING/Core/Inc/crc.h create mode 100644 G4CANTESTING/Core/Inc/dma.h create mode 100644 G4CANTESTING/Core/Inc/fdcan.h create mode 100644 G4CANTESTING/Core/Inc/gpio.h create mode 100644 G4CANTESTING/Core/Inc/i2c.h create mode 100644 G4CANTESTING/Core/Inc/main.h create mode 100644 G4CANTESTING/Core/Inc/spi.h create mode 100644 G4CANTESTING/Core/Inc/stm32_assert.h create mode 100644 G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h create mode 100644 G4CANTESTING/Core/Inc/stm32g4xx_it.h create mode 100644 G4CANTESTING/Core/Inc/tim.h create mode 100644 G4CANTESTING/Core/Inc/usart.h create mode 100644 G4CANTESTING/Core/Src/adc.c create mode 100644 G4CANTESTING/Core/Src/crc.c create mode 100644 G4CANTESTING/Core/Src/dma.c create mode 100644 G4CANTESTING/Core/Src/fdcan.c create mode 100644 G4CANTESTING/Core/Src/gpio.c create mode 100644 G4CANTESTING/Core/Src/i2c.c create mode 100644 G4CANTESTING/Core/Src/main.c create mode 100644 G4CANTESTING/Core/Src/spi.c create mode 100644 G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c create mode 100644 G4CANTESTING/Core/Src/stm32g4xx_it.c create mode 100644 G4CANTESTING/Core/Src/syscalls.c create mode 100644 G4CANTESTING/Core/Src/sysmem.c create mode 100644 G4CANTESTING/Core/Src/system_stm32g4xx.c create mode 100644 G4CANTESTING/Core/Src/tim.c create mode 100644 G4CANTESTING/Core/Src/usart.c create mode 100644 G4CANTESTING/G4PERTESTING.ioc create mode 100644 G4CANTESTING/README.md diff --git a/.vscode/launch.json b/.vscode/launch.json index 67c1ce84..9c1167a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -173,6 +173,37 @@ } ] } + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/G4CANTESTING.elf", + "name": "G4CANTESTING", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink.cfg", + "target/stm32g4x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build G4CANTESTING", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Platform/STM32G474xE/CompileDependencies/STM32G474.svd", + "swoConfig": { + "enabled": true, + "cpuFrequency": 160000000, + "swoFrequency": 2000000, + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "showOnStartup": true, + "port": 0, + "encoding": "ascii" + } + ] + } } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 7d069fb4..f88faf9a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -27,6 +27,15 @@ ], "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4PERTESTING" }, + { + "label": "CMake: configure and build G4CANTESTING", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure" + ], + "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4CANTESTING" + }, { "label": "CMake: configure and build G4HELLO", "type": "shell", diff --git a/CMakeLists.txt b/CMakeLists.txt index 3478a23b..0550ebea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ add_gr_project(STM32G474xE ECU) # Development add_gr_project(STM32G474xE G4PERTESTING) +add_gr_project(STM32G474xE G4CANTESTING) # BLINKY Demos add_gr_project(STM32G474xE BLINKY G4HELLO) @@ -56,7 +57,3 @@ add_gr_project(STM32L476xG BLINKY L4BLINKY) # Onboarding Workshops add_gr_project(STM32G474xE Onboarding W3_G4SPI_Receive) add_gr_project(STM32G474xE Onboarding W3_G4SPI_Transmit) - - -# Onboarding Projects -# TODO Add onboarding projects here as needed diff --git a/G4CANTESTING/CMakeLists.txt b/G4CANTESTING/CMakeLists.txt new file mode 100644 index 00000000..0f9f978c --- /dev/null +++ b/G4CANTESTING/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.25) + +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + +# Define the build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +endif() + +# Enable compile command to ease indexing with e.g. clangd +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) + +# Enable CMake support for ASM and C languages +enable_language( + C + ASM +) + +# Core project settings +project(${CMAKE_PROJECT_NAME}) + +# what, does in fact not get the filename of somthing but rather the name of the project from the path +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +add_library(${PROJECT_NAME}_USER_CODE INTERFACE) + +target_sources( + ${PROJECT_NAME}_USER_CODE + INTERFACE + Core/Src/adc.c + Core/Src/crc.c + Core/Src/dma.c + Core/Src/fdcan.c + Core/Src/gpio.c + Core/Src/i2c.c + Core/Src/main.c + Core/Src/spi.c + Core/Src/stm32g4xx_hal_msp.c + Core/Src/stm32g4xx_it.c + Core/Src/syscalls.c + Core/Src/sysmem.c + Core/Src/system_stm32g4xx.c + Core/Src/tim.c + Core/Src/usart.c +) + +target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_LIB) +target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_TEST_LIB) + + +target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) diff --git a/G4CANTESTING/Core/Inc/adc.h b/G4CANTESTING/Core/Inc/adc.h new file mode 100644 index 00000000..41154538 --- /dev/null +++ b/G4CANTESTING/Core/Inc/adc.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ADC_H__ +#define __ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_ADC1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_H__ */ diff --git a/G4CANTESTING/Core/Inc/crc.h b/G4CANTESTING/Core/Inc/crc.h new file mode 100644 index 00000000..133957e9 --- /dev/null +++ b/G4CANTESTING/Core/Inc/crc.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.h + * @brief This file contains all the function prototypes for + * the crc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRC_H__ +#define __CRC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern CRC_HandleTypeDef hcrc; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_CRC_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRC_H__ */ diff --git a/G4CANTESTING/Core/Inc/dma.h b/G4CANTESTING/Core/Inc/dma.h new file mode 100644 index 00000000..ae819cab --- /dev/null +++ b/G4CANTESTING/Core/Inc/dma.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.h + * @brief This file contains all the function prototypes for + * the dma.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DMA_H__ +#define __DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* DMA memory to memory transfer handles -------------------------------------*/ + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_DMA_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DMA_H__ */ diff --git a/G4CANTESTING/Core/Inc/fdcan.h b/G4CANTESTING/Core/Inc/fdcan.h new file mode 100644 index 00000000..56c4a8ad --- /dev/null +++ b/G4CANTESTING/Core/Inc/fdcan.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file fdcan.h + * @brief This file contains all the function prototypes for + * the fdcan.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FDCAN_H__ +#define __FDCAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern FDCAN_HandleTypeDef hfdcan2; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_FDCAN2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FDCAN_H__ */ diff --git a/G4CANTESTING/Core/Inc/gpio.h b/G4CANTESTING/Core/Inc/gpio.h new file mode 100644 index 00000000..843d4e9e --- /dev/null +++ b/G4CANTESTING/Core/Inc/gpio.h @@ -0,0 +1,48 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_GPIO_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif +#endif /*__ GPIO_H__ */ diff --git a/G4CANTESTING/Core/Inc/i2c.h b/G4CANTESTING/Core/Inc/i2c.h new file mode 100644 index 00000000..0a0a5080 --- /dev/null +++ b/G4CANTESTING/Core/Inc/i2c.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.h + * @brief This file contains all the function prototypes for + * the i2c.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __I2C_H__ +#define __I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_I2C2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __I2C_H__ */ diff --git a/G4CANTESTING/Core/Inc/main.h b/G4CANTESTING/Core/Inc/main.h new file mode 100644 index 00000000..af49e0e9 --- /dev/null +++ b/G4CANTESTING/Core/Inc/main.h @@ -0,0 +1,116 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32g4xx_hal.h" + +#include "stm32g4xx_ll_adc.h" +#include "stm32g4xx_ll_bus.h" +#include "stm32g4xx_ll_cortex.h" +#include "stm32g4xx_ll_crs.h" +#include "stm32g4xx_ll_dma.h" +#include "stm32g4xx_ll_exti.h" +#include "stm32g4xx_ll_gpio.h" +#include "stm32g4xx_ll_i2c.h" +#include "stm32g4xx_ll_lpuart.h" +#include "stm32g4xx_ll_pwr.h" +#include "stm32g4xx_ll_rcc.h" +#include "stm32g4xx_ll_spi.h" +#include "stm32g4xx_ll_system.h" +#include "stm32g4xx_ll_tim.h" +#include "stm32g4xx_ll_usart.h" +#include "stm32g4xx_ll_utils.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define BSPD_SIGNAL_Pin LL_GPIO_PIN_1 +#define BSPD_SIGNAL_GPIO_Port GPIOC +#define APPS1_SIGNAL_Pin LL_GPIO_PIN_2 +#define APPS1_SIGNAL_GPIO_Port GPIOC +#define APPS2_SIGNAL_Pin LL_GPIO_PIN_3 +#define APPS2_SIGNAL_GPIO_Port GPIOC +#define BLINKY_Pin LL_GPIO_PIN_5 +#define BLINKY_GPIO_Port GPIOA +#define IMD_SENSE_Pin LL_GPIO_PIN_6 +#define IMD_SENSE_GPIO_Port GPIOA +#define AMS_SENSE_Pin LL_GPIO_PIN_7 +#define AMS_SENSE_GPIO_Port GPIOA +#define BRAKE_F_SIGNAL_Pin LL_GPIO_PIN_0 +#define BRAKE_F_SIGNAL_GPIO_Port GPIOB +#define BRAKE_R_SIGNAL_Pin LL_GPIO_PIN_1 +#define BRAKE_R_SIGNAL_GPIO_Port GPIOB +#define LED_TEST_Pin LL_GPIO_PIN_11 +#define LED_TEST_GPIO_Port GPIOB +#define AUX_SIGNAL_Pin LL_GPIO_PIN_14 +#define AUX_SIGNAL_GPIO_Port GPIOB +#define STEERING_ANGLE_Pin LL_GPIO_PIN_15 +#define STEERING_ANGLE_GPIO_Port GPIOB +#define BRAKE_LIGHT_Pin LL_GPIO_PIN_4 +#define BRAKE_LIGHT_GPIO_Port GPIOB +#define TSSI_G_CONTROL_Pin LL_GPIO_PIN_5 +#define TSSI_G_CONTROL_GPIO_Port GPIOB +#define AUX_CONTROL_Pin LL_GPIO_PIN_8 +#define AUX_CONTROL_GPIO_Port GPIOB +#define SOFTWARE_OK_CONTROL_Pin LL_GPIO_PIN_9 +#define SOFTWARE_OK_CONTROL_GPIO_Port GPIOB + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/G4CANTESTING/Core/Inc/spi.h b/G4CANTESTING/Core/Inc/spi.h new file mode 100644 index 00000000..74bed003 --- /dev/null +++ b/G4CANTESTING/Core/Inc/spi.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.h + * @brief This file contains all the function prototypes for + * the spi.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SPI_H__ +#define __SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_SPI3_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPI_H__ */ diff --git a/G4CANTESTING/Core/Inc/stm32_assert.h b/G4CANTESTING/Core/Inc/stm32_assert.h new file mode 100644 index 00000000..c0d98f1d --- /dev/null +++ b/G4CANTESTING/Core/Inc/stm32_assert.h @@ -0,0 +1,53 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32_assert.h + * @author MCD Application Team + * @brief STM32 assert file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_ASSERT_H +#define __STM32_ASSERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) \ + ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_ASSERT_H */ diff --git a/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h b/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h new file mode 100644 index 00000000..dc9ea7ec --- /dev/null +++ b/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h @@ -0,0 +1,394 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32G4xx_HAL_CONF_H +#define STM32G4xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED + +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CORDIC_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +#define HAL_FDCAN_MODULE_ENABLED +/*#define HAL_FMAC_MODULE_ENABLED */ +/*#define HAL_HRTIM_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Register Callbacks selection + * ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_EXTI_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U + +/* ########################## Oscillator Values adaptation + * ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your + * application. This value is used by the RCC HAL module to compute the system + * frequency (when HSE is used as system clock source, directly or through the + * PLL). + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE (16000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system + * frequency (when HSI is used as system clock source, directly or through the + * PLL). + */ +#if !defined(HSI_VALUE) +#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS and RNG. + * This internal oscillator is mainly dedicated to provide a high + * precision clock to the USB peripheral by means of a special Clock Recovery + * System (CRS) circuitry. When the CRS is not used, the HSI48 RC oscillator + * runs on it default frequency which is subject to manufacturing process + * variations. + */ +#if !defined(HSI48_VALUE) +#define HSI48_VALUE \ + (48000000UL) /*!< Value of the Internal High Speed oscillator for USB \ + FS/RNG in Hz. The real value my vary depending on \ + manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined(LSI_VALUE) +/*!< Value of the Internal Low Speed oscillator in Hz +The real value may vary depending on the variations in voltage and +temperature.*/ +#define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system + * frequency + */ +#if !defined(LSE_VALUE) +#define LSE_VALUE \ + (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S and SAI peripherals + * This value is used by the I2S and SAI HAL modules to compute the I2S + * and SAI clock source frequency, this source is inserted directly through + * I2S_CKIN pad. + */ +#if !defined(EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE \ + (12288000UL) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY \ + (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32g4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32g4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32g4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32g4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32g4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32g4xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED +#include "stm32g4xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32g4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32g4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32g4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32g4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32g4xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32g4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED +#include "stm32g4xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_HRTIM_MODULE_ENABLED +#include "stm32g4xx_hal_hrtim.h" +#endif /* HAL_HRTIM_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32g4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32g4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32g4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32g4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32g4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32g4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32g4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32g4xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32g4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32g4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED +#include "stm32g4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32g4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32g4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32g4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32g4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32g4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32g4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32g4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32g4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32g4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32g4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32g4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) \ + ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32G4xx_HAL_CONF_H */ diff --git a/G4CANTESTING/Core/Inc/stm32g4xx_it.h b/G4CANTESTING/Core/Inc/stm32g4xx_it.h new file mode 100644 index 00000000..b6c3b2f7 --- /dev/null +++ b/G4CANTESTING/Core/Inc/stm32g4xx_it.h @@ -0,0 +1,67 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32G4xx_IT_H +#define __STM32G4xx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void FDCAN2_IT0_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32G4xx_IT_H */ diff --git a/G4CANTESTING/Core/Inc/tim.h b/G4CANTESTING/Core/Inc/tim.h new file mode 100644 index 00000000..c19e6cc7 --- /dev/null +++ b/G4CANTESTING/Core/Inc/tim.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TIM_H__ +#define __TIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_TIM2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_H__ */ diff --git a/G4CANTESTING/Core/Inc/usart.h b/G4CANTESTING/Core/Inc/usart.h new file mode 100644 index 00000000..daefd73e --- /dev/null +++ b/G4CANTESTING/Core/Inc/usart.h @@ -0,0 +1,50 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.h + * @brief This file contains all the function prototypes for + * the usart.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USART_H__ +#define __USART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_LPUART1_UART_Init(void); +void MX_USART1_UART_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USART_H__ */ diff --git a/G4CANTESTING/Core/Src/adc.c b/G4CANTESTING/Core/Src/adc.c new file mode 100644 index 00000000..529917dd --- /dev/null +++ b/G4CANTESTING/Core/Src/adc.c @@ -0,0 +1,209 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "adc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + LL_ADC_InitTypeDef ADC_InitStruct = {0}; + LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0}; + LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetADCClockSource(LL_RCC_ADC12_CLKSOURCE_SYSCLK); + + /* Peripheral clock enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**ADC1 GPIO Configuration + PC1 ------> ADC1_IN7 + PC2 ------> ADC1_IN8 + PC3 ------> ADC1_IN9 + PB0 ------> ADC1_IN15 + PB1 ------> ADC1_IN12 + PB14 ------> ADC1_IN5 + */ + GPIO_InitStruct.Pin = BSPD_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BSPD_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = APPS1_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(APPS1_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = APPS2_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(APPS2_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = BRAKE_F_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_F_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = BRAKE_R_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_R_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = AUX_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AUX_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + /* ADC1 DMA Init */ + + /* ADC1 Init */ + LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1); + + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, + LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, + LL_DMA_PRIORITY_LOW); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, + LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, + LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, + LL_DMA_PDATAALIGN_HALFWORD); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, + LL_DMA_MDATAALIGN_HALFWORD); + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Common config + */ + ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B; + ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE; + LL_ADC_Init(ADC1, &ADC_InitStruct); + ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; + ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS; + ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; + ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS; + ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED; + ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED; + LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct); + LL_ADC_SetGainCompensation(ADC1, 0); + LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE); + ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV256; + ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT; + LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), + &ADC_CommonInitStruct); + + /* Disable ADC deep power down (enabled by default after reset state) */ + LL_ADC_DisableDeepPowerDown(ADC1); + /* Enable ADC internal voltage regulator */ + LL_ADC_EnableInternalRegulator(ADC1); + /* Delay for ADC internal voltage regulator stabilization. */ + /* Compute number of CPU cycles to wait for, from delay in us. */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles (depends on compilation optimization). */ + /* Note: If system core clock frequency is below 200kHz, wait time */ + /* is only a few CPU processing cycles. */ + uint32_t wait_loop_index; + wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * + (SystemCoreClock / (100000 * 2))) / + 10); + while (wait_loop_index != 0) { + wait_loop_index--; + } + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, + LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, + LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_7); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, + LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, + LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_8); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, + LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, + LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_9); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, + LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, + LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, + LL_ADC_CHANNEL_12); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, + LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, + LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, + LL_ADC_CHANNEL_15); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, + LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, + LL_ADC_SINGLE_ENDED); + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/crc.c b/G4CANTESTING/Core/Src/crc.c new file mode 100644 index 00000000..213510a5 --- /dev/null +++ b/G4CANTESTING/Core/Src/crc.c @@ -0,0 +1,86 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.c + * @brief This file provides code for the configuration + * of the CRC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "crc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +CRC_HandleTypeDef hcrc; + +/* CRC init function */ +void MX_CRC_Init(void) +{ + + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ + hcrc.Instance = CRC; + hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + if (HAL_CRC_Init(&hcrc) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ +} + +void HAL_CRC_MspInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspInit 0 */ + + /* USER CODE END CRC_MspInit 0 */ + /* CRC clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + /* USER CODE BEGIN CRC_MspInit 1 */ + + /* USER CODE END CRC_MspInit 1 */ + } +} + +void HAL_CRC_MspDeInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspDeInit 0 */ + + /* USER CODE END CRC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CRC_CLK_DISABLE(); + /* USER CODE BEGIN CRC_MspDeInit 1 */ + + /* USER CODE END CRC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/dma.c b/G4CANTESTING/Core/Src/dma.c new file mode 100644 index 00000000..491e3889 --- /dev/null +++ b/G4CANTESTING/Core/Src/dma.c @@ -0,0 +1,50 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.c + * @brief This file provides code for the configuration + * of all the requested memory to memory DMA transfers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "dma.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure DMA */ +/*----------------------------------------------------------------------------*/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Enable DMA controller clock + */ +void MX_DMA_Init(void) +{ + + /* Init with LL driver */ + /* DMA controller clock enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/G4CANTESTING/Core/Src/fdcan.c b/G4CANTESTING/Core/Src/fdcan.c new file mode 100644 index 00000000..3fa841e1 --- /dev/null +++ b/G4CANTESTING/Core/Src/fdcan.c @@ -0,0 +1,133 @@ +// /* USER CODE BEGIN Header */ +// /** +// ****************************************************************************** +// * @file fdcan.c +// * @brief This file provides code for the configuration +// * of the FDCAN instances. +// ****************************************************************************** +// * @attention +// * +// * Copyright (c) 2024 STMicroelectronics. +// * All rights reserved. +// * +// * This software is licensed under terms that can be found in the LICENSE file +// * in the root directory of this software component. +// * If no LICENSE file comes with this software, it is provided AS-IS. +// * +// ****************************************************************************** +// */ +// /* USER CODE END Header */ +// /* Includes ------------------------------------------------------------------*/ +// #include "fdcan.h" + +// /* USER CODE BEGIN 0 */ + +// /* USER CODE END 0 */ + +// FDCAN_HandleTypeDef hfdcan2; + +// /* FDCAN2 init function */ +// void MX_FDCAN2_Init(void) +// { + +// /* USER CODE BEGIN FDCAN2_Init 0 */ + +// /* USER CODE END FDCAN2_Init 0 */ + +// /* USER CODE BEGIN FDCAN2_Init 1 */ + +// /* USER CODE END FDCAN2_Init 1 */ +// hfdcan2.Instance = FDCAN2; +// hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1; +// hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; +// hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; +// hfdcan2.Init.AutoRetransmission = ENABLE; +// hfdcan2.Init.TransmitPause = DISABLE; +// hfdcan2.Init.ProtocolException = ENABLE; +// hfdcan2.Init.NominalPrescaler = 1; +// hfdcan2.Init.NominalSyncJumpWidth = 16; +// hfdcan2.Init.NominalTimeSeg1 = 119; +// hfdcan2.Init.NominalTimeSeg2 = 40; +// hfdcan2.Init.DataPrescaler = 8; +// hfdcan2.Init.DataSyncJumpWidth = 16; +// hfdcan2.Init.DataTimeSeg1 = 14; +// hfdcan2.Init.DataTimeSeg2 = 5; +// hfdcan2.Init.StdFiltersNbr = 0; +// hfdcan2.Init.ExtFiltersNbr = 2; +// hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; +// if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { +// Error_Handler(); +// } +// /* USER CODE BEGIN FDCAN2_Init 2 */ + +// /* USER CODE END FDCAN2_Init 2 */ +// } + +// void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// GPIO_InitTypeDef GPIO_InitStruct = {0}; +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspInit 0 */ + +// /* USER CODE END FDCAN2_MspInit 0 */ +// LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + +// /* FDCAN2 clock enable */ +// __HAL_RCC_FDCAN_CLK_ENABLE(); + +// __HAL_RCC_GPIOB_CLK_ENABLE(); +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// GPIO_InitStruct.Pin = GPIO_PIN_12; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_PULLUP; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// GPIO_InitStruct.Pin = GPIO_PIN_13; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_NOPULL; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// /* FDCAN2 interrupt Init */ +// HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0); +// HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspInit 1 */ + +// /* USER CODE END FDCAN2_MspInit 1 */ +// } +// } + +// /*void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspDeInit 0 */ + +// /* USER CODE END FDCAN2_MspDeInit 0 */ +// /* Peripheral clock disable */ +// __HAL_RCC_FDCAN_CLK_DISABLE(); + +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13); + +// /* FDCAN2 interrupt Deinit */ +// HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspDeInit 1 */ + +// /* USER CODE END FDCAN2_MspDeInit 1 */ +// } +// } + +// /* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/gpio.c b/G4CANTESTING/Core/Src/gpio.c new file mode 100644 index 00000000..9aa78e16 --- /dev/null +++ b/G4CANTESTING/Core/Src/gpio.c @@ -0,0 +1,261 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "gpio.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI + * Free pins are configured automatically as Analog (this feature is + enabled through + * the Code Generation settings) + PA6 ------> ADC2_IN3 + PA7 ------> ADC2_IN4 + PB15 ------> ADC2_IN15 + PB7 ------> UART4_CTS +*/ +void MX_GPIO_Init(void) +{ + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOF); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOG); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + + /**/ + LL_GPIO_ResetOutputPin(BLINKY_GPIO_Port, BLINKY_Pin); + + /**/ + LL_GPIO_ResetOutputPin(LED_TEST_GPIO_Port, LED_TEST_Pin); + + /**/ + LL_GPIO_ResetOutputPin(BRAKE_LIGHT_GPIO_Port, BRAKE_LIGHT_Pin); + + /**/ + LL_GPIO_ResetOutputPin(TSSI_G_CONTROL_GPIO_Port, TSSI_G_CONTROL_Pin); + + /**/ + LL_GPIO_ResetOutputPin(AUX_CONTROL_GPIO_Port, AUX_CONTROL_Pin); + + /**/ + LL_GPIO_ResetOutputPin(SOFTWARE_OK_CONTROL_GPIO_Port, + SOFTWARE_OK_CONTROL_Pin); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_13; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_14; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_1; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = BLINKY_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BLINKY_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = IMD_SENSE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(IMD_SENSE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = AMS_SENSE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AMS_SENSE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LED_TEST_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(LED_TEST_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = STEERING_ANGLE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(STEERING_ANGLE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = BRAKE_LIGHT_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_LIGHT_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = TSSI_G_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(TSSI_G_CONTROL_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_14; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = AUX_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AUX_CONTROL_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = SOFTWARE_OK_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(SOFTWARE_OK_CONTROL_GPIO_Port, &GPIO_InitStruct); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/G4CANTESTING/Core/Src/i2c.c b/G4CANTESTING/Core/Src/i2c.c new file mode 100644 index 00000000..bfb4e015 --- /dev/null +++ b/G4CANTESTING/Core/Src/i2c.c @@ -0,0 +1,92 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.c + * @brief This file provides code for the configuration + * of the I2C instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "i2c.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* I2C2 init function */ +void MX_I2C2_Init(void) +{ + + /* USER CODE BEGIN I2C2_Init 0 */ + + /* USER CODE END I2C2_Init 0 */ + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetI2CClockSource(LL_RCC_I2C2_CLKSOURCE_PCLK1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**I2C2 GPIO Configuration + PC4 ------> I2C2_SCL + PA8 ------> I2C2_SDA + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2); + + /* USER CODE BEGIN I2C2_Init 1 */ + + /* USER CODE END I2C2_Init 1 */ + + /** I2C Initialization + */ + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.Timing = 0x30D29DE4; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + LL_I2C_Init(I2C2, &I2C_InitStruct); + LL_I2C_EnableAutoEndMode(I2C2); + LL_I2C_SetOwnAddress2(I2C2, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(I2C2); + LL_I2C_DisableGeneralCall(I2C2); + LL_I2C_EnableClockStretching(I2C2); + /* USER CODE BEGIN I2C2_Init 2 */ + + /* USER CODE END I2C2_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/main.c b/G4CANTESTING/Core/Src/main.c new file mode 100644 index 00000000..03635c54 --- /dev/null +++ b/G4CANTESTING/Core/Src/main.c @@ -0,0 +1,283 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "adc.h" +#include "dma.h" +#include "fdcan.h" +#include "gpio.h" +#include "i2c.h" +#include "spi.h" +#include "tim.h" +#include "usart.h" + +#include "can.h" // Assume this works +#include "can_tests.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "Logomatic.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ +/* Enable ITM for SWO output */ +static void ITM_Enable(void) +{ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; + + /* Enable TRC (Trace) */ + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + + /* Configure TPI for SWO output (set prescaler for 2MHz SWO clock) */ + TPI->SPPR = 2U; /* 2 = Manchester/async UART mode */ + TPI->ACPR = 84U; /* Prescaler: (170 MHz / (84+1) / 2) ≈ 1MHz SWO */ + + ITM->TER |= (1UL << 0); + ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); +} +static int toggleze = 0; +void DEBUG_callback(void *data, uint32_t size) +{ + toggleze = (*((char *)data) & 0x80); +} + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU + * Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the + * Systick. */ + HAL_Init(); + /* USER CODE BEGIN Init */ + ITM_Enable(); + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_DMA_Init(); + // MX_FDCAN2_Init(); + MX_ADC1_Init(); + MX_LPUART1_UART_Init(); + MX_I2C2_Init(); + MX_USART1_UART_Init(); + MX_SPI3_Init(); + MX_TIM2_Init(); + + /* USER CODE BEGIN 2 */ + + LOGOMATIC("Booted!\n"); + can_test(); + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) { + /* USER CODE END WHILE */ + LOGOMATIC("Main Loop\n"); + LL_mDelay(1000); + + // Receive on GPIOs + // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET + // : GPIO_PIN_RESET); HAL_Delay(1000); msg.data[0] = toggleze ? + // 0x00 : 0x80; can_send(can2Handle, &msg); + + // RCC->CFGR |= RCC_CFGR_SW; + /* USER CODE BEGIN 3 */ + } +} + +/** + * @brief System Clock Configuration + * @retval None + */ + +// void SystemClock_Config(void) +// { +// LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); +// while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { +// } +// LL_PWR_EnableRange1BoostMode(); +// LL_RCC_HSE_Enable(); + +// /* Wait till HSE is ready */ +// while (LL_RCC_HSE_IsReady() != 1) { +// } + +// LL_RCC_HSE_EnableCSS(); +// LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, +// LL_RCC_PLLR_DIV_2); +// //LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, ); +// LL_RCC_PLL_EnableDomain_SYS(); +// LL_RCC_PLL_Enable(); +// /* Wait till PLL is ready */ +// while (LL_RCC_PLL_IsReady() != 1) { +// } + +// LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); +// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); +// /* Wait till System clock is ready */ +// while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { +// } + +// /* Insure 1us transition state at intermediate medium speed clock*/ +// for (__IO uint32_t i = (170 >> 1); i != 0; i--) +// ; + +// /* Set AHB prescaler*/ +// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); +// LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); +// LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); +// LL_SetSystemCoreClock(160000000); + +// /* Update the time base */ +// if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { +// Error_Handler(); +// } +// }*/ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); + while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { + } + LL_PWR_EnableRange1BoostMode(); + LL_RCC_HSI_Enable(); + /* Wait till HSI is ready */ + while (LL_RCC_HSI_IsReady() != 1) { + } + + LL_RCC_HSI_SetCalibTrimming(64); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, + LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_EnableDomain_SYS(); + LL_RCC_PLL_Enable(); + /* Wait till PLL is ready */ + while (LL_RCC_PLL_IsReady() != 1) { + } + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + // LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + /* Wait till System clock is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { + } + + /* Insure 1us transition state at intermediate medium speed clock*/ + for (__IO uint32_t i = (170 >> 1); i != 0; i--) + ; + + /* Set AHB prescaler*/ + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + LL_SetSystemCoreClock(170000000); + + /* Update the time base */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return + * state */ + __disable_irq(); + while (1) { + } + /* USER CODE END Error_Handler_Debug */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line + number, ex: printf("Wrong parameters value: file %s on line %d\r\n", + file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/G4CANTESTING/Core/Src/spi.c b/G4CANTESTING/Core/Src/spi.c new file mode 100644 index 00000000..66459f2e --- /dev/null +++ b/G4CANTESTING/Core/Src/spi.c @@ -0,0 +1,95 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.c + * @brief This file provides code for the configuration + * of the SPI instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "spi.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* SPI3 init function */ +void MX_SPI3_Init(void) +{ + + /* USER CODE BEGIN SPI3_Init 0 */ + + /* USER CODE END SPI3_Init 0 */ + + LL_SPI_InitTypeDef SPI_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI3); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + /**SPI3 GPIO Configuration + PC10 ------> SPI3_SCK + PC11 ------> SPI3_MISO + PC12 ------> SPI3_MOSI + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI3_Init 1 */ + + /* USER CODE END SPI3_Init 1 */ + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_4BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32; + SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI3, &SPI_InitStruct); + LL_SPI_SetStandard(SPI3, LL_SPI_PROTOCOL_MOTOROLA); + LL_SPI_EnableNSSPulseMgt(SPI3); + /* USER CODE BEGIN SPI3_Init 2 */ + + /* USER CODE END SPI3_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c b/G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c new file mode 100644 index 00000000..69189ef4 --- /dev/null +++ b/G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c @@ -0,0 +1,86 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral + */ + HAL_PWREx_DisableUCPDDeadBattery(); + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/stm32g4xx_it.c b/G4CANTESTING/Core/Src/stm32g4xx_it.c new file mode 100644 index 00000000..1db87c69 --- /dev/null +++ b/G4CANTESTING/Core/Src/stm32g4xx_it.c @@ -0,0 +1,213 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32g4xx_it.h" +#include "main.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +//extern FDCAN_HandleTypeDef hfdcan2; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32G4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32g4xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles FDCAN2 interrupt 0. + */ +/* +// void FDCAN2_IT0_IRQHandler(void) +// { +// /* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */ + +// /* USER CODE END FDCAN2_IT0_IRQn 0 */ +// HAL_FDCAN_IRQHandler(&hfdcan2); +// /* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */ + +// /* USER CODE END FDCAN2_IT0_IRQn 1 */ +// } + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/syscalls.c b/G4CANTESTING/Core/Src/syscalls.c new file mode 100644 index 00000000..a2412b22 --- /dev/null +++ b/G4CANTESTING/Core/Src/syscalls.c @@ -0,0 +1,166 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeMX + * @brief Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Variables */ +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + +char *__env[1] = {0}; +char **environ = __env; + +/* Functions */ +void initialise_monitor_handles() {} + +int _getpid(void) { return 1; } + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + errno = EINVAL; + return -1; +} + +void _exit(int status) +{ + _kill(status, -1); + while (1) { + } /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) { + *ptr++ = __io_getchar(); + } + + return len; +} + +__attribute__((weak)) int _write(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + (void)file; + return -1; +} + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _open(char *path, int flags, ...) +{ + (void)path; + (void)flags; + /* Pretend like we always fail */ + return -1; +} + +int _wait(int *status) +{ + (void)status; + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + (void)name; + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + (void)buf; + return -1; +} + +int _stat(char *file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + (void)old; + (void)new; + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + (void)name; + (void)argv; + (void)env; + errno = ENOMEM; + return -1; +} diff --git a/G4CANTESTING/Core/Src/sysmem.c b/G4CANTESTING/Core/Src/sysmem.c new file mode 100644 index 00000000..619868a4 --- /dev/null +++ b/G4CANTESTING/Core/Src/sysmem.c @@ -0,0 +1,79 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Generated by STM32CubeMX + * @brief System Memory calls file + * + * For more information about which C functions + * need which of these lowlevel functions + * please consult the newlib libc manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc + * and others from the C library + * + * @verbatim + * ############################################################################ + * # .data # .bss # newlib heap # MSP stack # + * # # # # Reserved by _Min_Stack_Size # + * ############################################################################ + * ^-- RAM start ^-- _end _estack, RAM end --^ + * @endverbatim + * + * This implementation starts allocating at the '_end' linker symbol + * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack + * The implementation considers '_estack' linker symbol to be RAM end + * NOTE: If the MSP stack, at any point during execution, grows larger than the + * reserved size, please increase the '_Min_Stack_Size'. + * + * @param incr Memory size + * @return Pointer to allocated memory + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t + _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = + (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + const uint8_t *max_heap = (uint8_t *)stack_limit; + uint8_t *prev_heap_end; + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing into the reserved MSP stack */ + if (__sbrk_heap_end + incr > max_heap) { + errno = ENOMEM; + return (void *)-1; + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + return (void *)prev_heap_end; +} diff --git a/G4CANTESTING/Core/Src/system_stm32g4xx.c b/G4CANTESTING/Core/Src/system_stm32g4xx.c new file mode 100644 index 00000000..6254a05b --- /dev/null +++ b/G4CANTESTING/Core/Src/system_stm32g4xx.c @@ -0,0 +1,297 @@ +/** + ****************************************************************************** + * @file system_stm32g4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32g4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be + *used by the user application to setup the SysTick timer or configure other + *parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the HSI (16 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32g4xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 16 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * Require 48MHz for RNG | Disabled + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32g4xx_system + * @{ + */ + +/** @addtogroup STM32G4xx_System_Private_Includes + * @{ + */ + +#include "stm32g4xx.h" + +#if !defined(HSE_VALUE) +#define HSE_VALUE 24000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSI_VALUE) +#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate the vector table + anywhere in Flash or Sram, else the vector table is kept at the automatic + remap of boot address selected */ +/* #define USER_VECT_TAB_ADDRESS */ + +#if defined(USER_VECT_TAB_ADDRESS) +/*!< Uncomment the following line if you need to relocate your vector Table + in Sram else user remap will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS \ + SRAM_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#endif /* VECT_TAB_SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Variables + * @{ + */ +/* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock + frequency Note: If you use this function to configure the system clock; then + there is no need to call the 2 first functions listed above, since + SystemCoreClock variable is updated automatically. +*/ +uint32_t SystemCoreClock = HSI_VALUE; + +const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; +const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ +/* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << (10 * 2)) | + (3UL << (11 * 2))); /* set CP10 and CP11 Full Access */ +#endif + + /* Configure the Vector Table location add offset address + * ------------------*/ +#if defined(USER_VECT_TAB_ADDRESS) + SCB->VTOR = + VECT_TAB_BASE_ADDRESS | + VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or + * configure other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any + * configuration based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the + * HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the + * HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the + * HSE_VALUE(***) or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (**) HSI_VALUE is a constant defined in stm32g4xx_hal.h file (default + * value 16 MHz) but the real value may vary depending on the variations in + * voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32g4xx_hal.h file + * (default value 24 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using + * fractional value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp, pllvco, pllr, pllsource, pllm; + + /* Get SYSCLK source + * -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) { + case 0x04: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4) + 1U; + if (pllsource == + 0x02UL) /* HSI used as PLL clock source */ + { + pllvco = (HSI_VALUE / pllm); + } else /* HSE used as PLL clock source */ + { + pllvco = (HSE_VALUE / pllm); + } + pllvco = + pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8); + pllr = + (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * + 2U; + SystemCoreClock = pllvco / pllr; + break; + + default: + break; + } + /* Compute HCLK clock frequency + * --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/G4CANTESTING/Core/Src/tim.c b/G4CANTESTING/Core/Src/tim.c new file mode 100644 index 00000000..7f521c3b --- /dev/null +++ b/G4CANTESTING/Core/Src/tim.c @@ -0,0 +1,79 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "tim.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* TIM2 init function */ +void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 4294967295; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM2); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_FORCED_ACTIVE; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 0; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH1); + LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); + LL_TIM_DisableMasterSlaveMode(TIM2); + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**TIM2 GPIO Configuration + PA0 ------> TIM2_CH1 + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_1; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/usart.c b/G4CANTESTING/Core/Src/usart.c new file mode 100644 index 00000000..85df3b91 --- /dev/null +++ b/G4CANTESTING/Core/Src/usart.c @@ -0,0 +1,188 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.c + * @brief This file provides code for the configuration + * of the USART instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "usart.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* LPUART1 init function */ + +void MX_LPUART1_UART_Init(void) +{ + + /* USER CODE BEGIN LPUART1_Init 0 */ + + /* USER CODE END LPUART1_Init 0 */ + + LL_LPUART_InitTypeDef LPUART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_HSI); + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**LPUART1 GPIO Configuration + PA2 ------> LPUART1_TX + PA3 ------> LPUART1_RX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN LPUART1_Init 1 */ + + /* USER CODE END LPUART1_Init 1 */ + LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1; + LPUART_InitStruct.BaudRate = 115200; + LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; + LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; + LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; + LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; + LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; + LL_LPUART_Init(LPUART1, &LPUART_InitStruct); + LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_DisableFIFO(LPUART1); + + /* USER CODE BEGIN WKUPType LPUART1 */ + + /* USER CODE END WKUPType LPUART1 */ + + LL_LPUART_Enable(LPUART1); + + /* Polling LPUART1 initialisation */ + while ((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || + (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) { + } + /* USER CODE BEGIN LPUART1_Init 2 */ + + /* USER CODE END LPUART1_Init 2 */ +} +/* USART1 init function */ + +void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + LL_USART_InitTypeDef USART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + + /* Peripheral clock enable */ + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**USART1 GPIO Configuration + PC5 ------> USART1_RX + PA11 ------> USART1_CTS + PA12 ------> USART1_RTS + PB6 ------> USART1_TX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct.BaudRate = 115200; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_RTS_CTS; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_DisableFIFO(USART1); + LL_USART_ConfigAsyncMode(USART1); + + /* USER CODE BEGIN WKUPType USART1 */ + + /* USER CODE END WKUPType USART1 */ + + LL_USART_Enable(USART1); + + /* Polling USART1 initialisation */ + while ((!(LL_USART_IsActiveFlag_TEACK(USART1))) || + (!(LL_USART_IsActiveFlag_REACK(USART1)))) { + } + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/G4PERTESTING.ioc b/G4CANTESTING/G4PERTESTING.ioc new file mode 100644 index 00000000..8cf1860b --- /dev/null +++ b/G4CANTESTING/G4PERTESTING.ioc @@ -0,0 +1,382 @@ +#MicroXplorer Configuration settings - do not modify +ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_5 +ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_7 +ADC1.Channel-4\#ChannelRegularConversion=ADC_CHANNEL_8 +ADC1.Channel-5\#ChannelRegularConversion=ADC_CHANNEL_9 +ADC1.Channel-6\#ChannelRegularConversion=ADC_CHANNEL_12 +ADC1.Channel-7\#ChannelRegularConversion=ADC_CHANNEL_15 +ADC1.ClockPrescaler=ADC_CLOCK_ASYNC_DIV256 +ADC1.CommonPathInternal=null|null|null|null +ADC1.ContinuousConvMode=ENABLE +ADC1.DMAContinuousRequests=ENABLE +ADC1.EOCSelection=ADC_EOC_SEQ_CONV +ADC1.ExternalTrigConv=ADC_SOFTWARE_START +ADC1.IPParameters=Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,OffsetNumber-2\#ChannelRegularConversion,NbrOfConversionFlag,master,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,OffsetNumber-3\#ChannelRegularConversion,Rank-4\#ChannelRegularConversion,Channel-4\#ChannelRegularConversion,SamplingTime-4\#ChannelRegularConversion,OffsetNumber-4\#ChannelRegularConversion,Rank-5\#ChannelRegularConversion,Channel-5\#ChannelRegularConversion,SamplingTime-5\#ChannelRegularConversion,OffsetNumber-5\#ChannelRegularConversion,Rank-6\#ChannelRegularConversion,Channel-6\#ChannelRegularConversion,SamplingTime-6\#ChannelRegularConversion,OffsetNumber-6\#ChannelRegularConversion,Rank-7\#ChannelRegularConversion,Channel-7\#ChannelRegularConversion,SamplingTime-7\#ChannelRegularConversion,OffsetNumber-7\#ChannelRegularConversion,NbrOfConversion,ContinuousConvMode,DMAContinuousRequests,ClockPrescaler,EOCSelection,ExternalTrigConv,CommonPathInternal +ADC1.NbrOfConversion=6 +ADC1.NbrOfConversionFlag=1 +ADC1.OffsetNumber-2\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-3\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-4\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-5\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-6\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-7\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.Rank-2\#ChannelRegularConversion=1 +ADC1.Rank-3\#ChannelRegularConversion=2 +ADC1.Rank-4\#ChannelRegularConversion=3 +ADC1.Rank-5\#ChannelRegularConversion=4 +ADC1.Rank-6\#ChannelRegularConversion=5 +ADC1.Rank-7\#ChannelRegularConversion=6 +ADC1.SamplingTime-2\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-4\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-5\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-6\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-7\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.master=1 +CAD.formats=[] +CAD.pinconfig=Dual +CAD.provider= +Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY +Dma.ADC1.0.EventEnable=DISABLE +Dma.ADC1.0.Instance=DMA1_Channel1 +Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD +Dma.ADC1.0.MemInc=DMA_MINC_ENABLE +Dma.ADC1.0.Mode=DMA_CIRCULAR +Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD +Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE +Dma.ADC1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING +Dma.ADC1.0.Priority=DMA_PRIORITY_LOW +Dma.ADC1.0.RequestNumber=1 +Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber +Dma.ADC1.0.SignalID=NONE +Dma.ADC1.0.SyncEnable=DISABLE +Dma.ADC1.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT +Dma.ADC1.0.SyncRequestNumber=1 +Dma.ADC1.0.SyncSignalID=NONE +Dma.Request0=ADC1 +Dma.RequestsNb=1 +FDCAN2.AutoRetransmission=ENABLE +FDCAN2.CalculateBaudRateNominal=1000000 +FDCAN2.CalculateTimeBitNominal=1000 +FDCAN2.CalculateTimeQuantumNominal=6.25 +FDCAN2.DataPrescaler=8 +FDCAN2.DataSyncJumpWidth=16 +FDCAN2.DataTimeSeg1=14 +FDCAN2.DataTimeSeg2=5 +FDCAN2.ExtFiltersNbr=2 +FDCAN2.FrameFormat=FDCAN_FRAME_CLASSIC +FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,FrameFormat,NominalTimeSeg1,NominalTimeSeg2,NominalPrescaler,AutoRetransmission,StdFiltersNbr,TransmitPause,NominalSyncJumpWidth,DataTimeSeg1,DataTimeSeg2,DataPrescaler,DataSyncJumpWidth,ExtFiltersNbr,ProtocolException +FDCAN2.NominalPrescaler=1 +FDCAN2.NominalSyncJumpWidth=16 +FDCAN2.NominalTimeSeg1=119 +FDCAN2.NominalTimeSeg2=40 +FDCAN2.ProtocolException=ENABLE +FDCAN2.StdFiltersNbr=0 +FDCAN2.TransmitPause=DISABLE +File.Version=6 +GPIO.groupedBy=Group By Peripherals +I2C2.IPParameters=Timing +I2C2.Timing=0x30D29DE4 +KeepUserPlacement=false +LPUART1.BaudRate=115200 +LPUART1.IPParameters=BaudRate +Mcu.CPN=STM32G474RET6 +Mcu.Family=STM32G4 +Mcu.IP0=ADC1 +Mcu.IP1=DMA +Mcu.IP10=USART1 +Mcu.IP2=FDCAN2 +Mcu.IP3=I2C2 +Mcu.IP4=LPUART1 +Mcu.IP5=NVIC +Mcu.IP6=RCC +Mcu.IP7=SPI3 +Mcu.IP8=SYS +Mcu.IP9=TIM2 +Mcu.IPNb=11 +Mcu.Name=STM32G474R(B-C-E)Tx +Mcu.Package=LQFP64 +Mcu.Pin0=PF0-OSC_IN +Mcu.Pin1=PF1-OSC_OUT +Mcu.Pin10=PA7 +Mcu.Pin11=PC4 +Mcu.Pin12=PC5 +Mcu.Pin13=PB0 +Mcu.Pin14=PB1 +Mcu.Pin15=PB11 +Mcu.Pin16=PB12 +Mcu.Pin17=PB13 +Mcu.Pin18=PB14 +Mcu.Pin19=PB15 +Mcu.Pin2=PC1 +Mcu.Pin20=PA8 +Mcu.Pin21=PA11 +Mcu.Pin22=PA12 +Mcu.Pin23=PA13 +Mcu.Pin24=PA14 +Mcu.Pin25=PC10 +Mcu.Pin26=PC11 +Mcu.Pin27=PC12 +Mcu.Pin28=PB3 +Mcu.Pin29=PB4 +Mcu.Pin3=PC2 +Mcu.Pin30=PB5 +Mcu.Pin31=PB6 +Mcu.Pin32=PB7 +Mcu.Pin33=PB8-BOOT0 +Mcu.Pin34=PB9 +Mcu.Pin35=VP_SYS_VS_Systick +Mcu.Pin36=VP_SYS_VS_DBSignals +Mcu.Pin37=VP_TIM2_VS_ClockSourceINT +Mcu.Pin4=PC3 +Mcu.Pin5=PA0 +Mcu.Pin6=PA2 +Mcu.Pin7=PA3 +Mcu.Pin8=PA5 +Mcu.Pin9=PA6 +Mcu.PinsNb=38 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32G474RETx +MxCube.Version=6.15.0 +MxDb.Version=DB.6.0.150 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.FDCAN2_IT0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.ForceEnableDMAVector=false +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA0.Signal=S_TIM2_CH1 +PA11.Locked=true +PA11.Mode=CTS_RTS +PA11.Signal=USART1_CTS +PA12.Locked=true +PA12.Mode=CTS_RTS +PA12.Signal=USART1_RTS +PA13.Locked=true +PA13.Mode=Trace_Asynchronous_SW +PA13.Signal=SYS_JTMS-SWDIO +PA14.Locked=true +PA14.Mode=Trace_Asynchronous_SW +PA14.Signal=SYS_JTCK-SWCLK +PA2.GPIOParameters=GPIO_Speed +PA2.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA2.Locked=true +PA2.Mode=Asynchronous +PA2.Signal=LPUART1_TX +PA3.GPIOParameters=GPIO_Speed +PA3.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA3.Locked=true +PA3.Mode=Asynchronous +PA3.Signal=LPUART1_RX +PA5.GPIOParameters=GPIO_Label +PA5.GPIO_Label=BLINKY +PA5.Locked=true +PA5.Signal=GPIO_Output +PA6.GPIOParameters=GPIO_Label +PA6.GPIO_Label=IMD_SENSE +PA6.Locked=true +PA6.Signal=ADC2_IN3 +PA7.GPIOParameters=GPIO_Label +PA7.GPIO_Label=AMS_SENSE +PA7.Locked=true +PA7.Signal=ADC2_IN4 +PA8.Mode=I2C +PA8.Signal=I2C2_SDA +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=BRAKE_F_SIGNAL +PB0.Locked=true +PB0.Mode=IN15-Single-Ended +PB0.Signal=ADC1_IN15 +PB1.GPIOParameters=GPIO_Label +PB1.GPIO_Label=BRAKE_R_SIGNAL +PB1.Locked=true +PB1.Mode=IN12-Single-Ended +PB1.Signal=ADC1_IN12 +PB11.GPIOParameters=GPIO_Label +PB11.GPIO_Label=LED_TEST +PB11.Locked=true +PB11.Signal=GPIO_Output +PB12.GPIOParameters=GPIO_Speed,GPIO_PuPd +PB12.GPIO_PuPd=GPIO_PULLUP +PB12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PB12.Locked=true +PB12.Mode=FDCAN_Activate +PB12.Signal=FDCAN2_RX +PB13.GPIOParameters=GPIO_Speed +PB13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PB13.Locked=true +PB13.Mode=FDCAN_Activate +PB13.Signal=FDCAN2_TX +PB14.GPIOParameters=GPIO_Label +PB14.GPIO_Label=AUX_SIGNAL +PB14.Locked=true +PB14.Mode=IN5-Single-Ended +PB14.Signal=ADC1_IN5 +PB15.GPIOParameters=GPIO_Label +PB15.GPIO_Label=STEERING_ANGLE +PB15.Locked=true +PB15.Signal=ADC2_IN15 +PB3.Locked=true +PB3.Mode=Trace_Asynchronous_SW +PB3.Signal=SYS_JTDO-SWO +PB4.GPIOParameters=GPIO_Label +PB4.GPIO_Label=BRAKE_LIGHT +PB4.Locked=true +PB4.Signal=GPIO_Output +PB5.GPIOParameters=GPIO_Label +PB5.GPIO_Label=TSSI_G_CONTROL +PB5.Locked=true +PB5.Signal=GPIO_Output +PB6.Locked=true +PB6.Mode=Asynchronous +PB6.Signal=USART1_TX +PB7.Locked=true +PB7.Signal=UART4_CTS +PB8-BOOT0.GPIOParameters=GPIO_Label +PB8-BOOT0.GPIO_Label=AUX_CONTROL +PB8-BOOT0.Locked=true +PB8-BOOT0.Signal=GPIO_Output +PB9.GPIOParameters=GPIO_Label +PB9.GPIO_Label=SOFTWARE_OK_CONTROL +PB9.Locked=true +PB9.Signal=GPIO_Output +PC1.GPIOParameters=GPIO_Label +PC1.GPIO_Label=BSPD_SIGNAL +PC1.Locked=true +PC1.Mode=IN7-Single-Ended +PC1.Signal=ADC1_IN7 +PC10.Mode=Full_Duplex_Master +PC10.Signal=SPI3_SCK +PC11.Mode=Full_Duplex_Master +PC11.Signal=SPI3_MISO +PC12.Mode=Full_Duplex_Master +PC12.Signal=SPI3_MOSI +PC2.GPIOParameters=GPIO_Label +PC2.GPIO_Label=APPS1_SIGNAL +PC2.Locked=true +PC2.Mode=IN8-Single-Ended +PC2.Signal=ADC1_IN8 +PC3.GPIOParameters=GPIO_Label +PC3.GPIO_Label=APPS2_SIGNAL +PC3.Locked=true +PC3.Mode=IN9-Single-Ended +PC3.Signal=ADC1_IN9 +PC4.Mode=I2C +PC4.Signal=I2C2_SCL +PC5.Mode=Asynchronous +PC5.Signal=USART1_RX +PF0-OSC_IN.Locked=true +PF0-OSC_IN.Mode=HSE-External-Oscillator +PF0-OSC_IN.Signal=RCC_OSC_IN +PF1-OSC_OUT.Locked=true +PF1-OSC_OUT.Mode=HSE-External-Oscillator +PF1-OSC_OUT.Signal=RCC_OSC_OUT +PinOutPanel.RotationAngle=180 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=true +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32G474RETx +ProjectManager.FirmwarePackage=STM32Cube FW_G4 V1.6.1 +ProjectManager.FreePins=true +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=0 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=G4PERTESTING.ioc +ProjectManager.ProjectName=G4PERTESTING +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=CMake +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-LL-false,2-MX_GPIO_Init-GPIO-false-LL-true,3-MX_DMA_Init-DMA-false-LL-true,4-MX_FDCAN2_Init-FDCAN2-false-HAL-true,5-MX_ADC1_Init-ADC1-false-LL-true,6-MX_LPUART1_UART_Init-LPUART1-false-LL-true,7-MX_I2C2_Init-I2C2-false-LL-true,8-MX_USART1_UART_Init-USART1-false-LL-true,9-MX_SPI3_Init-SPI3-false-LL-true,10-MX_TIM2_Init-TIM2-false-LL-true +RCC.ADC12Freq_Value=160000000 +RCC.ADC345Freq_Value=160000000 +RCC.AHBFreq_Value=160000000 +RCC.APB1Freq_Value=160000000 +RCC.APB1TimFreq_Value=160000000 +RCC.APB2Freq_Value=160000000 +RCC.APB2TimFreq_Value=160000000 +RCC.CRSFreq_Value=48000000 +RCC.CortexFreq_Value=160000000 +RCC.EXTERNAL_CLOCK_VALUE=12288000 +RCC.EnbaleCSS=true +RCC.FCLKCortexFreq_Value=160000000 +RCC.FDCANFreq_Value=160000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=160000000 +RCC.HRTIM1Freq_Value=160000000 +RCC.HSE_VALUE=16000000 +RCC.HSI48_VALUE=48000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=160000000 +RCC.I2C2Freq_Value=160000000 +RCC.I2C3Freq_Value=160000000 +RCC.I2C4Freq_Value=160000000 +RCC.I2SFreq_Value=160000000 +RCC.IPParameters=ADC12Freq_Value,ADC345Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CRSFreq_Value,CortexFreq_Value,EXTERNAL_CLOCK_VALUE,EnbaleCSS,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HRTIM1Freq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2SFreq_Value,LPTIM1Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSI_VALUE,MCO1PinFreq_Value,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSourceVirtual,PWRFreq_Value,QSPIFreq_Value,RNGFreq_Value,SAI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value +RCC.LPTIM1Freq_Value=160000000 +RCC.LPUART1Freq_Value=160000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSE_VALUE=32768 +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=16000000 +RCC.PLLN=20 +RCC.PLLPoutputFreq_Value=160000000 +RCC.PLLQoutputFreq_Value=160000000 +RCC.PLLRCLKFreq_Value=160000000 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.PWRFreq_Value=160000000 +RCC.QSPIFreq_Value=160000000 +RCC.RNGFreq_Value=160000000 +RCC.SAI1Freq_Value=160000000 +RCC.SYSCLKFreq_VALUE=160000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.UART4Freq_Value=160000000 +RCC.UART5Freq_Value=160000000 +RCC.USART1Freq_Value=160000000 +RCC.USART2Freq_Value=160000000 +RCC.USART3Freq_Value=160000000 +RCC.USBFreq_Value=160000000 +RCC.VCOInputFreq_Value=16000000 +RCC.VCOOutputFreq_Value=320000000 +SH.S_TIM2_CH1.0=TIM2_CH1,Forced Output1 CH1 +SH.S_TIM2_CH1.ConfNb=1 +SPI3.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32 +SPI3.CalculateBaudRate=5.0 MBits/s +SPI3.Direction=SPI_DIRECTION_2LINES +SPI3.IPParameters=VirtualType,Mode,Direction,BaudRatePrescaler,CalculateBaudRate +SPI3.Mode=SPI_MODE_MASTER +SPI3.VirtualType=VM_MASTER +TIM2.Channel-Forced\ Output1\ CH1=TIM_CHANNEL_1 +TIM2.IPParameters=Channel-Forced Output1 CH1 +USART1.IPParameters=VirtualMode-Asynchronous +USART1.VirtualMode-Asynchronous=VM_ASYNC +VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals +VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM2_VS_ClockSourceINT.Mode=Internal +VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT +board=custom diff --git a/G4CANTESTING/README.md b/G4CANTESTING/README.md new file mode 100644 index 00000000..558f1c12 --- /dev/null +++ b/G4CANTESTING/README.md @@ -0,0 +1,5 @@ +# STM32G474 CAN +Nucleo-G474RE-C04 + +Plug in the board following ST-LINK pinout +Compile and flash G4CANTESTING.elf diff --git a/G4PERTESTING/CMakeLists.txt b/G4PERTESTING/CMakeLists.txt index 0f9f978c..fe543a8d 100644 --- a/G4PERTESTING/CMakeLists.txt +++ b/G4PERTESTING/CMakeLists.txt @@ -26,7 +26,6 @@ project(${CMAKE_PROJECT_NAME}) get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) add_library(${PROJECT_NAME}_USER_CODE INTERFACE) - target_sources( ${PROJECT_NAME}_USER_CODE INTERFACE @@ -47,8 +46,6 @@ target_sources( Core/Src/usart.c ) -target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_LIB) -target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_TEST_LIB) - +target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE) target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) diff --git a/G4PERTESTING/Core/Inc/main.h b/G4PERTESTING/Core/Inc/main.h index af49e0e9..23d7ffce 100644 --- a/G4PERTESTING/Core/Inc/main.h +++ b/G4PERTESTING/Core/Inc/main.h @@ -28,7 +28,6 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #include "stm32g4xx_hal.h" - #include "stm32g4xx_ll_adc.h" #include "stm32g4xx_ll_bus.h" #include "stm32g4xx_ll_cortex.h" diff --git a/G4PERTESTING/Core/Inc/stm32_assert.h b/G4PERTESTING/Core/Inc/stm32_assert.h index c0d98f1d..92460620 100644 --- a/G4PERTESTING/Core/Inc/stm32_assert.h +++ b/G4PERTESTING/Core/Inc/stm32_assert.h @@ -38,8 +38,7 @@ extern "C" { * If expr is true, it returns no value. * @retval None */ -#define assert_param(expr) \ - ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else diff --git a/G4PERTESTING/Core/Inc/stm32g4xx_hal_conf.h b/G4PERTESTING/Core/Inc/stm32g4xx_hal_conf.h index dc9ea7ec..3e1fcb01 100644 --- a/G4PERTESTING/Core/Inc/stm32g4xx_hal_conf.h +++ b/G4PERTESTING/Core/Inc/stm32g4xx_hal_conf.h @@ -144,9 +144,9 @@ extern "C" { * variations. */ #if !defined(HSI48_VALUE) -#define HSI48_VALUE \ - (48000000UL) /*!< Value of the Internal High Speed oscillator for USB \ - FS/RNG in Hz. The real value my vary depending on \ +#define HSI48_VALUE \ + (48000000UL) /*!< Value of the Internal High Speed oscillator for USB \ + FS/RNG in Hz. The real value my vary depending on \ manufacturing process variations.*/ #endif /* HSI48_VALUE */ @@ -165,9 +165,8 @@ temperature.*/ * frequency */ #if !defined(LSE_VALUE) -#define LSE_VALUE \ - (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ -#endif /* LSE_VALUE */ +#define LSE_VALUE (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ #if !defined(LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ @@ -180,9 +179,8 @@ temperature.*/ * I2S_CKIN pad. */ #if !defined(EXTERNAL_CLOCK_VALUE) -#define EXTERNAL_CLOCK_VALUE \ - (12288000UL) /*!< Value of the External oscillator in Hz*/ -#endif /* EXTERNAL_CLOCK_VALUE */ +#define EXTERNAL_CLOCK_VALUE (12288000UL) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ @@ -192,9 +190,8 @@ temperature.*/ * @brief This is the HAL system configuration section */ -#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ -#define TICK_INT_PRIORITY \ - (15UL) /*!< tick interrupt priority (lowest by default) */ +#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 0U #define INSTRUCTION_CACHE_ENABLE 1U @@ -379,8 +376,7 @@ temperature.*/ * If expr is true, it returns no value. * @retval None */ -#define assert_param(expr) \ - ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else diff --git a/G4PERTESTING/Core/Src/adc.c b/G4PERTESTING/Core/Src/adc.c index 529917dd..f3dbff8e 100644 --- a/G4PERTESTING/Core/Src/adc.c +++ b/G4PERTESTING/Core/Src/adc.c @@ -88,25 +88,19 @@ void MX_ADC1_Init(void) /* ADC1 Init */ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1); - LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); - LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_PRIORITY_LOW); + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR); - LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT); - LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT); - LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_PDATAALIGN_HALFWORD); + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD); - LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_MDATAALIGN_HALFWORD); + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD); /* USER CODE BEGIN ADC1_Init 1 */ @@ -129,8 +123,7 @@ void MX_ADC1_Init(void) LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE); ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV256; ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT; - LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), - &ADC_CommonInitStruct); + LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct); /* Disable ADC deep power down (enabled by default after reset state) */ LL_ADC_DisableDeepPowerDown(ADC1); @@ -143,9 +136,7 @@ void MX_ADC1_Init(void) /* Note: If system core clock frequency is below 200kHz, wait time */ /* is only a few CPU processing cycles. */ uint32_t wait_loop_index; - wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * - (SystemCoreClock / (100000 * 2))) / - 10); + wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10); while (wait_loop_index != 0) { wait_loop_index--; } @@ -153,52 +144,38 @@ void MX_ADC1_Init(void) /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_7); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_8); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_9); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ - LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, - LL_ADC_CHANNEL_12); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, - LL_ADC_SINGLE_ENDED); + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_12); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ - LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, - LL_ADC_CHANNEL_15); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, - LL_ADC_SINGLE_ENDED); + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, LL_ADC_CHANNEL_15); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED); /* USER CODE BEGIN ADC1_Init 2 */ /* USER CODE END ADC1_Init 2 */ diff --git a/G4PERTESTING/Core/Src/fdcan.c b/G4PERTESTING/Core/Src/fdcan.c index 3fa841e1..f39dbfa2 100644 --- a/G4PERTESTING/Core/Src/fdcan.c +++ b/G4PERTESTING/Core/Src/fdcan.c @@ -1,133 +1,133 @@ -// /* USER CODE BEGIN Header */ -// /** -// ****************************************************************************** -// * @file fdcan.c -// * @brief This file provides code for the configuration -// * of the FDCAN instances. -// ****************************************************************************** -// * @attention -// * -// * Copyright (c) 2024 STMicroelectronics. -// * All rights reserved. -// * -// * This software is licensed under terms that can be found in the LICENSE file -// * in the root directory of this software component. -// * If no LICENSE file comes with this software, it is provided AS-IS. -// * -// ****************************************************************************** -// */ -// /* USER CODE END Header */ -// /* Includes ------------------------------------------------------------------*/ -// #include "fdcan.h" - -// /* USER CODE BEGIN 0 */ - -// /* USER CODE END 0 */ - -// FDCAN_HandleTypeDef hfdcan2; - -// /* FDCAN2 init function */ -// void MX_FDCAN2_Init(void) -// { - -// /* USER CODE BEGIN FDCAN2_Init 0 */ - -// /* USER CODE END FDCAN2_Init 0 */ - -// /* USER CODE BEGIN FDCAN2_Init 1 */ - -// /* USER CODE END FDCAN2_Init 1 */ -// hfdcan2.Instance = FDCAN2; -// hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1; -// hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; -// hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; -// hfdcan2.Init.AutoRetransmission = ENABLE; -// hfdcan2.Init.TransmitPause = DISABLE; -// hfdcan2.Init.ProtocolException = ENABLE; -// hfdcan2.Init.NominalPrescaler = 1; -// hfdcan2.Init.NominalSyncJumpWidth = 16; -// hfdcan2.Init.NominalTimeSeg1 = 119; -// hfdcan2.Init.NominalTimeSeg2 = 40; -// hfdcan2.Init.DataPrescaler = 8; -// hfdcan2.Init.DataSyncJumpWidth = 16; -// hfdcan2.Init.DataTimeSeg1 = 14; -// hfdcan2.Init.DataTimeSeg2 = 5; -// hfdcan2.Init.StdFiltersNbr = 0; -// hfdcan2.Init.ExtFiltersNbr = 2; -// hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; -// if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { -// Error_Handler(); -// } -// /* USER CODE BEGIN FDCAN2_Init 2 */ - -// /* USER CODE END FDCAN2_Init 2 */ -// } - -// void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcanHandle) -// { - -// GPIO_InitTypeDef GPIO_InitStruct = {0}; -// if (fdcanHandle->Instance == FDCAN2) { -// /* USER CODE BEGIN FDCAN2_MspInit 0 */ - -// /* USER CODE END FDCAN2_MspInit 0 */ -// LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); - -// /* FDCAN2 clock enable */ -// __HAL_RCC_FDCAN_CLK_ENABLE(); - -// __HAL_RCC_GPIOB_CLK_ENABLE(); -// /**FDCAN2 GPIO Configuration -// PB12 ------> FDCAN2_RX -// PB13 ------> FDCAN2_TX -// */ -// GPIO_InitStruct.Pin = GPIO_PIN_12; -// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; -// GPIO_InitStruct.Pull = GPIO_PULLUP; -// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; -// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; -// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - -// GPIO_InitStruct.Pin = GPIO_PIN_13; -// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; -// GPIO_InitStruct.Pull = GPIO_NOPULL; -// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; -// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; -// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - -// /* FDCAN2 interrupt Init */ -// HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0); -// HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); -// /* USER CODE BEGIN FDCAN2_MspInit 1 */ - -// /* USER CODE END FDCAN2_MspInit 1 */ -// } -// } - -// /*void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcanHandle) -// { - -// if (fdcanHandle->Instance == FDCAN2) { -// /* USER CODE BEGIN FDCAN2_MspDeInit 0 */ - -// /* USER CODE END FDCAN2_MspDeInit 0 */ -// /* Peripheral clock disable */ -// __HAL_RCC_FDCAN_CLK_DISABLE(); - -// /**FDCAN2 GPIO Configuration -// PB12 ------> FDCAN2_RX -// PB13 ------> FDCAN2_TX -// */ -// HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13); - -// /* FDCAN2 interrupt Deinit */ -// HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); -// /* USER CODE BEGIN FDCAN2_MspDeInit 1 */ - -// /* USER CODE END FDCAN2_MspDeInit 1 */ -// } -// } - -// /* USER CODE BEGIN 1 */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file fdcan.c + * @brief This file provides code for the configuration + * of the FDCAN instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "fdcan.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +FDCAN_HandleTypeDef hfdcan2; + +/* FDCAN2 init function */ +void MX_FDCAN2_Init(void) +{ + + /* USER CODE BEGIN FDCAN2_Init 0 */ + + /* USER CODE END FDCAN2_Init 0 */ + + /* USER CODE BEGIN FDCAN2_Init 1 */ + + /* USER CODE END FDCAN2_Init 1 */ + hfdcan2.Instance = FDCAN2; + hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1; + hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; + hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; + hfdcan2.Init.AutoRetransmission = ENABLE; + hfdcan2.Init.TransmitPause = DISABLE; + hfdcan2.Init.ProtocolException = ENABLE; + hfdcan2.Init.NominalPrescaler = 1; + hfdcan2.Init.NominalSyncJumpWidth = 16; + hfdcan2.Init.NominalTimeSeg1 = 119; + hfdcan2.Init.NominalTimeSeg2 = 40; + hfdcan2.Init.DataPrescaler = 8; + hfdcan2.Init.DataSyncJumpWidth = 16; + hfdcan2.Init.DataTimeSeg1 = 14; + hfdcan2.Init.DataTimeSeg2 = 5; + hfdcan2.Init.StdFiltersNbr = 0; + hfdcan2.Init.ExtFiltersNbr = 2; + hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN FDCAN2_Init 2 */ + + /* USER CODE END FDCAN2_Init 2 */ +} + +void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcanHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if (fdcanHandle->Instance == FDCAN2) { + /* USER CODE BEGIN FDCAN2_MspInit 0 */ + + /* USER CODE END FDCAN2_MspInit 0 */ + LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + + /* FDCAN2 clock enable */ + __HAL_RCC_FDCAN_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**FDCAN2 GPIO Configuration + PB12 ------> FDCAN2_RX + PB13 ------> FDCAN2_TX + */ + GPIO_InitStruct.Pin = GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_13; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* FDCAN2 interrupt Init */ + HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); + /* USER CODE BEGIN FDCAN2_MspInit 1 */ + + /* USER CODE END FDCAN2_MspInit 1 */ + } +} + +void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcanHandle) +{ + + if (fdcanHandle->Instance == FDCAN2) { + /* USER CODE BEGIN FDCAN2_MspDeInit 0 */ + + /* USER CODE END FDCAN2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_FDCAN_CLK_DISABLE(); + + /**FDCAN2 GPIO Configuration + PB12 ------> FDCAN2_RX + PB13 ------> FDCAN2_TX + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13); + + /* FDCAN2 interrupt Deinit */ + HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); + /* USER CODE BEGIN FDCAN2_MspDeInit 1 */ + + /* USER CODE END FDCAN2_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/G4PERTESTING/Core/Src/gpio.c b/G4PERTESTING/Core/Src/gpio.c index 9aa78e16..d36e6eca 100644 --- a/G4PERTESTING/Core/Src/gpio.c +++ b/G4PERTESTING/Core/Src/gpio.c @@ -75,8 +75,7 @@ void MX_GPIO_Init(void) LL_GPIO_ResetOutputPin(AUX_CONTROL_GPIO_Port, AUX_CONTROL_Pin); /**/ - LL_GPIO_ResetOutputPin(SOFTWARE_OK_CONTROL_GPIO_Port, - SOFTWARE_OK_CONTROL_Pin); + LL_GPIO_ResetOutputPin(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin); /**/ GPIO_InitStruct.Pin = LL_GPIO_PIN_13; diff --git a/G4PERTESTING/Core/Src/main.c b/G4PERTESTING/Core/Src/main.c index 03635c54..d0c98d24 100644 --- a/G4PERTESTING/Core/Src/main.c +++ b/G4PERTESTING/Core/Src/main.c @@ -18,6 +18,7 @@ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" + #include "adc.h" #include "dma.h" #include "fdcan.h" @@ -27,12 +28,9 @@ #include "tim.h" #include "usart.h" -#include "can.h" // Assume this works -#include "can_tests.h" - /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ -#include "Logomatic.h" + /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -63,36 +61,6 @@ void SystemClock_Config(void); /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ -/* Enable ITM for SWO output */ -static void ITM_Enable(void) -{ - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Pin = LL_GPIO_PIN_3; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_0; - LL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; - - /* Enable TRC (Trace) */ - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - - /* Configure TPI for SWO output (set prescaler for 2MHz SWO clock) */ - TPI->SPPR = 2U; /* 2 = Manchester/async UART mode */ - TPI->ACPR = 84U; /* Prescaler: (170 MHz / (84+1) / 2) ≈ 1MHz SWO */ - - ITM->TER |= (1UL << 0); - ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); -} -static int toggleze = 0; -void DEBUG_callback(void *data, uint32_t size) -{ - toggleze = (*((char *)data) & 0x80); -} /* USER CODE END 0 */ @@ -102,6 +70,7 @@ void DEBUG_callback(void *data, uint32_t size) */ int main(void) { + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ @@ -112,8 +81,9 @@ int main(void) /* Reset of all peripherals, Initializes the Flash interface and the * Systick. */ HAL_Init(); + /* USER CODE BEGIN Init */ - ITM_Enable(); + /* USER CODE END Init */ /* Configure the system clock */ @@ -126,32 +96,28 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); - // MX_FDCAN2_Init(); + MX_FDCAN2_Init(); MX_ADC1_Init(); MX_LPUART1_UART_Init(); MX_I2C2_Init(); MX_USART1_UART_Init(); MX_SPI3_Init(); MX_TIM2_Init(); - /* USER CODE BEGIN 2 */ - LOGOMATIC("Booted!\n"); - can_test(); + /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ - LOGOMATIC("Main Loop\n"); - LL_mDelay(1000); - // Receive on GPIOs - // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET - // : GPIO_PIN_RESET); HAL_Delay(1000); msg.data[0] = toggleze ? - // 0x00 : 0x80; can_send(can2Handle, &msg); + // BLINKY + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); + HAL_Delay(1000); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); + HAL_Delay(1000); - // RCC->CFGR |= RCC_CFGR_SW; /* USER CODE BEGIN 3 */ } } @@ -160,64 +126,19 @@ int main(void) * @brief System Clock Configuration * @retval None */ - -// void SystemClock_Config(void) -// { -// LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); -// while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { -// } -// LL_PWR_EnableRange1BoostMode(); -// LL_RCC_HSE_Enable(); - -// /* Wait till HSE is ready */ -// while (LL_RCC_HSE_IsReady() != 1) { -// } - -// LL_RCC_HSE_EnableCSS(); -// LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, -// LL_RCC_PLLR_DIV_2); -// //LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, ); -// LL_RCC_PLL_EnableDomain_SYS(); -// LL_RCC_PLL_Enable(); -// /* Wait till PLL is ready */ -// while (LL_RCC_PLL_IsReady() != 1) { -// } - -// LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); -// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); -// /* Wait till System clock is ready */ -// while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { -// } - -// /* Insure 1us transition state at intermediate medium speed clock*/ -// for (__IO uint32_t i = (170 >> 1); i != 0; i--) -// ; - -// /* Set AHB prescaler*/ -// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); -// LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); -// LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); -// LL_SetSystemCoreClock(160000000); - -// /* Update the time base */ -// if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { -// Error_Handler(); -// } -// }*/ void SystemClock_Config(void) { LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { } LL_PWR_EnableRange1BoostMode(); - LL_RCC_HSI_Enable(); - /* Wait till HSI is ready */ - while (LL_RCC_HSI_IsReady() != 1) { + LL_RCC_HSE_Enable(); + /* Wait till HSE is ready */ + while (LL_RCC_HSE_IsReady() != 1) { } - LL_RCC_HSI_SetCalibTrimming(64); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, - LL_RCC_PLLR_DIV_2); + LL_RCC_HSE_EnableCSS(); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, LL_RCC_PLLR_DIV_2); LL_RCC_PLL_EnableDomain_SYS(); LL_RCC_PLL_Enable(); /* Wait till PLL is ready */ @@ -225,7 +146,7 @@ void SystemClock_Config(void) } LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); - // LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); /* Wait till System clock is ready */ while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { } @@ -238,7 +159,7 @@ void SystemClock_Config(void) LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); - LL_SetSystemCoreClock(170000000); + LL_SetSystemCoreClock(160000000); /* Update the time base */ if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { diff --git a/G4PERTESTING/Core/Src/stm32g4xx_it.c b/G4PERTESTING/Core/Src/stm32g4xx_it.c index 1db87c69..540b4b3e 100644 --- a/G4PERTESTING/Core/Src/stm32g4xx_it.c +++ b/G4PERTESTING/Core/Src/stm32g4xx_it.c @@ -19,6 +19,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32g4xx_it.h" + #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -55,7 +56,7 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ -//extern FDCAN_HandleTypeDef hfdcan2; +extern FDCAN_HandleTypeDef hfdcan2; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -196,17 +197,16 @@ void SysTick_Handler(void) /** * @brief This function handles FDCAN2 interrupt 0. */ -/* -// void FDCAN2_IT0_IRQHandler(void) -// { -// /* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */ +void FDCAN2_IT0_IRQHandler(void) +{ + /* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */ -// /* USER CODE END FDCAN2_IT0_IRQn 0 */ -// HAL_FDCAN_IRQHandler(&hfdcan2); -// /* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */ + /* USER CODE END FDCAN2_IT0_IRQn 0 */ + HAL_FDCAN_IRQHandler(&hfdcan2); + /* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */ -// /* USER CODE END FDCAN2_IT0_IRQn 1 */ -// } + /* USER CODE END FDCAN2_IT0_IRQn 1 */ +} /* USER CODE BEGIN 1 */ diff --git a/G4PERTESTING/Core/Src/sysmem.c b/G4PERTESTING/Core/Src/sysmem.c index 619868a4..00c39793 100644 --- a/G4PERTESTING/Core/Src/sysmem.c +++ b/G4PERTESTING/Core/Src/sysmem.c @@ -52,12 +52,10 @@ static uint8_t *__sbrk_heap_end = NULL; */ void *_sbrk(ptrdiff_t incr) { - extern uint8_t _end; /* Symbol defined in the linker script */ - extern uint8_t _estack; /* Symbol defined in the linker script */ - extern uint32_t - _Min_Stack_Size; /* Symbol defined in the linker script */ - const uint32_t stack_limit = - (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; const uint8_t *max_heap = (uint8_t *)stack_limit; uint8_t *prev_heap_end; diff --git a/G4PERTESTING/Core/Src/system_stm32g4xx.c b/G4PERTESTING/Core/Src/system_stm32g4xx.c index 6254a05b..990865b8 100644 --- a/G4PERTESTING/Core/Src/system_stm32g4xx.c +++ b/G4PERTESTING/Core/Src/system_stm32g4xx.c @@ -114,18 +114,18 @@ in Sram else user remap will be done in Flash. */ /* #define VECT_TAB_SRAM */ #if defined(VECT_TAB_SRAM) -#define VECT_TAB_BASE_ADDRESS \ - SRAM_BASE /*!< Vector Table base address field. \ +#define VECT_TAB_BASE_ADDRESS \ + SRAM_BASE /*!< Vector Table base address field. \ This value must be a multiple of 0x200. */ -#define VECT_TAB_OFFSET \ - 0x00000000U /*!< Vector Table base offset field. \ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ This value must be a multiple of 0x200. */ #else -#define VECT_TAB_BASE_ADDRESS \ - FLASH_BASE /*!< Vector Table base address field. \ +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ This value must be a multiple of 0x200. */ -#define VECT_TAB_OFFSET \ - 0x00000000U /*!< Vector Table base offset field. \ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ This value must be a multiple of 0x200. */ #endif /* VECT_TAB_SRAM */ #endif /* USER_VECT_TAB_ADDRESS */ @@ -155,8 +155,7 @@ */ uint32_t SystemCoreClock = HSI_VALUE; -const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, - 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; +const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; /** @@ -185,17 +184,14 @@ void SystemInit(void) { /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - SCB->CPACR |= ((3UL << (10 * 2)) | - (3UL << (11 * 2))); /* set CP10 and CP11 Full Access */ + SCB->CPACR |= ((3UL << (10 * 2)) | (3UL << (11 * 2))); /* set CP10 and CP11 Full Access */ #endif /* Configure the Vector Table location add offset address * ------------------*/ #if defined(USER_VECT_TAB_ADDRESS) - SCB->VTOR = - VECT_TAB_BASE_ADDRESS | - VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ -#endif /* USER_VECT_TAB_ADDRESS */ + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ } /** @@ -257,19 +253,15 @@ void SystemCoreClockUpdate(void) */ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4) + 1U; - if (pllsource == - 0x02UL) /* HSI used as PLL clock source */ + if (pllsource == 0x02UL) /* HSI used as PLL clock source */ { pllvco = (HSI_VALUE / pllm); } else /* HSE used as PLL clock source */ { pllvco = (HSE_VALUE / pllm); } - pllvco = - pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8); - pllr = - (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * - 2U; + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * 2U; SystemCoreClock = pllvco / pllr; break; diff --git a/G4PERTESTING/Core/Src/usart.c b/G4PERTESTING/Core/Src/usart.c index 85df3b91..1657154b 100644 --- a/G4PERTESTING/Core/Src/usart.c +++ b/G4PERTESTING/Core/Src/usart.c @@ -37,7 +37,7 @@ void MX_LPUART1_UART_Init(void) LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_HSI); + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); /* Peripheral clock enable */ LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); @@ -85,8 +85,7 @@ void MX_LPUART1_UART_Init(void) LL_LPUART_Enable(LPUART1); /* Polling LPUART1 initialisation */ - while ((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || - (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) { + while ((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) { } /* USER CODE BEGIN LPUART1_Init 2 */ @@ -175,8 +174,7 @@ void MX_USART1_UART_Init(void) LL_USART_Enable(USART1); /* Polling USART1 initialisation */ - while ((!(LL_USART_IsActiveFlag_TEACK(USART1))) || - (!(LL_USART_IsActiveFlag_REACK(USART1)))) { + while ((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))) { } /* USER CODE BEGIN USART1_Init 2 */ diff --git a/G4PERTESTING/README.md b/G4PERTESTING/README.md index 79c0032d..099ac620 100644 --- a/G4PERTESTING/README.md +++ b/G4PERTESTING/README.md @@ -1,5 +1,5 @@ -# STM32G474 Blinky +# STM32G474 ADC Nucleo-G474RE-C04 Plug in the board following ST-LINK pinout -Compile and flash G4PERTESTING.elf +Compile and flash G4ADCTESTING.elf From a1690635e997ab27d232073943ba62de547adbff Mon Sep 17 00:00:00 2001 From: "vihanjay@gmail.com" Date: Thu, 15 Jan 2026 22:39:36 -0800 Subject: [PATCH 13/18] Jan 19th ready, 1000% --- G4CANTESTING/Core/Src/main.c | 2 + Lib/Peripherals/CAN/Src/can.c | 4 ++ Lib/Peripherals/CAN/Test/can_tests.c | 67 +++++++++++++++++++++------- 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/G4CANTESTING/Core/Src/main.c b/G4CANTESTING/Core/Src/main.c index 03635c54..10ea034a 100644 --- a/G4CANTESTING/Core/Src/main.c +++ b/G4CANTESTING/Core/Src/main.c @@ -137,6 +137,7 @@ int main(void) /* USER CODE BEGIN 2 */ LOGOMATIC("Booted!\n"); + can_test(); /* Infinite loop */ @@ -146,6 +147,7 @@ int main(void) LOGOMATIC("Main Loop\n"); LL_mDelay(1000); + // Receive on GPIOs // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET // : GPIO_PIN_RESET); HAL_Delay(1000); msg.data[0] = toggleze ? diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index be849a50..9f2d5f67 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -5,6 +5,7 @@ #include #include + //HAL handles //#ifdef USECAN1 static FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; @@ -366,6 +367,7 @@ void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs //should switch this over to malloc at some point to avoid double copies? handle->rx_callback(rx_data, rx_header.DataLength); } + /* whoopsie, don't need the rx buffer yet while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) & !GR_CircularBuffer_IsFull(handle->rx_buffer)) { @@ -538,6 +540,8 @@ int can_send(CANHandle* canHandle, FDCANTxMessage* message) { //If TX Fifos are full, append to circular buffer //If circular buffer is full, return an error code uint32_t free = HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP); + + if (free > 0) { HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ( canHandle->hal_fdcanP, diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index 9ac739e4..8559d7dc 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -10,8 +10,15 @@ int can_test_instance(FDCAN_HandleTypeDef) { return 0; } -void can_test_rx_callback(void*data, uint32_t size) { - LOGOMATIC("Got data!\n"); +void can_test_rx_callback2(void*data, uint32_t size) { + LOGOMATIC("CAN2 Got data!\n"); + // Is within an ISR, so needs to exit quickly + return; +} + +void can_test_rx_callback1(void*data, uint32_t size) { + LOGOMATIC("CAN1 Got data!\n"); + // Is within an ISR, so needs to exit quickly return; } @@ -24,8 +31,7 @@ int can_test(void) { canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; - canCfg.hal_fdcan_init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; - canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + canCfg.hal_fdcan_init.Mode = FDCAN_MODE_NORMAL; canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; canCfg.hal_fdcan_init.TransmitPause = DISABLE; canCfg.hal_fdcan_init.ProtocolException = ENABLE; @@ -40,10 +46,10 @@ int can_test(void) { canCfg.hal_fdcan_init.StdFiltersNbr = 1; canCfg.hal_fdcan_init.ExtFiltersNbr = 0; - canCfg.rx_callback = can_test_rx_callback; // PLEASE SET + canCfg.rx_callback = NULL; // PLEASE SET canCfg.rx_interrupt_priority = 0; // PLEASE SET canCfg.tx_interrupt_priority = 0; // PLEASE SET - canCfg.tx_buffer_length = 20; // PLEASE SET + canCfg.tx_buffer_length = 3; // PLEASE SET //canCfg.rx_gpio = GPIOB; //canCfg.init_rx_gpio.Pin = GPIO_PIN_12; @@ -85,12 +91,31 @@ int can_test(void) { msg.tx_header = TxHeader; + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + #ifdef FDCAN1 + canCfg.fdcan_instance = FDCAN1; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_11; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; + + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_12; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; + + canCfg.rx_callback = can_test_rx_callback1; // PLEASE SET + + + CANHandle *can1Handle = can_init(&canCfg); + HAL_FDCAN_ConfigGlobalFilter(can1Handle->hal_fdcanP, 0, 0, 0,0); + + can_start(can1Handle); + + #endif #ifdef FDCAN2 - canCfg.fdcan_instance = FDCAN2; canCfg.rx_gpio = GPIOB; canCfg.init_rx_gpio.Pin = GPIO_PIN_12; @@ -100,13 +125,16 @@ int can_test(void) { canCfg.init_tx_gpio.Pin = GPIO_PIN_13; canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; - FDCAN_FilterTypeDef filter; - filter.IdType = FDCAN_STANDARD_ID; - filter.FilterIndex = 0; - filter.FilterType = FDCAN_FILTER_RANGE, - filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; - filter.FilterID1 = 0x00; - filter.FilterID2 = 0x02; + canCfg.rx_callback = can_test_rx_callback2; + + + // FDCAN_FilterTypeDef filter; + // filter.IdType = FDCAN_STANDARD_ID; + // filter.FilterIndex = 0; + // filter.FilterType = FDCAN_FILTER_RANGE, + // filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + // filter.FilterID1 = 0x00; + // filter.FilterID2 = 0x02; CANHandle *can2Handle = can_init(&canCfg); @@ -114,12 +142,11 @@ int can_test(void) { HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, 0, 0, 0,0); //not accepting filters - can_add_filter(can2Handle, &filter); + //can_add_filter(can2Handle, &filter); //API Testing //can_init(&canCfg); - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); can_start(can2Handle); can_send(can2Handle, &msg); @@ -130,6 +157,14 @@ int can_test(void) { #endif + while (1) { + HAL_Delay(1000); + msg.data[0] = 0x2; + can_send(can1Handle, &msg); + HAL_Delay(1000); + msg.data[0] = 0x10; + can_send(can2Handle, &msg); + } return 0; From 98dd4c1f3f7076bca89cb358f1b7844acfd5759b Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 06:47:08 +0000 Subject: [PATCH 14/18] Automatic Json Format: Standardized formatting automatically --- .vscode/launch.json | 2 +- .vscode/tasks.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 39925b3f..cdb5115c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -220,7 +220,7 @@ ] } }, - { + { "cwd": "${workspaceFolder}", "executable": "${command:cmake.buildDirectory}/G4ADCTESTING.elf", "name": "G4CANTESTING", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f8d685cb..0e2fd381 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -27,7 +27,7 @@ ], "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target CCU" }, - { + { "label": "CMake: configure and build G4ADCTESTING", "type": "shell", "dependsOrder": "sequence", @@ -36,7 +36,7 @@ ], "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4ADCTESTING" }, - { + { "label": "CMake: configure and build G4PERTESTING", "type": "shell", "dependsOrder": "sequence", From 976033b65a2912146a159810af0ac19e1d4eb0c9 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 06:47:42 +0000 Subject: [PATCH 15/18] Automatic CMake Format: Standardized formatting automatically --- G4CANTESTING/CMakeLists.txt | 7 +++++-- Lib/Peripherals/CAN/common.cmake | 14 +++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/G4CANTESTING/CMakeLists.txt b/G4CANTESTING/CMakeLists.txt index 0f9f978c..ef4620ac 100644 --- a/G4CANTESTING/CMakeLists.txt +++ b/G4CANTESTING/CMakeLists.txt @@ -48,7 +48,10 @@ target_sources( ) target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_LIB) -target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_TEST_LIB) - +target_link_libraries( + ${PROJECT_NAME}_USER_CODE + INTERFACE + PERIPHERAL_CAN_TEST_LIB +) target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake index a7f8fd2a..120a4dcb 100644 --- a/Lib/Peripherals/CAN/common.cmake +++ b/Lib/Peripherals/CAN/common.cmake @@ -1,12 +1,9 @@ add_library(PERIPHERAL_CAN_LIB INTERFACE) -target_link_libraries( - PERIPHERAL_CAN_LIB INTERFACE CircularBuffer_Lib -) +target_link_libraries(PERIPHERAL_CAN_LIB INTERFACE CircularBuffer_Lib) target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/can.c) - # Make headers accessible as #include "Peripherals/CAN/can.h" target_include_directories( PERIPHERAL_CAN_LIB @@ -14,10 +11,13 @@ target_include_directories( ${CMAKE_CURRENT_LIST_DIR}/Inc ) - #tests add_library(PERIPHERAL_CAN_TEST_LIB INTERFACE) -target_sources(PERIPHERAL_CAN_TEST_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Test/can_tests.c) +target_sources( + PERIPHERAL_CAN_TEST_LIB + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/Test/can_tests.c +) target_include_directories( PERIPHERAL_CAN_TEST_LIB INTERFACE @@ -39,4 +39,4 @@ target_include_directories( # PERIPHERAL_CAN_LIB_init # PERIPHERAL_CAN_LIB_init_test # ) -#endif() \ No newline at end of file +#endif() From ff7514b0ae212e54ac77a568b5c5dbd81afbfbdc Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 06:49:14 +0000 Subject: [PATCH 16/18] Automatic Clang-Format: Standardized formatting automatically --- G4CANTESTING/Core/Inc/main.h | 1 - G4CANTESTING/Core/Inc/stm32_assert.h | 3 +- G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h | 24 +- G4CANTESTING/Core/Src/adc.c | 67 +- G4CANTESTING/Core/Src/gpio.c | 3 +- G4CANTESTING/Core/Src/main.c | 19 +- G4CANTESTING/Core/Src/stm32g4xx_it.c | 3 +- G4CANTESTING/Core/Src/sysmem.c | 10 +- G4CANTESTING/Core/Src/system_stm32g4xx.c | 38 +- G4CANTESTING/Core/Src/usart.c | 6 +- Lib/Peripherals/CAN/Inc/can.h | 115 ++- Lib/Peripherals/CAN/Inc/can_platform_deps.h | 12 +- Lib/Peripherals/CAN/Src/can.c | 927 +++++++++++--------- Lib/Peripherals/CAN/Test/can_tests.c | 145 ++- Lib/Peripherals/CAN/Test/can_tests.h | 18 +- 15 files changed, 690 insertions(+), 701 deletions(-) diff --git a/G4CANTESTING/Core/Inc/main.h b/G4CANTESTING/Core/Inc/main.h index af49e0e9..23d7ffce 100644 --- a/G4CANTESTING/Core/Inc/main.h +++ b/G4CANTESTING/Core/Inc/main.h @@ -28,7 +28,6 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #include "stm32g4xx_hal.h" - #include "stm32g4xx_ll_adc.h" #include "stm32g4xx_ll_bus.h" #include "stm32g4xx_ll_cortex.h" diff --git a/G4CANTESTING/Core/Inc/stm32_assert.h b/G4CANTESTING/Core/Inc/stm32_assert.h index c0d98f1d..92460620 100644 --- a/G4CANTESTING/Core/Inc/stm32_assert.h +++ b/G4CANTESTING/Core/Inc/stm32_assert.h @@ -38,8 +38,7 @@ extern "C" { * If expr is true, it returns no value. * @retval None */ -#define assert_param(expr) \ - ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else diff --git a/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h b/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h index dc9ea7ec..3e1fcb01 100644 --- a/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h +++ b/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h @@ -144,9 +144,9 @@ extern "C" { * variations. */ #if !defined(HSI48_VALUE) -#define HSI48_VALUE \ - (48000000UL) /*!< Value of the Internal High Speed oscillator for USB \ - FS/RNG in Hz. The real value my vary depending on \ +#define HSI48_VALUE \ + (48000000UL) /*!< Value of the Internal High Speed oscillator for USB \ + FS/RNG in Hz. The real value my vary depending on \ manufacturing process variations.*/ #endif /* HSI48_VALUE */ @@ -165,9 +165,8 @@ temperature.*/ * frequency */ #if !defined(LSE_VALUE) -#define LSE_VALUE \ - (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ -#endif /* LSE_VALUE */ +#define LSE_VALUE (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ #if !defined(LSE_STARTUP_TIMEOUT) #define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ @@ -180,9 +179,8 @@ temperature.*/ * I2S_CKIN pad. */ #if !defined(EXTERNAL_CLOCK_VALUE) -#define EXTERNAL_CLOCK_VALUE \ - (12288000UL) /*!< Value of the External oscillator in Hz*/ -#endif /* EXTERNAL_CLOCK_VALUE */ +#define EXTERNAL_CLOCK_VALUE (12288000UL) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ /* Tip: To avoid modifying this file each time you need to use different HSE, === you can define the HSE value in your toolchain compiler preprocessor. */ @@ -192,9 +190,8 @@ temperature.*/ * @brief This is the HAL system configuration section */ -#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ -#define TICK_INT_PRIORITY \ - (15UL) /*!< tick interrupt priority (lowest by default) */ +#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ #define USE_RTOS 0U #define PREFETCH_ENABLE 0U #define INSTRUCTION_CACHE_ENABLE 1U @@ -379,8 +376,7 @@ temperature.*/ * If expr is true, it returns no value. * @retval None */ -#define assert_param(expr) \ - ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) /* Exported functions ------------------------------------------------------- */ void assert_failed(uint8_t *file, uint32_t line); #else diff --git a/G4CANTESTING/Core/Src/adc.c b/G4CANTESTING/Core/Src/adc.c index 529917dd..f3dbff8e 100644 --- a/G4CANTESTING/Core/Src/adc.c +++ b/G4CANTESTING/Core/Src/adc.c @@ -88,25 +88,19 @@ void MX_ADC1_Init(void) /* ADC1 Init */ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1); - LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); - LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_PRIORITY_LOW); + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR); - LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_PERIPH_NOINCREMENT); + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT); - LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_MEMORY_INCREMENT); + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT); - LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_PDATAALIGN_HALFWORD); + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD); - LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, - LL_DMA_MDATAALIGN_HALFWORD); + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD); /* USER CODE BEGIN ADC1_Init 1 */ @@ -129,8 +123,7 @@ void MX_ADC1_Init(void) LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE); ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV256; ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT; - LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), - &ADC_CommonInitStruct); + LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct); /* Disable ADC deep power down (enabled by default after reset state) */ LL_ADC_DisableDeepPowerDown(ADC1); @@ -143,9 +136,7 @@ void MX_ADC1_Init(void) /* Note: If system core clock frequency is below 200kHz, wait time */ /* is only a few CPU processing cycles. */ uint32_t wait_loop_index; - wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * - (SystemCoreClock / (100000 * 2))) / - 10); + wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10); while (wait_loop_index != 0) { wait_loop_index--; } @@ -153,52 +144,38 @@ void MX_ADC1_Init(void) /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_7); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_8); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_9); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, - LL_ADC_SINGLE_ENDED); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ - LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, - LL_ADC_CHANNEL_12); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, - LL_ADC_SINGLE_ENDED); + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_12); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SINGLE_ENDED); /** Configure Regular Channel */ - LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, - LL_ADC_CHANNEL_15); - LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, - LL_ADC_SAMPLINGTIME_92CYCLES_5); - LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, - LL_ADC_SINGLE_ENDED); + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, LL_ADC_CHANNEL_15); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED); /* USER CODE BEGIN ADC1_Init 2 */ /* USER CODE END ADC1_Init 2 */ diff --git a/G4CANTESTING/Core/Src/gpio.c b/G4CANTESTING/Core/Src/gpio.c index 9aa78e16..d36e6eca 100644 --- a/G4CANTESTING/Core/Src/gpio.c +++ b/G4CANTESTING/Core/Src/gpio.c @@ -75,8 +75,7 @@ void MX_GPIO_Init(void) LL_GPIO_ResetOutputPin(AUX_CONTROL_GPIO_Port, AUX_CONTROL_Pin); /**/ - LL_GPIO_ResetOutputPin(SOFTWARE_OK_CONTROL_GPIO_Port, - SOFTWARE_OK_CONTROL_Pin); + LL_GPIO_ResetOutputPin(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin); /**/ GPIO_InitStruct.Pin = LL_GPIO_PIN_13; diff --git a/G4CANTESTING/Core/Src/main.c b/G4CANTESTING/Core/Src/main.c index 10ea034a..15335005 100644 --- a/G4CANTESTING/Core/Src/main.c +++ b/G4CANTESTING/Core/Src/main.c @@ -18,7 +18,10 @@ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" + #include "adc.h" +#include "can.h" // Assume this works +#include "can_tests.h" #include "dma.h" #include "fdcan.h" #include "gpio.h" @@ -27,9 +30,6 @@ #include "tim.h" #include "usart.h" -#include "can.h" // Assume this works -#include "can_tests.h" - /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "Logomatic.h" @@ -82,17 +82,14 @@ static void ITM_Enable(void) CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; /* Configure TPI for SWO output (set prescaler for 2MHz SWO clock) */ - TPI->SPPR = 2U; /* 2 = Manchester/async UART mode */ + TPI->SPPR = 2U; /* 2 = Manchester/async UART mode */ TPI->ACPR = 84U; /* Prescaler: (170 MHz / (84+1) / 2) ≈ 1MHz SWO */ ITM->TER |= (1UL << 0); ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); } static int toggleze = 0; -void DEBUG_callback(void *data, uint32_t size) -{ - toggleze = (*((char *)data) & 0x80); -} +void DEBUG_callback(void *data, uint32_t size) { toggleze = (*((char *)data) & 0x80); } /* USER CODE END 0 */ @@ -137,7 +134,7 @@ int main(void) /* USER CODE BEGIN 2 */ LOGOMATIC("Booted!\n"); - + can_test(); /* Infinite loop */ @@ -147,7 +144,6 @@ int main(void) LOGOMATIC("Main Loop\n"); LL_mDelay(1000); - // Receive on GPIOs // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET // : GPIO_PIN_RESET); HAL_Delay(1000); msg.data[0] = toggleze ? @@ -218,8 +214,7 @@ void SystemClock_Config(void) } LL_RCC_HSI_SetCalibTrimming(64); - LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, - LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, LL_RCC_PLLR_DIV_2); LL_RCC_PLL_EnableDomain_SYS(); LL_RCC_PLL_Enable(); /* Wait till PLL is ready */ diff --git a/G4CANTESTING/Core/Src/stm32g4xx_it.c b/G4CANTESTING/Core/Src/stm32g4xx_it.c index 1db87c69..de1160d3 100644 --- a/G4CANTESTING/Core/Src/stm32g4xx_it.c +++ b/G4CANTESTING/Core/Src/stm32g4xx_it.c @@ -19,6 +19,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32g4xx_it.h" + #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -55,7 +56,7 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ -//extern FDCAN_HandleTypeDef hfdcan2; +// extern FDCAN_HandleTypeDef hfdcan2; /* USER CODE BEGIN EV */ /* USER CODE END EV */ diff --git a/G4CANTESTING/Core/Src/sysmem.c b/G4CANTESTING/Core/Src/sysmem.c index 619868a4..00c39793 100644 --- a/G4CANTESTING/Core/Src/sysmem.c +++ b/G4CANTESTING/Core/Src/sysmem.c @@ -52,12 +52,10 @@ static uint8_t *__sbrk_heap_end = NULL; */ void *_sbrk(ptrdiff_t incr) { - extern uint8_t _end; /* Symbol defined in the linker script */ - extern uint8_t _estack; /* Symbol defined in the linker script */ - extern uint32_t - _Min_Stack_Size; /* Symbol defined in the linker script */ - const uint32_t stack_limit = - (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; const uint8_t *max_heap = (uint8_t *)stack_limit; uint8_t *prev_heap_end; diff --git a/G4CANTESTING/Core/Src/system_stm32g4xx.c b/G4CANTESTING/Core/Src/system_stm32g4xx.c index 6254a05b..990865b8 100644 --- a/G4CANTESTING/Core/Src/system_stm32g4xx.c +++ b/G4CANTESTING/Core/Src/system_stm32g4xx.c @@ -114,18 +114,18 @@ in Sram else user remap will be done in Flash. */ /* #define VECT_TAB_SRAM */ #if defined(VECT_TAB_SRAM) -#define VECT_TAB_BASE_ADDRESS \ - SRAM_BASE /*!< Vector Table base address field. \ +#define VECT_TAB_BASE_ADDRESS \ + SRAM_BASE /*!< Vector Table base address field. \ This value must be a multiple of 0x200. */ -#define VECT_TAB_OFFSET \ - 0x00000000U /*!< Vector Table base offset field. \ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ This value must be a multiple of 0x200. */ #else -#define VECT_TAB_BASE_ADDRESS \ - FLASH_BASE /*!< Vector Table base address field. \ +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ This value must be a multiple of 0x200. */ -#define VECT_TAB_OFFSET \ - 0x00000000U /*!< Vector Table base offset field. \ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ This value must be a multiple of 0x200. */ #endif /* VECT_TAB_SRAM */ #endif /* USER_VECT_TAB_ADDRESS */ @@ -155,8 +155,7 @@ */ uint32_t SystemCoreClock = HSI_VALUE; -const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, - 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; +const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; /** @@ -185,17 +184,14 @@ void SystemInit(void) { /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - SCB->CPACR |= ((3UL << (10 * 2)) | - (3UL << (11 * 2))); /* set CP10 and CP11 Full Access */ + SCB->CPACR |= ((3UL << (10 * 2)) | (3UL << (11 * 2))); /* set CP10 and CP11 Full Access */ #endif /* Configure the Vector Table location add offset address * ------------------*/ #if defined(USER_VECT_TAB_ADDRESS) - SCB->VTOR = - VECT_TAB_BASE_ADDRESS | - VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ -#endif /* USER_VECT_TAB_ADDRESS */ + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ } /** @@ -257,19 +253,15 @@ void SystemCoreClockUpdate(void) */ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4) + 1U; - if (pllsource == - 0x02UL) /* HSI used as PLL clock source */ + if (pllsource == 0x02UL) /* HSI used as PLL clock source */ { pllvco = (HSI_VALUE / pllm); } else /* HSE used as PLL clock source */ { pllvco = (HSE_VALUE / pllm); } - pllvco = - pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8); - pllr = - (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * - 2U; + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * 2U; SystemCoreClock = pllvco / pllr; break; diff --git a/G4CANTESTING/Core/Src/usart.c b/G4CANTESTING/Core/Src/usart.c index 85df3b91..45c8c7ad 100644 --- a/G4CANTESTING/Core/Src/usart.c +++ b/G4CANTESTING/Core/Src/usart.c @@ -85,8 +85,7 @@ void MX_LPUART1_UART_Init(void) LL_LPUART_Enable(LPUART1); /* Polling LPUART1 initialisation */ - while ((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || - (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) { + while ((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) { } /* USER CODE BEGIN LPUART1_Init 2 */ @@ -175,8 +174,7 @@ void MX_USART1_UART_Init(void) LL_USART_Enable(USART1); /* Polling USART1 initialisation */ - while ((!(LL_USART_IsActiveFlag_TEACK(USART1))) || - (!(LL_USART_IsActiveFlag_REACK(USART1)))) { + while ((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))) { } /* USER CODE BEGIN USART1_Init 2 */ diff --git a/Lib/Peripherals/CAN/Inc/can.h b/Lib/Peripherals/CAN/Inc/can.h index 194b8cc1..6c2b7e0b 100644 --- a/Lib/Peripherals/CAN/Inc/can.h +++ b/Lib/Peripherals/CAN/Inc/can.h @@ -1,87 +1,80 @@ #ifndef CAN_H #define CAN_H -//Supported STM32 Families +// Supported STM32 Families #ifdef STM32G4 #elif defined(STM32L4) #elif defined(STM32U5) #error "Unsupported STM32 Family" -#endif - - +#endif #include "can_platform_deps.h" #include "circularBuffer.h" - -//RX Callback must perform a deep copy of the data +// RX Callback must perform a deep copy of the data // -typedef void (*CAN_RXCallback) (void* data, uint32_t size); +typedef void (*CAN_RXCallback)(void *data, uint32_t size); typedef struct { - //can baud rate is set by fdcan prescaler and RCC clock configurations - FDCAN_GlobalTypeDef *fdcan_instance; //Base address of FDCAN peripheral in memory (FDCAN1, FDCAN2, FDCAN3 macros) + // can baud rate is set by fdcan prescaler and RCC clock configurations + FDCAN_GlobalTypeDef *fdcan_instance; // Base address of FDCAN peripheral in memory (FDCAN1, FDCAN2, FDCAN3 macros) - FDCAN_InitTypeDef hal_fdcan_init; - CAN_RXCallback rx_callback; - uint32_t rx_interrupt_priority; - uint32_t tx_interrupt_priority; + FDCAN_InitTypeDef hal_fdcan_init; + CAN_RXCallback rx_callback; + uint32_t rx_interrupt_priority; + uint32_t tx_interrupt_priority; - //Circular Buffer - uint32_t tx_buffer_length; + // Circular Buffer + uint32_t tx_buffer_length; - GPIO_TypeDef *rx_gpio; //Instance name, like GPIOA, GPIOB, etc. - GPIO_InitTypeDef init_rx_gpio; //GPIO Parameters - set correct Alternate Function, no pullup/pulldown, high/very_high frequency - GPIO_TypeDef *tx_gpio; - GPIO_InitTypeDef init_tx_gpio; + GPIO_TypeDef *rx_gpio; // Instance name, like GPIOA, GPIOB, etc. + GPIO_InitTypeDef init_rx_gpio; // GPIO Parameters - set correct Alternate Function, no pullup/pulldown, high/very_high frequency + GPIO_TypeDef *tx_gpio; + GPIO_InitTypeDef init_tx_gpio; - //additional parameters + // additional parameters } CANConfig; +// FDCAN peripheral for STM32G4 +typedef struct { + FDCAN_HandleTypeDef *hal_fdcanP; + CircularBuffer *tx_buffer; + uint32_t tx_buffer_length; + CAN_RXCallback rx_callback; -//FDCAN peripheral for STM32G4 -typedef struct { - FDCAN_HandleTypeDef *hal_fdcanP; - CircularBuffer* tx_buffer; - uint32_t tx_buffer_length; - - CAN_RXCallback rx_callback; - - //for release - GPIO_TypeDef * rx_gpio; - GPIO_TypeDef * tx_gpio; - uint32_t Clock_Source; - - //state - bool init; - bool started; - - //error states + // for release + GPIO_TypeDef *rx_gpio; + GPIO_TypeDef *tx_gpio; + uint32_t Clock_Source; + + // state + bool init; + bool started; + + // error states } CANHandle; #define FDCAN_MAX_DATA_BYTES 64 typedef struct { - FDCAN_TxHeaderTypeDef tx_header; - uint8_t data[FDCAN_MAX_DATA_BYTES]; -} FDCANTxMessage; + FDCAN_TxHeaderTypeDef tx_header; + uint8_t data[FDCAN_MAX_DATA_BYTES]; +} FDCANTxMessage; typedef struct { - FDCAN_RxHeaderTypeDef rx_header; - uint8_t data[FDCAN_MAX_DATA_BYTES]; -} FDCANRxMessage; - - -CANHandle* can_init(const CANConfig *config); //user must supply an rx callback function -int can_start(CANHandle*handle); -int can_stop(CANHandle*handle); -int can_send(CANHandle*handle, FDCANTxMessage* buffer); -int can_release(CANHandle* handle); //deinit circular buffer and turn off can peripheral and gpios -int can_add_filter(CANHandle* handle, FDCAN_FilterTypeDef * filter); -//alternatively use -//HAL_FDCAN_ConfigGlobalFilter() //important to accept nonmatching frames into -//HAL_FDCAN_ConfigFilter() - -//doesn't need a handle, CAN cores share peripheral clock -int can_set_clksource(uint32_t clksource); //ex. LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE - - -#endif //End Header Guard + FDCAN_RxHeaderTypeDef rx_header; + uint8_t data[FDCAN_MAX_DATA_BYTES]; +} FDCANRxMessage; + +CANHandle *can_init(const CANConfig *config); // user must supply an rx callback function +int can_start(CANHandle *handle); +int can_stop(CANHandle *handle); +int can_send(CANHandle *handle, FDCANTxMessage *buffer); +int can_release(CANHandle *handle); // deinit circular buffer and turn off can peripheral and gpios +int can_add_filter(CANHandle *handle, FDCAN_FilterTypeDef *filter); +// alternatively use +// HAL_FDCAN_ConfigGlobalFilter() //important to accept nonmatching frames into +// HAL_FDCAN_ConfigFilter() + +// doesn't need a handle, CAN cores share peripheral clock +int can_set_clksource(uint32_t clksource); // ex. LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE + +#endif // End Header Guard diff --git a/Lib/Peripherals/CAN/Inc/can_platform_deps.h b/Lib/Peripherals/CAN/Inc/can_platform_deps.h index 885b6559..3958adbc 100644 --- a/Lib/Peripherals/CAN/Inc/can_platform_deps.h +++ b/Lib/Peripherals/CAN/Inc/can_platform_deps.h @@ -1,20 +1,18 @@ #ifndef CAN_PLATFORM_DEPS_H #define CAN_PLATFORM_DEPS_H - #if defined(STM32G4) #include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_fdcan.h" #include "stm32g4xx_hal_gpio.h" #include "stm32g4xx_hal_gpio_ex.h" -#include "stm32g4xx_hal_fdcan.h" #include "stm32g4xx_hal_rcc.h" -#include "stm32g4xx_ll_rcc.h" #include "stm32g4xx_ll_gpio.h" -//#elif defined(STM32L4) -//#elif defined(STM32U5) +#include "stm32g4xx_ll_rcc.h" +// #elif defined(STM32L4) +// #elif defined(STM32U5) #else #error "Unsupported STM32 family" #endif - -#endif //end header guard +#endif // end header guard diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 9f2d5f67..02ede7f8 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -1,28 +1,29 @@ #include "can.h" -#include "Logomatic.h" + +#include #include -#include #include -#include +#include +#include "Logomatic.h" -//HAL handles -//#ifdef USECAN1 +// HAL handles +// #ifdef USECAN1 static FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; static CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; -//#endif +// #endif -//#ifdef USECAN2 +// #ifdef USECAN2 static FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; static CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; -//#endif +// #endif -//#ifdef USECAN3 +// #ifdef USECAN3 static FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; -//#endif +// #endif -//macro lore +// macro lore /* #define CAT(a,b) a##b #define CAT3(a, b, c) a##b##c @@ -30,286 +31,327 @@ static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; #define CAT5(a, b,c,d,e) a##b##c##d##e #define ACTIVATE_FDCAN_HELPER(FDCANX, ITY, preirq, subirq) \ - do { \ - HAL_NVIC_SetPriority( CAT4(FDCANX##,_,ITY, _IRQn ) , preirq, subirq ); \ - HAL_NVIC_EnableIRQ( CAT4(FDCANX##,_,ITY, _IRQn ) ); \ - } while(0) + do { \ + HAL_NVIC_SetPriority( CAT4(FDCANX##,_,ITY, _IRQn ) , preirq, subirq ); \ + HAL_NVIC_EnableIRQ( CAT4(FDCANX##,_,ITY, _IRQn ) ); \ + } while(0) #define HAL_NVIC_ACTIVATE_FDCAN(FDCANX, ITY, preirq, subirq) \ do { \ - if (FDCANX == ##FDCAN1 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT0, preirq, subirq); } \ - else if (FDCANX == FDCAN1 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT1, preirq, subirq); } \ - else if (FDCANX == FDCAN2 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT0, preirq, subirq); } \ - else if (FDCANX == FDCAN2 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT1, preirq, subirq); } \ - else if (FDCANX == FDCAN3 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT0, preirq, subirq); } \ - else if (FDCANX == FDCAN3 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT1, preirq, subirq); } \ - else { LOGOMATIC("Unrecognized FDCAN and Interrupt Line combination"); } \ + if (FDCANX == ##FDCAN1 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN1 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT1, preirq, subirq); } \ + else { LOGOMATIC("Unrecognized FDCAN and Interrupt Line combination"); } \ } while(0) */ -#define GPIOx_CLK_ENABLE(GPIOX) \ - do {\ - switch ( (uint32_t) GPIOX ) { \ - case (uint32_t) GPIOA: __HAL_RCC_GPIOA_CLK_ENABLE(); break; \ - case (uint32_t) GPIOB: __HAL_RCC_GPIOB_CLK_ENABLE(); break; \ - case (uint32_t) GPIOD: __HAL_RCC_GPIOD_CLK_ENABLE(); break; \ - default: LOGOMATIC("BAD FDCAN GPIO Port"); \ - } \ - } while(0) - - -#define GPIOx_CLK_DISABLE(GPIOX) \ - do {\ - switch ( (uint32_t) GPIOX ){ \ - case (uint32_t) GPIOA: __HAL_RCC_GPIOA_CLK_DISABLE(); break; \ - case (uint32_t) GPIOB: __HAL_RCC_GPIOB_CLK_DISABLE(); break; \ - case (uint32_t) GPIOD: __HAL_RCC_GPIOD_CLK_DISABLE(); break; \ - default: LOGOMATIC("BAD FDCAN GPIO Port"); \ - } \ - } while(0) - - +#define GPIOx_CLK_ENABLE(GPIOX) \ + do { \ + switch ((uint32_t)GPIOX) { \ + case (uint32_t)GPIOA: \ + __HAL_RCC_GPIOA_CLK_ENABLE(); \ + break; \ + case (uint32_t)GPIOB: \ + __HAL_RCC_GPIOB_CLK_ENABLE(); \ + break; \ + case (uint32_t)GPIOD: \ + __HAL_RCC_GPIOD_CLK_ENABLE(); \ + break; \ + default: \ + LOGOMATIC("BAD FDCAN GPIO Port"); \ + } \ + } while (0) + +#define GPIOx_CLK_DISABLE(GPIOX) \ + do { \ + switch ((uint32_t)GPIOX) { \ + case (uint32_t)GPIOA: \ + __HAL_RCC_GPIOA_CLK_DISABLE(); \ + break; \ + case (uint32_t)GPIOB: \ + __HAL_RCC_GPIOB_CLK_DISABLE(); \ + break; \ + case (uint32_t)GPIOD: \ + __HAL_RCC_GPIOD_CLK_DISABLE(); \ + break; \ + default: \ + LOGOMATIC("BAD FDCAN GPIO Port"); \ + } \ + } while (0) static int fdcan_shared_clock_ref = 0; -static inline void fdcan_enable_shared_clock(void) { - uint32_t primask = __get_PRIMASK(); - __disable_irq(); +static inline void fdcan_enable_shared_clock(void) +{ + uint32_t primask = __get_PRIMASK(); + __disable_irq(); - if (fdcan_shared_clock_ref == 0) { - __HAL_RCC_FDCAN_CLK_ENABLE(); - } - fdcan_shared_clock_ref++; + if (fdcan_shared_clock_ref == 0) { + __HAL_RCC_FDCAN_CLK_ENABLE(); + } + fdcan_shared_clock_ref++; - __set_PRIMASK(primask); + __set_PRIMASK(primask); } -static inline void fdcan_disable_shared_clock(void) { - uint32_t primask = __get_PRIMASK(); - __disable_irq(); - - if (fdcan_shared_clock_ref > 0) { - fdcan_shared_clock_ref--; - if (fdcan_shared_clock_ref == 0) { - __HAL_RCC_FDCAN_CLK_DISABLE(); - } - } - __set_PRIMASK(primask); +static inline void fdcan_disable_shared_clock(void) +{ + uint32_t primask = __get_PRIMASK(); + __disable_irq(); + + if (fdcan_shared_clock_ref > 0) { + fdcan_shared_clock_ref--; + if (fdcan_shared_clock_ref == 0) { + __HAL_RCC_FDCAN_CLK_DISABLE(); + } + } + __set_PRIMASK(primask); } - -static inline void gpio_clk_enable(GPIO_TypeDef *gpio) { - if (gpio == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE(); - else if (gpio == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE(); - else if (gpio == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE(); +static inline void gpio_clk_enable(GPIO_TypeDef *gpio) +{ + if (gpio == GPIOA) { + __HAL_RCC_GPIOA_CLK_ENABLE(); + } else if (gpio == GPIOB) { + __HAL_RCC_GPIOB_CLK_ENABLE(); + } else if (gpio == GPIOD) { + __HAL_RCC_GPIOD_CLK_ENABLE(); + } } -static inline void gpio_clk_disable(GPIO_TypeDef *gpio) { - if (gpio == GPIOA) __HAL_RCC_GPIOA_CLK_DISABLE(); - else if (gpio == GPIOB) __HAL_RCC_GPIOB_CLK_DISABLE(); - else if (gpio == GPIOD) __HAL_RCC_GPIOD_CLK_DISABLE(); +static inline void gpio_clk_disable(GPIO_TypeDef *gpio) +{ + if (gpio == GPIOA) { + __HAL_RCC_GPIOA_CLK_DISABLE(); + } else if (gpio == GPIOB) { + __HAL_RCC_GPIOB_CLK_DISABLE(); + } else if (gpio == GPIOD) { + __HAL_RCC_GPIOD_CLK_DISABLE(); + } } -static int can_get_irqs(FDCAN_GlobalTypeDef *instance, - IRQn_Type *it0, - IRQn_Type *it1); - -static int can_msp_init(CANHandle* handle, const CANConfig*config); -CANHandle* can_init(const CANConfig *config) { - //config validation? - //assert(config != 0) - - //#ifdef STM32G474xx - CANHandle * canHandle = 0; - //#ifdef USECAN1 - if (config->fdcan_instance == FDCAN1) { - if (CAN1.init) {LOGOMATIC("CAN: CAN1 is already initialized\n"); return 0;} - else canHandle = &CAN1; - } - //#endif - //#ifdef USECAN2 - else if (config->fdcan_instance == FDCAN2) { - if (CAN2.init) {LOGOMATIC("CAN: CAN2 is already initialized\n"); return 0;} - else canHandle = &CAN2; - } - //#ifdef USECAN3 - else if (config->fdcan_instance == FDCAN3) { - if (CAN3.init) {LOGOMATIC("CAN: CAN3 is already initialized\n"); return 0;} - else canHandle = &CAN3; - } - //#endif - //#elif defined(STM32L476xx) - //#else - //#error "Unsupported STM32 family" - //#endif - else { - LOGOMATIC("CAN: Unrecognized FDCAN instance"); - return 0; - } - canHandle->init = false; - canHandle->started = false; - - //Initialize handle - assert( config->hal_fdcan_init.TxFifoQueueMode == FDCAN_TX_FIFO_OPERATION ); - - canHandle->hal_fdcanP->Init = config->hal_fdcan_init; //copy FDCAN parameters from user - //canHandle->hal_fdcanP->Instance = config->fdcan_instance //handles initialized with correct base instance addresses - - canHandle->rx_gpio = config->rx_gpio; - canHandle->tx_gpio = config->tx_gpio; - canHandle->rx_callback = config->rx_callback; - canHandle->tx_buffer_length = config->tx_buffer_length; - - //alternately -> have can_msp_init setup state for HAL_FDCAN_MspInit to work correctly - //have can_msp_deinit setup state for HAL_FDCAN_MspDeInit to work correctly - //Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() - - //Current idea, redefine HAL_FDCAN_MspInit and MspDeInit do nothing at all, do all the work in can_msp_init() - if (can_msp_init(canHandle, config)) { - LOGOMATIC("CAN_init: could not initialize MSP resources"); - can_release(canHandle); - } - - //PROBLEM: HAL_FDCAN_Init expects HAL_FDCAN_MspInit() to be defined - if (HAL_FDCAN_Init( canHandle->hal_fdcanP ) != HAL_OK) - { - LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); - return NULL; - //Error_Handler(); - } - - //Active FDCAN callbacks - rxcalback uses line0, txcallback uses line1 - //uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; - uint32_t status = 0; - uint32_t rx_events = FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL; - status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, rx_events, 0); - status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, rx_events, FDCAN_INTERRUPT_LINE0); - - //uint32_t txevents = FDCAN_IT_TX_COMPLETE; - uint32_t destinations = FDCAN_TX_BUFFER0; - uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; - status |= HAL_FDCAN_ActivateNotification( canHandle->hal_fdcanP, tx_events, destinations); - status |= HAL_FDCAN_ConfigInterruptLines( canHandle->hal_fdcanP, tx_events, FDCAN_INTERRUPT_LINE1); - //Callbacks redefined later - - if (status & HAL_ERROR) { - LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); - return NULL; - } - - //Circular Buffer - canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); - if (!canHandle->tx_buffer ) { - LOGOMATIC("CAN: Could not allocate circular buffer\n"); - return 0; - } - - canHandle->init = true; - canHandle->started = false; - - return canHandle; +static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1); + +static int can_msp_init(CANHandle *handle, const CANConfig *config); +CANHandle *can_init(const CANConfig *config) +{ + // config validation? + // assert(config != 0) + + // #ifdef STM32G474xx + CANHandle *canHandle = 0; + // #ifdef USECAN1 + if (config->fdcan_instance == FDCAN1) { + if (CAN1.init) { + LOGOMATIC("CAN: CAN1 is already initialized\n"); + return 0; + } else { + canHandle = &CAN1; + } + } + // #endif + // #ifdef USECAN2 + else if (config->fdcan_instance == FDCAN2) { + if (CAN2.init) { + LOGOMATIC("CAN: CAN2 is already initialized\n"); + return 0; + } else { + canHandle = &CAN2; + } + } + // #ifdef USECAN3 + else if (config->fdcan_instance == FDCAN3) { + if (CAN3.init) { + LOGOMATIC("CAN: CAN3 is already initialized\n"); + return 0; + } else { + canHandle = &CAN3; + } + } + // #endif + // #elif defined(STM32L476xx) + // #else + // #error "Unsupported STM32 family" + // #endif + else { + LOGOMATIC("CAN: Unrecognized FDCAN instance"); + return 0; + } + canHandle->init = false; + canHandle->started = false; + + // Initialize handle + assert(config->hal_fdcan_init.TxFifoQueueMode == FDCAN_TX_FIFO_OPERATION); + + canHandle->hal_fdcanP->Init = config->hal_fdcan_init; // copy FDCAN parameters from user + // canHandle->hal_fdcanP->Instance = config->fdcan_instance //handles initialized with correct base instance addresses + + canHandle->rx_gpio = config->rx_gpio; + canHandle->tx_gpio = config->tx_gpio; + canHandle->rx_callback = config->rx_callback; + canHandle->tx_buffer_length = config->tx_buffer_length; + + // alternately -> have can_msp_init setup state for HAL_FDCAN_MspInit to work correctly + // have can_msp_deinit setup state for HAL_FDCAN_MspDeInit to work correctly + // Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() + + // Current idea, redefine HAL_FDCAN_MspInit and MspDeInit do nothing at all, do all the work in can_msp_init() + if (can_msp_init(canHandle, config)) { + LOGOMATIC("CAN_init: could not initialize MSP resources"); + can_release(canHandle); + } + + // PROBLEM: HAL_FDCAN_Init expects HAL_FDCAN_MspInit() to be defined + if (HAL_FDCAN_Init(canHandle->hal_fdcanP) != HAL_OK) { + LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); + return NULL; + // Error_Handler(); + } + + // Active FDCAN callbacks - rxcalback uses line0, txcallback uses line1 + // uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; + uint32_t status = 0; + uint32_t rx_events = FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL; + status |= HAL_FDCAN_ActivateNotification(canHandle->hal_fdcanP, rx_events, 0); + status |= HAL_FDCAN_ConfigInterruptLines(canHandle->hal_fdcanP, rx_events, FDCAN_INTERRUPT_LINE0); + + // uint32_t txevents = FDCAN_IT_TX_COMPLETE; + uint32_t destinations = FDCAN_TX_BUFFER0; + uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; + status |= HAL_FDCAN_ActivateNotification(canHandle->hal_fdcanP, tx_events, destinations); + status |= HAL_FDCAN_ConfigInterruptLines(canHandle->hal_fdcanP, tx_events, FDCAN_INTERRUPT_LINE1); + // Callbacks redefined later + + if (status & HAL_ERROR) { + LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); + return NULL; + } + + // Circular Buffer + canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); + if (!canHandle->tx_buffer) { + LOGOMATIC("CAN: Could not allocate circular buffer\n"); + return 0; + } + + canHandle->init = true; + canHandle->started = false; + + return canHandle; } inline int can_set_clksource(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } +// only valid for #STM32G474x, must redefine for each family +static int can_msp_init(CANHandle *canHandle, const CANConfig *config) +{ + // MSP Init ------- This could be inside HAL_FDCAN_MspInit() instead + // FDCAN Clock Select -//only valid for #STM32G474x, must redefine for each family -static int can_msp_init(CANHandle *canHandle, const CANConfig *config) { - //MSP Init ------- This could be inside HAL_FDCAN_MspInit() instead - //FDCAN Clock Select - - fdcan_enable_shared_clock(); - //Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler + fdcan_enable_shared_clock(); + // Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler - //GPIOs init - GPIOx_CLK_ENABLE(config->rx_gpio); - GPIOx_CLK_ENABLE(config->tx_gpio); + // GPIOs init + GPIOx_CLK_ENABLE(config->rx_gpio); + GPIOx_CLK_ENABLE(config->tx_gpio); - HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio)); - HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio)); + HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio)); + HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio)); - IRQn_Type rxit, txit; - can_get_irqs(canHandle->hal_fdcanP->Instance, &rxit, &txit); + IRQn_Type rxit, txit; + can_get_irqs(canHandle->hal_fdcanP->Instance, &rxit, &txit); - //rxfifo0 - HAL_NVIC_SetPriority(rxit, config->rx_interrupt_priority, 0); - HAL_NVIC_EnableIRQ(rxit); + // rxfifo0 + HAL_NVIC_SetPriority(rxit, config->rx_interrupt_priority, 0); + HAL_NVIC_EnableIRQ(rxit); - //tx - HAL_NVIC_SetPriority(txit, config->tx_interrupt_priority,0); - HAL_NVIC_EnableIRQ(txit); - //End MSP Init -------------- + // tx + HAL_NVIC_SetPriority(txit, config->tx_interrupt_priority, 0); + HAL_NVIC_EnableIRQ(txit); + // End MSP Init -------------- - return 0; + return 0; } -void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcan) { return; } - //use can_msp_init() instead to initialize MSP before calling HAL_FDCAN_Init() - -void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcan) { return; } - //use can_msp_deinit() instead +void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcan) { return; } +// use can_msp_init() instead to initialize MSP before calling HAL_FDCAN_Init() +void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcan) { return; } +// use can_msp_deinit() instead -//valid only for STM32G4 -static int can_get_irqs(FDCAN_GlobalTypeDef *instance, - IRQn_Type *it0, - IRQn_Type *it1) +// valid only for STM32G4 +static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1) { - if (instance == FDCAN1) { - *it0 = FDCAN1_IT0_IRQn; - *it1 = FDCAN1_IT1_IRQn; - return 0; - } - if (instance == FDCAN2) { - *it0 = FDCAN2_IT0_IRQn; - *it1 = FDCAN2_IT1_IRQn; - return 0; - } - if (instance == FDCAN3) { - *it0 = FDCAN3_IT0_IRQn; - *it1 = FDCAN3_IT1_IRQn; - return 0; - } - - return -1; // invalid instance + if (instance == FDCAN1) { + *it0 = FDCAN1_IT0_IRQn; + *it1 = FDCAN1_IT1_IRQn; + return 0; + } + if (instance == FDCAN2) { + *it0 = FDCAN2_IT0_IRQn; + *it1 = FDCAN2_IT1_IRQn; + return 0; + } + if (instance == FDCAN3) { + *it0 = FDCAN3_IT0_IRQn; + *it1 = FDCAN3_IT1_IRQn; + return 0; + } + + return -1; // invalid instance } -//valid only for STM32G4 -static const char* can_get_instance_name(FDCAN_GlobalTypeDef *instance) { - if (instance == FDCAN1) return "FDCAN1"; - else if (instance == FDCAN2) return "FDCAN2"; - else if (instance == FDCAN3) return "FDCAN3"; +// valid only for STM32G4 +static const char *can_get_instance_name(FDCAN_GlobalTypeDef *instance) +{ + if (instance == FDCAN1) { + return "FDCAN1"; + } else if (instance == FDCAN2) { + return "FDCAN2"; + } else if (instance == FDCAN3) { + return "FDCAN3"; + } } -//valid only for STM32G4 -static CANHandle* can_get_buffer_handle(FDCAN_HandleTypeDef * hfdcan) { - CANHandle* handle = 0; - //#ifdef STM32G474xx - if (hfdcan->Instance == FDCAN1) return &CAN1; - else if (hfdcan->Instance == FDCAN2) return &CAN2; - else if (hfdcan->Instance == FDCAN3) return &CAN3; - else { - LOGOMATIC("CAN_get_buffer_handle: was given invalid FDCAN instance\n"); - return 0; - } +// valid only for STM32G4 +static CANHandle *can_get_buffer_handle(FDCAN_HandleTypeDef *hfdcan) +{ + CANHandle *handle = 0; + // #ifdef STM32G474xx + if (hfdcan->Instance == FDCAN1) { + return &CAN1; + } else if (hfdcan->Instance == FDCAN2) { + return &CAN2; + } else if (hfdcan->Instance == FDCAN3) { + return &CAN3; + } else { + LOGOMATIC("CAN_get_buffer_handle: was given invalid FDCAN instance\n"); + return 0; + } } -static void can_tx_buffer_helper(CANHandle* handle) { - while (HAL_FDCAN_GetTxFifoFreeLevel(handle->hal_fdcanP) && !GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { - FDCANTxMessage* msg = GR_CircularBuffer_Pop(handle->tx_buffer); +static void can_tx_buffer_helper(CANHandle *handle) +{ + while (HAL_FDCAN_GetTxFifoFreeLevel(handle->hal_fdcanP) && !GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { + FDCANTxMessage *msg = GR_CircularBuffer_Pop(handle->tx_buffer); - if (!msg) break; + if (!msg) { + break; + } - HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ(handle->hal_fdcanP, &msg->tx_header, msg->data ); + HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ(handle->hal_fdcanP, &msg->tx_header, msg->data); - if (status != HAL_OK) { - LOGOMATIC("CAN_tx_helper: failed to add message to FIFO\n"); - free(msg); // Free the message we couldn't send - break; // Stop trying to send more - } + if (status != HAL_OK) { + LOGOMATIC("CAN_tx_helper: failed to add message to FIFO\n"); + free(msg); // Free the message we couldn't send + break; // Stop trying to send more + } - free(msg); // Successfully sent, free the memory - } + free(msg); // Successfully sent, free the memory + } } void FDCAN1_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } @@ -321,65 +363,70 @@ void FDCAN2_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } void FDCAN3_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } void FDCAN3_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } -void HAL_FDCAN_TxBufferCompleteCallback( FDCAN_HandleTypeDef * hfdcan, uint32_t BufferIndexes ) { +void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) +{ - //If circular buffer has elements, send to queue - //Otherwise do nothing - //#ifdef USECAN1 - CANHandle* handle = can_get_buffer_handle(hfdcan); + // If circular buffer has elements, send to queue + // Otherwise do nothing + // #ifdef USECAN1 + CANHandle *handle = can_get_buffer_handle(hfdcan); - if (!handle|| !handle->tx_buffer) { - return; - } + if (!handle || !handle->tx_buffer) { + return; + } - if (GR_CircularBuffer_IsEmpty(handle->tx_buffer)) return; + if (GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { + return; + } - //see if you can pop any more from the buffer - can_tx_buffer_helper(handle); + // see if you can pop any more from the buffer + can_tx_buffer_helper(handle); } -void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs) { - CANHandle * handle = can_get_buffer_handle(hfdcan); +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) +{ + CANHandle *handle = can_get_buffer_handle(hfdcan); - if (!handle || !handle->init || !handle->rx_callback) { - return; - } + if (!handle || !handle->init || !handle->rx_callback) { + return; + } - /*if (!handle->rx_buffer) { - LOGOMATIC("CAN: RX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); - return; - } */ // no rx buffer at the moment + /*if (!handle->rx_buffer) { + LOGOMATIC("CAN: RX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); + return; + } */ // no rx buffer at the moment - /*if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_MESSAGE_LOST) { - lost_rx++; - }*/ + /*if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_MESSAGE_LOST) { + lost_rx++; + }*/ - if ( !(RxFifo0ITs & ~FDCAN_IT_RX_FIFO0_MESSAGE_LOST)) return; + if (!(RxFifo0ITs & ~FDCAN_IT_RX_FIFO0_MESSAGE_LOST)) { + return; + } - //if (GR_CircularBuffer_IsFull(handle->rx_buffer)) return; + // if (GR_CircularBuffer_IsFull(handle->rx_buffer)) return; - FDCAN_RxHeaderTypeDef rx_header; - uint8_t rx_data[64] = {0}; + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; - while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) { - HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, rx_data); + while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) { + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, rx_data); - //stack allocation should be fine? Callback needs to terminate first before stack is popped - //should switch this over to malloc at some point to avoid double copies? - handle->rx_callback(rx_data, rx_header.DataLength); - } - + // stack allocation should be fine? Callback needs to terminate first before stack is popped + // should switch this over to malloc at some point to avoid double copies? + handle->rx_callback(rx_data, rx_header.DataLength); + } - /* whoopsie, don't need the rx buffer yet - while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) & !GR_CircularBuffer_IsFull(handle->rx_buffer)) { - FDCAN_RxHeaderTypeDef rx_header; - uint8_t rx_data[64] = {0}; - HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); + /* whoopsie, don't need the rx buffer yet + while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) & !GR_CircularBuffer_IsFull(handle->rx_buffer)) { + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); - if (GR_CircularBuffer_IsEmpty(handle->rx_buffer)) handle->rx_callback(rx_data, rx_header.DataLength); - else { - GR_CircularBuffer_Push(handle->rx_buffer, rx_data, rx_header.DataLength); - } - }*/ + if (GR_CircularBuffer_IsEmpty(handle->rx_buffer)) handle->rx_callback(rx_data, rx_header.DataLength); + else { + GR_CircularBuffer_Push(handle->rx_buffer, rx_data, rx_header.DataLength); + } + }*/ } /* @@ -394,54 +441,63 @@ void can_read_rx_buffer(CANHandle* canHandle) { }*/ -//Just alternatively just use the HAL_FDCAN_ConfigFilter directly with the canHandle->hal_fdcan -int can_add_filter(CANHandle* canHandle, FDCAN_FilterTypeDef *filter){ - if (!canHandle) { - LOGOMATIC("CAN_add_filter: handle is null"); - return -1; - } - - if ( !canHandle->init || canHandle->started ) { - LOGOMATIC("CAN_add_filter: can instance is not initialized or already started"); - return -1; - } - - if (HAL_FDCAN_ConfigFilter(canHandle->hal_fdcanP, filter) != HAL_OK ) { - LOGOMATIC("CAN_add_filter: failed to configure filter"); - return -1; - } - return 0; - //check that # of filters isn't exceeding max value +// Just alternatively just use the HAL_FDCAN_ConfigFilter directly with the canHandle->hal_fdcan +int can_add_filter(CANHandle *canHandle, FDCAN_FilterTypeDef *filter) +{ + if (!canHandle) { + LOGOMATIC("CAN_add_filter: handle is null"); + return -1; + } + + if (!canHandle->init || canHandle->started) { + LOGOMATIC("CAN_add_filter: can instance is not initialized or already started"); + return -1; + } + + if (HAL_FDCAN_ConfigFilter(canHandle->hal_fdcanP, filter) != HAL_OK) { + LOGOMATIC("CAN_add_filter: failed to configure filter"); + return -1; + } + return 0; + // check that # of filters isn't exceeding max value } -//Need to -int can_start(CANHandle * canHandle) { - if (!canHandle || !canHandle->init) return -1; +// Need to +int can_start(CANHandle *canHandle) +{ + if (!canHandle || !canHandle->init) { + return -1; + } - GPIOx_CLK_ENABLE(canHandle->rx_gpio); - GPIOx_CLK_ENABLE(canHandle->tx_gpio); + GPIOx_CLK_ENABLE(canHandle->rx_gpio); + GPIOx_CLK_ENABLE(canHandle->tx_gpio); - HAL_FDCAN_Start(canHandle->hal_fdcanP); - canHandle->started = true; + HAL_FDCAN_Start(canHandle->hal_fdcanP); + canHandle->started = true; - return 0; + return 0; } -int can_stop(CANHandle * canHandle) { - if (!canHandle || !canHandle->init) return -1; - if (!canHandle->started) return 0; +int can_stop(CANHandle *canHandle) +{ + if (!canHandle || !canHandle->init) { + return -1; + } + if (!canHandle->started) { + return 0; + } - HAL_FDCAN_Stop(canHandle->hal_fdcanP); + HAL_FDCAN_Stop(canHandle->hal_fdcanP); - GPIOx_CLK_DISABLE(canHandle->rx_gpio); - GPIOx_CLK_DISABLE(canHandle->tx_gpio); + GPIOx_CLK_DISABLE(canHandle->rx_gpio); + GPIOx_CLK_DISABLE(canHandle->tx_gpio); - canHandle->started = false; + canHandle->started = false; - return 0; + return 0; } -//Valid only for STM32G474xE +// Valid only for STM32G474xE /*int can_msp_deinit(CANHandle* canHandle) { //MSP DeInit //turn off gpio clocks - can only turn off GPIOs if no other instances are using them @@ -450,133 +506,126 @@ int can_stop(CANHandle * canHandle) { return 0; }*/ -static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef* hfdcan) +static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef *hfdcan) { - // Enter INIT mode - hfdcan->Instance->CCCR |= FDCAN_CCCR_INIT; - while (!(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT)); - - // Clear filters - //TODO: fix magic numbers - memset((void *) hfdcan->msgRam.StandardFilterSA, 0, 0x0070); - memset((void *) hfdcan->msgRam.ExtendedFilterSA, 0, 0x0050); - - // Optionally reset FIFOs / buffers - - // Disable interrupts - __HAL_FDCAN_DISABLE_IT(hfdcan, - FDCAN_IT_LIST_RX_FIFO0 | FDCAN_IT_LIST_RX_FIFO1 | - FDCAN_IT_LIST_SMSG | FDCAN_IT_LIST_TX_FIFO_ERROR | - FDCAN_IT_LIST_MISC | FDCAN_IT_LIST_BIT_LINE_ERROR | - FDCAN_IT_LIST_PROTOCOL_ERROR - ); - - // Exit INIT mode - hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT; - while (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT); - - // Update handle state - hfdcan->State = HAL_FDCAN_STATE_RESET; + // Enter INIT mode + hfdcan->Instance->CCCR |= FDCAN_CCCR_INIT; + while (!(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT)) + ; + + // Clear filters + // TODO: fix magic numbers + memset((void *)hfdcan->msgRam.StandardFilterSA, 0, 0x0070); + memset((void *)hfdcan->msgRam.ExtendedFilterSA, 0, 0x0050); + + // Optionally reset FIFOs / buffers + + // Disable interrupts + __HAL_FDCAN_DISABLE_IT(hfdcan, FDCAN_IT_LIST_RX_FIFO0 | FDCAN_IT_LIST_RX_FIFO1 | FDCAN_IT_LIST_SMSG | FDCAN_IT_LIST_TX_FIFO_ERROR | FDCAN_IT_LIST_MISC | FDCAN_IT_LIST_BIT_LINE_ERROR | + FDCAN_IT_LIST_PROTOCOL_ERROR); + + // Exit INIT mode + hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT; + while (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) + ; + + // Update handle state + hfdcan->State = HAL_FDCAN_STATE_RESET; } -int can_release(CANHandle * canHandle) { - if (!canHandle) { - LOGOMATIC("CAN: Tried to release a null handle"); - return -1; - } +int can_release(CANHandle *canHandle) +{ + if (!canHandle) { + LOGOMATIC("CAN: Tried to release a null handle"); + return -1; + } - if (!canHandle->init) { - LOGOMATIC("CAN_release: can instance is already deinitialized"); - return -1; - } - can_stop(canHandle); //try to prevent more interrupts from firing + if (!canHandle->init) { + LOGOMATIC("CAN_release: can instance is already deinitialized"); + return -1; + } + can_stop(canHandle); // try to prevent more interrupts from firing - //must disable NVIC IRQs before freeing circular buffer + // must disable NVIC IRQs before freeing circular buffer - //turn off NVIC resources - IRQn_Type rx0it, txit; - can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); - HAL_NVIC_DisableIRQ(rx0it); - HAL_NVIC_DisableIRQ(txit); + // turn off NVIC resources + IRQn_Type rx0it, txit; + can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); + HAL_NVIC_DisableIRQ(rx0it); + HAL_NVIC_DisableIRQ(txit); - //need to check if other pins are using before disabling - do this after mvp - //GPIOx_CLK_DISABLE(canHandle->rx_gpio); - //GPIOx_CLK_DISABLE(canHandle->tx_gpio); + // need to check if other pins are using before disabling - do this after mvp + // GPIOx_CLK_DISABLE(canHandle->rx_gpio); + // GPIOx_CLK_DISABLE(canHandle->tx_gpio); - //reset FDCANx instance and message RAM and filters, clear interrupts - //HAL_FDCAN_DeInit(canHandle->hal_fdcanP); resets a little too hard - FDCAN_InstanceDeInit(canHandle->hal_fdcanP); + // reset FDCANx instance and message RAM and filters, clear interrupts + // HAL_FDCAN_DeInit(canHandle->hal_fdcanP); resets a little too hard + FDCAN_InstanceDeInit(canHandle->hal_fdcanP); - __DSB(); // Data Synchronization Barrier - __ISB(); // Instruction Synchronization Barrier + __DSB(); // Data Synchronization Barrier + __ISB(); // Instruction Synchronization Barrier - //free circular buffer contents - GR_CircularBuffer_Free(&(canHandle->tx_buffer)); + // free circular buffer contents + GR_CircularBuffer_Free(&(canHandle->tx_buffer)); - //reset can instance - FDCAN_HandleTypeDef * temp = canHandle->hal_fdcanP; - memset(canHandle, 0, sizeof(*canHandle)); - canHandle->hal_fdcanP = temp; + // reset can instance + FDCAN_HandleTypeDef *temp = canHandle->hal_fdcanP; + memset(canHandle, 0, sizeof(*canHandle)); + canHandle->hal_fdcanP = temp; - fdcan_disable_shared_clock(); //only turns off clock if no other instances are running. + fdcan_disable_shared_clock(); // only turns off clock if no other instances are running. - return 0; + return 0; } -int can_send(CANHandle* canHandle, FDCANTxMessage* message) { - if (!canHandle || !message) { - LOGOMATIC("CAN_send: received null pointer\n"); - return -1; - } - - if (!canHandle->init || !canHandle->started) { - LOGOMATIC("CAN_send: CAN not initialized or started\n"); - return -1; - } - - uint32_t primask = __get_PRIMASK(); - __disable_irq(); - //IF TX Fifos are not full, send directly to them - //If TX Fifos are full, append to circular buffer - //If circular buffer is full, return an error code - uint32_t free = HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP); - - - if (free > 0) { - HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ( - canHandle->hal_fdcanP, - &(message->tx_header), - message->data // Not &message->data if data is array - ); - - __set_PRIMASK(primask); - - if (status != HAL_OK) { - LOGOMATIC("CAN_send: failed to add to HW FIFO\n"); - return -1; - } - return 0; - } - - // Hardware FIFO full, try software buffer - if (!GR_CircularBuffer_IsFull(canHandle->tx_buffer)) { - int result = GR_CircularBuffer_Push( - canHandle->tx_buffer, - message, - sizeof(FDCANTxMessage) - ); - - __set_PRIMASK(primask); - - if (result != 0) { - LOGOMATIC("CAN_send: buffer push failed\n"); - return -1; - } - return 0; - } - - // Both buffers full - __set_PRIMASK(primask); - LOGOMATIC("CAN_send: all buffers full\n"); - return -1; +int can_send(CANHandle *canHandle, FDCANTxMessage *message) +{ + if (!canHandle || !message) { + LOGOMATIC("CAN_send: received null pointer\n"); + return -1; + } + + if (!canHandle->init || !canHandle->started) { + LOGOMATIC("CAN_send: CAN not initialized or started\n"); + return -1; + } + + uint32_t primask = __get_PRIMASK(); + __disable_irq(); + // IF TX Fifos are not full, send directly to them + // If TX Fifos are full, append to circular buffer + // If circular buffer is full, return an error code + uint32_t free = HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP); + + if (free > 0) { + HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ(canHandle->hal_fdcanP, &(message->tx_header), + message->data // Not &message->data if data is array + ); + + __set_PRIMASK(primask); + + if (status != HAL_OK) { + LOGOMATIC("CAN_send: failed to add to HW FIFO\n"); + return -1; + } + return 0; + } + + // Hardware FIFO full, try software buffer + if (!GR_CircularBuffer_IsFull(canHandle->tx_buffer)) { + int result = GR_CircularBuffer_Push(canHandle->tx_buffer, message, sizeof(FDCANTxMessage)); + + __set_PRIMASK(primask); + + if (result != 0) { + LOGOMATIC("CAN_send: buffer push failed\n"); + return -1; + } + return 0; + } + + // Both buffers full + __set_PRIMASK(primask); + LOGOMATIC("CAN_send: all buffers full\n"); + return -1; } diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index 8559d7dc..56cfece2 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -1,34 +1,35 @@ #include "can_tests.h" -#include "can.h" -#include -//each family has a constant number of CAN peripherals +#include +#include "can.h" -int can_test_instance(FDCAN_HandleTypeDef) { +// each family has a constant number of CAN peripherals - return 0; -} +int can_test_instance(FDCAN_HandleTypeDef) { return 0; } -void can_test_rx_callback2(void*data, uint32_t size) { +void can_test_rx_callback2(void *data, uint32_t size) +{ LOGOMATIC("CAN2 Got data!\n"); // Is within an ISR, so needs to exit quickly return; } -void can_test_rx_callback1(void*data, uint32_t size) { +void can_test_rx_callback1(void *data, uint32_t size) +{ LOGOMATIC("CAN1 Got data!\n"); // Is within an ISR, so needs to exit quickly return; } -int can_test(void) { +int can_test(void) +{ - CANConfig canCfg; - //canCfg.fdcan_instance = FDCAN2; + CANConfig canCfg; + // canCfg.fdcan_instance = FDCAN2; - canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; canCfg.hal_fdcan_init.Mode = FDCAN_MODE_NORMAL; @@ -37,52 +38,51 @@ int can_test(void) { canCfg.hal_fdcan_init.ProtocolException = ENABLE; canCfg.hal_fdcan_init.NominalPrescaler = 1; canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; - canCfg.hal_fdcan_init.NominalTimeSeg1 = 127; // Updated for 170MHz: (1+127+42)*1 = 170 ticks -> 1 Mbps + canCfg.hal_fdcan_init.NominalTimeSeg1 = 127; // Updated for 170MHz: (1+127+42)*1 = 170 ticks -> 1 Mbps canCfg.hal_fdcan_init.NominalTimeSeg2 = 42; canCfg.hal_fdcan_init.DataPrescaler = 8; canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; - canCfg.hal_fdcan_init.DataTimeSeg1 = 15; // Updated for 170MHz: (1+15+5)*8 = 168 ticks -> ~5 Mbps + canCfg.hal_fdcan_init.DataTimeSeg1 = 15; // Updated for 170MHz: (1+15+5)*8 = 168 ticks -> ~5 Mbps canCfg.hal_fdcan_init.DataTimeSeg2 = 5; canCfg.hal_fdcan_init.StdFiltersNbr = 1; canCfg.hal_fdcan_init.ExtFiltersNbr = 0; - canCfg.rx_callback = NULL; // PLEASE SET + canCfg.rx_callback = NULL; // PLEASE SET canCfg.rx_interrupt_priority = 0; // PLEASE SET canCfg.tx_interrupt_priority = 0; // PLEASE SET - canCfg.tx_buffer_length = 3; // PLEASE SET + canCfg.tx_buffer_length = 3; // PLEASE SET - //canCfg.rx_gpio = GPIOB; - //canCfg.init_rx_gpio.Pin = GPIO_PIN_12; + // canCfg.rx_gpio = GPIOB; + // canCfg.init_rx_gpio.Pin = GPIO_PIN_12; canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; canCfg.init_rx_gpio.Pull = GPIO_PULLUP; canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - //canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + // canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; - //canCfg.tx_gpio = GPIOB; - //canCfg.init_tx_gpio.Pin = GPIO_PIN_13; + // canCfg.tx_gpio = GPIOB; + // canCfg.init_tx_gpio.Pin = GPIO_PIN_13; canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; canCfg.init_tx_gpio.Pull = GPIO_NOPULL; canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - //canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; - + // canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; - //Not testing filters at the moment - //FDCAN_FilterTypeDef filter; + // Not testing filters at the moment + // FDCAN_FilterTypeDef filter; - //can_add_filter(can2Handle, &filter); + // can_add_filter(can2Handle, &filter); /* USER CODE END 2 */ FDCAN_TxHeaderTypeDef TxHeader = { - .Identifier = 1, - - .IdType = FDCAN_STANDARD_ID, - .TxFrameType = FDCAN_DATA_FRAME, - .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node - // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors - .DataLength = 1, - .BitRateSwitch = FDCAN_BRS_OFF, - .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages - .MessageMarker = 0 // also change this to a real address if you change fifo control + .Identifier = 1, + + .IdType = FDCAN_STANDARD_ID, + .TxFrameType = FDCAN_DATA_FRAME, + .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node + // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors + .DataLength = 1, + .BitRateSwitch = FDCAN_BRS_OFF, + .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages + .MessageMarker = 0 // also change this to a real address if you change fifo control }; FDCANTxMessage msg; @@ -90,43 +90,39 @@ int can_test(void) { memset(&(msg.data), 0, sizeof(msg.data)); msg.tx_header = TxHeader; - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); - #ifdef FDCAN1 +#ifdef FDCAN1 canCfg.fdcan_instance = FDCAN1; - canCfg.rx_gpio = GPIOA; - canCfg.init_rx_gpio.Pin = GPIO_PIN_11; - canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_11; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; - canCfg.tx_gpio = GPIOA; - canCfg.init_tx_gpio.Pin = GPIO_PIN_12; - canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_12; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; canCfg.rx_callback = can_test_rx_callback1; // PLEASE SET - CANHandle *can1Handle = can_init(&canCfg); - HAL_FDCAN_ConfigGlobalFilter(can1Handle->hal_fdcanP, 0, 0, 0,0); + HAL_FDCAN_ConfigGlobalFilter(can1Handle->hal_fdcanP, 0, 0, 0, 0); can_start(can1Handle); +#endif +#ifdef FDCAN2 - #endif - #ifdef FDCAN2 + canCfg.fdcan_instance = FDCAN2; + canCfg.rx_gpio = GPIOB; + canCfg.init_rx_gpio.Pin = GPIO_PIN_12; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; - canCfg.fdcan_instance = FDCAN2; - canCfg.rx_gpio = GPIOB; - canCfg.init_rx_gpio.Pin = GPIO_PIN_12; - canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; - - canCfg.tx_gpio = GPIOB; - canCfg.init_tx_gpio.Pin = GPIO_PIN_13; - canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; - - canCfg.rx_callback = can_test_rx_callback2; + canCfg.tx_gpio = GPIOB; + canCfg.init_tx_gpio.Pin = GPIO_PIN_13; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + canCfg.rx_callback = can_test_rx_callback2; // FDCAN_FilterTypeDef filter; // filter.IdType = FDCAN_STANDARD_ID; @@ -136,36 +132,35 @@ int can_test(void) { // filter.FilterID1 = 0x00; // filter.FilterID2 = 0x02; - CANHandle *can2Handle = can_init(&canCfg); + CANHandle *can2Handle = can_init(&canCfg); - //accept unmatched standard and extended frames into RXFIFO0 - default behaviour - HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, 0, 0, 0,0); + // accept unmatched standard and extended frames into RXFIFO0 - default behaviour + HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, 0, 0, 0, 0); - //not accepting filters - //can_add_filter(can2Handle, &filter); + // not accepting filters + // can_add_filter(can2Handle, &filter); - //API Testing - //can_init(&canCfg); + // API Testing + // can_init(&canCfg); - can_start(can2Handle); + can_start(can2Handle); - can_send(can2Handle, &msg); - //can_release(can2Handle); + can_send(can2Handle, &msg); + // can_release(can2Handle); - #endif - #ifdef FDCAN3 +#endif +#ifdef FDCAN3 - #endif +#endif while (1) { HAL_Delay(1000); msg.data[0] = 0x2; - can_send(can1Handle, &msg); + can_send(can1Handle, &msg); HAL_Delay(1000); msg.data[0] = 0x10; - can_send(can2Handle, &msg); + can_send(can2Handle, &msg); } - return 0; - + return 0; } diff --git a/Lib/Peripherals/CAN/Test/can_tests.h b/Lib/Peripherals/CAN/Test/can_tests.h index 052c27ce..39cdec72 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.h +++ b/Lib/Peripherals/CAN/Test/can_tests.h @@ -1,19 +1,19 @@ #ifndef CAN_TESTS_H #define CAN_TESTS_H +#include "Logomatic.h" #include "can.h" #include "can_platform_deps.h" -#include "Logomatic.h" -//Tested STM32 Families +// Tested STM32 Families #ifdef STM32G4 -//#elif defined(STM32L4) -//#elif defined(STM32U5) -#else +// #elif defined(STM32L4) +// #elif defined(STM32U5) +#else #error "Untested STM32 Family" -#endif +#endif -//Assume the LOGOMATIC is setup correctly -int can_test(void); //top-level function, just call this and check if the return status is correct +// Assume the LOGOMATIC is setup correctly +int can_test(void); // top-level function, just call this and check if the return status is correct -#endif \ No newline at end of file +#endif \ No newline at end of file From 6ae7fa23dddd88494e674fae0cc5a757bac7d2d0 Mon Sep 17 00:00:00 2001 From: ahoysal Date: Thu, 15 Jan 2026 23:20:31 -0800 Subject: [PATCH 17/18] fixed all warnings Co-authored-by: Daniel Hansen Co-authored-by: Nathan So Co-authored-by: ShortSideburns --- G4CANTESTING/CMakeLists.txt | 1 - G4CANTESTING/Core/Src/fdcan.c | 2 + G4CANTESTING/Core/Src/main.c | 4 +- G4CANTESTING/Core/Src/stm32g4xx_it.c | 19 ------ Lib/Peripherals/CAN/Inc/can.h | 2 +- Lib/Peripherals/CAN/README.md | 2 +- Lib/Peripherals/CAN/Src/can.c | 88 ++++++++++------------------ Lib/Peripherals/CAN/Test/can_tests.c | 9 ++- 8 files changed, 42 insertions(+), 85 deletions(-) diff --git a/G4CANTESTING/CMakeLists.txt b/G4CANTESTING/CMakeLists.txt index ef4620ac..0c52f1d1 100644 --- a/G4CANTESTING/CMakeLists.txt +++ b/G4CANTESTING/CMakeLists.txt @@ -33,7 +33,6 @@ target_sources( Core/Src/adc.c Core/Src/crc.c Core/Src/dma.c - Core/Src/fdcan.c Core/Src/gpio.c Core/Src/i2c.c Core/Src/main.c diff --git a/G4CANTESTING/Core/Src/fdcan.c b/G4CANTESTING/Core/Src/fdcan.c index 3fa841e1..a50e4b05 100644 --- a/G4CANTESTING/Core/Src/fdcan.c +++ b/G4CANTESTING/Core/Src/fdcan.c @@ -1,3 +1,4 @@ +//#include "unused.h" // /* USER CODE BEGIN Header */ // /** // ****************************************************************************** @@ -131,3 +132,4 @@ // /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ +//UNUSED(5); \ No newline at end of file diff --git a/G4CANTESTING/Core/Src/main.c b/G4CANTESTING/Core/Src/main.c index 15335005..d89e69b1 100644 --- a/G4CANTESTING/Core/Src/main.c +++ b/G4CANTESTING/Core/Src/main.c @@ -88,9 +88,7 @@ static void ITM_Enable(void) ITM->TER |= (1UL << 0); ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); } -static int toggleze = 0; -void DEBUG_callback(void *data, uint32_t size) { toggleze = (*((char *)data) & 0x80); } - +//static int toggleze = 0; /* USER CODE END 0 */ /** diff --git a/G4CANTESTING/Core/Src/stm32g4xx_it.c b/G4CANTESTING/Core/Src/stm32g4xx_it.c index de1160d3..51eefbe0 100644 --- a/G4CANTESTING/Core/Src/stm32g4xx_it.c +++ b/G4CANTESTING/Core/Src/stm32g4xx_it.c @@ -193,22 +193,3 @@ void SysTick_Handler(void) /* For the available peripheral interrupt handler names, */ /* please refer to the startup file (startup_stm32g4xx.s). */ /******************************************************************************/ - -/** - * @brief This function handles FDCAN2 interrupt 0. - */ -/* -// void FDCAN2_IT0_IRQHandler(void) -// { -// /* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */ - -// /* USER CODE END FDCAN2_IT0_IRQn 0 */ -// HAL_FDCAN_IRQHandler(&hfdcan2); -// /* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */ - -// /* USER CODE END FDCAN2_IT0_IRQn 1 */ -// } - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ diff --git a/Lib/Peripherals/CAN/Inc/can.h b/Lib/Peripherals/CAN/Inc/can.h index 6c2b7e0b..d37d614d 100644 --- a/Lib/Peripherals/CAN/Inc/can.h +++ b/Lib/Peripherals/CAN/Inc/can.h @@ -75,6 +75,6 @@ int can_add_filter(CANHandle *handle, FDCAN_FilterTypeDef *filter); // HAL_FDCAN_ConfigFilter() // doesn't need a handle, CAN cores share peripheral clock -int can_set_clksource(uint32_t clksource); // ex. LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE +void can_set_clksource(uint32_t clksource); // ex. LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE #endif // End Header Guard diff --git a/Lib/Peripherals/CAN/README.md b/Lib/Peripherals/CAN/README.md index db96f9a3..43d257b0 100644 --- a/Lib/Peripherals/CAN/README.md +++ b/Lib/Peripherals/CAN/README.md @@ -2,7 +2,7 @@ CANHandle* can_init(CANConfig *config); //user must supply an rx callback function -int can_set_clksource(uint32_t LL_RCC_FDCAN_CLKSOURCE); //ex LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE +void can_set_clksource(uint32_t LL_RCC_FDCAN_CLKSOURCE); //ex LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE int can_start(CANHandle*handle); int can_stop(CANHandle*handle); diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 02ede7f8..824fa262 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -49,39 +49,17 @@ static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; */ -#define GPIOx_CLK_ENABLE(GPIOX) \ - do { \ - switch ((uint32_t)GPIOX) { \ - case (uint32_t)GPIOA: \ - __HAL_RCC_GPIOA_CLK_ENABLE(); \ - break; \ - case (uint32_t)GPIOB: \ - __HAL_RCC_GPIOB_CLK_ENABLE(); \ - break; \ - case (uint32_t)GPIOD: \ - __HAL_RCC_GPIOD_CLK_ENABLE(); \ - break; \ - default: \ - LOGOMATIC("BAD FDCAN GPIO Port"); \ - } \ - } while (0) - -#define GPIOx_CLK_DISABLE(GPIOX) \ - do { \ - switch ((uint32_t)GPIOX) { \ - case (uint32_t)GPIOA: \ - __HAL_RCC_GPIOA_CLK_DISABLE(); \ - break; \ - case (uint32_t)GPIOB: \ - __HAL_RCC_GPIOB_CLK_DISABLE(); \ - break; \ - case (uint32_t)GPIOD: \ - __HAL_RCC_GPIOD_CLK_DISABLE(); \ - break; \ - default: \ - LOGOMATIC("BAD FDCAN GPIO Port"); \ - } \ - } while (0) +#define GPIOx_CLK_ENABLE(GPIOX) \ + do { if (GPIOX == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE();\ + else if (GPIOX == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE(); \ + else if (GPIOX == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE(); \ + else LOGOMATIC("BAD FDCAN GPIO Port"); } while (0) + +#define GPIOx_CLK_DISABLE(GPIOX) \ + do { if (GPIOX == GPIOA) __HAL_RCC_GPIOA_CLK_DISABLE();\ + else if (GPIOX == GPIOB) __HAL_RCC_GPIOB_CLK_DISABLE(); \ + else if (GPIOX == GPIOD) __HAL_RCC_GPIOD_CLK_DISABLE(); \ + else LOGOMATIC("BAD FDCAN GPIO Port"); } while (0) static int fdcan_shared_clock_ref = 0; static inline void fdcan_enable_shared_clock(void) @@ -135,7 +113,7 @@ static inline void gpio_clk_disable(GPIO_TypeDef *gpio) static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1); -static int can_msp_init(CANHandle *handle, const CANConfig *config); +static int can_msp_init(CANHandle *handle, CANConfig *config); CANHandle *can_init(const CANConfig *config) { // config validation? @@ -199,7 +177,7 @@ CANHandle *can_init(const CANConfig *config) // Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() // Current idea, redefine HAL_FDCAN_MspInit and MspDeInit do nothing at all, do all the work in can_msp_init() - if (can_msp_init(canHandle, config)) { + if (can_msp_init(canHandle, (CANConfig*)config)) { LOGOMATIC("CAN_init: could not initialize MSP resources"); can_release(canHandle); } @@ -243,10 +221,10 @@ CANHandle *can_init(const CANConfig *config) return canHandle; } -inline int can_set_clksource(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } +inline void can_set_clksource(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } // only valid for #STM32G474x, must redefine for each family -static int can_msp_init(CANHandle *canHandle, const CANConfig *config) +static int can_msp_init(CANHandle *canHandle, CANConfig *config) { // MSP Init ------- This could be inside HAL_FDCAN_MspInit() instead // FDCAN Clock Select @@ -261,7 +239,8 @@ static int can_msp_init(CANHandle *canHandle, const CANConfig *config) HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio)); HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio)); - IRQn_Type rxit, txit; + IRQn_Type rxit = -1; + IRQn_Type txit = -1; can_get_irqs(canHandle->hal_fdcanP->Instance, &rxit, &txit); // rxfifo0 @@ -276,12 +255,6 @@ static int can_msp_init(CANHandle *canHandle, const CANConfig *config) return 0; } -void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcan) { return; } -// use can_msp_init() instead to initialize MSP before calling HAL_FDCAN_Init() - -void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcan) { return; } -// use can_msp_deinit() instead - // valid only for STM32G4 static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1) { @@ -305,21 +278,21 @@ static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type } // valid only for STM32G4 -static const char *can_get_instance_name(FDCAN_GlobalTypeDef *instance) -{ - if (instance == FDCAN1) { - return "FDCAN1"; - } else if (instance == FDCAN2) { - return "FDCAN2"; - } else if (instance == FDCAN3) { - return "FDCAN3"; - } -} +// static const char *can_get_instance_name(FDCAN_GlobalTypeDef *instance) +// { +// if (instance == FDCAN1) { +// return "FDCAN1"; +// } else if (instance == FDCAN2) { +// return "FDCAN2"; +// } else if (instance == FDCAN3) { +// return "FDCAN3"; +// } +// return "UNKNOWN"; +// } // valid only for STM32G4 static CANHandle *can_get_buffer_handle(FDCAN_HandleTypeDef *hfdcan) { - CANHandle *handle = 0; // #ifdef STM32G474xx if (hfdcan->Instance == FDCAN1) { return &CAN1; @@ -365,7 +338,7 @@ void FDCAN3_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) { - + UNUSED(BufferIndexes); // If circular buffer has elements, send to queue // Otherwise do nothing // #ifdef USECAN1 @@ -549,7 +522,8 @@ int can_release(CANHandle *canHandle) // must disable NVIC IRQs before freeing circular buffer // turn off NVIC resources - IRQn_Type rx0it, txit; + IRQn_Type rx0it = -1; + IRQn_Type txit = -1; can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); HAL_NVIC_DisableIRQ(rx0it); HAL_NVIC_DisableIRQ(txit); diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index 56cfece2..bb4cc344 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -6,18 +6,21 @@ // each family has a constant number of CAN peripherals -int can_test_instance(FDCAN_HandleTypeDef) { return 0; } +int can_test_instance(FDCAN_HandleTypeDef fdcan_handle) { + UNUSED(fdcan_handle); + return 0; +} void can_test_rx_callback2(void *data, uint32_t size) { - LOGOMATIC("CAN2 Got data!\n"); + LOGOMATIC("CAN2 Got data! Size %ld, data[0] = 0x%x\n", size, *(char*) data); // Is within an ISR, so needs to exit quickly return; } void can_test_rx_callback1(void *data, uint32_t size) { - LOGOMATIC("CAN1 Got data!\n"); + LOGOMATIC("CAN1 Got data! Size %ld, data[0] = 0x%x\n", size, *(char*) data); // Is within an ISR, so needs to exit quickly return; From 00a42c7c04075e2f22e2047209704fa794d34058 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 07:21:34 +0000 Subject: [PATCH 18/18] Automatic Clang-Format: Standardized formatting automatically --- G4CANTESTING/Core/Src/fdcan.c | 46 ++++++++++++++-------------- G4CANTESTING/Core/Src/main.c | 2 +- Lib/Peripherals/CAN/Src/can.c | 36 ++++++++++++++-------- Lib/Peripherals/CAN/Test/can_tests.c | 7 +++-- 4 files changed, 52 insertions(+), 39 deletions(-) diff --git a/G4CANTESTING/Core/Src/fdcan.c b/G4CANTESTING/Core/Src/fdcan.c index a50e4b05..5373c38c 100644 --- a/G4CANTESTING/Core/Src/fdcan.c +++ b/G4CANTESTING/Core/Src/fdcan.c @@ -1,25 +1,25 @@ -//#include "unused.h" -// /* USER CODE BEGIN Header */ -// /** -// ****************************************************************************** -// * @file fdcan.c -// * @brief This file provides code for the configuration -// * of the FDCAN instances. -// ****************************************************************************** -// * @attention -// * -// * Copyright (c) 2024 STMicroelectronics. -// * All rights reserved. -// * -// * This software is licensed under terms that can be found in the LICENSE file -// * in the root directory of this software component. -// * If no LICENSE file comes with this software, it is provided AS-IS. -// * -// ****************************************************************************** -// */ -// /* USER CODE END Header */ -// /* Includes ------------------------------------------------------------------*/ -// #include "fdcan.h" +// #include "unused.h" +// /* USER CODE BEGIN Header */ +// /** +// ****************************************************************************** +// * @file fdcan.c +// * @brief This file provides code for the configuration +// * of the FDCAN instances. +// ****************************************************************************** +// * @attention +// * +// * Copyright (c) 2024 STMicroelectronics. +// * All rights reserved. +// * +// * This software is licensed under terms that can be found in the LICENSE file +// * in the root directory of this software component. +// * If no LICENSE file comes with this software, it is provided AS-IS. +// * +// ****************************************************************************** +// */ +// /* USER CODE END Header */ +// /* Includes ------------------------------------------------------------------*/ +// #include "fdcan.h" // /* USER CODE BEGIN 0 */ @@ -132,4 +132,4 @@ // /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ -//UNUSED(5); \ No newline at end of file +// UNUSED(5); \ No newline at end of file diff --git a/G4CANTESTING/Core/Src/main.c b/G4CANTESTING/Core/Src/main.c index d89e69b1..b5850c37 100644 --- a/G4CANTESTING/Core/Src/main.c +++ b/G4CANTESTING/Core/Src/main.c @@ -88,7 +88,7 @@ static void ITM_Enable(void) ITM->TER |= (1UL << 0); ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); } -//static int toggleze = 0; +// static int toggleze = 0; /* USER CODE END 0 */ /** diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 824fa262..1bea5c95 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -49,17 +49,29 @@ static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; */ -#define GPIOx_CLK_ENABLE(GPIOX) \ - do { if (GPIOX == GPIOA) __HAL_RCC_GPIOA_CLK_ENABLE();\ - else if (GPIOX == GPIOB) __HAL_RCC_GPIOB_CLK_ENABLE(); \ - else if (GPIOX == GPIOD) __HAL_RCC_GPIOD_CLK_ENABLE(); \ - else LOGOMATIC("BAD FDCAN GPIO Port"); } while (0) - -#define GPIOx_CLK_DISABLE(GPIOX) \ - do { if (GPIOX == GPIOA) __HAL_RCC_GPIOA_CLK_DISABLE();\ - else if (GPIOX == GPIOB) __HAL_RCC_GPIOB_CLK_DISABLE(); \ - else if (GPIOX == GPIOD) __HAL_RCC_GPIOD_CLK_DISABLE(); \ - else LOGOMATIC("BAD FDCAN GPIO Port"); } while (0) +#define GPIOx_CLK_ENABLE(GPIOX) \ + do { \ + if (GPIOX == GPIOA) \ + __HAL_RCC_GPIOA_CLK_ENABLE(); \ + else if (GPIOX == GPIOB) \ + __HAL_RCC_GPIOB_CLK_ENABLE(); \ + else if (GPIOX == GPIOD) \ + __HAL_RCC_GPIOD_CLK_ENABLE(); \ + else \ + LOGOMATIC("BAD FDCAN GPIO Port"); \ + } while (0) + +#define GPIOx_CLK_DISABLE(GPIOX) \ + do { \ + if (GPIOX == GPIOA) \ + __HAL_RCC_GPIOA_CLK_DISABLE(); \ + else if (GPIOX == GPIOB) \ + __HAL_RCC_GPIOB_CLK_DISABLE(); \ + else if (GPIOX == GPIOD) \ + __HAL_RCC_GPIOD_CLK_DISABLE(); \ + else \ + LOGOMATIC("BAD FDCAN GPIO Port"); \ + } while (0) static int fdcan_shared_clock_ref = 0; static inline void fdcan_enable_shared_clock(void) @@ -177,7 +189,7 @@ CANHandle *can_init(const CANConfig *config) // Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() // Current idea, redefine HAL_FDCAN_MspInit and MspDeInit do nothing at all, do all the work in can_msp_init() - if (can_msp_init(canHandle, (CANConfig*)config)) { + if (can_msp_init(canHandle, (CANConfig *)config)) { LOGOMATIC("CAN_init: could not initialize MSP resources"); can_release(canHandle); } diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c index bb4cc344..6e436cc4 100644 --- a/Lib/Peripherals/CAN/Test/can_tests.c +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -6,21 +6,22 @@ // each family has a constant number of CAN peripherals -int can_test_instance(FDCAN_HandleTypeDef fdcan_handle) { +int can_test_instance(FDCAN_HandleTypeDef fdcan_handle) +{ UNUSED(fdcan_handle); return 0; } void can_test_rx_callback2(void *data, uint32_t size) { - LOGOMATIC("CAN2 Got data! Size %ld, data[0] = 0x%x\n", size, *(char*) data); + LOGOMATIC("CAN2 Got data! Size %ld, data[0] = 0x%x\n", size, *(char *)data); // Is within an ISR, so needs to exit quickly return; } void can_test_rx_callback1(void *data, uint32_t size) { - LOGOMATIC("CAN1 Got data! Size %ld, data[0] = 0x%x\n", size, *(char*) data); + LOGOMATIC("CAN1 Got data! Size %ld, data[0] = 0x%x\n", size, *(char *)data); // Is within an ISR, so needs to exit quickly return;