Jump to content
  • 0

UART


zahid

Question

Hello everyone

I am currently working on a fpga UART code I can Transmit and Receive a single byte from pc and board.but when I send string of data I skip alternate bytes.

like suppose I send 123 then at receiver I get 13. if I send 12345 then I receive 135 and so on.i have used this site code.http://fpga4fun.com/SerialInterface.html any suggestion please.

Link to comment
Share on other sites

24 answers to this question

Recommended Posts

@zahid,

Yeah, ... but ... we still haven't solved your original problem--that of receiving every other letter when you pipe things directly from the GPS to your computer.  But, at least now, we know some new things:

  1. We know that your computer isn't broken, neither is the serial port or terminal on it, and the cable you are using appears to be good then.
  2. We know there are no foreign character set issues, such as things that take 2 characters to print one.
  3. We know that it can successfully receive at 9600 Baud.  (We're you trying with the extra stop bit, or not?

So, the question now is, what happened and what can we do to fix it?

Here's my thought: when you used the echo test program to read from your GPS device, we rounded the number of baud clocks downward (as the spec suggests).  The result, though, was that the receiver--which calibrates its input to the start bit of each character, was receiving the characters in just a couple clocks fewer than the transmitter was using.  The result, then, was that when the receiver was done with the second character -- the transmitter was still transmitting the last one.  The receiver strobes the line for the transmitter to start (i_wr inside txuart.v), but the transmitter is still busy ... so it ignores the write request.  By the time the next byte is received, the transmitter is now idle and ready to accept the next request.  As a result, you got what you saw above: every other character received.  The problem was in your FPGA code, and not within your host.

Suppose we test this? 

  1. If you want to go back to your echo test and try again, then try setting the i_setup register to one or two clocks faster.
  2. When I personally ran the test to echo what was received from the GPS receiver to the PC/host (I haven't posted the code for this), I switched the line speed from 9600 Baud up to 115,200 Baud or faster, such as 1MBaud.  At this high speed, you wouldn't have a problem.  To do this, you'd need to set the setup register on the transmitter (txuart) for 115,200 Baud and that on the receiver (rxuart) for 9600 Baud--you'd also set your PC for the 115,200 Baud.
  3. Another possibility might be to try the line testing program.  This one should manage to do large strings without losing anything, but I expect it would still struggle after a long series of things were received--only to recover by the top of the next second.

So, at this point, I think we know what's going on and can move forward successfully.  Feel free to tell me how any of these new tests work!

Dan

Link to comment
Share on other sites

@zahid,

I managed to recreate your problem, and found this thread to describe it and a solution.  According to that thread, ISE can't handle hex files when using readmemh.

So ... let's try this instead:  Replace the initial section that sets speechfifo.v with either

`include "speech.inc"

or with the contents of speech.inc.  (Attached)  And let me know if that gets you any closer.

Dan

speech.inc

Link to comment
Share on other sites

@D@n

i have past it in bench/verilog and now it say

INFO:Xst:2546 - "../../fyp project/wbuart32-master/bench/verilog/speechfifo.v" line 105: reading initialization file "speech.hex".
ERROR:Xst:2352 - "../../fyp project/wbuart32-master/bench/verilog/speechfifo.v" line 105: Address -1 found at line 1 is invalid in call of system task $readmemh.

Link to comment
Share on other sites

@zahid,

Ok, I just adjusted the master repository so the next person won't have to copy speech.hex into bench/verilog.  Sorry about that.

As for the for loop condition ... the error makes no sense to me.  I'm not sure what's causing it.  The design should be robust enough that you can kill the for loop without any consequences.  In the worst case, it'll output garbage at the end of the known text.

I've tried importing speech.hex, adding it to my project file, etc.  It seems the only thing Vivado understands is to have it within the same directory.  I just remembered, though, you are using ISE aren't you?  I haven't built this with ISE, only Vivado and yosys.  It should work just fine, but we may have to adjust things so ISE can find the speech.hex file.

FYI: speech.hex is a hex file representation of bench/cpp/speech.txt.  The mkspeech program in bench/cpp is a simple C++ program (really a C program in a C++ wrapper) that converts speech.txt into a hex file.  The file is then ingested into speechfifo.v via the $readmemh("speech.hex", message); command.

Dan

 

Link to comment
Share on other sites

@zahid,

Speech hex is made by running "make speech.hex" in the bench/cpp directory.  If you ran "make" in the main directory, then you'll find it built for you in the bench/cpp directory.  It's placed there because Verilator wants in there, but sadly Vivado can't find it there.  Go ahead and build it and then copy it to bench/verilog and Vivado should then have no problem finding it.

Dan

Link to comment
Share on other sites

@D@n

I appreciates your efforts. i tried to use speechfifo which require wbuart (rxuart,txuart,ufifo) files, which i added am i right? then i changed the i_setup as you said.now when i synthesis the program i get this error

Analyzing top module <speechfifo>.
ERROR:Xst:1918 - "speechfifo.v" line 78: Unable to find file "speech.hex".
ERROR:Xst:2634 - "speechfifo.v" line 79: For loop stop condition should depend on loop variable or be static.

 

i was also thinking from where speechfifo will recieve data as defined in a code reg    [7:0]    message [0:2047]; keep data.but how?will i have to import file like speech.hex?

Link to comment
Share on other sites

@zahid,

Okay, now you've answered my question, and now I'm scratching my head.  That's not what's happened here for similar tests.  So, let's think of what we know:

  1. You appear to have a problem receiving many bytes in succession.
  2. When you forced your transmitter to use two stop bits, things (sometimes) worked
  3. You are using code that works just fine on my computer.

This leaves us with a couple of possible problems still to work through:

  1. It is possible you have your windows machine set up to work with a foreign character set, and that your terminal is trying to compose two bytes into one display character
  2. It is also possible that you have a subtle difference of clocks--such as perhaps your 50MHz Nexys clock isn't quite at the speed you think it's at, or perhaps the one on your CPU isn't at the speed it thinks it's at, etc.
  3. It's also possible that you don't have the right serial port driver.  Do you have some other serial port hardware to try this on?  Does your other hardware have the same problem?

Let's try chasing #2 down for a bit.  Suppose we have you ignore the GPS PMod for a bit, and try and get something like this running instead--just trying to isolate our problem down.  If nothing else, that'll reduce the number of clock differences we might need to track down from 3 clocks (GPS, FPGA, PC) down to two (FPGA, PC).  Use that SpeechFifo.v as a first program, let's try a couple of setups:

  1. If you set the setup register to 30'h8001458 (the same number, but plus 0x08000000 or two stop bits).  This'll give your PC an extra stop bit while reading things, and prove that it's not the foreign character set at fault.  Indeed, it may prove that the problem is a subtle clock difference problem--such as perhaps the GPS UART is transmitting slightly faster than the PC is ready to read ...
  2. You can also try 30'd5208 or 30'd5209 ... although I'm not expecting much of a difference by doing that, it's still worth trying.

Does this make any sense?

Dan

Link to comment
Share on other sites

@zahid,

That's almost what I was asking, there's one more piece: To receive it on the PC, you need to use a terminal program ... right?  How do you have the serial port set up via that terminal program?  Is that serial port program set up to use one stop bit and no parity bits?

Dan

Link to comment
Share on other sites

@zahid,

Yeah, yeah, but ... that's not my question.  My question is how you have your PC's terminal setup?  Do you have your device plugged into a PC?  Windows?  Linux?  Something else?  Either way, what are the serial port parameters of that connection?

Dan

Link to comment
Share on other sites

when i was passing string (more than one char) if i use 1 stop it skip as same as i said but by selecting 2 stop bit i get full string but when iuse gpsthen even on two stop bit i get result i showed.

i set two stopbit

noparity,8databit

i_setup=5208 because 9600 baud and 50mhz

 

Link to comment
Share on other sites

Hello Sir @D@n i used the code of rxuart and txuart with top module of echotest you provide in link.now i can pass the string from Pc to fpga and receving whole string back thats great.but when i connect gps and try to receive Nmea sentence that gps through and want to see them on pc i still get same issue this is what i receive.

NB:Gps is not fix at this time

$PT,.0T,,.0N00,,*2$PG,08079,,00,M,,*7GGAA1,,,,,,,*EGRC011.9,,,,.000,610,N4
$PT,.0T,,.0N00,,*2$PG,08179,,00,M,,*6GGAA1,,,,,,,*EGRC011.9,,,,.000,610,N4
$PT,.0T,,.0N00,,*2$PG,08279,,00,M,,*5GGAA1,,,,,,,*EGRC011.9,,,,.000,610,N4
$PT,.0T,,.0N00,,*2$PG,08379,,00,M,,*4GGAA1,,,,,,,*EGGV110*9GRC011.9,,,,.000,610,N4
$PT,.0T,,.0N00,,*2$PG,08479,,00,M,,*3GGAA1,,,,,,,*EGRC011.9,,,,.000,610,N4
$PT,.0T,,.0N00,,*2$PG,08579,,00,M,,*2GGAA1,,,,,,,*EGRC011.9,,,,.000,610,N4
$PT,.0T,,.0N00,,*2$PG,08679,,00,M,,*1GGAA1,,,,,,,*EGRC011.9,,,,.000,610,N4

Link to comment
Share on other sites

You might consider this project.  It is one I know and can speak to.  I know, for example, that this file when used as a top-level not only works, but also broadcasts a long speech with no breaks between the characters.  You will need to change the setup register to 30'd434 if you wish to get 115200 baud out from a 50MHz clock.

If you only get some characters through while using this approach, then the problem is on the receiving end.

Dan

Link to comment
Share on other sites

thanks @artvvb for reply yeah i changed the ClkFrequecy to 50000000(50 Mhz) my board nexys 2 frequency. and also applied the chanes ypu mentioned but still i m facing same problem but one thing i have noticed that when i choose two stop bit on terminal then sometime it receive complete string but not all the time.

Link to comment
Share on other sites

Specifically, I used their serialGPIO example with the async.v file imported into my vivado project. For the Basys3's 100MHz clock, I changed the module instantiations from:

async_receiver RX(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));

async_transmitter TX(.clk(clk), .TxD(TxD), .TxD_start(RxD_data_ready), .TxD_data(GPin));

to:

async_receiver #(
    .ClkFrequency(100000000)
) RX (
    .clk(clk),
    .RxD(RxD),
    .RxD_data_ready(RxD_data_ready),
    .RxD_data(RxD_data)
);

async_transmitter #(
    .ClkFrequency(100000000)
) TX (
    .clk(clk),
    .TxD(TxD),
    .TxD_start(RxD_data_ready),
    .TxD_data(GPin)
);

Edit: I also tied the GPout and GPin ports to leds and switches in my xdc file.

Hope this helps,

Arthur

Link to comment
Share on other sites

Hi @zahid,

Did you update the ClkFrequency parameter in the transmitter and receiver modules to reflect the actual clock rate of your board? Also, which board are you using? I ran through the tutorial with a Basys 3, and the only modifications I had to do to make it work was to change the ClkFrequency to 100000000 (100MHz).

Hope this helps,

Arthur

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...