STM32: FDCAN support for H7 family

pull/9354/head
jeromecoutant 2019-01-15 13:30:51 +01:00
parent aff2bee8a4
commit f1d10cfeff
3 changed files with 497 additions and 81 deletions

View File

@ -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;

View File

@ -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

View File

@ -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 | <hz>
Bit_length | 10 µs = 100 tq | <n_tq> = 10 000 000 / <hz>
Synchronization_segment | 1 tq | 1 tq
Phase_segment_1 | 69 tq | <nts1> = <n_tq> * 0.75
Phase_segment_2 | 30 tq | <nts2> = <n_tq> - 1 - <nts1>
Synchronization_Jump_width | 30 tq | <nsjw> = <nts2>
*/
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