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.

TMS570LS0714: TMS570LS0714 - SCI2 RX (LIN) interrupt handling using sciNotification

Part Number: TMS570LS0714
Other Parts Discussed in Thread: HALCOGEN, SN65HVD73

Dear TI Team

I am using the TMS570LS0714 in the PZ package. Currently I am trying to setup an SCI implementation using PIN 94 (LIN RX).
PIN 94 is connected with the RX singal of my external sensor.

My problem is that the sciNotification(sciBASE_t *sci, uint32 flags) function is not triggered by the RX interrupt (which is my intension)
Could you please have a look on my CCS code and Hal Gen settings?


Do you have an idea why sciNotification is not triggered?


The settings in HAL GEN -> SCI2 -> SCI/LIN Global: was tested with RX int connected with High Level (as shown above) and tested with RX int NOT connected with High Level) both without success.
Also the settings in HAL GEN -> COM Ch. 0-31 was tested LIN1 High + LIN1 Low connected to IRQ and was tested with only LIN1 High conected to IRQ, both combinations without success.

/* USER CODE BEGIN (1) */

#include "sci.h"
#include "het.h"
#include "gio.h"

#include "system.h"

#include <stdio.h>

/* USER CODE END */

/* USER CODE BEGIN (2) */


uint8 sci_cmd;

/* USER CODE END */

int main(void)
{
/* USER CODE BEGIN (3) */

    /* Initialize HET driver */
    hetInit();

    /* Initialize GIO driver */
    gioInit();
    gioSetBit(hetPORT1, 0, 1);        

    /* Initialize SCI and enable ISR */
    sciInit();
    sciReceive(scilinREG, 1, &sci_cmd);//sciReceive(sciREG, 1, &sci_cmd);

    /* Enable Interrupt Processing */
    //_enable_interrupt_();
    _enable_IRQ ();


   while(1)
   {
   }

/* USER CODE END */

    return 0;
}


/* USER CODE BEGIN (4) */
void sciNotification(sciBASE_t *sci, uint32 flags)
{
    printf("Test\r");
}
 /* USER CODE END */


gioSetBit(hetPORT1, 0, 1) is set to activate the sensor

