Hi,
We have the example of FlexCan based on FlexCan driver and OS in SDK platform, which is located at:
D:\Freescale\KSDK_1.3.0\examples\twrk60d100m\driver_examples\flexcan\flexcan_network\kds
The following is the code to receive data from receiver mailbox.
after first look, it seems that the following code uses polling mode, but actually, the api function
FLEXCAN_DRV_GetReceiveStatus() uses interrupt mode. This is the sequence of state updation.
when interrupt occurs, FLEXCAN_DRV_IRQHandler(0) is called, in the function, FLEXCAN_DRV_CompleteRxMessageBufferData() is called, which update the "state" structure. The FLEXCAN_DRV_GetReceiveStatus() polls the state structure variable to know the transfer state.
If you do want to use interrupt, I suggest you use FLEXCAN_DRV_RxMessageBufferBlocking(). it uses semphore to switch tasks.
Hope it can help you.
BR
Xiangjun Rong
//polling code
if (FLEXCAN_DRV_GetReceiveStatus(flexcanInstance) == kStatus_FLEXCAN_Success)
{
result = FLEXCAN_DRV_RxMessageBuffer(flexcanInstance, RX_mailbox_num,&rx_mb);
temp = ((rx_mb.cs) >> 16) & 0xF;
for(j = 0; j < temp; j++)
{
ch2[j] = rx_mb.data[j];
}
UART_DRV_SendData(uartInstance,ch2,temp);
if (result)
{
PRINTF("\r\nReceive failed. result: 0x%lx", result);
return (-1);
}
}
//////////////////////////////////////////////////////////////////////
void FLEXCAN_DRV_IRQHandler(uint8_t instance)
{
volatile uint32_t flag_reg;
uint32_t temp;
CAN_Type * base = g_flexcanBase[instance];
flexcan_state_t * state = g_flexcanStatePtr[instance];
/* Get the interrupts that are enabled and ready */
flag_reg = ((FLEXCAN_HAL_GetAllMsgBuffIntStatusFlag(base)) & CAN_IMASK1_BUFLM_MASK) &
CAN_RD_IMASK1(base);
/* Check Tx/Rx interrupt flag and clear the interrupt */
if(flag_reg)
{
if ((flag_reg & 0x20) && CAN_BRD_MCR_RFEN(base))
{
if (state->fifo_message != NULL)
{
/* Get RX FIFO field values */
FLEXCAN_HAL_ReadRxFifo(base, state->fifo_message);
/* Complete receive data */
FLEXCAN_DRV_CompleteRxMessageFifoData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, flag_reg);
}
}
else
{
/* Check mailbox completed reception*/
temp = (1 << state->rx_mb_idx);
if (temp & flag_reg)
{
/* Unlock RX message buffer and RX FIFO*/
FLEXCAN_HAL_LockRxMsgBuff(base, state->rx_mb_idx);
/* Get RX MB field values*/
FLEXCAN_HAL_GetMsgBuff(base, state->rx_mb_idx, state->mb_message);
/* Unlock RX message buffer and RX FIFO*/
FLEXCAN_HAL_UnlockRxMsgBuff(base);
/* Complete receive data */
FLEXCAN_DRV_CompleteRxMessageBufferData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg);
}
/* Check mailbox completed transmission*/
temp = (1 << state->tx_mb_idx);
if (temp & flag_reg)
{
/* Complete transmit data */
FLEXCAN_DRV_CompleteSendData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg);
}
}
/* Check mailbox completed transmission*/
temp = (1 << state->tx_mb_idx);
if (flag_reg & temp)
{
/* Complete transmit data */
FLEXCAN_DRV_CompleteSendData(instance);
FLEXCAN_HAL_ClearMsgBuffIntStatusFlag(base, temp & flag_reg);
}
}
/* Clear all other interrupts in ERRSTAT register (Error, Busoff, Wakeup) */
FLEXCAN_HAL_ClearErrIntStatusFlag(base);
return;
}
static void FLEXCAN_DRV_CompleteRxMessageBufferData(uint32_t instance)
{
assert(instance < CAN_INSTANCE_COUNT);
CAN_Type * base = g_flexcanBase[instance];
flexcan_state_t * state = g_flexcanStatePtr[instance];
FLEXCAN_HAL_SetMsgBuffIntCmd(base, state->rx_mb_idx, false);
/* Disable error interrupts */
FLEXCAN_HAL_SetErrIntCmd(base,kFlexCanIntErr,false);
/* Signal the synchronous completion object. */
if (state->isRxBlocking)
{
OSA_SemaPost(&state->rxIrqSync);
}
/* Update the information of the module driver state */
state->isRxBusy = false;
}