How to implement two CAN channels on UCANS32K146 dev board (using SDK example can_pal_s32k146 )

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

How to implement two CAN channels on UCANS32K146 dev board (using SDK example can_pal_s32k146 )

1,150 次查看
johngreenjets
Contributor III

I am using the NXP UCANS32K146 development board with the SDK example 'can_pal_s32k146'.

I had to modify the code slightly to get it working with this development board, including additional digital outputs to pull the STB (standby) pin on the CAN transceivers low.

I can get CAN0 or CAN1 to work, but not both at the same time.  If I try to use both CAN channels at the same time, CAN1 works but CAN0 stops working and the CAN0 ECR and ESR1 registers shows there are faults...

 

johngreenjets_0-1683899158503.png

I have fitted 60R terminating resistors (x2) for each CAN transceiver and both CAN0 and CAN1 are connected together (I measured the total bus impedance to be 60R). 

I use a PeakCAN USB with Busmaster to read the CAN messages (PeakCAN has no terminating resistor fitted).

I'm not entirely sure how to configure the CAN peripheral on these processors, so I hoping its just something simple I've missed or done wrong.

The changes I made to the code are shown below - the original code is on the left pane and the modified code is on the right pane.

johngreenjets_8-1683899968768.png

johngreenjets_9-1683899994038.png

johngreenjets_10-1683900013693.png

johngreenjets_11-1683900030892.png

johngreenjets_12-1683900049886.png

 

Below are the Processor Expert settings for both CAN0 and CAN1...

johngreenjets_1-1683899272792.png

johngreenjets_3-1683899339195.png

Below is the Tx/Rx pins for CAN1...

johngreenjets_7-1683899902176.png

 

Below is the GPIO for the digital outputs (for the CAN transceiver STB pin)... 

johngreenjets_6-1683899854553.png

The project (zip) is attached for reference.

0 项奖励
回复
5 回复数

1,003 次查看
johngreenjets
Contributor III

Hi Robin

Interesting to hear it works for you.

I have both CAN0 and CAN1 buses connected together with the PEAK CAN USB spliced into the bus - see picture below...

johngreenjets_2-1684832142648.png

 

 

I have also fitted 60R terminating resistors on the board for both CAN channels i.e. R23 & R24 for CAN1 and R3 & R4 for CAN0...

johngreenjets_3-1684832261078.png

 

johngreenjets_4-1684832337994.png

 

As both CAN0 and CAN1 buses are connected together, I checked that the bus impedance is 60R.

 

0 项奖励
回复

988 次查看
Robin_Shen
NXP TechSupport
NXP TechSupport

The root cause is PINS_DRV_SetPinsDirection(STB_PORT, (1 << CAN0_STB)); and PINS_DRV_SetPinsDirection(STB_PORT, (1 << CAN1_STB)); . The default pin setting already configure the direction of CAN0_STB and CAN1_STB as output. But PINS_DRV_SetPinsDirection reconfigure one of pin as input.

The project is able to work on S32K146EVB is due to there is no STB pin on my external CAN transceiver. 

0 项奖励
回复

1,114 次查看
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi

CAN frame can be sent when CAN0_ENABLE or CAN1_ENABLE is defined, but cannot be sent if both are defined at the same time?

Have you try to move the CAN_Send to main function and configure interrupt priority(INT_SYS_SetPriority) for CAN0 and CAN1 and PORTE?

INT_SYS_SetPriority.png

Sorry, only CAN0 connected to the CAN transceiver on S32K146EVB, so it is not convenient for me to test.


Best Regards,
Robin

0 项奖励
回复

1,110 次查看
johngreenjets
Contributor III

Thanks Robin

Yes that is correct, CAN frame can be sent when CAN0_ENABLE or CAN1_ENABLE is defined, but cannot be sent if both are defined at the same time.

I added a toggle to the switch ISR, so that each time the button is pressed it will toggle between sending either the CAN0 message or the CAN1 message (but not both).

I did this to avoid any possible conflicts of trying to send a message on CAN0 and CAN1 at the same time.

However, the result is the same i.e.CAN1 works but CAN0 doesn't.

