Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32L5/STM32U5 : CAN support #15065

Merged
merged 1 commit into from
Sep 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions targets/TARGET_STM/TARGET_STM32L5/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,9 @@ struct dac_s {

#if DEVICE_CAN
struct can_s {
CAN_HandleTypeDef CanHandle;
FDCAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqEnabled;
};
#endif

Expand Down
3 changes: 1 addition & 2 deletions targets/TARGET_STM/TARGET_STM32U5/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,9 @@ struct dac_s {

#if DEVICE_CAN
struct can_s {
CAN_HandleTypeDef CanHandle;
FDCAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqEnabled;
};
#endif

Expand Down
46 changes: 36 additions & 10 deletions targets/TARGET_STM/can_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz
{
MBED_ASSERT((int)pinmap->peripheral != NC);

#if defined(__HAL_RCC_FDCAN1_CLK_ENABLE)
__HAL_RCC_FDCAN1_CLK_ENABLE();
#else
__HAL_RCC_FDCAN_CLK_ENABLE();
#endif

if (pinmap->peripheral == CAN_1) {
obj->index = 0;
Expand All @@ -90,8 +94,13 @@ static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz

// Select PLL1Q as source of FDCAN clock
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
#if (defined RCC_PERIPHCLK_FDCAN1)
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN1;
RCC_PeriphClkInit.Fdcan1ClockSelection = RCC_FDCAN1CLKSOURCE_PLL1;
#else
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL; // 10 MHz (RCC_OscInitStruct.PLL.PLLQ = 80)
RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
#endif
#if defined(DUAL_CORE) && (TARGET_STM32H7)
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
}
Expand Down Expand Up @@ -128,14 +137,18 @@ static void _can_init_freq_direct(can_t *obj, const can_pinmap_t *pinmap, int hz
// !Attention Not all bitrates can be covered with all fdcan-core-clk values. When a clk
// does not work for the desired bitrate, change system_clock settings for FDCAN_CLK
// (default FDCAN_CLK is PLLQ)
#ifdef TARGET_STM32G4
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN) / hz;
#else
#if (defined TARGET_STM32H7)
// STM32H7 doesn't support yet HAL_RCCEx_GetPeriphCLKFreq for FDCAN
// We use PLL1.Q clock right now so get its frequency
PLL1_ClocksTypeDef pll1_clocks;
HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
int ntq = pll1_clocks.PLL1_Q_Frequency / hz;
#else
#if (defined RCC_PERIPHCLK_FDCAN1)
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN1) / hz;
#else
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN) / hz;
#endif
#endif

int nominalPrescaler = 1;
Expand Down Expand Up @@ -250,7 +263,7 @@ void can_irq_free(can_t *obj)
else {
return;
}
#ifndef TARGET_STM32G4
#if (defined TARGET_STM32H7)
HAL_NVIC_DisableIRQ(FDCAN_CAL_IRQn);
#endif
can_irq_ids[obj->index] = 0;
Expand All @@ -262,12 +275,21 @@ void can_free(can_t *obj)
while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) {
}
#endif /* DUAL_CORE */
#if defined(__HAL_RCC_FDCAN1_FORCE_RESET)
__HAL_RCC_FDCAN1_FORCE_RESET();
__HAL_RCC_FDCAN1_RELEASE_RESET();
#else
__HAL_RCC_FDCAN_FORCE_RESET();
__HAL_RCC_FDCAN_RELEASE_RESET();
#endif
#if defined(DUAL_CORE) && (TARGET_STM32H7)
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, HSEM_CR_COREID_CURRENT);
#endif /* DUAL_CORE */
#if defined(__HAL_RCC_FDCAN1_CLK_DISABLE)
__HAL_RCC_FDCAN1_CLK_DISABLE();
#else
__HAL_RCC_FDCAN_CLK_DISABLE();
#endif
}


Expand Down Expand Up @@ -296,13 +318,17 @@ int can_frequency(can_t *obj, int f)
* does not work for the desired bitrate, change system_clock settings for FDCAN_CLK
* (default FDCAN_CLK is PLLQ)
*/
#ifdef TARGET_STM32G4
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN) / f;
#else
#if (defined TARGET_STM32H7)
// STM32H7 doesn't support yet HAL_RCCEx_GetPeriphCLKFreq for FDCAN
PLL1_ClocksTypeDef pll1_clocks;
HAL_RCCEx_GetPLL1ClockFreq(&pll1_clocks);
int ntq = pll1_clocks.PLL1_Q_Frequency / f;
#else
#if (defined RCC_PERIPHCLK_FDCAN1)
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN1) / f;
#else
int ntq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_FDCAN) / f;
#endif
#endif

int nominalPrescaler = 1;
Expand Down Expand Up @@ -520,7 +546,7 @@ static void can_irq(CANName name, int id)
irq_handler(can_irq_ids[id], IRQ_TX);
}
}
#ifndef TARGET_STM32G4
#if (defined FDCAN_IT_RX_BUFFER_NEW_MESSAGE)
if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE)) {
__HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_IT_RX_BUFFER_NEW_MESSAGE);
Expand Down Expand Up @@ -602,7 +628,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
interrupts = FDCAN_IT_TX_COMPLETE;
break;
case IRQ_RX:
#ifndef TARGET_STM32G4
#if (defined FDCAN_IT_RX_BUFFER_NEW_MESSAGE)
interrupts = FDCAN_IT_RX_BUFFER_NEW_MESSAGE;
#else
interrupts = FDCAN_IT_RX_FIFO0_NEW_MESSAGE;
Expand Down
2 changes: 2 additions & 0 deletions targets/targets.json
Original file line number Diff line number Diff line change
Expand Up @@ -4147,6 +4147,7 @@
},
"device_has_add": [
"ANALOGOUT",
"CAN",
"CRC",
"FLASH",
"MPU",
Expand Down Expand Up @@ -4262,6 +4263,7 @@
},
"device_has_add": [
"ANALOGOUT",
"CAN",
"CRC",
"FLASH",
"MPU",
Expand Down