大家好:
我在使用KW38的时候想使用CAN FIFO模式接收数据(不使用CAN FIFO DMA),以下是我的初始化逻辑,但是无法进入中断处理函数,想要请教一下大家是不是我设置的问题:
初始化代码:
FLEXCAN_Init(Can_ptr, &flexcanConfig, Can_sourceClock_Hz);
FLEXCAN_SetRxFifoGlobalMask(Can_ptr, 0);
/* enable fifo interrupt */
fifoConfig.idFilterTable = rxFifoFilter;
fifoConfig.idFilterNum = sizeof(rxFifoFilter) / sizeof(rxFifoFilter[0]);
fifoConfig.idFilterType = kFLEXCAN_RxFifoFilterTypeA;
fifoConfig.priority = kFLEXCAN_RxFifoPrioHigh;
FLEXCAN_SetRxFifoConfig(Can_ptr, &fifoConfig, true);
FLEXCAN_TransferCreateHandle(Can_ptr, &flexcanHandle, kw38can_callback, NULL);
我想要进入此函数中断的红色字段中
void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
{
/* Assertion. */
assert(NULL != handle);
status_t status = kStatus_FLEXCAN_UnHandled;
uint32_t result = 0U;
/* Store Current FlexCAN Module Error and Status. */
uint32_t EsrStatus = base->ESR1;
do
{
/* Solve FlexCAN Error and Status Interrupt. */
if (0U != (EsrStatus & ((uint32_t)kFLEXCAN_TxWarningIntFlag | (uint32_t)kFLEXCAN_RxWarningIntFlag |
(uint32_t)kFLEXCAN_BusOffIntFlag | (uint32_t)kFLEXCAN_ErrorIntFlag)))
{
status = kStatus_FLEXCAN_ErrorStatus;
/* Clear FlexCAN Error and Status Interrupt. */
FLEXCAN_ClearStatusFlags(base, (uint32_t)kFLEXCAN_TxWarningIntFlag | (uint32_t)kFLEXCAN_RxWarningIntFlag |
(uint32_t)kFLEXCAN_BusOffIntFlag | (uint32_t)kFLEXCAN_ErrorIntFlag);
}
else if (0U != (EsrStatus & (uint32_t)kFLEXCAN_WakeUpIntFlag))
{
status = kStatus_FLEXCAN_WakeUp;
FLEXCAN_ClearStatusFlags(base, (uint32_t)kFLEXCAN_WakeUpIntFlag);
}
/* Solve FlexCAN Rx FIFO & Message Buffer Interrupt. */
else
{
/* For this implementation, we solve the Message with lowest MB index first. */
for (result = 0U; result < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); result++)
{
/* Get the lowest unhandled Message Buffer */
#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
uint64_t u64flag = 1;
if (0U != FLEXCAN_GetMbStatusFlags(base, (u64flag << result)))
{
if (true == FLEXCAN_IsMbIntEnabled(base, result))
#else
uint32_t u32flag = 1;
if (0U != FLEXCAN_GetMbStatusFlags(base, (u32flag << result)))
{
if (true == FLEXCAN_IsMbIntEnabled(base, (uint8_t)result))
#endif
{
break;
}
}
}
/* Does not find Message to deal with. */
if (result == (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))
{
break;
}
/* Solve Rx FIFO interrupt. */
if (((uint8_t)kFLEXCAN_StateIdle != handle->rxFifoState) && (result <= (uint32_t)CAN_IFLAG1_BUF7I_SHIFT))
{
uint32_t u32mask = 1;
switch (u32mask << result)
{
case (int32_t)kFLEXCAN_RxFifoOverflowFlag:
status = kStatus_FLEXCAN_RxFifoOverflow;
break;
case (int32_t)kFLEXCAN_RxFifoWarningFlag:
status = kStatus_FLEXCAN_RxFifoWarning;
break;
case (int32_t)kFLEXCAN_RxFifoFrameAvlFlag:
status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
if (kStatus_Success == status)
{
status = kStatus_FLEXCAN_RxFifoIdle;
}
FLEXCAN_TransferAbortReceiveFifo(base, handle);
break;
default:
status = kStatus_FLEXCAN_UnHandled;
break;
}
}
else
{
/* To sove Mail Box interrupt. */
status = FLEXCAN_SubHandlerForMailBoxTransfered(base, handle, result);
}
......
/* Calling Callback Function if has one. */
if (handle->callback != NULL)
{
handle->callback(base, handle, status, result, handle->userData);
}
.....
}
应该是我没有使能中断的原因,在主循环中频繁调用了这段话就可以进入FIFO中断了
FLEXCAN_TransferReceiveFifoNonBlocking(Can_ptr, &flexcanHandle, &rxFIFOBuffer);
还有一个问题,我现在打算封装一个CAN FIFO中断处理的逻辑,但是每次进入中断后会红色粗体那里失能中断,并且将FIFO换成置为NULL,之后的函数我在那个位置在重新使能中断呢?
/* Disable Rx Message FIFO Interrupts. */
FLEXCAN_DisableMbInterrupts(base, (uint32_t)kFLEXCAN_RxFifoOverflowFlag | (uint32_t)kFLEXCAN_RxFifoWarningFlag |
(uint32_t)kFLEXCAN_RxFifoFrameAvlFlag);
/* Un-register handle. */
handle->rxFifoFrameBuf = NULL;
void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
{
/* Assertion. */
assert(NULL != handle);
status_t status = kStatus_FLEXCAN_UnHandled;
uint32_t result = 0U;
/* Store Current FlexCAN Module Error and Status. */
uint32_t EsrStatus = base->ESR1;
do
{
.....
/* Solve Rx FIFO interrupt. */
if (((uint8_t)kFLEXCAN_StateIdle != handle->rxFifoState) && (result <= (uint32_t)CAN_IFLAG1_BUF7I_SHIFT))
{
uint32_t u32mask = 1;
switch (u32mask << result)
{
case (int32_t)kFLEXCAN_RxFifoOverflowFlag:
status = kStatus_FLEXCAN_RxFifoOverflow;
break;
case (int32_t)kFLEXCAN_RxFifoWarningFlag:
status = kStatus_FLEXCAN_RxFifoWarning;
break;
case (int32_t)kFLEXCAN_RxFifoFrameAvlFlag:
status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
if (kStatus_Success == status)
{
status = kStatus_FLEXCAN_RxFifoIdle;
}
FLEXCAN_TransferAbortReceiveFifo(base, handle);
break;
default:
status = kStatus_FLEXCAN_UnHandled;
break;
}
}
else
{
/* To sove Mail Box interrupt. */
status = FLEXCAN_SubHandlerForMailBoxTransfered(base, handle, result);
}
/* Calling Callback Function if has one. */
if (handle->callback != NULL)
{
handle->callback(base, handle, status, result, handle->userData);
}
}
正确是初始化流程应该是怎么样的,想请教一下您
还有一个问题,为什么在这个进入处理FIFO中断逻辑中,不去判断是否使能FIFO中断,而是handle->rxFifoState判断,这个handle->rxFifoState感觉不是根据某个寄存器设置的
/*! @brief FlexCAN handle structure. */
struct _flexcan_handle
{
flexcan_transfer_callback_t callback; /*!< Callback function. */
void *userData; /*!< FlexCAN callback function parameter.*/
flexcan_frame_t *volatile mbFrameBuf[CAN_WORD1_COUNT];
#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
flexcan_fd_frame_t *volatile mbFDFrameBuf[CAN_WORD1_COUNT];
#endif
/*!< The buffer for received data from Message Buffers. */
flexcan_frame_t *volatile rxFifoFrameBuf; /*!< The buffer for received data from Rx FIFO. */
volatile uint8_t mbState[CAN_WORD1_COUNT]; /*!< Message Buffer transfer state. */
volatile uint8_t rxFifoState; /*!< Rx FIFO transfer state. */
};
/* Solve Rx FIFO interrupt. */
if (((uint8_t)kFLEXCAN_StateIdle != handle->rxFifoState) && (result <= (uint32_t)CAN_IFLAG1_BUF7I_SHIFT))
{
uint32_t u32mask = 1;
switch (u32mask << result)
{
case (int32_t)kFLEXCAN_RxFifoOverflowFlag:
status = kStatus_FLEXCAN_RxFifoOverflow;
break;
case (int32_t)kFLEXCAN_RxFifoWarningFlag:
status = kStatus_FLEXCAN_RxFifoWarning;
break;
case (int32_t)kFLEXCAN_RxFifoFrameAvlFlag:
status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
if (kStatus_Success == status)
{
status = kStatus_FLEXCAN_RxFifoIdle;
}
FLEXCAN_TransferAbortReceiveFifo(base, handle);
break;
default:
status = kStatus_FLEXCAN_UnHandled;
break;
}
}