The end goal is to send messages at the same time on both CAN0 and CAN1, because I am trying to emulate a redundant CAN bus.

The code is shown below (where canToggle is used to toggle between message sending)..

void buttonISR(void)

{

    /* Check if one of the buttons was pressed */

    uint32_t buttonsPressed = PINS_DRV_GetPortIntFlag(BTN_PORT) &

                                           ((1 << BTN1_PIN) | (1 << BTN2_PIN));

    bool sendFrame = false;

    static bool canToggle;

    if(buttonsPressed != 0)

    {

        /* Set FlexCAN TX value according to the button pressed */

        switch (buttonsPressed)

        {

            case (1 << BTN1_PIN):

                ledRequested = LED0_CHANGE_REQUESTED;

                sendFrame = true;

                /* Clear interrupt flag */

                PINS_DRV_ClearPinIntFlagCmd(BTN_PORT, BTN1_PIN);

                break;

            case (1 << BTN2_PIN):

                ledRequested = LED1_CHANGE_REQUESTED;

                sendFrame = true;

                /* Clear interrupt flag */

                PINS_DRV_ClearPinIntFlagCmd(BTN_PORT, BTN2_PIN);

                break;

            default:

                PINS_DRV_ClearPortIntFlagCmd(BTN_PORT);

                break;

        }

        if (sendFrame)

        {

            /* Set information about the data to be sent

             *  - Standard message ID

             *  - Bit rate switch enabled to use a different bitrate for the data segment

             *  - Flexible data rate enabled

             *  - Use zeros for FD padding

             */

if (canToggle)

{

#ifdef CAN1_ENABLE

            can_buff_config_t buffCfg1 =  {

                            .enableFD = false,

                            .enableBRS = true,

                            .fdPadding = 0U,

                            .idType = CAN_MSG_ID_STD,

                            .isRemote = false

                        };

                        /* Configure TX buffer with index TX_MAILBOX*/

                        CAN_ConfigTxBuff(&can_1_instance, 2, &buffCfg1);

                        /* Prepare message to be sent */

                        can_message_t message1 = {

                            .cs = 0U,

                            .id = 0x0C1,

                            .data[0] = 0x01,

            .data[1] = 0x23,

            .data[2] = 0x45,

            .data[3] = 0x67,

            .data[4] = 0x89,

            .data[5] = 0xAB,

            .data[6] = 0xCD,

            .data[7] = 0xEF,

                            .length = 8U

                        };

                        /* Send the information via CAN */

                        CAN_Send(&can_1_instance, 2, &message1);

#endif

}

else

{

#ifdef CAN0_ENABLE

            can_buff_config_t buffCfg =  {

                .enableFD = false,

                .enableBRS = true,

                .fdPadding = 0U,

                .idType = CAN_MSG_ID_STD,

                .isRemote = false

            };

            /* Configure TX buffer with index TX_MAILBOX*/

            CAN_ConfigTxBuff(&can_0_instance, 1, &buffCfg);

            /* Prepare message to be sent */

            can_message_t message = {

                .cs = 0U,

                .id = TX_MSG_ID,

                .data[0] = 0x01,

.data[1] = 0x23,

.data[2] = 0x45,

.data[3] = 0x67,

.data[4] = 0x89,

.data[5] = 0xAB,

.data[6] = 0xCD,

.data[7] = 0xEF,

                .length = 8U

            };

            /* Send the information via CAN */

            CAN_Send(&can_0_instance, 1, &message);

#endif

}

canToggle ^= 1;

        }

    }

}

 

0 项奖励
回复

1,057 次查看
Robin_Shen
NXP TechSupport
NXP TechSupport

I programed your project on S32K146EVB and connect external CAN transceiver on CAN1_TX(PTA13) CAN1_RX(PTA12). I am able to receive CAN frame from CAN0 and CAN1 at the same time. Did you connect the two CAN signals of UCANS32K146 to the two channels of PEAK_CAN as shown in the figure below? I am using PEAK-USB Pro.

CAN connection PEAK_CAN UCANS32K146.pngcan_pal_s32k146 without error.png

0 项奖励
回复