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.

UART Read FIFO problems (C6678)

Hello,

I have some problems with the UART of the C6678 (on the EVM, connected to a PC vt100 emulation program). When hte FIFO is disable, everythings seems to works, but when the FIFO is enable (polling mode) and the application generates a continuous flow of output characters, the data read from the FIFO semms to be corrupted.

My program continuosly display on the VT100 a page with the status of the application and, at the end of every display refresh cycle, check for keytstroke so the user can break the refresh by pressing the key 'q'.  The program correctly detect the data-ready, but the charread from the UART is seldom wrong. If I set a breakpoint in the read routine and then I hit the key 'q', I can see that the data read form the UART is wrong. If I hold down the key (repeat), after some senconds the UART returns the good char.

When the TX is idle (console waiting for commands), the input is correctly read and processed.

The speed is 115200, no parity, 1 stop bit, 8 data bits, no flow control. The behaviour doesn't change if I slow down the baud rate.

 

 

 

 

  • Alberto Chessa,

    It confuses me, since application and program are often used to mean the same thing, which is the code that is running on the C6678.

    Can you enable just the TX FIFO, since that data is continuous? This appears to be a case where you would not want to use an RX FIFO because the external source does not send continuous data, but just occasional single chars.

    It is interesting that once you send a lot of 'q' chars, then you are able to read it correctly. Perhaps in this case the FIFO has filled. Try typing individually the 'q' key and see how many much be sent before you get good data.

    When you get bad data, is there a return code that says there is no data present yet?

    Sorry, but this is the best I can do. You have waited a couple of days, and I at least wanted to get something started with you.

    Please let us know what experiments you try and what you find.

    Regards,
    RandyP

  •  

    Yes, I'm sorry: application and program is the same things.

    Anyway maybe the problem regards also the data ready flags from the UART. For instance, the following program that only use the platform library for EVM6678, doesn't break when I hit "x". If I set the second breakpoint, I can see that the platform_uart_read() don't see the Data Ready. So, I try to recompile the uart driver to cache the LSR so to "remember" the DR status bit read during the write operation also (the cached flag is cleared after a read operation): the program detect all the keystroke, but the char extracted form the uart is wrong. Finally, if I disable the fifo everything seems to work.

    #include "platform.h"

    uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment) { return 0;}
    void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes) { }
    void Osal_platformSpiCsEnter(void) {  return; }
    void Osal_platformSpiCsExit (void) { return; }

    volatile unsigned long x_hit, skip_chars;

    unsigned char datum;

    void main(void)
    {

        platform_uart_init();
        platform_uart_set_baudrate(115200);

        for(;;)
        {
            platform_uart_write('.');
            Platform_STATUS sts=platform_uart_read(&datum, 1);
            if (sts==Platform_EOK) 
            {
              if (datum=='x')   /*then, BREAKPOINT 2 HERE*/
              {
                  ++x_hit;                          /* BREAKPOINT 1 HERE !!!! */
                  skip_chars=0;
              }
              else
                ++skip_chars;
            }
        }
    }

  • Alberto Chessa,

    This is not how the FIFO mode is intended to be used. You are doing single char transfers both ways and polling for each char, which is the classic non-FIFO method.

    My suggestion is that if you want to get FIFO mode working, convert your program to use interrupts and get it working that way, which would be more efficient.

    If you are trying to evaluate this feature of the UART to the bit level, you may need to modify some of the functions that are used from the platform and uart source files. That is not an official statement about the drivers, but it would make sense to me that the drivers are intended for char mode and not FIFO mode. What differences there would need to be, I do not know. For using the FIFO in your real application, you would not want to use the code the way your test program does.

    My apologies if this is not of any help.

    Regards,
    RandyP

  •  

    RandyP,

    Regardless the best way to use the FIFO in my scenario, I wonder why the C6678 UART doesn't work as expected (I'm reusing some code that  work without problems on other UART with FIFO). IMHO it should be considered a bug, since the documentation say nothing about such a limitation.

    I agree with you about the interrupts consideration, but unfortunately I have to use it for a non intrusive monitoring of my real-time application: the monitor runs in the lower priority thread and it should never introduce real-time interrupts latency generated by the I/O to the UART.

    With the performance of the C6678 I could migrate to an interrupt FIFO driver, but so far I prefer to disable the FIFO and continue to work in polling. For bulk data transfer, I'll use an interrupt approach (on my final system the Ethernet is not accessible and I have to use the UART to download the code).

    Thanks,

    Alberto

     

  • Alberto Chessa,

    It looks like I am in over my head on this, and I can only offer advice, not answers. Hopefully, someone else will jump in with answers.

    If this is a software problem, then it needs to be addressed in a different forum, the BIOS forum where the PDK is supported. I saw in one copy of platform.c that the read operation will read the data register even if there is an error. This could be a problem for a FIFO implementation, but I have not looked into it more than just looking at a source file snapshot.

    Depending on what you do on the transmit side, the polling code for transmit could be a big problem for interrupt latency. The driver that I looked at (might not be the same as you and might not be the latest) checks the status of the write buffer and waits until it can write successfully. It includes a code delay loop, and that could be very bad for interrupt latency.

    I agree that API calls like you have used should work with any mode, but the drivers may not have been tested with the FIFO enabled. I would recommend that you either close this thread (Verify Answer) and post a new one on the BIOS forum, or reply to ask this thread be moved there.

    If you want low impact, use the EDMA3 to do all of the receive char interaction. It does not look like we have drivers like that, yet. If you write something, please post your successful code to the forum or write a Wiki page.

    Sorry I could not be of more help.

    Regards,
    RandyP

  •  

    In my real sw I'm not using the original driver delivered with the PDK: I took it as a base only and then I rewrite it with wating loops that should not introduce latency in the interrupts. I thought I introduce a sort of bug modifing the original code, so first I look at the UART manual, then I verify for tx/rx erros (no erros at all signaled by the UART), at last I build a simple test program using the PDK libraries to see if the problem is in the UART or in my code (the behaviour is exactly the same).

    Thanks, I'll look to EDMA3 also and I'll post if I'll produce something of usable.

     

     

  • After some month of quatatine, I'm returned on this problem and finally I have discovered that all my problems was due to a bug in the platfrom library (pdk_C6678_1_0_0_12: evmc66x_uart.c):

    1. UartWriteData() use macro CSL_FINS(THR) to write a char, but this macro first read the register, removing a maybe pending received datum, and then write the data (RBR is at same address of THR)

    2. UartInit() use multiple macro CSL_FINS() to setup the FCR, but FCR is write only so the macro first read IIR  and modify it instead of  FCR value.

    After these fixes, the UART works without problems.