diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h index 8022de0cb7..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h index 8022de0cb7..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F072RB/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h index 8022de0cb7..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F091RC/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h index 3d11acebd0..c6ebc7bd02 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h @@ -128,6 +128,14 @@ struct dac_s { }; #endif +#if DEVICE_CAN +struct can_s { + CAN_HandleTypeDef CanHandle; + int index; + int hz; +}; +#endif + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h index 24fa9d1f17..5ddc595468 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_BLUEPILL_F103C8/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h index 24fa9d1f17..5ddc595468 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/TARGET_NUCLEO_F103RB/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F1/common_objects.h b/targets/TARGET_STM/TARGET_STM32F1/common_objects.h index 12487fcf0b..3bd078970c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/common_objects.h @@ -116,6 +116,14 @@ struct analogin_s { uint8_t channel; }; +#if DEVICE_CAN +struct can_s { + CAN_HandleTypeDef CanHandle; + int index; + int hz; +}; +#endif + #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F2/objects.h b/targets/TARGET_STM/TARGET_STM32F2/objects.h index c2489cb851..e87ecf78a7 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F2/objects.h @@ -136,10 +136,13 @@ struct pwmout_s { uint8_t inverted; }; +#ifdef DEVICE_CAN struct can_s { - CANName can; + CAN_HandleTypeDef CanHandle; int index; + int hz; }; +#endif #define GPIO_IP_WITHOUT_BRR #include "gpio_object.h" diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/objects.h index 8022de0cb7..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F302x8/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/objects.h index 8022de0cb7..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303x8/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/objects.h index 8022de0cb7..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xC/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/objects.h index 8022de0cb7..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F303xE/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/objects.h b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/objects.h index 90b0f732c1..d0f3565f66 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/TARGET_STM32F334x8/objects.h @@ -54,13 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -#if defined (DEVICE_CAN) -struct can_s { - CANName can; - int index; -}; -#endif - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h index 8db726ed14..ba731890ce 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h @@ -124,6 +124,14 @@ struct analogin_s { uint8_t channel; }; +#if DEVICE_CAN +struct can_s { + CAN_HandleTypeDef CanHandle; + int index; + int hz; +}; +#endif + #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/objects.h index 9ab04158e0..565319422c 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F412xG/objects.h @@ -40,11 +40,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h index ceee07a594..9b3aa0b3f9 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F413xH/objects.h @@ -40,11 +40,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/objects.h index a7e928ec3a..ece5f1679f 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F429xI/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/objects.h index e1b80b20e4..d2474f4e52 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F437xG/objects.h @@ -59,11 +59,6 @@ struct trng_s { }; #include "common_objects.h" -struct can_s { - CANName can; - int index; -}; - #include "gpio_object.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/objects.h index a7e928ec3a..ece5f1679f 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F439xI/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/objects.h index a2e2ad0f34..16467b7c87 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F446xE/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h index 0de614ff89..bea7fef547 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_STM32F469xI/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F4/common_objects.h b/targets/TARGET_STM/TARGET_STM32F4/common_objects.h index d5d8a6c184..3f39a9ce53 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/common_objects.h @@ -133,6 +133,14 @@ struct dac_s { }; #endif +#if DEVICE_CAN +struct can_s { + CAN_HandleTypeDef CanHandle; + int index; + int hz; +}; +#endif + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h index 52b8e159eb..2894691118 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F746xG/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h index 52b8e159eb..2894691118 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F756xG/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/objects.h index 52b8e159eb..2894691118 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F767xI/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h index 52b8e159eb..2894691118 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/TARGET_STM32F769xI/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h index ee81970f04..b3f02642c7 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h @@ -132,6 +132,14 @@ struct flash_s { uint32_t dummy; }; +#if DEVICE_CAN +struct can_s { + CAN_HandleTypeDef CanHandle; + int index; + int hz; +}; +#endif + #ifdef __cplusplus } #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/objects.h index a7e928ec3a..ece5f1679f 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h index a0dee029b4..e68c4eb619 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h index a7e928ec3a..ece5f1679f 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h index a7e928ec3a..ece5f1679f 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/objects.h @@ -54,11 +54,6 @@ struct port_s { __IO uint32_t *reg_out; }; -struct can_s { - CANName can; - int index; -}; - struct trng_s { RNG_HandleTypeDef handle; }; diff --git a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h index e9e10f3069..9ee16729ea 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h @@ -135,6 +135,14 @@ struct dac_s { } #endif +#if DEVICE_CAN +struct can_s { + CAN_HandleTypeDef CanHandle; + int index; + int hz; +}; +#endif + /* STM32L4 HAL doesn't provide this API called in rtc_api.c */ #define __HAL_RCC_RTC_CLKPRESCALER(__RTCCLKSource__) diff --git a/targets/TARGET_STM/can_api.c b/targets/TARGET_STM/can_api.c index cd3c9b8888..b89f62891c 100644 --- a/targets/TARGET_STM/can_api.c +++ b/targets/TARGET_STM/can_api.c @@ -25,10 +25,21 @@ #include #include -static CAN_HandleTypeDef CanHandle; static uint32_t can_irq_ids[CAN_NUM] = {0}; static can_irq_handler irq_handler; +static void can_registers_init(can_t *obj) +{ + if (HAL_CAN_Init(&obj->CanHandle) != HAL_OK) { + error("Cannot initialize CAN"); + } + + // Set initial CAN frequency to specified frequency + if (can_frequency(obj, obj->hz) != 1) { + error("Can frequency could not be set\n"); + } +} + void can_init(can_t *obj, PinName rd, PinName td) { can_init_freq(obj, rd, td, 100000); @@ -38,16 +49,16 @@ void can_init_freq (can_t *obj, PinName rd, PinName td, int hz) { CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + CANName can = (CANName)pinmap_merge(can_rd, can_td); - obj->can = (CANName)pinmap_merge(can_rd, can_td); - MBED_ASSERT((int)obj->can != NC); + MBED_ASSERT((int)can != NC); - if (obj->can == CAN_1) { + if (can == CAN_1) { __HAL_RCC_CAN1_CLK_ENABLE(); obj->index = 0; } #if defined(CAN2_BASE) && (CAN_NUM == 2) - else if (obj->can == CAN_2) { + else if (can == CAN_2) { __HAL_RCC_CAN1_CLK_ENABLE(); // needed to set filters __HAL_RCC_CAN2_CLK_ENABLE(); obj->index = 1; @@ -67,33 +78,30 @@ void can_init_freq (can_t *obj, PinName rd, PinName td, int hz) pin_mode(td, PullUp); } - CanHandle.Instance = (CAN_TypeDef *)(obj->can); + /* Use default values for rist init */ + obj->CanHandle.Instance = (CAN_TypeDef *)can; + obj->CanHandle.Init.TTCM = DISABLE; + obj->CanHandle.Init.ABOM = DISABLE; + obj->CanHandle.Init.AWUM = DISABLE; + obj->CanHandle.Init.NART = DISABLE; + obj->CanHandle.Init.RFLM = DISABLE; + obj->CanHandle.Init.TXFP = DISABLE; + obj->CanHandle.Init.Mode = CAN_MODE_NORMAL; + obj->CanHandle.Init.SJW = CAN_SJW_1TQ; + obj->CanHandle.Init.BS1 = CAN_BS1_6TQ; + obj->CanHandle.Init.BS2 = CAN_BS2_8TQ; + obj->CanHandle.Init.Prescaler = 2; - CanHandle.Init.TTCM = DISABLE; - CanHandle.Init.ABOM = DISABLE; - CanHandle.Init.AWUM = DISABLE; - CanHandle.Init.NART = DISABLE; - CanHandle.Init.RFLM = DISABLE; - CanHandle.Init.TXFP = DISABLE; - CanHandle.Init.Mode = CAN_MODE_NORMAL; - CanHandle.Init.SJW = CAN_SJW_1TQ; - CanHandle.Init.BS1 = CAN_BS1_6TQ; - CanHandle.Init.BS2 = CAN_BS2_8TQ; - CanHandle.Init.Prescaler = 2; + /* Store frequency to be restored in case of reset */ + obj->hz = hz; - if (HAL_CAN_Init(&CanHandle) != HAL_OK) { - error("Cannot initialize CAN"); - } + can_registers_init(obj); - // Set initial CAN frequency to specified frequency - if (can_frequency(obj, hz) != 1) { - error("Can frequency could not be set\n"); - } - - uint32_t filter_number = (obj->can == CAN_1) ? 0 : 14; + uint32_t filter_number = (can == CAN_1) ? 0 : 14; can_filter(obj, 0, 0, CANStandard, filter_number); } + void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) { irq_handler = handler; @@ -102,7 +110,7 @@ void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) void can_irq_free(can_t *obj) { - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); @@ -111,14 +119,15 @@ void can_irq_free(can_t *obj) void can_free(can_t *obj) { + CANName can = (CANName) obj->CanHandle.Instance; // Reset CAN and disable clock - if (obj->can == CAN_1) { + if (can == CAN_1) { __HAL_RCC_CAN1_FORCE_RESET(); __HAL_RCC_CAN1_RELEASE_RESET(); __HAL_RCC_CAN1_CLK_DISABLE(); } #if defined(CAN2_BASE) && (CAN_NUM == 2) - if (obj->can == CAN_2) { + if (can == CAN_2) { __HAL_RCC_CAN2_FORCE_RESET(); __HAL_RCC_CAN2_RELEASE_RESET(); __HAL_RCC_CAN2_CLK_DISABLE(); @@ -196,7 +205,7 @@ int can_frequency(can_t *obj, int f) { int pclk = HAL_RCC_GetPCLK1Freq(); int btr = can_speed(pclk, (unsigned int)f, 1); - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; uint32_t tickstart = 0; int status = 1; @@ -211,7 +220,11 @@ int can_frequency(can_t *obj, int f) } } if (status != 0) { - can->BTR = btr; + /* Do not erase all BTR registers (e.g. silent mode), only the + * ones calculated in can_speed */ + can->BTR &= ~(CAN_BTR_TS2 | CAN_BTR_TS1 | CAN_BTR_SJW | CAN_BTR_BRP); + can->BTR |= btr; + can->MCR &= ~(uint32_t)CAN_MCR_INRQ; /* Get tick */ tickstart = HAL_GetTick(); @@ -236,7 +249,7 @@ int can_frequency(can_t *obj, int f) int can_write(can_t *obj, CAN_Message msg, int cc) { uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; /* Select one empty transmit mailbox */ if ((can->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) { @@ -279,7 +292,7 @@ int can_read(can_t *obj, CAN_Message *msg, int handle) { //handle is the FIFO number - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; // check FPM0 which holds the pending message count in FIFO 0 // if no message is pending, return 0 @@ -324,46 +337,61 @@ int can_read(can_t *obj, CAN_Message *msg, int handle) void can_reset(can_t *obj) { - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; + + /* Reset IP and delete errors */ can->MCR |= CAN_MCR_RESET; can->ESR = 0x0; + + /* restore registers state as saved in obj context */ + can_registers_init(obj); } unsigned char can_rderror(can_t *obj) { - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; return (can->ESR >> 24) & 0xFF; } unsigned char can_tderror(can_t *obj) { - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; return (can->ESR >> 16) & 0xFF; } void can_monitor(can_t *obj, int silent) { - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); - - can->MCR |= CAN_MCR_INRQ ; - while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { - } - - if (silent) { - can->BTR |= ((uint32_t)1 << 31); + CanMode mode = MODE_NORMAL; + /* Update current state w/ or w/o silent */ + if(silent) { + switch (obj->CanHandle.Init.Mode) { + case CAN_MODE_LOOPBACK: + case CAN_MODE_SILENT_LOOPBACK: + mode = MODE_TEST_SILENT; + break; + default: + mode = MODE_SILENT; + break; + } } else { - can->BTR &= ~((uint32_t)1 << 31); + switch (obj->CanHandle.Init.Mode) { + case CAN_MODE_LOOPBACK: + case CAN_MODE_SILENT_LOOPBACK: + mode = MODE_TEST_LOCAL; + break; + default: + mode = MODE_NORMAL; + break; + } } - can->MCR &= ~(uint32_t)CAN_MCR_INRQ; - while ((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { - } + can_mode(obj, mode); } int can_mode(can_t *obj, CanMode mode) { int success = 0; - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; can->MCR |= CAN_MCR_INRQ ; while ((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { @@ -371,21 +399,25 @@ int can_mode(can_t *obj, CanMode mode) switch (mode) { case MODE_NORMAL: + obj->CanHandle.Init.Mode = CAN_MODE_NORMAL; can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); success = 1; break; case MODE_SILENT: + obj->CanHandle.Init.Mode = CAN_MODE_SILENT; can->BTR |= CAN_BTR_SILM; can->BTR &= ~CAN_BTR_LBKM; success = 1; break; case MODE_TEST_GLOBAL: case MODE_TEST_LOCAL: + obj->CanHandle.Init.Mode = CAN_MODE_LOOPBACK; can->BTR |= CAN_BTR_LBKM; can->BTR &= ~CAN_BTR_SILM; success = 1; break; case MODE_TEST_SILENT: + obj->CanHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK; can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); success = 1; break; @@ -407,7 +439,6 @@ int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t // filter for CANAny format cannot be configured for STM32 if ((format == CANStandard) || (format == CANExtended)) { - CanHandle.Instance = (CAN_TypeDef *)(obj->can); CAN_FilterConfTypeDef sFilterConfig; sFilterConfig.FilterNumber = handle; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; @@ -429,7 +460,7 @@ int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14 + handle; - HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); + HAL_CAN_ConfigFilter(&obj->CanHandle, &sFilterConfig); retval = handle; } return retval; @@ -438,6 +469,7 @@ int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t static void can_irq(CANName name, int id) { uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; + CAN_HandleTypeDef CanHandle; CanHandle.Instance = (CAN_TypeDef *)name; if (__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { @@ -535,13 +567,12 @@ void CAN2_SCE_IRQHandler(void) void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) { - - CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + CAN_TypeDef *can = obj->CanHandle.Instance; IRQn_Type irq_n = (IRQn_Type)0; uint32_t vector = 0; uint32_t ier; - if (obj->can == CAN_1) { + if ((CANName) can == CAN_1) { switch (type) { case IRQ_RX: ier = CAN_IT_FMP0; @@ -573,7 +604,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) } } #if defined(CAN2_BASE) && (CAN_NUM == 2) - else if (obj->can == CAN_2) { + else if ((CANName) can == CAN_2) { switch (type) { case IRQ_RX: ier = CAN_IT_FMP0;