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.

Problem while working with UART Receive and transmit together on C6747

Hi
I'm developing a UART driver for the C6747.
When Working with the Tx and the Rx alone, All is well.
When Working with both the channels together, I get 2 kinds of errors :
1.Some of the Bytes I send into the DSP (My Rx Channel) get lost on the way and dont find their way into the Rx FIFO
2.as the number of lost bytes in the RX Fifo, I get Unidentifyed interrupts,
That means interrupts with an ID of "000" written in the IIR.

It works Like so:
1.TX :
I have a task with high priority which Sends 1 byte by writing to the THR Register.
 CSL_FINS(BSW_t_Uart2Regs->THR, UART_THR_DATA, pu8_DataSource[u16_ReadIndex]);
I'm writing to this register only After I made sure that the TX Fifo and the Tx Shift Register is empty
 CSL_FEXT(BSW_t_Uart2Regs->LSR, UART_LSR_TEMT) == CSL_UART_LSR_TEMT_EMPTY

2.RX :
I configured the BIOS to give me an interrupt incase there is 1 byte waiting in the Rx Fifo.
Once the byte had arrived, my ISR Goes to the IIR Register to identify which interrupt was it
If the interrupt was an "Threshold Reached" or "Byte in fifo Time out", I go and read the Rx Fifo
For All the bytes that are in there
 while(CSL_FEXT(BSW_t_Uart2Regs->LSR, UART_LSR_DR) == CSL_UART_LSR_DR_READY)
 {
  pu8_RecBuffer[u16_WriteIndex] = CSL_FEXT(BSW_t_Uart2Regs->RBR, UART_RBR_DATA);
 }
 


For Example :
I'm writing 200 bytes into the Rx Channel while I'm randomly writing data out of my Tx channel.
I get 200 interrupts, lets say 198 of them are "Data Ready" interrupts and 2 of them come with "000" in the IIR register.

