Skip to content

Commit

Permalink
Merge pull request #15065 from jeromecoutant/PR_CAN
Browse files Browse the repository at this point in the history
STM32L5/STM32U5 : CAN support
  • Loading branch information
0xc0170 authored Sep 29, 2021
2 parents fc62b15 + abe2e48 commit 963aa8b
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 14 deletions.
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 @@ -4309,6 +4309,7 @@
},
"device_has_add": [
"ANALOGOUT",
"CAN",
"CRC",
"FLASH",
"MPU",
Expand Down Expand Up @@ -4424,6 +4425,7 @@
},
"device_has_add": [
"ANALOGOUT",
"CAN",
"CRC",
"FLASH",
"MPU",
Expand Down

0 comments on commit 963aa8b

Please sign in to comment.