Uart16550 can't receive data over 16byte a time

I send 50 bytes character to serial port of UART1655 in FPGA Board,But only the first 16 bytes of received data is correct in turn, and the left is out of order,what is the matter?

thanks for your help!!!

Reply to
ARRON
Loading thread data ...

the first 16 bytes of received data is correct in turn, and the left is out of order,what is the matter?

Do you read the characters as they're received or wait until all 50 are sent?

I'm assuming the UART1655 is a core in the FPGA; this is probably implemented with a simple 16 byte FIFO beacause the software is expected to service the characters as they're received without extreme latency; if nothing else, a high priority service when the FULL flag is set if the low priority service for partial fill (or single characters) haven't been serviced.

If you need a larger receive buffer, it can be done but I don't know if you have access to the UART1655 source code. If you do, (assuming Xilinx:) the 16-byte SRL16 style FIFO can be changed to a 2 kByte BlockRAM to have more storage.

Reply to
John_H

first 16 bytes of received data is correct in turn, and the left is out of order,what is the matter?

--
 __
/ /\/\ Aurelian Lazarut
\ \  / System Verification Engineer
/ /  \ Xilinx Ireland
\_\/\/
 
phone:	353 01 4032639
fax:	353 01 4640324
Reply to
Aurelian Lazarut

Generally speaking.. by the time you get fifo-full.. its too late... 1/2 full is a better option

Simon

only the first 16 bytes of received data is correct in turn, and the left is out of order,what is the matter?

Reply to
Simon Peacock

Can UART16550 receive only 16bytes a time, if so, how long should the next receive wait after the first receive? how can i receive the data without losting? I think the FIFO will never be full,when you receive the data from FIFO, it is right?

Reply to
ARRON

receive wait after the first receive? how can i receive the data without losting? I think the FIFO will never be full,when you receive the data from FIFO, it is right?

If you are responsible for wrapping sandwiches prepared by a cook and handing them off to the person who packs bagged lunches...

You wrap each sandwich and put it on the table in front of you but your table space is limited.

The bag packer takes the sandwiches from the table one at a time but can take several within the time it takes you to wrap one sandwich depending on what else they're doing.

If the bag packer is on a break, you can only wrap so many sandwiches before you run out of table space and have to stop wrapping or start eating the sandwiches.

UARTs are meant to have the characters removed before the FIFO is full (before the table runs out of space). You should have another process which handles your messages to move them out of the UART's FIFO and into local storage or to process them on the fly. You should not expect the simple UART core to give you unlimited buffer size.

Reply to
John_H

Normally, you have to configure the 16550 to generate an interrup when the buffer get to a certain level. I think you have 4 level you can set. For example, if you set an interrupt to occur after th fifo is half-full, this meen that after receiving 8 bytes, you'll ge an interrupt. Then you have a margin of 8 bytes to clear the fifo. Note that if you receive for example only 4 bytes, then, after timeout, an interrupt will be generated so you don't have to worr about data staying lattent in the buffer

The lower you set the threshold, the more interrupts you'll have. Th

higher you set it, less interrupt will occur, so your code will b interrupted less often, however, if your interrupt service routine i too slow, the FIFO may get full. So, the level at which you trigge an interrupt must be set depending on your application. I think tha be default the 16550 won't generate interrupt. You have to configur it, and also configure at which fifo level it will generat interrupt. This is because it will start in compatibility mode wit it's ancestor, the 8250, which could generate an interrupt, but onl after receiving a single byte (had no FIFO). Though not 100% sure

You can always implement a software fifo which is larger than 1

bytes. Then, the interrupt service routine simply fill the fifo while your main code can poll the fifo less often. Just make sur that your code and interrupt routine do handle the fifo correctly s they don't mutually interfere

Reply to
Big Boy

Thanks for everyone's help! I have resolved the problem.In my program, i have inserted the "print("start receive");" sentence, but now i find this statement wastes so much time that i lost many characters in UART16550 FIFO, so i can receive all data wheni delete the statement,thanks for everyone's help!!!!

Reply to
ARRON

That's why the best way to implement is to create an interrupt servic routine (ISR) that respond to the UART

This way, even if you do slow-speed processing, in background, the IS

will respond quickly to the UART

Sooner or later, you may have parts of your code that start takin

more time and have slower response time. Of course, you're the on who know what requirement your application have. If you think tha

16-bytes buffer would be well enough, then no need to trouble wit interrupts ;
Reply to
Big Boy

Another is to re-write the parallel interface to use one of the FPGA internal memories... it can form part of a circular buffer that the ISR would normally use, then you can use it as if there was an ISR doing the work for you. All I am describing is a hardwired ISR of course, but it is something that you will always use :-)

Simon

Reply to
Simon Peacock

Thank you very much!

Reply to
ARRON

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.