Thank you in advance!

  • Hello,

    printf is line-buffered, so the output doesn't appear until either a \n or an explicit fflush(stdout). 

    Please add a breakpoint in SCI ISR to check if the RX interrupt is generated when you type a char in UART terminal.

  • Dear Wang,

    I tried what you recommended. The sciNotification() was still not triggered.

    It is only triggered once at the beginnning of the main() loop when I call:
    sciReceive(scilinREG, 1, &sci_cmd);

    Also, when I put:
    sciReceive(scilinREG, 1, &sci_cmd);

    in the while() loop of the main() function, the sciNotification() is also triggered.

    I tried to analyse this by doing this:

    I inserted a breakpoint in sci.c -> void linHighLevelInterrupt(void)

        case 11U:
            /* receive */
    			byte = (uint8)(scilinREG->RD & 0x000000FFU);
    
                if (g_sciTransfer_t[1U].rx_length > 0U)
                {
                    *g_sciTransfer_t[1U].rx_data = byte;
                    /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
    				g_sciTransfer_t[1U].rx_data++;
                    g_sciTransfer_t[1U].rx_length--;
                    if (g_sciTransfer_t[1U].rx_length == 0U)
                    {
                        sciNotification(scilinREG, (uint32)SCI_RX_INT);
                    }
                }
            break;

    I could see that "byte" continously receives new values, however "if (g_sciTransfer_t[1U].rx_length > 0U)"
    is not entered (only when I call "sciReceive(scilinREG, 1, &sci_cmd);"). It seems like that the length is somehow somewhere overwritten?! Is this possible? The length should be "1" since I set this at the beginnning of the main() function.

    In a previous work, I used not the LIN RX port but the SCI RX port (I used the PGE package). And there, everything is working with the code above but not for the LIN port resp. the PZ package.

    Any idea?

  • Hello,

    To receive the RX interrupt continuously, the sciReceive() should be called in while() loop.

    Calling sciReceive(scilinREG, 1, &sci_cmd) is to get 1 char in the interrupt mode, and only 1 interrupt is generated. 

    The RX interrupt is enabled in your configuration, the RX data should be read in the RX Interrupt routine, and the length is decremented in the if() condition. 

    Can you do another test using a big value for length? for example length=2 or 3.

  • Hello Wang

    My understanding is now that I have to continously use sciReceive(scilinREG, 6, &sci_cmd) in the main while() loop since I want to receive 6 sequential frames each 1 Byte long (these 6 frame are repeated continously (I only use the RX pin)). The sciNotification() is only called when all 6 bytes are received within linHighLevelInterrupt(void) (this makes sense now).

    However:

    1. Would it be also correct to call sciReceive() at the end of sciNotofication() compared to placing it in main while() loop?

    2. I have still the problem to receive all 6frames within sciNotification(). Could you please explain me, how I can get access to the data buffer of the received 6 Bytes. So far I used

    rx_data = sci->RD;

    within sciNotification(). However, I dont understand how to receive the full data of 6 bytes. From my understanding, RD is defined as uint32 and would not be able to contain my data stream of 6 Byte? Also I dont understand how the data (byte) is stored in linHighLevelInterrupt(void).

    Thank you for the explanation!!!

  • There is no problem for receiving 1 byte or more bytes:

    void main(void)
    {
    /* USER CODE BEGIN (3) */

    //_enable_IRQ ();

    sciInit(); /* initialize sci/sci-lin */

    /* even parity , 1 stop bits */
    sciDisplayText(sciREG1,&TEXT1[0],TSIZE1); /* send text code 1 */
    wait(200);

    sciReceive(sciREG1, 1, &sci_cmd);

    _enable_IRQ ();

    while(1);
    /* USER CODE END */
    }

    /* USER CODE BEGIN (4) */
    void sciNotification(sciBASE_t *sci, uint32 flags)
    {
    if (flags == SCI_RX_INT)
    {
    sciDisplayText(sciREG1, "GET a RX INT! ", 16);
    sciDisplayText(sciREG1, "The received char is: ", 23);

    sciDisplayText(sciREG1, &sci_cmd, 1);

    sciDisplayText(sciREG1, " ---- Please type another char...... ", 38);

    }
    sciReceive(sciREG1, 1, &sci_cmd);
    }

    void sciDisplayText(sciBASE_t *sci, uint8 *text,uint32 length)
    {
    while(length--)
    {
    while ((sci->FLR & 0x4) == 4); /* wait until busy */
    sciSendByte(sci,*text++); /* send out text */
    };
    }

  • You can call sciReceive() anywhere:

    Here is an example to read the received 6 bytes data:

    void main(void)
    {
    /* USER CODE BEGIN (3) */

    //_enable_IRQ ();

    sciInit(); /* initialize sci/sci-lin */

    /* even parity , 1 stop bits */
    sciDisplayText(sciREG1,&TEXT1[0],TSIZE1); /* send text code 1 */
    wait(200);

    sciReceive(sciREG1, 6, &sci_cmd[0]);

    _enable_IRQ ();

    while(1);
    /* USER CODE END */
    }

    /* USER CODE BEGIN (4) */
    void sciNotification(sciBASE_t *sci, uint32 flags)
    {
    if (flags == SCI_RX_INT)
    {
    sciDisplayText(sciREG1, "GET a RX INT! ", 16);
    sciDisplayText(sciREG1, "The received chars are: ", 23);

    sciDisplayText(sciREG1, &sci_cmd[0], 1);
    sciDisplayText(sciREG1, &sci_cmd[1], 1);
    sciDisplayText(sciREG1, &sci_cmd[2], 1);
    sciDisplayText(sciREG1, &sci_cmd[3], 1);
    sciDisplayText(sciREG1, &sci_cmd[4], 1);
    sciDisplayText(sciREG1, &sci_cmd[5], 1);

    sciDisplayText(sciREG1, " ", 6);

    }
    sciReceive(sciREG1, 6, &sci_cmd[0]);
    }

    void sciDisplayText(sciBASE_t *sci, uint8 *text,uint32 length)
    {
    while(length--)
    {
    while ((sci->FLR & 0x4) == 4); /* wait until busy */
    sciSendByte(sci,*text++); /* send out text */
    };
    }

  • You can call sciReceive() in a while() loop, but you need to check a flag to make sure the last interrupt has been serviced:

    uint8 sci_cmd[6];
    uint32 RECEIVE_DONE;
    /* USER CODE END */

    void main(void)
    {
    /* USER CODE BEGIN (3) */

    //_enable_IRQ ();

    sciInit(); /* initialize sci/sci-lin */

    /* even parity , 1 stop bits */
    sciDisplayText(sciREG1,&TEXT1[0],TSIZE1); /* send text code 1 */
    wait(200);

    RECEIVE_DONE = 0;

    sciReceive(sciREG1, 6, &sci_cmd[0]);

    _enable_IRQ ();

    while(1){
    if ( RECEIVE_DONE == 1)
    {
    RECEIVE_DONE = 0;
    sciReceive(sciREG1, 6, &sci_cmd[0]);
    }
    }
    /* USER CODE END */
    }

    /* USER CODE BEGIN (4) */
    void sciNotification(sciBASE_t *sci, uint32 flags)
    {
    if (flags == SCI_RX_INT)
    {
    sciDisplayText(sciREG1, "GET a RX INT! ", 16);
    sciDisplayText(sciREG1, "The received chars are: ", 23);

    sciDisplayText(sciREG1, &sci_cmd[0], 1);
    sciDisplayText(sciREG1, &sci_cmd[1], 1);
    sciDisplayText(sciREG1, &sci_cmd[2], 1);
    sciDisplayText(sciREG1, &sci_cmd[3], 1);
    sciDisplayText(sciREG1, &sci_cmd[4], 1);
    sciDisplayText(sciREG1, &sci_cmd[5], 1);

    sciDisplayText(sciREG1, " ", 6);

    }
    //sciReceive(sciREG1, 6, &sci_cmd[0]);

    RECEIVE_DONE = 1;
    }

    void sciDisplayText(sciBASE_t *sci, uint8 *text,uint32 length)
    {
    while(length--)
    {
    while ((sci->FLR & 0x4) == 4); /* wait until busy */
    sciSendByte(sci,*text++); /* send out text */
    };
    }

  • Dear Wang

    This helped already thank you!
    Please bear with me for the following question:
    The data frame I want to receive via the SCI2 RX pin is the following:

    Each frame is defined as 6bytes

    My current HalGen setting is (I tried also 2 stop bits):

    I am not sure if I need to define a start bit in HalGen as shown in the first graphic above.
    And if yes, I dont know where I could add a start bit in the settings..

    I am currently struggeling to receive the 6 byte data frame via the sciReceive(scilinREG, 6, &sci_cmd) correctly. I am currently using the following code:

    void sciNotification(sciBASE_t *sci, uint32 flags)
    {
      
            static uint8 byte0;
            static uint8 byte1;
            static uint8 byte2;
            static uint8 byte3;
            static uint8 byte4;
            static uint8 byte5;
    
    
            if (flags == SCI_RX_INT)
            {
                byte0 = sci_cmd[0];
                byte1 = sci_cmd[1];
                byte2 = sci_cmd[2];
                byte3 = sci_cmd[3];
                byte4 = sci_cmd[4];
                byte5 = sci_cmd[5];
            }
            sciReceive(scilinREG, 6, &sci_cmd);//scilinREG
    }

    I receive 6 bytes but they are not what I expect.

    I would really much apprechiate if you could give me an advide on how I can receive the data frame shown above.
    Since there is not much to change in HalGen, it must have something to do with my current code in CCS.

    Thank you very much!

  • Hello,

    There is only one start bit at the beginning of the frame.  It is not configurable. The number of stop bit is configurable (1 bit or 2 bits).

    The code in SCI notification looks fine to me. I used this way to read the received chars, and didn't see any issue.

    The data you get is ASCII code. If you type 1a in the UART terminal, you will get 0x31 and 0x61.

  • Hello Wang

    Thank you for your answer. Unfortunatel I am still trying to find out why I can not receive the expected 6bytes of my frame (I receive 6 bytes but they are not what I expect). Do you think it has something to do that I use the LIN port and its registers (scilinREG) in a wrong way?

  • Do you think it has something to do that I use the LIN port and its registers (scilinREG) in a wrong way?

    No, this module can be used for LIN and SCI. To use this modules as SCI, the LIN MODE in SCIGCR1 register should be disabled. If you select SCI in HALCOGen "Enable Driver" page, this bit is cleared in sciInit().

  • Thank you for the response! Could you please have a look again on the above data protocol. The sensor I use sends within one frame 6 bytes. Each byte is send with one start and one stop bit. After the last byte of the frame is send (byte number 6) an idle high state is activated until the frame is initialised again (after 10kHz). My Baud rate is 921600 using an PLL generated internal clock of 90MHz.

    Do I need to handle the idle state in a special way, since it is only send after the last byte of the frame (byte number 6) and not after each byte?

    Thank you so much.

  • Does the sensor need a command for sending data back to you? Did you get any data (correct data or not) from sensor?

  • The sensor does not need a command to send the data. The sensor sends continuously every 10kHz a frame of 6bytes (+start/stop bit). After the last byte is send, an idle state, high state, is initialised until one 10kHz period is finished. I measure the correct analouge signals of the sensor on the RX pin of the microcontroller. I do receive data in CCS but not what I expect in comparison with the anlouge signals.

    To be more precise: baudrate is 921600 bit/sec, 8 bit data words, 1 stop bit, no parity, frame transmitted at 10KHz. One frame has 6 bytes:

    This means:
    - The time to send one byte is      (1/921600)*(8data+1 stop+1 start) = 10.85usec
    - The time to send all six bytes is (1/921600)*(8data+1 stop+1 start)*6 = 65.1usec
    - The idle state (waiting time at high level until next frame) is (1/10kHz) - 65.1usec = 35usec

    Does it have sonmething to do with the idle state which is only send after the byte number 6?
    Is the Sensor BaudRate of 921600 bit/sec too high?
    Do I have to use the SCI in another operation mode such as in (multi drop mode)?:

    https://e2e.ti.com/support/microcontrollers/c2000/f/c2000-microcontrollers-forum/538986/c28x-sci-idle-line-mode-speed


    Thank you!

  • MCU SCI RX pin should be connected to the TX pin of your sensor. The MCU SCI TX pin is connected to sensor's RX pin.

  • The sensor has an UART asynchronous serial interface where the data is send only through a differential output signal which is then connected to a UART transcveiver (the sensor has no RX pin). The output of this transceiver is connected to the RX pin of the MCU.  It is a one way communication.

    Do you think it might have something to do with the points (questions) I mentioned in my last answer?

  • I am using the TMS570LS0714 in the PZ package. Currently I am trying to setup an SCI implementation using PIN 94 (LIN RX).
    PIN 94 is connected with the RX singal of my external sensor.

    You said the external sensor has RX signal. 

  • How do you connect sensor differential signals to the UART transceiver? Which UART transceiver is used?

  • My bad. I wanted to say that the sensor data B and data A of the sensor is connected to the input side of the transceiver. I am using the SN65HVD73DGSR transceiver:

    https://www.ti.com/lit/ds/symlink/sn65hvd73.pdf?HQS=dis-mous-null-mousermode-dsf-pf-null-wwe&ts=1620624486233&ref_url=https%253A%252F%252Fwww.mouser.de%252F

    The sensor signals are differential:

    The output of the transceiver is connected to the RX pin of the MCU. The analouge signals are looking very good (there should be no problem caused by noise)

  • Hi,

    The SN65HVD73 has nRE signal to enable/disable the receiving. Is nRE connected to LOW or GND on your board? 

  • Hi,

    yes it is connected to GND and I can measure analouge signals on the MCU RX pin

  • Hi Sam,

    Since the SCI2 is receiving data from microUSB port, can you use SCI1 to interface with SN65HVD73 the your sensor?

    When three devices are connected to UART signal lines, even if the slave at microUSB is not transmitting, it is outputting an idle state onto the line. The sensor and device on microUSB will fight each other as one tries to transmit and another tries to hold the line in idle.

    If MCU SCI2 wants to receive data from your sensor, you need to disable the UART TX from micoUSB. The TM4C129 device on launchpad acts as a UART transceiver for SCI2, but it's driver doesn't provide command for use to put the TX disable in high impedance. 

  • Dear Wang,

    I don't use an evaluation board. I use the TMS570LS0714 (PZ package) on our own design.
    You said in another case, that the SCI1 is not supported on this package:


    e2e.ti.com/.../tms570ls0714-tms570ls0714---sci2-rx-interrupt-handling

    We are using the JTAG pins for programming the MCU but this should not have an impact?...


  • Yes, the TMS570LS0714PZ has only 1 SCI module. Is this SCI only used for interfacing your sensor through a transceiver?

    Using JTAG doesn't impact the SCI.

  • Yes, this SCI is only used for this sensor.

    Could you please have a look on the baud rate settings (HalCodGen) as shown above. I use 921600 as the SCI Baudrate because it is the sensor baudrate.

  • The 1.7% baud-rate difference should be fine. 

    You can adjust the baudrate by changing the VCLK. If PLL=177MHz, you can get 921875Hz of baudrate.

  • It is noted in HalCoGen that your suggested PLL of 177MHz is too high, please see below.
    I therefore changed the settings to (0.07%):


    But no improvement.

    Can it be that the SCI Baud Clock must be 8 times higher than the baud rate of the sensor? When I look on page 10 in "TMS470R1x Serial Communication
    Interface (SCI) Reference Guide" I can see that each bit is sampled by 8 SCI baud clock periods:



  • Dear Wang

    I have a possible hint to find the problem. I measured the ECLK output pin with an external scope.
    I connected the oscillator frequency of 16Mhz with a divider of 8 to the ECLK pin. From this, I expect to measure a frequency of 2MHz. However, I measured a frequency of 2.5MHz. Could it be that the internal clock/oscillator is not working healthy?

    I also generated an RTI interrupt and toggled an output pin. The setting was 10 Hz and 100 Hz. I measured at the toggle pin 6.25Hz and 62.5Hz. It seems like there is a deterministic error of one internal clock.

    I use as an external clock signal the following device (20MHz): DSC1003DL5-020.0000
    connected as:


    Do I need to change the Crystal Freq. from 16MHz to 20Mhz (red box)?
    What happens when I dont connect the external 1 clock (black box)?


  • For TMS570 devices, each SCI data bit has a duration of 16 vclk periods. This means that the VCLK has to be at least 16 times of SCI baudrate.

  • Do I need to change the Crystal Freq. from 16MHz to 20Mhz (red box)?
    What happens when I dont connect the external 1 clock (black box)?

    Yes, you need to change the crystal frequency accordingly.

    The external clock 1 (black box) means the clock is from the external clock input #1 (pin 10 on PZ package).

  • Please change the crystal frequency to 20.0 in the read box:

  • The problem was the wrong setting of the crystal Freq. I receive the expected data stream after I changed the crystal frequency from the standard configuration of 16MHz to 20MHz of the external clock. Thank you for the support!