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.

MCU-PLUS-SDK-AM263X: LIN only send header part

Part Number: MCU-PLUS-SDK-AM263X
Other Parts Discussed in Thread: SYSCONFIG

Hi I have used the SDK example code for external LIN. But, It only sends the header part of the LIN frame. It is supposed to send the txData after LIN_setIDByte but when I check it in the oscilloscope and in CANAlayzer software, I dont see any response field after header part.

LIN_setFrameLength(APP_LIN_BASE_ADDR, i);

/*
* 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, txData);

/*
* 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);

  • Hi ,

    What is the configuration of the LIN responder ? Is it configured in subscriber mode and ready to receive the data for the ids mentioned in the example ?

    Can you confirm this ?

    Best Regards,
    Aakash

  • It is in the "Commander Mode"

  • Hi,

    Do you have a responder connected to AM263x or is that just a LIN commander (AM263x) connected to oscilloscope and CANAnalyzer ?

    I think CANAnalyzer should be configured as a responder. Is that the case ?

    Best Regards,
    Aakash

  • Hi Aakash,

    AM263x (LIN commander) is only connected to CANAlyzer. 

    I need that AM263x act as both master and slave (both commander and responder). (I mean both send the header part and then send the response part)

    How can I do it like that?

    Thanks

  • Hi ,

    There is an internal documentation ticket for the bug - https://jira.itg.ti.com/browse/MCUSDK-11668 regarding the documentation of https://software-dl.ti.com/mcu-plus-sdk/esd/AM263X/latest/exports/docs/api_guide_am263x/EXAMPLES_DRIVERS_LIN_EXTERNAL_COMMANDER.html

    Switch Status
    SW9 ON
    SW10 1-2

    Best Regards,
    Aakash

  • Hi Aakash,

    I don't have access to https://jira.itg.ti.com/browse/MCUSDK-11668 

    I am exactly running this example 

    AM263x MCU+ SDK: LIN External Commander Transmit (ti.com)

    The only difference is that I have connected to CANAlyzer instead of PLIN-USB.

    But I get the error (TransmError - Slave not responding) since the example code do not send the response after sending the header part of the LIN frame.

    My question is that why the example code only sends the header part of the LIN frame (not followed by the data part)

    BR

    Saman

  • Hi Saman,

    I don't have access to

    As mentioned this is a internal ticket, this is just for tracking purpose for TI.

    My question is that why the example code only sends the header part of the LIN frame (not followed by the data part)

    Can you share your observation on a logic analyzer or a oscilloscope instead of CANAlyzer ?

    Best Regards,
    Aakash

  • Hi Aakash,

    Here is the oscilloscope capture of one LIN frame generated by the following code from the SDK "External Lin Example"

    The only change that I made is to replace for-loop with while forever loop with "i=1" in order to have only one frame to be investigated.

    As I have indicated the header part seems to be complete but there is no response field sent.

    Best Regards,

    Saman

  • Hi Aakash,

    Is there any feedback on my issue?

    Thanks 

    Saman

  • Hi ,

    I tried to replicate the issue and I see this to be completely working. Can you send your lin_external.c file which is modified ?

    Best Regards,
    Aakash

  • Hi Aakash, 

    Here is the plain text of modified lin_external.c, 

    /*
    * 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 :
    *
    */

    /* 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 (0x8)
    #define LIN_ID (0x10)

    #define LIN_PASS (0xABCD)
    #define LIN_FAIL (0xFFFF)

    #define I2C_TARGET_ADDRESS (0x20U)
    #define I2C_POLARITY_INV (0x5U)

    #define APP_LIN_BASE_ADDR (CONFIG_LIN1_BASE_ADDR)

    /* Globals */
    uint16_t result;
    uint16_t txData[8] = {0x12, 0x34, 0x56, 0x78, 0x00, 0xAB, 0xCD, 0xEF};
    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);

    DebugP_log("[I2C] LIN Volatage Level Shifter started ...\r\n");

    I2C_Transaction_init(&i2cTransaction);
    i2cTransaction.writeBuf = txBuffer;
    i2cTransaction.writeCount = 1;
    i2cTransaction.targetAddress = I2C_TARGET_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.
    */
    i = 1;
    while (1)
    {

    // for(i = 1 ; i <= FRAME_LENGTH; i++)
    {
    /* Create a new transmit ID and update with parity bits */
    txID = (LIN_ID + i);
    txID = LIN_generateParityID(txID);

    /*
    * Set the frame length (number of bytes to be transmitted)
    */
    LIN_setFrameLength(APP_LIN_BASE_ADDR, i);

    /*
    * 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, txData);

    /*
    * 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);

    DebugP_log("[LIN] : New Data Sent = %x\r\n", txData[i-1]);
    }

    vTaskDelay(1000);

    }


    /* 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 Aakash,

    Did you check it with PLIN-USB? 

    I have also tested it without any slave node connected (disconnecting CANAlyzer), only with oscilloscope. Is that fine? or there must be at least one slave node connected?

    Thanks

    Saman

  • Hi,

    After sending the LIN ID can you do this check ?

    LIN_setIDByte(APP_LIN_BASE_ADDR, txID);

    while (LIN_FLAG_TXEMPTY & LIN_getInterruptStatus() != LIN_FLAG_TXEMPTY);

    Best Regards,
    Aakash

  • Hi,

    I checked it.

    It only sends one time (only header part) and waits FOREVER.

    Thanks

    Saman

  • Hi Saman,

    Even I have checked it on my machine. It works with your file with the following changes. Although, I have PLIN connected on the setup.

            /*
            * 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);

            while ((LIN_FLAG_TXEMPTY & LIN_getInterruptStatus(APP_LIN_BASE_ADDR)) != LIN_FLAG_TXEMPTY)
            {
                ;
            }

            DebugP_log("[LIN] : New Data Sent = %x\r\n", txData[i-1]);
    Best Regards,
    Aakash
  • Hi Aakash,

    Still not sending "Response field" in my setup.

    Do you test it in AM263x CC board?

    Which version of the SYSCONFIG and SDK and CCS are you using?

    Although I have tested it with the latest versions

    Can we have a video call in Teams on Monday to figure out the issue?

    Thanks

    Saman

  • Hi Aakash,

    Are you also testing on the LIN_EXTERNAL example project?

    since Interrupt is not configured in that example and using LIN_getInterruptStatus seems not to be a good idea. I am wondering how it has worked in your setup.


    while ((LIN_FLAG_TXEMPTY & LIN_getInterruptStatus(APP_LIN_BASE_ADDR)) != LIN_FLAG_TXEMPTY)

    By the way, I have also tested the LIN_External without any changes, but it did not work again. 

    I am thinking about any SYSConfig or CCS or SDK version need to be changed.

    I am using  CCS version Version: 12.3.0.00005, SysConfig version 1.17.0 and SDK version 9.0.0.33.

    Is that all right?

    Thanks

  • Hi Aakash,

    I realized that if I tick the checkbox "Use Default Configuration", then it works well.

    It is strange that this checkbox is not enabled by default when I import the example code.

    My question is that if I disable the checkbox. How should I configure the modes to have LIN working as default configuration?

    BR

    Saman

  • Hi Saman,

    Yes. I have the same observation however for me, the default configuration is always enabled. I have raised an internal issue for the bypass of default configuration leading to failure.

    MCUSDK-11828 (This link is not accessible outside TI network but it is shared for tracking purpose)

    Best Regards,
    Aakash

  • Hi Aakash,

    By the way could you please tell me which configuration is equal to "default configuration"?

    I mean how "LIN Mode", "LIN Communication mode", "LIN Debug mode", "LIN Checksum Type" and "LIN Message filter" should be configured in order to have LIN working as default configuration?

    Thanks 

    Saman

  • Hi ,

    I updated these two files -

    1. one in the example
    2. another in the syscfg template.

    Attaching the two files here - https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/908/lin.c.xdt

    /*
     *  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 :
     *
     */
    
    /* 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        (0x8)
    #define LIN_ID              (0x10)
    
    #define LIN_PASS            (0xABCD)
    #define LIN_FAIL            (0xFFFF)
    
    #define I2C_TARGET_ADDRESS   (0x20U)
    #define I2C_POLARITY_INV    (0x5U)
    
    #define APP_LIN_BASE_ADDR   (CONFIG_LIN1_BASE_ADDR)
    
    /* Globals */
    uint16_t result;
    uint16_t txData[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xAB, 0xCD, 0xEF};
    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 multi-buffer mode */
        LIN_enableMultibufferMode(APP_LIN_BASE_ADDR);
    
        LIN_setSyncFields(APP_LIN_BASE_ADDR, 5U, 3U);
    
        /* Enable Fixed baud rate mode */
        LIN_disableAutomaticBaudrate(APP_LIN_BASE_ADDR);
    
        /* Reaching the Baud of 19200 */
        LIN_setBaudRatePrescaler(APP_LIN_BASE_ADDR, 624U, 0U);
        LIN_setMaximumBaudRate(APP_LIN_BASE_ADDR, 100000000U);
    
        /* Set Mask ID so TX/RX match will always happen */
        LIN_setTxMask(APP_LIN_BASE_ADDR, 0xFFU);
        LIN_setRxMask(APP_LIN_BASE_ADDR, 0xFFU);
    
        /* Enable transfer of data to the shift registers  */
        LIN_enableDataTransmitter(APP_LIN_BASE_ADDR);
        LIN_enableDataReceiver(APP_LIN_BASE_ADDR);
    
        /* Enable the triggering of checksum compare on extended frames */
        LIN_triggerChecksumCompare(APP_LIN_BASE_ADDR);
    
        DebugP_log("[I2C] LIN Volatage Level Shifter started ...\r\n");
    
        I2C_Transaction_init(&i2cTransaction);
        i2cTransaction.writeBuf   = txBuffer;
        i2cTransaction.writeCount = 1;
        i2cTransaction.targetAddress = I2C_TARGET_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++)
        {
            /* Create a new transmit ID and update with parity bits */
            txID = (LIN_ID + i);
            txID = LIN_generateParityID(txID);
    
            /*
             * Set the frame length (number of bytes to be transmitted)
             */
            LIN_setFrameLength(APP_LIN_BASE_ADDR, i);
    
            /*
             * 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, txData);
    
            /*
             * 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);
    
            DebugP_log("[LIN] : New Data Sent = %x\r\n", txData[i-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();
    }
    

    Path for the same - examples/drivers/lin/lin_external/lin_external.c and source/drivers/.meta/lin/templates/lin.c.xdt

    This way, any of the given configuration mentioned in the syscfg will work for you.

    Best Regards,
    Aakash

  • Hi Aakash,

    I have used lin_external.c code in one thread in my own code. But, again it only sends the header part not the response field !!!! even when I check the LIN in default configuration. 

    I also used the attached above lin_external code but it does not work.

    I guess that there should be some adjustment in SDK to have it completely fixed.

    Would you give me any advise regarding that please?

    Thanks 

    Saman

  • Hi ,

    Did you also update the lin.c.xdt at source/drivers/.meta/lin/templates/lin.c.xdt ? This will impact the generated files via syscfg.

    Best Regards,
    Aakash

  • Yes I have updated the file lin.c.xdt

  • Hi ,

    You will find the generated file to create a different driver_init and with the updated lin_external file, this works with all the combinations in the sysconfig.

    Hope it helps.

    Best Regards,
    Aakash

  • Hi Aakash, 
    Where can I find this "driver_init"?

    BR

    Saman

  • Hi Aakash,

    The Sysconfig/SDK behaves confusing. 


    When I change LIN_TXD/RXD pins from (LIN1_RXD/A9,LIN1_TXD/B9) --> (UART1_RXD/L3, UART1_TXD/M3) the firmware which was working fine, again , it does not work (ONLY send "Header part").

    I have updated lin.c.xdt file and updated lin_external.c as well. 

    One more point is that when I change back the TXD/RXD pins to A9/B9 then I need to power off/on the board in order to have the LIN completely working.

    otherwise it only sends the header part.

    BR

    Saman

  • Hi Aakash,

    My question is that:

    Why only changing TXD/RXD pins in SYSCONFIG impacts the LIN behavior ? 

    Saman

  • Can you replicate this at your side and confirm this?

  • Hi ,

    We are not able to replicate this on our end. Please try adding a transceiver on another pads and check if the example works or not.

    Best Regards,
    Aakash