This driver fixes three existing issues with the Nios Altera Avalon JTAG UART driver.
(Fast driver) Under certain conditions the driver returns erro code -EIO when it should not which convinces the "C" library that the device is unavailible so it never tries to talk to it again.
(Fast driver) If a nios2-terminal ( or equivalent ) has been unavailble for more than 10 seconds the driver may return -EIO causing the "C" library to never try to talk to the uart again.
(small driver) if you don't have a nios2-terminal (or equivalent) and you are using the small driver, you r code will look like it is hung.
This issue occurs when you are using a HAL based OS like UCOSII or ThreadX, FreeRTOS and you are using the fast driver for the JTAG UART. This is the problematic line of code
if (out == sp->tx_out)
it occurs right after a ALT_FLAG_PEND request.
This is a test to see if there is any space in the tx circular buffer. The thinking is if the ALT_JTAG_UART_WRITE_RDY is set there should be room in the circular buffer. Normally this works fine. If there is no new space it assumes that the ALT_FLAG_PEND terminated with a ALT_JATG_UART_TIMEOUT so it returns a –EIO and the stdio library assumes this connection is broken and will never send to it again. ( What is funny is, this is on a thread by thread bases and if one thread printf is now disabled it does not mean the others are disabled.
HOWEVER another situation can cause “out == sp->tx_out”
Problematic scenario —
If printf is called and it has more data than the circular buffer can handle. And if before printf was called ( or shortly after) the JTAG UART interrupt fired off with the tx interrupt. Then the ALT_JTAG_UART_WRITE_RDY flag would be set.
As the altera_avalon_jtag_uart_write function starts executing it will fill the tx circular buffer full -- so “out == sp->tx_out” -- and there are still more chars to be place in the buffer when space is available.
When the code reaches the ALT_FLAG_PEND call it will immediately return because the ALT_JTAG_UART_WRITE_RDY flag was previously set. However “out == sp->tx_out” is still true causing the return of –EIO which disables the use of the jtag uart at the stdiolib level. ( you can actually clear this, by issuing the clearerr(fp) from somewhere in the thread but I haven’t been able to find the fp ( file pointer ) that printf uses).
You could clear the FLAGs when you first enter the write function – but you still have a race condition between the clear and setting of the variable out, unless you create a critical section. This turns out to be unnecessary overhead.
In reality we should not be checking for “out== sp->tx_out” at all.
What we need to check is
if (sp->host_inactive)//<- this is correct.
After all we are just looking for an escape route if we find the jtag uart is no longer connected to a host. This works in the non threaded cases as well. Because if we haven’t timed out (host_inactive) we have to continue to wait for the tx circular buffer to become available.
If the driver evere issues a -EIO stdio libraries will never try to communicate with the driver again. So it is just a metter of making sure that happens. The a nios2-terminal is not availible, instead of return -EIO just dump the data and return the number of bytes to be written. Now whenever the nios 2 -terminal is connected. Some old data will be flushed out and then new data will flow out of the jtag uart.
If you are using the small driver and no nios2-teminal is attached, once the tx fifo is full the code will wait in a tight loop for more space to become availible. The effect is it looks like your code is hung, until a nios2-terminal is attached. At shich point the code run normally. To fix this we hae to provide a timout feature to the small uart. So this driver includes a timeout. It will try 1000 times before determining that the JTAG uart is unavailible.
If you are using the fast driver and the same thing happens you probably do not have a system timer defined. Your best bet is to add one.
These files were tested with 11.0 but shoudl work with any version.
replace the driver files for the altera_avalon_jtag_uart which these in the component.
If you are using the fast driver you only need to copy the included .c file into your application project.