工具配置
基本就是默认配置就行,有需要的话就按照下面的方式改改。
生成代码
在Generated_Code/canCom1.c里面,对应刚才配置的信息。canCom1_InitConfig0是配置结构体,canCom1_State是初始化之后的状态结构体。
flexcan_state_t canCom1_State;
const flexcan_user_config_t canCom1_InitConfig0 = {
.fd_enable = false,
.pe_clock = FLEXCAN_CLK_SOURCE_OSC,
.max_num_mb = 32,
.num_id_filters = FLEXCAN_RX_FIFO_ID_FILTERS_32,
.is_rx_fifo_needed = true,
.flexcanMode = FLEXCAN_NORMAL_MODE,
.payload = FLEXCAN_PAYLOAD_SIZE_8,
.bitrate = {
.propSeg = 7,
.phaseSeg1 = 3,
.phaseSeg2 = 2,
.preDivider = 0,
.rJumpwidth = 1
},
.bitrate_cbt = {
.propSeg = 7,
.phaseSeg1 = 3,
.phaseSeg2 = 2,
.preDivider = 0,
.rJumpwidth = 1
},
.transfer_type = FLEXCAN_RXFIFO_USING_INTERRUPTS,
.rxFifoDMAChannel = 0U
};
接口使用
FLEXCAN_DRV_SetBitrate
设置波特率
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_SetBitrate
* Description : Set FlexCAN baudrate.
* This function will set up all the time segment values for classical frames or the
* extended time segments for the arbitration phase of FD frames. Those time segment
* values are passed in by the user and are based on the required baudrate.
*
* Implements : FLEXCAN_DRV_SetBitrate_Activity
*END**************************************************************************/
void FLEXCAN_DRV_SetBitrate(uint8_t instance, const flexcan_time_segment_t *bitrate)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
DEV_ASSERT(bitrate != NULL);
CAN_Type * base = g_flexcanBase[instance];
#if FEATURE_CAN_HAS_FD
bool fdEnabled = FLEXCAN_IsFDEnabled(base);
#endif
FLEXCAN_EnterFreezeMode(base);
#if FEATURE_CAN_HAS_FD
if (fdEnabled)
{
/* Set extended time segments*/
FLEXCAN_SetExtendedTimeSegments(base, bitrate);
}
else
#endif
{
/* Set time segments*/
FLEXCAN_SetTimeSegments(base, bitrate);
}
FLEXCAN_ExitFreezeMode(base);
}
FLEXCAN_DRV_GetBitrate
获取波特率
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_GetBitrate
* Description : Get FlexCAN baudrate.
* This function will be return the current bit rate settings for classical frames
* or the arbitration phase of FD frames.
*
* Implements : FLEXCAN_DRV_GetBitrate_Activity
*END**************************************************************************/
void FLEXCAN_DRV_GetBitrate(uint8_t instance, flexcan_time_segment_t *bitrate)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
DEV_ASSERT(bitrate != NULL);
const CAN_Type * base = g_flexcanBase[instance];
/* Get the time segments*/
FLEXCAN_GetTimeSegments(base, bitrate);
}
FLEXCAN_DRV_SetRxMaskType
设置接收掩码类型
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_SetMasktype
* Description : Set RX masking type.
* This function will set RX masking type as RX global mask or RX individual
* mask.
*
* Implements : FLEXCAN_DRV_SetRxMaskType_Activity
*END**************************************************************************/
void FLEXCAN_DRV_SetRxMaskType(uint8_t instance, flexcan_rx_mask_type_t type)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
CAN_Type * base = g_flexcanBase[instance];
FLEXCAN_EnterFreezeMode(base);
FLEXCAN_SetRxMaskType(base, type);
FLEXCAN_ExitFreezeMode(base);
}
FLEXCAN_DRV_SetRxFifoGlobalMask
设置接收队列掩码
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_SetRxFifoGlobalMask
* Description : Set Rx FIFO global mask as the 11-bit standard mask or the
* 29-bit extended mask.
*
* Implements : FLEXCAN_DRV_SetRxFifoGlobalMask_Activity
*END**************************************************************************/
void FLEXCAN_DRV_SetRxFifoGlobalMask(
uint8_t instance,
flexcan_msgbuff_id_type_t id_type,
uint32_t mask)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
flexcan_rx_fifo_id_element_format_t formatType;
CAN_Type * base = g_flexcanBase[instance];
uint32_t calcMask = 0U;
FLEXCAN_EnterFreezeMode(base);
if (true == FLEXCAN_IsRxFifoEnabled(base))
{
formatType = FLEXCAN_GetRxFifoIdFormat(base);
calcMask = FLEXCAN_GetRxFifoMask(id_type, formatType, mask);
switch (formatType)
{
case FLEXCAN_RX_FIFO_ID_FORMAT_A :
FLEXCAN_SetRxFifoGlobalMask(base, calcMask);
break;
case FLEXCAN_RX_FIFO_ID_FORMAT_B :
FLEXCAN_SetRxFifoGlobalMask(base, (calcMask | (calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1)));
break;
case FLEXCAN_RX_FIFO_ID_FORMAT_C :
FLEXCAN_SetRxFifoGlobalMask(base, (calcMask | (calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1) |
(calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2) |
(calcMask >> FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3)));
break;
default :
/* Will Enable all filter fields mask */
FLEXCAN_SetRxFifoGlobalMask(base, 0xFFFFFFFFU);
break;
}
}
FLEXCAN_ExitFreezeMode(base);
}
FLEXCAN_DRV_SetRxMbGlobalMask
设置接收报文缓冲区的掩码
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_SetRxMbGlobalMask
* Description : Set Rx Message Buffer global mask as the 11-bit standard mask
* or the 29-bit extended mask.
*
* Implements : FLEXCAN_DRV_SetRxMbGlobalMask_Activity
*END**************************************************************************/
void FLEXCAN_DRV_SetRxMbGlobalMask(
uint8_t instance,
flexcan_msgbuff_id_type_t id_type,
uint32_t mask)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
CAN_Type * base = g_flexcanBase[instance];
FLEXCAN_EnterFreezeMode(base);
if (id_type == FLEXCAN_MSG_ID_STD)
{
/* Set standard global mask for RX MB*/
FLEXCAN_SetRxMsgBuffGlobalStdMask(base, mask);
}
else if (id_type == FLEXCAN_MSG_ID_EXT)
{
/* Set extended global mask for RX MB*/
FLEXCAN_SetRxMsgBuffGlobalExtMask(base, mask);
}
else {
/* Should not get here */
}
FLEXCAN_ExitFreezeMode(base);
}
FLEXCAN_DRV_Init
初始化接口
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_Init
* Description : Initialize FlexCAN driver.
* This function will select a source clock, reset FlexCAN module, set maximum
* number of message buffers, initialize all message buffers as inactive, enable
* RX FIFO if needed, mask all mask bits, disable all MB interrupts, enable
* FlexCAN normal mode, and enable all the error interrupts if needed.
*
* Implements : FLEXCAN_DRV_Init_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_Init(
uint8_t instance,
flexcan_state_t *state,
const flexcan_user_config_t *data)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
DEV_ASSERT(state != NULL);
DEV_ASSERT(g_flexcanStatePtr[instance] == NULL);
#ifdef ERRATA_E10595
if (instance != 0U)
{
DEV_ASSERT((MC_ME->GS & MC_ME_GS_S_FXOSC_MASK) != 0U);
}
#endif
status_t result;
CAN_Type * base = g_flexcanBase[instance];
flexcan_time_segment_t bitrate;
status_t osifStat;
uint32_t i, j;
if(FLEXCAN_IsEnabled(base))
{
/* To enter Disable Mode requires FreezMode first */
FLEXCAN_EnterFreezeMode(base);
FLEXCAN_Disable(base);
}
#if FEATURE_CAN_HAS_PE_CLKSRC_SELECT
/* Select a source clock for the FlexCAN engine */
FLEXCAN_SelectClock(base, data->pe_clock);
#endif
/* Enable the CAN clock */
FLEXCAN_Enable(base);
FLEXCAN_EnterFreezeMode(base);
/* Initialize FLEXCAN device */
FLEXCAN_Init(base);
#ifdef ERRATA_E10368
#if FEATURE_CAN_HAS_FD
FLEXCAN_Errata10368(instance, data);
#endif /* FEATURE_CAN_HAS_FD */
#endif /* ERRATA_E10368 */
#if FEATURE_CAN_HAS_FD
/* Enable/Disable FD and check FD was set as expected. Setting FD as enabled
* might fail if the current CAN instance does not support FD. */
FLEXCAN_SetFDEnabled(base, data->fd_enable);
if (FLEXCAN_IsFDEnabled(base) != data->fd_enable)
{
return STATUS_ERROR;
}
/* If the FD feature is enabled, enable the Stuff Bit Count, in order to be
* ISO-compliant. */
FLEXCAN_SetStuffBitCount(base, data->fd_enable);
#endif
/* Disable the self reception feature if FlexCAN is not in loopback mode. */
if (data->flexcanMode != FLEXCAN_LOOPBACK_MODE)
{
FLEXCAN_SetSelfReception(base, false);
}
/* Enable RxFIFO feature, if requested. This might fail if the FD mode is
* enabled. */
if (data->is_rx_fifo_needed)
{
result = FLEXCAN_EnableRxFifo(base, (uint32_t)data->num_id_filters);
if (result != STATUS_SUCCESS)
{
return result;
}
}
#if FEATURE_CAN_HAS_DMA_ENABLE
/* Enable DMA support for RxFIFO transfer, if requested. */
if (data->transfer_type == FLEXCAN_RXFIFO_USING_DMA)
{
if (FLEXCAN_IsRxFifoEnabled(base))
{
FLEXCAN_SetRxFifoDMA(base, true);
}
else
{
return STATUS_ERROR;
}
}
if (data->transfer_type == FLEXCAN_RXFIFO_USING_INTERRUPTS)
{
FLEXCAN_SetRxFifoDMA(base, false);
}
#endif
#if FEATURE_CAN_HAS_FD
/* Set payload size. */
FLEXCAN_SetPayloadSize(base, data->payload);
#endif
result = FLEXCAN_SetMaxMsgBuffNum(base, data->max_num_mb);
if (result != STATUS_SUCCESS)
{
return result;
}
#if FEATURE_CAN_HAS_FD
/* Set bit rate. */
if (FLEXCAN_IsFDEnabled(base))
{
bitrate = data->bitrate;
FLEXCAN_SetExtendedTimeSegments(base, &bitrate);
bitrate = data->bitrate_cbt;
FLEXCAN_SetFDTimeSegments(base, &bitrate);
}
else
#endif
{
bitrate = data->bitrate;
FLEXCAN_SetTimeSegments(base, &bitrate);
}
/* Select mode */
FLEXCAN_SetOperationMode(base, data->flexcanMode);
if (data->flexcanMode != FLEXCAN_FREEZE_MODE)
{
FLEXCAN_ExitFreezeMode(base);
}
/* Enable FlexCAN interrupts.*/
FLEXCAN_EnableIRQs(instance);
for (i = 0; i < FEATURE_CAN_MAX_MB_NUM; i++)
{
osifStat = OSIF_SemaCreate(&state->mbs[i].mbSema, 0U);
if (osifStat != STATUS_SUCCESS)
{
for (j = 0; j < i; j++)
{
(void)OSIF_SemaDestroy(&state->mbs[j].mbSema);
}
return STATUS_ERROR;
}
state->mbs[i].isBlocking = false;
state->mbs[i].mb_message = NULL;
state->mbs[i].state = FLEXCAN_MB_IDLE;
}
#if FEATURE_CAN_HAS_MEM_ERR_DET
FLEXCAN_DisableMemErrorDetection(base);
#endif
/* Store transfer type and DMA channel number used in transfer */
state->transferType = data->transfer_type;
#if FEATURE_CAN_HAS_DMA_ENABLE
state->rxFifoDMAChannel = data->rxFifoDMAChannel;
#endif
/* Clear Callbacks in case of autovariables garbage */
state->callback = NULL;
state->callbackParam = NULL;
state->error_callback = NULL;
state->errorCallbackParam = NULL;
/* Save runtime structure pointers so irq handler can point to the correct state structure */
g_flexcanStatePtr[instance] = state;
return (STATUS_SUCCESS);
}
FLEXCAN_DRV_Deinit
逆初始化
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_Deinit
* Description : Shutdown a FlexCAN module.
* This function will disable all FlexCAN interrupts, and disable the FlexCAN.
*
* Implements : FLEXCAN_DRV_Deinit_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_Deinit(uint8_t instance)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
CAN_Type * base = g_flexcanBase[instance];
const flexcan_state_t * state = g_flexcanStatePtr[instance];
status_t result = STATUS_SUCCESS;
status_t osifStat;
uint32_t i;
/* Disable FlexCAN interrupts.*/
if (state != NULL)
{
if (state->error_callback != NULL)
{
FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_ERR, false);
FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_RX_WARNING, false);
FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_TX_WARNING, false);
FLEXCAN_SetErrIntCmd(base, FLEXCAN_INT_BUSOFF, false);
}
}
#if FEATURE_CAN_HAS_WAKE_UP_IRQ
if (g_flexcanWakeUpIrqId[instance] != NotAvail_IRQn)
{
INT_SYS_DisableIRQ(g_flexcanWakeUpIrqId[instance]);
}
#endif
INT_SYS_DisableIRQ(g_flexcanErrorIrqId[instance]);
INT_SYS_DisableIRQ(g_flexcanBusOffIrqId[instance]);
for (i = 0; i < FEATURE_CAN_MB_IRQS_MAX_COUNT; i++)
{
if (g_flexcanOredMessageBufferIrqId[i][instance] != NotAvail_IRQn)
{
INT_SYS_DisableIRQ(g_flexcanOredMessageBufferIrqId[i][instance]);
}
}
if(FLEXCAN_IsEnabled(g_flexcanBase[instance]))
{
/* Enter Freeze Mode Required before to enter Disabled Mode */
FLEXCAN_EnterFreezeMode(g_flexcanBase[instance]);
/* Disable FlexCAN.*/
FLEXCAN_Disable(g_flexcanBase[instance]);
/* Check if the state have been initialized */
}
if (state != NULL)
{
for (i = 0; i < FEATURE_CAN_MAX_MB_NUM; i++)
{
osifStat = OSIF_SemaDestroy(&state->mbs[i].mbSema);
if (osifStat != STATUS_SUCCESS)
{
result = STATUS_ERROR;
}
}
}
if (result == STATUS_SUCCESS)
{
/* Clear state pointer that is checked by FLEXCAN_DRV_Init */
g_flexcanStatePtr[instance] = NULL;
}
return result;
}
FLEXCAN_DRV_ConfigTxMb
配置发送报文缓存区,入参为索引、缓存区ID、数据信息结构体、报文ID。
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_ConfigTxMb
* Description : Configure a Tx message buffer.
* This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
* the function will make sure if the MB requested is not occupied by RX FIFO
* and ID filter table. Then this function will set up the message buffer fields,
* configure the message buffer code for Tx buffer as INACTIVE, and enable the
* Message Buffer interrupt.
*
* Implements : FLEXCAN_DRV_ConfigTxMb_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_ConfigTxMb(
uint8_t instance,
uint8_t mb_idx,
const flexcan_data_info_t *tx_info,
uint32_t msg_id)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
DEV_ASSERT(tx_info != NULL);
flexcan_msgbuff_code_status_t cs;
CAN_Type * base = g_flexcanBase[instance];
/* Initialize transmit mb*/
cs.dataLen = tx_info->data_length;
cs.msgIdType = tx_info->msg_id_type;
#if FEATURE_CAN_HAS_FD
cs.enable_brs = tx_info->enable_brs;
cs.fd_enable = tx_info->fd_enable;
cs.fd_padding = tx_info->fd_padding;
#endif
cs.code = (uint32_t)FLEXCAN_TX_INACTIVE;
return FLEXCAN_SetTxMsgBuff(base, mb_idx, &cs, msg_id, NULL);
}
FLEXCAN_DRV_SendBlocking
阻塞发送
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_SendBlocking
* Description : This function sends a CAN frame using a configured message
* buffer. The function blocks until either the frame was sent, or the specified
* timeout expired.
*
* Implements : FLEXCAN_DRV_SendBlocking_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_SendBlocking(
uint8_t instance,
uint8_t mb_idx,
const flexcan_data_info_t *tx_info,
uint32_t msg_id,
const uint8_t *mb_data,
uint32_t timeout_ms)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
DEV_ASSERT(tx_info != NULL);
status_t result;
flexcan_state_t * state = g_flexcanStatePtr[instance];
CAN_Type * base = g_flexcanBase[instance];
result = FLEXCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data, true);
if (result == STATUS_SUCCESS)
{
status_t status;
/* Enable message buffer interrupt*/
(void)FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, true);
status = OSIF_SemaWait(&state->mbs[mb_idx].mbSema, timeout_ms);
if (status == STATUS_TIMEOUT)
{
if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE)
{
/* Disable message buffer interrupt */
(void)FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, false);
/* Clear message buffer flag */
FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
FLEXCAN_AbortTxMsgBuff(base, mb_idx);
uint32_t flexcan_mb_config;
#ifndef ERRATA_E9527
/* Wait to finish abort operation */
while(FLEXCAN_GetBuffStatusFlag(base, mb_idx) == 0U)
{
/* Do Nothing wait for the flag */
}
#endif
volatile const uint32_t *flexcan_mb = FLEXCAN_GetMsgBuffRegion(base, mb_idx);
flexcan_mb_config = * flexcan_mb;
/* Check if the MBs have been safely Inactivated */
if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32_t)FLEXCAN_TX_INACTIVE)
{
#ifndef ERRATA_E9527
/* Transmission have occurred */
result = STATUS_SUCCESS;
#else
/* Transmission have not occurred because it uses the inactivation operation */
if (FLEXCAN_GetBuffStatusFlag(base, mb_idx) == 0U)
{
result = STATUS_TIMEOUT;
}
else
{
result = STATUS_SUCCESS;
}
#endif
}
if (((flexcan_mb_config & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32_t)FLEXCAN_TX_ABORT)
{
/* Transmission have occurred */
result = STATUS_TIMEOUT;
}
/* Clear message buffer flag */
FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
}
}
}
return result;
}
FLEXCAN_DRV_Send
普通发送,入参就是索引、报文缓存区ID、发送信息、报文ID、缓存区数据。
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_Send
* Description : This function sends a CAN frame using a configured message
* buffer. The function returns immediately. If a callback is installed, it will
* be invoked after the frame was sent.
*
* Implements : FLEXCAN_DRV_Send_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_Send(
uint8_t instance,
uint8_t mb_idx,
const flexcan_data_info_t *tx_info,
uint32_t msg_id,
const uint8_t *mb_data)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
DEV_ASSERT(tx_info != NULL);
status_t result;
CAN_Type * base = g_flexcanBase[instance];
result = FLEXCAN_StartSendData(instance, mb_idx, tx_info, msg_id, mb_data, false);
if(result == STATUS_SUCCESS)
{
/* Enable message buffer interrupt*/
result = FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, true);
}
return result;
}
FLEXCAN_DRV_ReceiveBlocking
阻塞接收
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_ReceiveBlocking
* Description : This function receives a CAN frame into a configured message
* buffer. The function blocks until either a frame was received, or the
* specified timeout expired.
*
* Implements : FLEXCAN_DRV_ReceiveBlocking_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_ReceiveBlocking(
uint8_t instance,
uint8_t mb_idx,
flexcan_msgbuff_t *data,
uint32_t timeout_ms)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
status_t result;
flexcan_state_t * state = g_flexcanStatePtr[instance];
CAN_Type * base = g_flexcanBase[instance];
result = FLEXCAN_StartRxMessageBufferData(instance, mb_idx, data, true);
if(result == STATUS_SUCCESS)
{
status_t status;
status = OSIF_SemaWait(&state->mbs[mb_idx].mbSema, timeout_ms);
if (status == STATUS_TIMEOUT)
{
/* If the flag is set Successful reception else report TimeOut */
if(FLEXCAN_GetMsgBuffIntStatusFlag(base,mb_idx) == (uint8_t)0U)
{
result = STATUS_TIMEOUT;
}
/* Disable message buffer interrupt */
(void)FLEXCAN_SetMsgBuffIntCmd(base, mb_idx, false);
}
/* Consider the MB state has been changed by interrupt as frame received */
if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
{
return STATUS_SUCCESS;
}
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
}
return result;
}
FLEXCAN_DRV_Receive
普通接收
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_Receive
* Description : This function receives a CAN frame into a configured message
* buffer. The function returns immediately. If a callback is installed, it will
* be invoked after the frame was received and read into the specified buffer.
*
* Implements : FLEXCAN_DRV_Receive_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_Receive(
uint8_t instance,
uint8_t mb_idx,
flexcan_msgbuff_t *data)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
status_t result;
result = FLEXCAN_StartRxMessageBufferData(instance, mb_idx, data, false);
return result;
}
FLEXCAN_DRV_RxFifoBlocking
阻塞接收到FIFO里面
/*FUNCTION**********************************************************************
*
* Function Name : FLEXCAN_DRV_RxFifoBlocking
* Description : This function receives a CAN frame using the Rx FIFO. The
* function blocks until either a frame was received, or the specified timeout
* expired.
*
* Implements : FLEXCAN_DRV_RxFifoBlocking_Activity
*END**************************************************************************/
status_t FLEXCAN_DRV_RxFifoBlocking(
uint8_t instance,
flexcan_msgbuff_t *data,
uint32_t timeout_ms)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
status_t result;
flexcan_state_t * state = g_flexcanStatePtr[instance];
CAN_Type * base = g_flexcanBase[instance];
result = FLEXCAN_StartRxMessageFifoData(instance, data, true);
if (result == STATUS_SUCCESS)
{
result = OSIF_SemaWait(&state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mbSema, timeout_ms);
if (result == STATUS_TIMEOUT)
{
/* If the status is updated reception successful else report TimeOut */
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_IDLE)
{
result = STATUS_SUCCESS;
}
/* Disable RX FIFO interrupts*/
(void)FLEXCAN_SetMsgBuffIntCmd(base, FEATURE_CAN_RXFIFO_FRAME_AVAILABLE, false);
(void)FLEXCAN_SetMsgBuffIntCmd(base, FEATURE_CAN_RXFIFO_WARNING, false);
(void)FLEXCAN_SetMsgBuffIntCmd(base, FEATURE_CAN_RXFIFO_OVERFLOW, false);
#if FEATURE_CAN_HAS_DMA_ENABLE
/* Check if transfer is done over DMA and stop transfer */
if ((state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_RX_BUSY) && (state->transferType == FLEXCAN_RXFIFO_USING_DMA))
{
/* This function always return status success */
(void)EDMA_DRV_StopChannel(state->rxFifoDMAChannel);
}
#endif
}
state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state = FLEXCAN_MB_IDLE;
}
return result;
}