This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM2634: LIN driver is not sending a Published frame after Subscribed frame is sent

Part Number: AM2634

Dear TI experts,

I am sending a schedule table which has 10 frames with combination of Published and Subscribed frames.

I am able send subscribed frame but after that if published frame is sent I get a error.

Should I clear any register after sending a subscribed frame ?

** Note: I am commenting //LIN_sendData(APP_LIN_BASE_ADDR, txData1); for SUBSCRIBED frames because data will be filled by slave device.

I have attached the driver code below:

  • Hi ,

    Are you using LIN example from the Interrupt mode or the Polling mode ?

    Best Regards,
    Aakash

  • Hi Aakash, I am using LIN External Example code, In this there is no loopback mode set:

  • /*
     *  Copyright (C) 2022 Texas Instruments Incorporated
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *   This example configures the LIN module in LIN mode for The LIN module
     *   performs sends a data over LIN_1 which is connected to PC via PLIN_USB.
     *   The data is sent over LIN at 19200 baud rate.
     *
     *   Make sure to move the SW9 to ON. This will turn ON the LIN Transceiver.
     *   I2C_2 is configured to set the level shifter so the LIN_MUX_SEL is set as LOW.
     *   So the Transceiver is set as LIN Mode.
     *
     *   External Connections :
     *    - PLIN-USB connected to Windows Machine.
     *
     *   Watch Variables :
     *
     */
    
    #include <stdint.h>
    #include <kernel/dpl/SystemP.h>
    #include <kernel/dpl/SemaphoreP.h>
    #include <kernel/dpl/HwiP.h>
    #include <drivers/hw_include/cslr.h>
    #include <drivers/hw_include/cslr_soc.h>
    #include <drivers/hw_include/cslr_lin.h>
    #include <drivers/hw_include/hw_types.h>
    
    /* Included Files */
    #include <kernel/dpl/DebugP.h>
    #include <drivers/lin.h>
    #include <drivers/i2c.h>
    #include <ti_drivers_config.h>
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    /* Defines */
    #define FRAME_LENGTH        (0x1)
    #define LIN_ID              (0x10)
    
    #define LIN_PASS            (0xABCD)
    #define LIN_FAIL            (0xFFFF)
    
    #define I2C_SLAVE_ADDRESS   (0x20U)
    #define I2C_POLARITY_INV    (0x5U)
    
    #define APP_LIN_BASE_ADDR   (CONFIG_LIN1_BASE_ADDR)
    
    /* Globals */
    uint16_t result;
    
    uint16_t txData1[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xAB, 0xCD, 0xEF};
    uint16_t txData2[8] = {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28};
    uint16_t txData3[8] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38};
    uint16_t txData4[8] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48};
    uint16_t txData5[8] = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58};
    
    uint16_t rxData[8] = {0x00};
    
    /* lin_external_main */
    void lin_external_main(void)
    {
        uint32_t                i;
        uint16_t                txID, error = 0;
        int32_t                 status;
        uint8_t                 txBuffer[1];
        I2C_Handle              i2cHandle;
        I2C_Transaction         i2cTransaction;
    
        /* Open drivers to open the UART driver for console */
        Drivers_open();
        Board_driversOpen();
    
        i2cHandle = gI2cHandle[CONFIG_I2C2];
    
        DebugP_log("[LIN] LIN mode external, application started ...\r\n");
    
        /* Enable parity check */
        LIN_enableParity(APP_LIN_BASE_ADDR);
    
        /* Enable multi-buffer mode */
        LIN_enableMultibufferMode(APP_LIN_BASE_ADDR);
    
        /* Enable Fixed baud rate mode */
        LIN_disableAutomaticBaudrate(APP_LIN_BASE_ADDR);
    
        /* Reaching the Baud of 19200 */
        LIN_setBaudRatePrescaler(APP_LIN_BASE_ADDR, 624U, 0U);
    
        /* Enable transfer of data to the shift registers  */
        LIN_enableDataTransmitter(APP_LIN_BASE_ADDR);
    
        /* Enable the triggering of checksum compare on extended frames */
        LIN_triggerChecksumCompare(APP_LIN_BASE_ADDR);
    
        //LIN_setChecksumType(APP_LIN_BASE_ADDR, LIN_CHECKSUM_ENHANCED);
    
        /**
         *  \brief  Send Checksum Byte.
         *
         *  \param  base is the LIN module base address
         *
         *  In LIN mode only, this function enables the transmitter with extended
         *  frames to send a checkbyte.
         *
         */
    
         /* Setting the Check Sum */
        HW_WR_FIELD32_RAW((APP_LIN_BASE_ADDR + CSL_LIN_SCIGCR1), CSL_LIN_SCIGCR1_CTYPE_MASK, CSL_LIN_SCIGCR1_CTYPE_SHIFT, LIN_CHECKSUM_ENHANCED);
    
        DebugP_log("[I2C] LIN Volatage Level Shifter started ...\r\n");
    
     /*   I2C_Transaction_init(&i2cTransaction);
        i2cTransaction.writeBuf   = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.slaveAddress = I2C_SLAVE_ADDRESS;
        txBuffer[0] = I2C_POLARITY_INV;
        status = I2C_transfer(i2cHandle, &i2cTransaction);
        DebugP_assert(status == SystemP_SUCCESS);
    */
    
        /*
         * Perform 8 data transmissions with different transmit IDs and varying
         * number of bytes transmitted. Received data is checked for correctness.
         */
        //for(i = 1 ; i <= FRAME_LENGTH; i++)
        //{
        while(1)
        {
            /* Create a new transmit ID and update with parity bits */
            //txID = (LIN_ID + i);
            txID = (0x22);
            txID = LIN_generateParityID(txID);
    
            /*
             * Set the frame length (number of bytes to be transmitted)
             */
            //LIN_setFrameLength(APP_LIN_BASE_ADDR, i);
    
            LIN_setFrameLength(APP_LIN_BASE_ADDR, FRAME_LENGTH);
    
            /*
             * This places data into the transmit buffer.
             * No ID or data is placed on the bus and transmitted yet.
             */
            LIN_sendData(APP_LIN_BASE_ADDR, txData1);
    
            /*
             * Set the message ID to initiate a header transmission.
             * This causes the ID to be written to the bus followed by the
             * data in the transmit buffers.
             */
            LIN_setIDByte(APP_LIN_BASE_ADDR, txID);
    
            /* Wait until Transmit buffer is empty and has completed transmission */
            //while(!LIN_isTxBufferEmpty(APP_LIN_BASE_ADDR));
    
            /* Wait for the Reception */
            //while(!LIN_isRxMatch(APP_LIN_BASE_ADDR));
    
            //LIN_clearInterruptStatus(APP_LIN_BASE_ADDR,LIN_INT_ID);
    
            /* Read the received data in the receive buffers */
            //LIN_getData(APP_LIN_BASE_ADDR, rxData);
    
            DebugP_log("[LIN] : New Data Sent = %x\r\n", txData1[FRAME_LENGTH-1]);
    
            //-----------------------------------------------------------------------
            /* Create a new transmit ID and update with parity bits */
            //txID = (LIN_ID + i);
            txID = (0x27);
            txID = LIN_generateParityID(txID);
    
            /*
             * Set the frame length (number of bytes to be transmitted)
             */
            //LIN_setFrameLength(APP_LIN_BASE_ADDR, i);
    
            LIN_setFrameLength(APP_LIN_BASE_ADDR, FRAME_LENGTH);
    
            /*
             * This places data into the transmit buffer.
             * No ID or data is placed on the bus and transmitted yet.
             */
            //LIN_sendData(APP_LIN_BASE_ADDR, txData2);
    
            /*
             * Set the message ID to initiate a header transmission.
             * This causes the ID to be written to the bus followed by the
             * data in the transmit buffers.
             */
            LIN_setIDByte(APP_LIN_BASE_ADDR, txID);
    
            /* Wait until Transmit buffer is empty and has completed transmission */
            //while(!LIN_isTxBufferEmpty(APP_LIN_BASE_ADDR));
    
            /* Wait for the Reception */
            //while(!LIN_isRxMatch(APP_LIN_BASE_ADDR));
    
            //LIN_clearInterruptStatus(APP_LIN_BASE_ADDR,LIN_INT_ID);
    
            /* Read the received data in the receive buffers */
            LIN_getData(APP_LIN_BASE_ADDR, rxData);
    
            DebugP_log("[LIN] : New Data Sent = %x\r\n", txData2[FRAME_LENGTH-1]);
            //-----------------------------------------------------------------------
                    /* Create a new transmit ID and update with parity bits */
                    //txID = (LIN_ID + i);
                    txID = (0x22);
                    txID = LIN_generateParityID(txID);
    
                    /*
                     * Set the frame length (number of bytes to be transmitted)
                     */
                    //LIN_setFrameLength(APP_LIN_BASE_ADDR, i);
    
                    LIN_setFrameLength(APP_LIN_BASE_ADDR, 2);
    
                    /*
                     * This places data into the transmit buffer.
                     * No ID or data is placed on the bus and transmitted yet.
                     */
                    LIN_sendData(APP_LIN_BASE_ADDR, txData3);
    
                    /*
                     * Set the message ID to initiate a header transmission.
                     * This causes the ID to be written to the bus followed by the
                     * data in the transmit buffers.
                     */
                    LIN_setIDByte(APP_LIN_BASE_ADDR, txID);
    
                    /* Wait until Transmit buffer is empty and has completed transmission */
                    //while(!LIN_isTxBufferEmpty(APP_LIN_BASE_ADDR));
    
                    /* Wait for the Reception */
                    //while(!LIN_isRxMatch(APP_LIN_BASE_ADDR));
    
                    //LIN_clearInterruptStatus(APP_LIN_BASE_ADDR,LIN_INT_ID);
    
                    /* Read the received data in the receive buffers */
                    //LIN_getData(APP_LIN_BASE_ADDR, rxData);
    
                    DebugP_log("[LIN] : New Data Sent = %x\r\n", txData3[FRAME_LENGTH-1]);
                    //-----------------------------------------------------------------------
                            /* Create a new transmit ID and update with parity bits */
                            //txID = (LIN_ID + i);
                            txID = (0x27);
                            txID = LIN_generateParityID(txID);
    
                            /*
                             * Set the frame length (number of bytes to be transmitted)
                             */
                            //LIN_setFrameLength(APP_LIN_BASE_ADDR, i);
    
                            LIN_setFrameLength(APP_LIN_BASE_ADDR, FRAME_LENGTH);
    
                            /*
                             * This places data into the transmit buffer.
                             * No ID or data is placed on the bus and transmitted yet.
                             */
                            //LIN_sendData(APP_LIN_BASE_ADDR, txData4);
    
                            /*
                             * Set the message ID to initiate a header transmission.
                             * This causes the ID to be written to the bus followed by the
                             * data in the transmit buffers.
                             */
                            LIN_setIDByte(APP_LIN_BASE_ADDR, txID);
    
                            /* Wait until Transmit buffer is empty and has completed transmission */
                            //while(!LIN_isTxBufferEmpty(APP_LIN_BASE_ADDR));
    
                            /* Wait for the Reception */
                            //while(!LIN_isRxMatch(APP_LIN_BASE_ADDR));
    
                            //LIN_clearInterruptStatus(APP_LIN_BASE_ADDR,LIN_INT_ID);
    
                            /* Read the received data in the receive buffers */
                            LIN_getData(APP_LIN_BASE_ADDR, rxData);
    
                            DebugP_log("[LIN] : New Data Sent = %x\r\n", txData4[FRAME_LENGTH-1]);
                            //-----------------------------------------------------------------------
                                    /* Create a new transmit ID and update with parity bits */
                                    //txID = (LIN_ID + i);
                                    txID = (0x22);
                                    txID = LIN_generateParityID(txID);
    
                                    /*
                                     * Set the frame length (number of bytes to be transmitted)
                                     */
                                    //LIN_setFrameLength(APP_LIN_BASE_ADDR, i);
    
                                    LIN_setFrameLength(APP_LIN_BASE_ADDR, FRAME_LENGTH);
    
                                    /*
                                     * This places data into the transmit buffer.
                                     * No ID or data is placed on the bus and transmitted yet.
                                     */
                                    LIN_sendData(APP_LIN_BASE_ADDR, txData5);
    
                                    /*
                                     * Set the message ID to initiate a header transmission.
                                     * This causes the ID to be written to the bus followed by the
                                     * data in the transmit buffers.
                                     */
                                    LIN_setIDByte(APP_LIN_BASE_ADDR, txID);
    
                                    /* Wait until Transmit buffer is empty and has completed transmission */
                                    //while(!LIN_isTxBufferEmpty(APP_LIN_BASE_ADDR));
    
                                    /* Wait for the Reception */
                                    //while(!LIN_isRxMatch(APP_LIN_BASE_ADDR));
    
                                    //LIN_clearInterruptStatus(APP_LIN_BASE_ADDR,LIN_INT_ID);
    
                                    /* Read the received data in the receive buffers */
                                   // LIN_getData(APP_LIN_BASE_ADDR, rxData);
    
                                    DebugP_log("[LIN] : New Data Sent = %x\r\n", txData5[FRAME_LENGTH-1]);
                                    //-----------------------------------------------------------------------
        }
        //}
    
        /* Check if any data errors occurred */
        if(error == 0)
        {
            result = LIN_PASS;
            DebugP_log("All tests have passed!!\r\n");
        }
        else
        {
            result = LIN_FAIL;
            DebugP_log("Test FAILED!!\r\n");
        }
    
        Board_driversClose();
        Drivers_close();
    }
    

  • Hi  Please find code above which I am using.

  • Hi ,

    Can I reproduce this issue if I use your SW on AM263x-CC (I will use syscfg like lin_external.c example) ?

    Best Regards,
    Aakash

  • Hi  Yes you can use same lin external example syscfg, Only change is they are sending only subscribed frame in the example code and waiting for rxdata. You need to send rxframe (Subscribed) and txframe(Published) in a while loop with some delay. You should be able to reproduce that scenario.

    If you are using the above code with linexternal syscfg then no need of any change, you should be able to reproduce the issue.

    I have attached some evidences of Published frames not sent after Subscribed frame sent below:

    **Note: https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1189452/mcu-plus-sdk-am263x-lin-sdk-function-is-setting-a-improper-register-bit-for-selecting-the-checksum-type-in-the-register

    You may get wrong checksum until the above SDK bug is fixed but you should be able to reproduce the issue by commenting //LIN_setChecksumType(APP_LIN_BASE_ADDR, LIN_CHECKSUM_ENHANCED); and using  HW_WR_FIELD32_RAW((APP_LIN_BASE_ADDR + CSL_LIN_SCIGCR1), CSL_LIN_SCIGCR1_CTYPE_MASK, CSL_LIN_SCIGCR1_CTYPE_SHIFT, LIN_CHECKSUM_ENHANCED);

  • Hi can you please let us know if you were able to reproduce the issue ?

  • Hi ,

    I could not replicate the issue. For me the LIN Responder was not configurable into a subscriber or publisher properly.

    By the way, if you want to use the LIN Responder as a publisher then you should support a wait functionality in LIN Commander. For the same I suggest you to call -

    while(!LIN_isRxReady(APP_LIN_BASE_ADDR));
    before LIN_getData(APP_LIN_BASE_ADDR, rxData); is called.
    Best Regards,
    Aakash
  • Hi  Please find here my complete project : 

    https://drive.google.com/file/d/1TzOSH5z2pWDMqKhuaQF5PIgAqwXOKmUL/view?usp=sharing

    Please find below my link to LIN simulation and logs :

    https://drive.google.com/file/d/1tp8-qiGSswvrZmLZX4i4CmafKlYHRMNO/view?usp=share_link

    My problem is I am developing software for LIN Master.

    After I send a header and wait for slave to respond after that I am not able to send a header even after 100ms of actual slave response.

    In the attached project you can also see the Lin Trace files attached with complete project code.

    Please flash the above project i have shared in google link and watch the output in any analyser you shall see the header for frame id 0x22 is not getting transmitted after frame id 0x27 has been responded by the simulated slave.

  • Hi ,

    I have analyzed the data and it seems like the packet from Responder for ID: 0x27 is not considered complete. The next packet sent as ID: 0x22 is parsed as data packet by the analyzer/LIN Node. 

    I am still analyzing the problem. I might have to discuss the same with experts internally. Please wait 04/07/2023 till I find more update on this.

    Best Regards,
    Aakash

  • Hi  ,

    Do you mean we can have an answer by 7th April 2023 ?

    I have also captured the logic analyser logs of the LinBus for capturing the exact errors.

    https://drive.google.com/file/d/1PRtDRHnIRsAVeWsOL5IeuaAKFJ2HfHPj/view?usp=sharing

    Please find the snap for frame Id 0x27 which is responded by the simulated slave from the Canalyser configuration.

    Below are the signals transmitted by AM2634 instead of frame  0x22(Header and data to be transmitted by AM263x)

    Thanks & Regards,

    Prashanth Arun

  • Hi ,

    Yes, my analysis is also the same.

    I am configuring my master to follow these flow and this is the observations -

    SUBSCRIBER --> PUBLISHER --> SUBSCRIBER : 1st Subscriber and All Publisher Packets are good, rest all Subscriber packets are bad.
    PUBLISHER --> SUBSCRIBER : All Publisher Packets are good, Subscriber packets are bad.
    PUBLISHER --> PUBLISHER : ALL Publisher PACKETS are GOOD.
    SUBSCRIBER --> SUBSCRIBER --> PUBLISHER --> SUBSCRIBER --> SUBSCRIBER --> PUBLISHER : ALL the first Subscriber packets are considered BAD.

    I have raised an request and we are analyzing this with Pre-Si to get more idea on this. Please be patient.

    Best Regards,
    Aakash

  • Hi Prashanth,

    We have responded to the issue on another thread -

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1222639/am2634-lin-driver-is-not-sending-a-published-frame-after-subscribed-frame-is-sent

    ------------------------------------------------------------------------------------------------------------------------------

    We have confirmed this is not an issue.

    To determine, if the packet is supposed to be received or transmitted, that id filter needs to be updated in the filter mask.

    Hence, in case of transmit, you need to call -

    txID = LIN_generateParityID(txID);
    LIN_setTxMask(APP_LIN_BASE_ADDR, txID);

    In case of receive -

    rxID = LIN_generateParityID(rxID);
    LIN_setRxMask(APP_LIN_BASE_ADDR, rxID);

    We tested the same and we don't see the packet drop anymore.

    ------------------------------------------------------------------------------------------------------------------------------

    I am closing this thread to avoid duplicity. In case of discussion, we will use the above mentioned thread.

    Best Regards,
    Aakash