S32K148 CAN Rx issue

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

S32K148 CAN Rx issue

3,294 Views
hewei03
Contributor III

Hello NXP,

I can correctly receive CAN messages with the FLEXCAN_DRV_RxFifo function, 
but I can't receive any messages with the FLEXCAN_DRV_RxFifoBlocking function. 
I don't know what the difference between the two is? 
I use them like this:
(1)if(FLEXCAN_DRV_RxFifoBlocking(INST_CANCOM1,&recvBuff,100)==STATUS_SUCCESS)
{
   Test++;
}

(2) if(FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recvBuff)==STATUS_SUCCESS)

     {

         Test++;

    }

The case (1) can't receive any messages,but the case (2) can correctly receive CAN messages.

The Case(1) seems to be dead in the function : OSIF_SemaWait(&state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mbSema, timeout_ms)

,Enter this function,but can't jump out.

What is the cause of this problem.
I want to use interrupt reception, which function should I use?

Thanks!

Owen
0 Kudos
Reply
7 Replies

2,351 Views
hewei03
Contributor III

Hello Alexandru Nan,

I have an another question. I have used the old SDK, What can I do change to the new BETA 2.9.0 SDK?  Need I re-new the work project with the new SDK?

0 Kudos
Reply

2,351 Views
hewei03
Contributor III

Hello Alexandru Nan,

I used the receive call back function, The code is the following, I can receive CAN message, but many times later, I Can't get any can message. Which issue is it?

static void ReceCANData_CallBack(uint8_t instance, flexcan_event_type_t eventType,
                                   uint32_t buffIdx, flexcan_state_t *flexcanState)
{
    /* Define receive buffer */
    flexcan_msgbuff_t recvBuff;
    
    if((FLEXCAN_EVENT_RXFIFO_COMPLETE==eventType)&&(FLEXCAN_MB_HANDLE_RXFIFO==buffIdx))
    {
        FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recvBuff);    

        switch(recvBuff.msgId)    // FOR Test
        {
            case Test1_ID:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED0));
                PINS_DRV_ClearPins(LED_GPIO,(1 << LED1)|(1 << LED2));
                break;
            case Test2_ID:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED1));
                PINS_DRV_ClearPins(LED_GPIO,(1 << LED0)|(1 << LED2));
                break;
            case Test3_ID:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED2));
                PINS_DRV_ClearPins(LED_GPIO,(1 << LED0)|(1 << LED1));
                break;
            case Test4_ID:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED0));
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED1));
                PINS_DRV_ClearPins(LED_GPIO,(1 << LED2));
                break;
            case Test5_ID:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED0));
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED2));
                PINS_DRV_ClearPins(LED_GPIO,(1 << LED1));
                break;
            case Test6_ID:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED1));
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED2));
                PINS_DRV_ClearPins(LED_GPIO,(1 << LED0));
                break;
            case Test7_ID:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED0));
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED1));
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED2));

                break;
            case Test8_ID:
                /* Toggle output value LED1 */
                //PINS_DRV_TogglePins(LED_GPIO, (1 << LED0));
                PINS_DRV_ClearPins(LED_GPIO,(1 << LED0)|(1 << LED1)|(1 << LED2));
                break;
            default:
                /* Toggle output value LED1 */
                PINS_DRV_TogglePins(LED_GPIO, (1 << LED2));
                break;
        }
                /* Send the information via CAN */
                //SendCANData(TX_MAILBOX, recvBuff.msgId, recvBuff.data, recvBuff.dataLen);    
    }

0 Kudos
Reply

2,351 Views
alexandrunan
NXP Employee
NXP Employee

I have watched on the code and have a little issue the  flexcan_msgbuff_t recvBuff; is stack allocated this should be static or global variable. 

another issue you need to call first time the FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recvBuff);  to configure the call back; and the interrupt of the receive fifo will transfer the message on the desired location as recvBuff. so the call that rearm the receive process should be after you handle the message. 

0 Kudos
Reply

2,351 Views
alexandrunan
NXP Employee
NXP Employee

Hello Owen,

Can you please provide more details about what version of SDK did you use, Initialization configuration, and previous steps before actually trying to receive.

Did you configured the GPIO pins for CAN interface you used ?!

The correct sequence for fifo mode in interrupt mode are :

