diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c index 77102818ee..42c013a9be 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI/system_clock.c @@ -127,10 +127,10 @@ uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLM = 4; - RCC_OscInitStruct.PLL.PLLN = 400; - RCC_OscInitStruct.PLL.PLLP = 2; - RCC_OscInitStruct.PLL.PLLQ = 32; + RCC_OscInitStruct.PLL.PLLM = 4; // 2 MHz + RCC_OscInitStruct.PLL.PLLN = 400; // 800 MHz + RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 400 MHz + RCC_OscInitStruct.PLL.PLLQ = 80; // PLL1Q used for FDCAN = 10 MHz RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLFRACN = 0; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; diff --git a/targets/TARGET_STM/TARGET_STM32H7/can_device.h b/targets/TARGET_STM/TARGET_STM32H7/can_device.h deleted file mode 100644 index 1652fb9491..0000000000 --- a/targets/TARGET_STM/TARGET_STM32H7/can_device.h +++ /dev/null @@ -1,73 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2017 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_CAN_DEVICE_H -#define MBED_CAN_DEVICE_H - -#include "cmsis.h" -#include "stm32h7xx.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if DEVICE_CAN - -#if defined(CAN3_BASE) - -#define CAN_NUM 3 // Number of CAN peripherals present in the STM32 serie - -#define CAN3_IRQ_RX_IRQN CAN3_RX0_IRQn -#define CAN3_IRQ_RX_VECT CAN3_RX0_IRQHandler -#define CAN3_IRQ_TX_IRQN CAN3_TX_IRQn -#define CAN3_IRQ_TX_VECT CAN3_TX_IRQHandler -#define CAN3_IRQ_ERROR_IRQN CAN3_SCE_IRQn -#define CAN3_IRQ_ERROR_VECT CAN3_SCE_IRQHandler -#define CAN3_IRQ_PASSIVE_IRQN CAN3_SCE_IRQn -#define CAN3_IRQ_PASSIVE_VECT CAN3_SCE_IRQHandler -#define CAN3_IRQ_BUS_IRQN CAN3_SCE_IRQn -#define CAN3_IRQ_BUS_VECT CAN3_SCE_IRQHandler - -#else - -#define CAN_NUM 2 // Number of CAN peripherals present in the STM32 serie - -#endif - -#define CAN1_IRQ_RX_IRQN CAN1_RX0_IRQn -#define CAN1_IRQ_RX_VECT CAN1_RX0_IRQHandler -#define CAN1_IRQ_TX_IRQN CAN1_TX_IRQn -#define CAN1_IRQ_TX_VECT CAN1_TX_IRQHandler -#define CAN1_IRQ_ERROR_IRQN CAN1_SCE_IRQn -#define CAN1_IRQ_ERROR_VECT CAN1_SCE_IRQHandler -#define CAN1_IRQ_PASSIVE_IRQN CAN1_SCE_IRQn -#define CAN1_IRQ_PASSIVE_VECT CAN1_SCE_IRQHandler -#define CAN1_IRQ_BUS_IRQN CAN1_SCE_IRQn -#define CAN1_IRQ_BUS_VECT CAN1_SCE_IRQHandler - -#define CAN2_IRQ_RX_IRQN CAN2_RX0_IRQn -#define CAN2_IRQ_RX_VECT CAN2_RX0_IRQHandler -#define CAN2_IRQ_TX_IRQN CAN2_TX_IRQn -#define CAN2_IRQ_TX_VECT CAN2_TX_IRQHandler -#define CAN2_IRQ_ERROR_IRQN CAN2_SCE_IRQn -#define CAN2_IRQ_ERROR_VECT CAN2_SCE_IRQHandler -#define CAN2_IRQ_PASSIVE_IRQN CAN2_SCE_IRQn -#define CAN2_IRQ_PASSIVE_VECT CAN2_SCE_IRQHandler -#define CAN2_IRQ_BUS_IRQN CAN2_SCE_IRQn -#define CAN2_IRQ_BUS_VECT CAN2_SCE_IRQHandler - -#endif // DEVICE_CAN - -#endif diff --git a/targets/TARGET_STM/can_api.c b/targets/TARGET_STM/can_api.c index ecada7bb4b..d5fa84cd7a 100644 --- a/targets/TARGET_STM/can_api.c +++ b/targets/TARGET_STM/can_api.c @@ -17,6 +17,495 @@ #if DEVICE_CAN +#ifdef FDCAN1 + +#include "pinmap.h" +#include "PeripheralPins.h" +#include "mbed_error.h" + +static uint32_t can_irq_ids[2] = {0}; +static can_irq_handler irq_handler; + +/** Call all the init functions + * + * @returns + * 0 if mode change failed or unsupported, + * 1 if mode change was successful + */ +int can_internal_init(can_t *obj) +{ + if (HAL_FDCAN_Init(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Init error\n"); + } + + if (can_filter(obj, 0, 0, CANStandard, 0) == 0) { + error("can_filter error\n"); + } + + if (can_filter(obj, 0, 0, CANExtended, 0) == 0) { + error("can_filter error\n"); + } + + if (HAL_FDCAN_ConfigGlobalFilter(&obj->CanHandle, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK) { + error("HAL_FDCAN_ConfigGlobalFilter error\n"); + } + + if (HAL_FDCAN_Start(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Start error\n"); + } + + return 1; +} + +void can_init(can_t *obj, PinName rd, PinName td) +{ + /* default frequency is 100 kHz */ + can_init_freq(obj, rd, td, 100000); +} + + +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); + MBED_ASSERT((int)can != NC); + + __HAL_RCC_FDCAN_CLK_ENABLE(); + + if (can == CAN_1) { + obj->index = 0; + } +#if defined(FDCAN2_BASE) + else if (can == CAN_2) { + obj->index = 1; + } +#endif + else { + error("can_init wrong instance\n"); + return; + } + + // Select PLL1Q as source of FDCAN clock + RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; + RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN; + RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL; // 10 MHz (RCC_OscInitStruct.PLL.PLLQ = 80) + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) { + error("HAL_RCCEx_PeriphCLKConfig error\n"); + } + + // Configure CAN pins + pinmap_pinout(rd, PinMap_CAN_RD); + pinmap_pinout(td, PinMap_CAN_TD); + // Add pull-ups + if (rd != NC) { + pin_mode(rd, PullUp); + } + if (td != NC) { + pin_mode(td, PullUp); + } + + // Default values + obj->CanHandle.Instance = (FDCAN_GlobalTypeDef *)can; + + /* Bit time parameter + ex with 100 kHz requested frequency hz + fdcan_ker_ck | 10 MHz | 10 MHz + Prescaler | 1 | 1 + Time_quantum (tq) | 100 ns | 100 ns + Bit_rate | 0.1 MBit/s | + Bit_length | 10 µs = 100 tq | = 10 000 000 / + Synchronization_segment | 1 tq | 1 tq + Phase_segment_1 | 69 tq | = * 0.75 + Phase_segment_2 | 30 tq | = - 1 - + Synchronization_Jump_width | 30 tq | = + */ + int ntq = 10000000 / hz; + + obj->CanHandle.Init.FrameFormat = FDCAN_FRAME_CLASSIC; + obj->CanHandle.Init.Mode = FDCAN_MODE_NORMAL; + obj->CanHandle.Init.AutoRetransmission = ENABLE; + obj->CanHandle.Init.TransmitPause = DISABLE; + obj->CanHandle.Init.ProtocolException = ENABLE; + obj->CanHandle.Init.NominalPrescaler = 1; // Prescaler + obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1 + obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2 + obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width + obj->CanHandle.Init.DataPrescaler = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.DataSyncJumpWidth = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.DataTimeSeg1 = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.DataTimeSeg2 = 0x1; // Not used - only in FDCAN + obj->CanHandle.Init.MessageRAMOffset = 0; + obj->CanHandle.Init.StdFiltersNbr = 1; // to be aligned with the handle parameter in can_filter + obj->CanHandle.Init.ExtFiltersNbr = 1; // to be aligned with the handle parameter in can_filter + obj->CanHandle.Init.RxFifo0ElmtsNbr = 8; + obj->CanHandle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8; + obj->CanHandle.Init.RxFifo1ElmtsNbr = 0; + obj->CanHandle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8; + obj->CanHandle.Init.RxBuffersNbr = 0; + obj->CanHandle.Init.RxBufferSize = FDCAN_DATA_BYTES_8; + obj->CanHandle.Init.TxEventsNbr = 3; + obj->CanHandle.Init.TxBuffersNbr = 0; + obj->CanHandle.Init.TxFifoQueueElmtsNbr = 3; + obj->CanHandle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + obj->CanHandle.Init.TxElmtSize = FDCAN_DATA_BYTES_8; + + can_internal_init(obj); +} + + +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) +{ + irq_handler = handler; + can_irq_ids[obj->index] = id; +} + +void can_irq_free(can_t *obj) +{ + CANName can = (CANName)obj->CanHandle.Instance; + if (can == CAN_1) { + HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn); + HAL_NVIC_DisableIRQ(FDCAN1_IT1_IRQn); + } +#if defined(FDCAN2_BASE) + else if (can == CAN_2) { + HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); + HAL_NVIC_DisableIRQ(FDCAN2_IT1_IRQn); + } +#endif + else { + return; + } + HAL_NVIC_DisableIRQ(FDCAN_CAL_IRQn); + can_irq_ids[obj->index] = 0; +} + +void can_free(can_t *obj) +{ + __HAL_RCC_FDCAN_FORCE_RESET(); + __HAL_RCC_FDCAN_RELEASE_RESET(); + __HAL_RCC_FDCAN_CLK_DISABLE(); +} + + +/** Reset CAN interface. + * + * To use after error overflow. + */ +void can_reset(can_t *obj) +{ + can_mode(obj, MODE_RESET); + HAL_FDCAN_ResetTimeoutCounter(&obj->CanHandle); + HAL_FDCAN_ResetTimestampCounter(&obj->CanHandle); +} + + +int can_frequency(can_t *obj, int f) +{ + if (HAL_FDCAN_Stop(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Stop error\n"); + } + + /* See can_init_freq function for calculation details */ + int ntq = 10000000 / f; + obj->CanHandle.Init.NominalTimeSeg1 = ntq * 0.75; // Phase_segment_1 + obj->CanHandle.Init.NominalTimeSeg2 = ntq - 1 - obj->CanHandle.Init.NominalTimeSeg1; // Phase_segment_2 + obj->CanHandle.Init.NominalSyncJumpWidth = obj->CanHandle.Init.NominalTimeSeg2; // Synchronization_Jump_width + + return can_internal_init(obj); +} + + +/** Filter out incoming messages + * + * @param obj CAN object + * @param id the id to filter on + * @param mask the mask applied to the id + * @param format format to filter on + * @param handle message filter handle (not supported yet) + * + * @returns + * 0 if filter change failed or unsupported, + * new filter handle if successful (not supported yet => returns 1) + */ +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) +{ + UNUSED(handle); // Not supported yet (seems to be a used in read function?) + + FDCAN_FilterTypeDef sFilterConfig = {0}; + + if (format == CANStandard) { + sFilterConfig.IdType = FDCAN_STANDARD_ID; + sFilterConfig.FilterIndex = 0; + sFilterConfig.FilterType = FDCAN_FILTER_MASK; + sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + sFilterConfig.FilterID1 = id; + sFilterConfig.FilterID2 = mask; + } else if (format == CANExtended) { + sFilterConfig.IdType = FDCAN_EXTENDED_ID; + sFilterConfig.FilterIndex = 0; + sFilterConfig.FilterType = FDCAN_FILTER_MASK; + sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + sFilterConfig.FilterID1 = id; + sFilterConfig.FilterID2 = mask; + } else { // Filter for CANAny format cannot be configured for STM32 + return 0; + } + + if (HAL_FDCAN_ConfigFilter(&obj->CanHandle, &sFilterConfig) != HAL_OK) { + return 0; + } + + return 1; +} + + +int can_write(can_t *obj, CAN_Message msg, int cc) +{ + FDCAN_TxHeaderTypeDef TxHeader = {0}; + + UNUSED(cc); + + // Configure Tx buffer message + TxHeader.Identifier = msg.id; + if (msg.format == CANStandard) { + TxHeader.IdType = FDCAN_STANDARD_ID; + } else { + TxHeader.IdType = FDCAN_EXTENDED_ID; + } + + TxHeader.TxFrameType = FDCAN_DATA_FRAME; + TxHeader.DataLength = msg.len << 16; + TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + TxHeader.BitRateSwitch = FDCAN_BRS_OFF; + TxHeader.FDFormat = FDCAN_CLASSIC_CAN; + TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS; + TxHeader.MessageMarker = 0; + + if (HAL_FDCAN_AddMessageToTxFifoQ(&obj->CanHandle, &TxHeader, msg.data) != HAL_OK) { + // Note for debug: you can get the error code calling HAL_FDCAN_GetError(&obj->CanHandle) + return 0; + } + + return 1; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) +{ + UNUSED(handle); // Not supported yet (seems to be a handle to a filter configuration?) + + if (HAL_FDCAN_GetRxFifoFillLevel(&obj->CanHandle, FDCAN_RX_FIFO0) == 0) { + return 0; // No message arrived + } + + FDCAN_RxHeaderTypeDef RxHeader = {0}; + if (HAL_FDCAN_GetRxMessage(&obj->CanHandle, FDCAN_RX_FIFO0, &RxHeader, msg->data) != HAL_OK) { + error("HAL_FDCAN_GetRxMessage error\n"); // Should not occur as previous HAL_FDCAN_GetRxFifoFillLevel call reported some data + return 0; + } + + if (RxHeader.IdType == FDCAN_STANDARD_ID) { + msg->format = CANStandard; + } else { + msg->format = CANExtended; + } + msg->id = RxHeader.Identifier; + msg->type = CANData; + msg->len = RxHeader.DataLength >> 16; // see FDCAN_data_length_code value + + return 1; +} + +unsigned char can_rderror(can_t *obj) +{ + FDCAN_ErrorCountersTypeDef ErrorCounters; + + HAL_FDCAN_GetErrorCounters(&obj->CanHandle, &ErrorCounters); + + return (unsigned char)ErrorCounters.RxErrorCnt; +} + +unsigned char can_tderror(can_t *obj) +{ + FDCAN_ErrorCountersTypeDef ErrorCounters; + + HAL_FDCAN_GetErrorCounters(&obj->CanHandle, &ErrorCounters); + + return (unsigned char)ErrorCounters.TxErrorCnt; +} + +void can_monitor(can_t *obj, int silent) +{ + CanMode mode = MODE_NORMAL; + if (silent) { + switch (obj->CanHandle.Init.Mode) { + case FDCAN_MODE_INTERNAL_LOOPBACK: + mode = MODE_TEST_SILENT; + break; + default: + mode = MODE_SILENT; + break; + } + } else { + switch (obj->CanHandle.Init.Mode) { + case FDCAN_MODE_INTERNAL_LOOPBACK: + case FDCAN_MODE_EXTERNAL_LOOPBACK: + mode = MODE_TEST_LOCAL; + break; + default: + mode = MODE_NORMAL; + break; + } + } + + can_mode(obj, mode); +} + +/** Change CAN operation to the specified mode + * + * @param mode The new operation mode (MODE_RESET, MODE_NORMAL, MODE_SILENT, MODE_TEST_LOCAL, MODE_TEST_GLOBAL, MODE_TEST_SILENT) + * + * @returns + * 0 if mode change failed or unsupported, + * 1 if mode change was successful + */ +int can_mode(can_t *obj, CanMode mode) +{ + if (HAL_FDCAN_Stop(&obj->CanHandle) != HAL_OK) { + error("HAL_FDCAN_Stop error\n"); + } + + switch (mode) { + case MODE_RESET: + break; + case MODE_NORMAL: + obj->CanHandle.Init.Mode = FDCAN_MODE_NORMAL; + // obj->CanHandle.Init.NominalPrescaler = 100; // Prescaler + break; + case MODE_SILENT: // Bus Monitoring + obj->CanHandle.Init.Mode = FDCAN_MODE_BUS_MONITORING; + break; + case MODE_TEST_GLOBAL: // External LoopBack + case MODE_TEST_LOCAL: + obj->CanHandle.Init.Mode = FDCAN_MODE_EXTERNAL_LOOPBACK; + break; + case MODE_TEST_SILENT: // Internal LoopBack + obj->CanHandle.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK; + // obj->CanHandle.Init.NominalPrescaler = 1; // Prescaler + break; + default: + return 0; + } + + return can_internal_init(obj); +} + + +static void can_irq(CANName name, int id) +{ + FDCAN_HandleTypeDef CanHandle; + CanHandle.Instance = (FDCAN_GlobalTypeDef *)name; + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_TX_COMPLETE)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_TX_COMPLETE)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_TX_COMPLETE); + irq_handler(can_irq_ids[id], IRQ_TX); + } + } + + 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); + irq_handler(can_irq_ids[id], IRQ_RX); + } + } + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_ERROR_WARNING)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_ERROR_WARNING)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_ERROR_WARNING); + irq_handler(can_irq_ids[id], IRQ_ERROR); + } + } + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_ERROR_PASSIVE)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_ERROR_PASSIVE)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_ERROR_PASSIVE); + irq_handler(can_irq_ids[id], IRQ_PASSIVE); + } + } + + if (__HAL_FDCAN_GET_IT_SOURCE(&CanHandle, FDCAN_IT_BUS_OFF)) { + if (__HAL_FDCAN_GET_FLAG(&CanHandle, FDCAN_FLAG_BUS_OFF)) { + __HAL_FDCAN_CLEAR_FLAG(&CanHandle, FDCAN_FLAG_BUS_OFF); + irq_handler(can_irq_ids[id], IRQ_BUS); + } + } +} + +void FDCAN1_IT0_IRQHandler(void) +{ + can_irq(CAN_1, 0); +} + +void FDCAN1_IT1_IRQHandler(void) +{ + can_irq(CAN_1, 0); +} + +void FDCAN2_IT0_IRQHandler(void) +{ + can_irq(CAN_2, 1); +} + +void FDCAN2_IT1_IRQHandler(void) +{ + can_irq(CAN_2, 1); +} + +// TODO Add other interrupts ? +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) +{ + uint32_t interrupts = 0; + + switch (type) { + case IRQ_TX: + interrupts = FDCAN_IT_TX_COMPLETE; + break; + case IRQ_RX: + interrupts = FDCAN_IT_RX_BUFFER_NEW_MESSAGE; + break; + case IRQ_ERROR: + interrupts = FDCAN_IT_ERROR_WARNING; + break; + case IRQ_PASSIVE: + interrupts = FDCAN_IT_ERROR_PASSIVE; + break; + case IRQ_BUS: + interrupts = FDCAN_IT_BUS_OFF; + default: + return; + } + + if (enable) { + HAL_FDCAN_ActivateNotification(&obj->CanHandle, interrupts, 0); + } else { + HAL_FDCAN_DeactivateNotification(&obj->CanHandle, interrupts); + } + + NVIC_SetVector(FDCAN1_IT0_IRQn, (uint32_t)&FDCAN1_IT0_IRQHandler); + NVIC_EnableIRQ(FDCAN1_IT0_IRQn); + NVIC_SetVector(FDCAN1_IT1_IRQn, (uint32_t)&FDCAN1_IT1_IRQHandler); + NVIC_EnableIRQ(FDCAN1_IT1_IRQn); +#if defined(FDCAN2_BASE) + NVIC_SetVector(FDCAN2_IT0_IRQn, (uint32_t)&FDCAN2_IT0_IRQHandler); + NVIC_EnableIRQ(FDCAN2_IT0_IRQn); + NVIC_SetVector(FDCAN2_IT1_IRQn, (uint32_t)&FDCAN2_IT1_IRQHandler); + NVIC_EnableIRQ(FDCAN2_IT1_IRQn); +#endif +} + +#else /* FDCAN1 */ + #include "cmsis.h" #include "pinmap.h" #include "PeripheralPins.h" @@ -454,8 +943,6 @@ int can_mode(can_t *obj, CanMode mode) int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) { - int retval = 0; - // filter for CANAny format cannot be configured for STM32 if ((format == CANStandard) || (format == CANExtended)) { CAN_FilterConfTypeDef sFilterConfig; @@ -480,9 +967,9 @@ int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t sFilterConfig.BankNumber = 14 + handle; HAL_CAN_ConfigFilter(&obj->CanHandle, &sFilterConfig); - retval = handle; } - return retval; + + return 1; } static void can_irq(CANName name, int id) @@ -716,4 +1203,6 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) NVIC_EnableIRQ(irq_n); } +#endif /* FDCAN1 */ + #endif // DEVICE_CAN