Any Ideas?
Yoav 

  • Hello,

    I used FIFO mode for both transmit and receive. In order to minimize collisions I used EDMA3 to read data from FIFO to memory, i.e I get interrupt after 8 bytes received and copied into desired memory location. It works in my program. I suggest you try this.

    Regards

    Arye.

  • hi, Sorry for the delayed responce

    Anyway, We had some issues with the EDMA3 as well...Thats why we tried not to use it.

    Did you use the PSP drivers for the EDMA3? or have you written something from scratch (using the CSL).

    Yoav

     

  • Hello Yoav,

    No, I used LLD (LOW LEVEL DRIVER) for EDMA3 - it is a little bit combersome, for my application at least, so I simplified it. But it is working great.

    You can download it, if you look for them in the TI site. The only problem I have (and I am not sure its is related to LLD) is that I cant use ECM Dispatcher. If this is not a problem for You, I can help You to bring it up.

    Regards

    Arye

  • Hi Arye,

    Before I'm diving into the LLD for the EDMA3, I just wanted to ask you a few things
    1.When you wrote "minimize collisions", you meant that you also experienced any issues like the ones I did? (interrupts with ID 0x0, loosing bytes in the receive channel while trying to receive and transmit simultaneously)

    2.when you work with the "hEdma" handler, Did you successfully manage to use more then one channel with the same entity of "hEdma"?

    Thanks,

    Yoav

     

     

  • HelloYoav,

    When I wrote 'minimize collisions', I ment I didn't experienced them at all, but I cannot guarantee that it would not happen. I use C6747 @ 300MHz, and the usart parameters are is: UART2, 115200,8,none,1

    I is not required in my case to have a full duplex comunication (i.e. when there is a data transmitted, simultaneously it will be received), but when I was debugging the project I saw that it happens a lot and not causing any problems.

    I think that in my configuration, the collisions is a subject to a FIFO length: I use 8 byte trigger level, i.e I must ne able to process data every 48 bit time period (a fifo is 14 byte long) so as long as you keep that in mind, no collisions should happen.

    In my project I've opened 3 EDMA channels on one hEdma enity: one for receive, one for transmit and another one for data transfer (my application).

    The things You need to do for that is:

    • Initialize the entity by using edma3init(). I didn't changed this function.
    •  Open channels using that hdma: EDMA3_DRV_requestChannel (hEdma, &ch1Id, &tcc1,(EDMA3_RM_EventQueue)0,&callback1, NULL); Note that ch1id is the name of your channel, connected to certain peripheral - You cannot use just any channel - see device specific data-sheet for it. In C6747, for example UART2 Transmit channel is 31, UART2 receive is 30, just data transfer - 16 or 17, etc.... tcc You can set same as channel parameter if you are not using chaining.
    • callback is an interrupt handler for the channel. The problem that there is only two of them : callback1 and callback2. if you need more, just find the function declarations in LLD (or/and copy the file in your project) and duplicate them for more channels.
    • You can modify all the parameter set functions - they are really useless, all they do is put values in PaRAM set, and all the rest is a debug warning messages. You can use the macros they use in those functions instead.
    • There are some variable I suggest You make global in your project: look for them in the driver's code:
    1. globalRegs - all registers map - is usefull if you want to modify functions by yourself.
    2. hEdma - You allready know it.
    3. EdmaCCRegs - EDMA register's map.
    4. sampleEdma3GblCfgParams, edma3DrvChBoundRes - Those variables are nesserary for most edma functions, they are pointing to PaRAM set arrays. Just declared them (using extern) if you dont want to modify them.

     

    Write if You will have a problem/questions.

    Regards

    Arye

     

  • Thanks, I'll try it.

    anyway, I'm not sure that this is the issue in my case because as I see it, my problem begins before I start reading bytes from the RBR.
    We kind of  isolated the problem with the parallelism of Data arriving to the Receive buffer (Async action) and an attempt to send data by writing to the THR (i.e. the data is lost on arrival due to a collision with a Tx operation and not when trying to read it).

    But using the LLD is still worth a shot
    in the mean time,
    Yoav

     

  • Hi,

    I read the forum history, You siad that the trigger level You are using is one byte, i.e each byte You get an interrupt.

    Is it possible that You dont have enougth time to proccess an interrupt, espessialy when You are transmitting simultaneously? Can it be that You receive an interrupt when interrupt flag is not yet cleared? This way it is possible that You get missing bytes. I'll suggest you raise a trigger level to, for example 8, and see if the lost-to-received bytes ratio has changed. This will give you some indication.

    Regards

    Arye

    P.S. what is the baud rate you are using and what is the clock speed?

     

  • Hi,


    I already tried 8 bytes threshold, and 14...It only made the problem worst (I lost more bytes and got more of these bad interrupts).
    In addition, when I'm receiving an interrupt, I dont leave the ISR until I clear all pending interrupts (I'm polling on the IIR[0] pending bit) So I dont think I'm missing an interrupt.

    I also tried to collect bytes regardless of the interrupt arriving and every time that I collected data when an unidentified interrupt arrived, I collected garbage (an old byte that was in the fifo)

    I'm working with 115200, but I tried lowering the baudrate and it didnt make a difference

    Any other thoughts? Ideas? I can really use them.

    Thanks again,

    Yoav

  • Hello Yoav,

    I tried to perform the fullduplex test with UART2 @ 115200bps and it does not shows any problem. This is what I've done:

    This is a software algorithm:

    SWI_disable();
     for(i=0;i<15;i++)
      DEBUG_test_chars1[i] = i+0x10;
     
    memset(DEBUG_test_chars2,0,13);
     while(1)
     {
      EVMOMAPL137_UART_putString( ARM_uart_handle, (unsigned char*)DEBUG_test_chars1 , 16);
      EVMOMAPL137_UART_getString( ARM_uart_handle, (unsigned char*)(DEBUG_test_chars2) , 13);
      if(strncmp(DEBUG_test_chars2,"THISISTESTSTR",13)) break;
     }

    The UART is configured to 14-byte trigger level.

    I use two arrays: DEBUG_test_chars1 for transmit, and DEBUG_test_chars2 for receive. The functions are of OMAPL137 evm of spectrum digital. This is same as C6747 only with ARM module on it, which I dont use.

    I used Docklight terminal program to simulate simultaneously reseive and transmit (You can use TeraTerm to do the same):

    The Docklight  sends ASCII string "THISISTESTSTR" upon reception of first byte that the software sends which is 0x10. So it appears that transmission and reception is performed similtaneously. In case it does not receives the expected string, it quits the loop. It appears that this does not happens after ~1000 runs, that means 1000*13=13000 bytes are sent and received OK.

    I am not using EDMA in this example, there is no need for this demonstration, but if you will add EDMA here this would not change the result. It may not look like a full duplex, since both of those functions use loops to read a data from FIFOs, but the actual TX/RX is performed simultaneously. I guess that this happens because the FIFO keeps operating regardless of CPU. In case You know exact amount of bytes You are to receive, the full duplex cam be simulated perfectly.

    If this demonstration answers the requirements of your project, I suggest You try to use this algorithm as is, just to check if this will work in your project, so you will have a starting point for solving the problem.

    Regards

    Arye