1. FLEXCAN_DRV_Init() will configure the CAN module;
2. FLEXCAN_DRV_ConfigRxFifo() that will configure the acceptance filters for Rx FIFO;

3. FLEXCAN_DRV_SetRxIndividualMask() or FLEXCAN_DRV_SetRxFifoGlobalMask() based on your configuration set acceptance mask filter IDs affected.

4. FLEXCAN_DRV_RxFifo() CAN and configure the transfer parameters;

5. wait for transfer status complete while(FLEXCAN_DRV_GetTransferStatus(INST_CANCOM1, 0U) == STATUS_BUSY);

The differences between functions FLEXCAN_DRV_RxFifoBlocking and FLEXCAN_DRV_RxFifo is that the blocking function will block the flow by a wait event equal with the time parameter in ms and then check the transfer status, the non blocking function only will configure the transfer and the transfer need to be checked with FLEXCAN_DRV_GetTransferStatus when ever the user wants.

In case you don't want to pull the transfer, you can install a callback event and will be signaled by ISR triggered by successfully receive message with message FLEXCAN_EVENT_RXFIFO_COMPLETE. After each message pulled from FIFO you need to rearm the transfer by calling again FLEXCAN_DRV_RxFifo()

0 Kudos
Reply

2,336 Views
lzjregister
Contributor I

This function must be called again after you receive data to allow another data to be received.

where to call this function? Thread or Callback? sdk3.0, thank you very much!

0 Kudos
Reply

2,351 Views
hewei03
Contributor III

Hello Alexandru Nan

The SDK version is S32K14x EAR 0.8.6, Initialization configuration is the following:

1. FLEXCAN_DRV_Init()

2.FLEXCAN_DRV_SetRxMaskType()

3.FLEXCAN_DRV_ConfigRxFifo()

The next step is in a FreeRtos task which is running in 1 ms cycle.

while(1)

{

/* Check the received message ID and payload */
   case(1)     if(FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recvBuff)==STATUS_SUCCESS)    /* CAN receive any message.*/
    case(2)   //if(FLEXCAN_DRV_RxFifoBlocking(INST_CANCOM1,&recvBuff,100)==STATUS_SUCCESS)   /*Can't receive any message,dead in OSIF_SemaWait(&state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].mbSema, timeout_ms)*/
        {
            switch(recvBuff.msgId)
            {
                case Test1_ID:
                    /* Toggle output value LED1 */
                    PINS_DRV_TogglePins(LED_GPIO, (1 << LED0));
                    PINS_DRV_ClearPins(LED_GPIO,(1 << LED1)|(1 << LED2));
                    break;
                case Test2_ID:
                    /* Toggle output value LED1 */
                    PINS_DRV_TogglePins(LED_GPIO, (1 << LED1));
                    PINS_DRV_ClearPins(LED_GPIO,(1 << LED0)|(1 << LED2));
                    break;
                case Test3_ID:
                    /* Toggle output value LED1 */
                    PINS_DRV_TogglePins(LED_GPIO, (1 << LED2));
                    PINS_DRV_ClearPins(LED_GPIO,(1 << LED0)|(1 << LED1));
                    break;

             default:

                  break;

         }

}

Which step need to modify?

Thanks!

Owen

0 Kudos
Reply

2,351 Views
alexandrunan
NXP Employee
NXP Employee

Hello Owen,

 Did you power externally by 12V supply the board if you use EVB board. The can interface use a transceiver that is powered by that supply. 

You should update the SDK to latest version S32SDK K1xx BETA 2.9.0 you can find it here S32 Design Studio IDE for Arm® based MCUs|NXP , that have many bugs fixed. 

Regards  OSIF_SemaWait crashing you should check if the FREE RTOS is configured correctly to use PIT source. 

Check if the initialization operations succeeded before call reception.   

In you software case 1 if(FLEXCAN_DRV_RxFifo(INST_CANCOM1,&recvBuff)==STATUS_SUCCESS)   will always report success if is fine and only configure the transfer. Actually the message will be transfer by a triggered interruption when will be received. To check if have been transferred you need to pull 

while(FLEXCAN_DRV_GetTransferStatus(INST_CANCOM1, 0U) == STATUS_BUSY); where MB 0 is the Rx FIFO MB.

BR,

Alexandru Nan

0 Kudos
Reply