MQX + KSDK +FLEXCAN

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MQX + KSDK +FLEXCAN

934 Views
profprogrammer
Contributor III

Hello.

I used MK60DN512.

1) How to get date from CAN in interrupt?

2)i need code ..

void canCom1_MbHandler(void)

{

FLEXCAN_DRV_IRQHandler(canCom1_IDX);

if (FLEXCAN_DRV_GetReceiveStatus(canCom1_IDX) == kStatus_FLEXCAN_Succe) {

    FLEXCAN_DRV_RxFifo(canCom1_IDX, &data);

    globalVar= data.data[0];

}

if (FLEXCAN_DRV_GetTransmitStatus (canCom1_IDX) == kStatus_FLEXCAN_Success) {

}

}

this code is correct?

0 Kudos
3 Replies

511 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

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;

}

0 Kudos

511 Views
profprogrammer
Contributor III

it didn't help me.

l have guetion.

1) How to get date from CAN in interrupt?

void canCom1_MbHandler(void) {

.........

}

0 Kudos

511 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Dear customer,

I see your requirement that you want an interrupt driven code as usual, you do all your work in Flexcan interrupt. But the SDK driver is based on OS, we hope you call the blocking api function for example FLEXCAN_DRV_RxMessageBufferBlocking()  and FLEXCAN_DRV_SendBlocking() so that OS can switch the task. If you do not want to use blocking function above, and do not want to use the polling function as following either:

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

                }

and you want to use usual interrupt driven code, you have to modify the driver yourself. for example, you can add an api function in the  void FLEXCAN_DRV_IRQHandler(uint8_t instance), the function can finish your work, for example read data length/data/ID from receiver MB, deal with the data as your desire, it is okay. generally, the function is called callback function.

This is my opinion, welcome anyone post comments here.

Hope it can help you.

BR

Xiangjun Rong