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.

SCI RX Interrupt on TMS570LC43

Hi,

I am trying to receive data from the SCI1 on TMS570LC43. I generated the code using Halcogen setting:

1- SCI1 Driver

2- VIM channel 13

3- The SCI port as follows:

4- Interrupts as follows:

A portion of my code:


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


_enable_IRQ();
 

  sciInit();

sciEnableNotification(UART, SCI_RX_INT);

while(1){

sciReceive(UART, 1, (u8 *)&RX_DATA);

}

}

RX_DATA will be the content of my received data which for now is just one byte. In the final application will be a telegram with a specific protocol format.
At each received byte I would like an interrupt to be generated and consequently the function:

void sciNotification(sciBASE_t *sci, unsigned flags)

to be called. The sciNotification will contain a state machine that allows me to control what to do with each received byte. 

Currently The sciNotification is never called.

How to solve this? What am I missing?

Thank you in advance.

Regards.

Gabriele

  • Hi Gabriele,

     I think you are repeating the same screenshot for #3 and #4. Below are what I would expect in the HalCoGen setting as far as SCI1 interrupt is concerned.

     1. Enable SCI RX interrupt.

      2. Make sure the TX/RX pins are in functional mode, not GIO mode.

      3. enable VIM channel 13 since LIN1 is used in SCI mode.

      

      

      Also who is transmitting the data? Make sure both transmitter and receiver have the same baudrate and data format. If you use the scope do you see the RX pin activity?

  • Hi Charles,

    thank you for your reply. You are right I made a mistake while attaching the screenshot, sorry for that. But the setup is exactly like your. Except I don't have the channel 2 connected in the VIM channels. Should I connect it?

    Regards,

    Gabriele
  • If I connect it I get the following error:

    undefined first referenced
    symbol in file
    --------- ----------------
    rtiCompare0Interrupt ./source/HL_sys_vim.obj

    error #10234-D: unresolved symbols remain

    error #10010: errors encountered during linking; "uart.out" not built
    >> Compilation failure
    makefile:158: recipe for target 'uart.out' failed
    gmake: *** [uart.out] Error 1
    gmake: Target 'all' not remade because of errors.

    I am not sure what is required to get the function sciNotification called at data reception.
    Currently I am not sending the data from an outside source. I am passing the test data byte per byte to the sciReceive function. My target it to trigger the interrupt in that way and then process the data in the sciNotification.
    Regards,

    Gabriele
  • Gabriele,
    No, you do not need to enable RTI. It was my mistake. I tried to use one of my existing HalCoGen projects that already has the RTI interrupt enabled.
    I don't understand what you meant by passing the test data to the sciReceive function. sciReceive() is what you would have used in the sciNotification if you get an RX interrupt to read out the received data. The SCI kernel/statemachine needs to detect a valid message per UART protocol (i.e. start bit, data, parity, stop bits) and upon the completion the received data will be moved from the shift register to the receiver buffer. Once the data is copied to the received buffer an RX interrupt is generated to the VIM module. From the VIM, the interrupt request is then raised to the CPU. When CPU is interrupted it will then jump to the sciNotification.

    You can connect the SCI1 to the hyperterminal on your PC and use the terminal to input the character for the SCI1 to receive.
  • Hi Charles,

    thank you. I probably confused the use of the sciReceive(). Is it possible to test the SCI RX in loopback?
    I would like to send data from the hercules SCI TX and have it available in the receive buffer of the same device.
    Could you please advise how to do it?
    Regards,

    Gabriele
  • Hi Gabriele,

    We don't have a readily available SCI example in loopback using interrupt mode. But you can first reference the the example_sci_uart_9600.c by going to HalCoGen->Help->Help Topics->Examples.

    Or you can just continue with the SCI project you have already built. You just need to call the sciEnableLoopback() to enable the loopback mode. Call the sciSendByte() to send some data on the TX pin. You should see an interrupt generated for the RX since you are receiving the data from the TX in loopback mode.
  • Hi Charles,

    thank you very much for your reply I will test my sw in loopback mode.

    Best Regards,

    Gabriele

  • Hi,

    I still cannot receive the data in the XR line in loopback. Now the sciNotification is called though but if I call the sciReceive() nothing is written in the rx_data buffer:

    Below the code:

    void main(void)
    {
    /* USER CODE BEGIN (3) */
    
    
    	_enable_IRQ();
    	sciInit();
    
    
    
        sciEnableNotification(UART, SCI_TX_INT);
        sciEnableLoopback(UART, Digital_Lbk);
    
        int i;
        for(i = 0 ; i < 12; i++)
        {sciSend(UART, 1 , (u8 *)&test_telegram[i]);}
    
         while(1){
          
         }
    /* USER CODE END */
    }
    
    /* USER CODE BEGIN (4) */
    void sciNotification(sciBASE_t *sci, unsigned flags)
    {
        printf("Receiving data:\n");
    	sciReceive(UART, 1, (u8 *)&RX_DATA);
        
         /* do something with data */
    }
    
    

    The RX_DATA is always empty.

    What is wrong with my code?

    Thank you for your advise.

    Regards,

    Gabriele

  • Hi Gabriele,

     I suspect it is cache related.

     In HalCoGen under the R5-MPU-PMU tab, can you change to write through cache like below? Let me know if it makes a difference.

  • Hi Charles,

    still the same behaviour, again sciNotification is called but no data is pointed by RX_DATA.
    I also tried to remove the loop and get just one byte (the first), no luck :(

    Gabriele
  • I think I am having the same problem as here:

    e2e.ti.com/.../432292

    But don't know how it can be solved.

    Could you please advise the solution?

    Thank you?

    Regards,

    Gabriele
  • Hi Gabriele,

     I created a simple project in SCI loopback mode. The transmitter sends a string "HERCULES.." and the receiver is able to receive the entire message in the pointer RECEIVE_DATA. The receiver is in interrupt mode. See if you can take from here. 

    8664.LC4357_SCI_LoopBack.zip

  • Hi Charles,

    thank you for the application you sent, it clarifies the use of the functions. I successfully developed an application that "sniffs" telegrams according to a specific protocol and stores them.

    It works but still I am not totally convinced on how to use the sciReceive function here is my code:

    void main(void)
    {
    /* USER CODE BEGIN (3) */
    
    	_enable_IRQ_interrupt_();
    
        sciInit();      /* initialize sci/sci-lin    */
                        /* even parity , 2 stop bits */
    
    
        sciEnableLoopback(UART, Digital_Lbk);
    //    UART->GCR1 |= 0x010000; // Enable loopback
    
    
    
    
       sciReceive(UART,1,&RX_DATA );
    
       while(1)
       {
    	   
    
        for(i=0; i < TSIZE1 ; i++)        /* simulates sending a telegram      */
        {
        	sendData(UART, &TEXT1[i], 1); // sends a whole telegram
    
        	printf("Sending Data: %02x\n", TEXT1[i]);
    
        	wait(200);
    
       	   sciReceive(UART,1,&RX_DATA );
    
           elaboratesTelegram();
    
         }
    
        
       }
    /* USER CODE END */
    }
    

    In particular I don't understand why I need to use two sciReceive() functions. If I just leave the first call it doesn't work (but it works if I take a complete telegram instead of 1 single byte), while adding the second after the while it works like a charm?

    What is the use of the first call and why is before the sciSend? 

    Another question: why you use _enable_IRQ_Interrupt() instead of _enable_IRQ()?

    Thank you very much.

    Regards,

    Gabriele

  • Hi Gabriele,

     Let me explain but if it is still not clear I will suggest that you spend a bit of time on lin1HighLevelInterrupt() and sciReceive() functions in the HL_sci.c file.

        case 11U:
            /* receive */
            byte = (uint8)(sciREG1->RD & 0x000000FFU);
    
                if (g_sciTransfer_t[0U].rx_length > 0U)
                {
                    *g_sciTransfer_t[0U].rx_data = byte;
                    g_sciTransfer_t[0U].rx_data++;
                    
                    g_sciTransfer_t[0U].rx_length--;
                    if (g_sciTransfer_t[0U].rx_length == 0U)
                    {
                        sciNotification(sciREG1, (uint32)SCI_RX_INT);
                    }
                }
            
            break;

    If you look at the above code snippet which is part of the  lin1HighLevelInterrupt() you see that when you get a receive interrupt it will check for the rx_length > 0. The rx_length was first setup when you called the first sciRecieve(). Since you are in interrupt mode, the first time you called the sciReceive() it simply prepares the g_sciTransfer_t telling where to receive the data and how long the message is. It then immediately jumps out.

      Since in the first call the sciRecieve() the length is set to 1 then after you receive the first character in the telegram the length is decremented to 0 and the subsequent characters in the telegram are not stored to the data pointer rx_data anymore. This is the reason why leaving only the first sciReceive will not work for the entire telegram if you specify the length to be 1.

      As you keep calling the sciReceive() in the while loop, each time you send a character the receiver generates an RX interrupt to receive that character. This is why it works. 

  • Hi Charles,

    thank you for the explanation now is clear and working properly. Problem solved.

    Best Regards,

    Gabriele
  • Glad it is clear to you now!