sending hex file to atmega using Hardware flow control

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Guys,

I am sending a hex file through a real serial port (not usb adapter)

to my atmega8515. The data gets stored in a very slow I2C eeprom.

 

I have connected the CTS and RTS lines accordingly. The baud rate is 115200.

 

I have tested the code using brays terminal and it works.

Not even one byte of data is lost.

 

Trouble is that Brays terminal locks up and is a real pain to use,

anyone that has used it knows.

 

I tried to use Teraterm, but it seems that the hardware flow control

doesn't seem to work (or maybe it works with pins other than CTS and RTS).

 

If I lower the baud rate it doesn't seem to help much until I get real low (like 9600). 

However, it still loses data.

 

Just wondering if anyone noticed this problem? 

I have searched everywhere for info on this and I have found nothing.

 

I will upload my code in case someone sees a better software solution.

;******************************************************
;**** the names RTS and CTS refer to the PC side
;**** that is RTS on PC = output and RTS on avr = input
;**** CTS on PC = input and CTS on avr = output
;******************************************************
;
;on startup:
    ldi    temp1, 0b00000011    ; PC0 & PC1 (CTS & RTS) high others low
    out    PORTC, temp1           ;          
    ldi    temp1, 0b00000001    ; PC0 (CTS) = output, PC1 (RTS) = input
    out    DDRC, temp1            ; 

Usart_RX:
	cbi    PORTC, CTS   ; signal terminal, Clear To Send

Usart_RX1:
	sbis   UCSRA, RXC   ; wait for receive complete = 1
	rjmp   Usart_RX1    ; reading the USR clears the RXC bit

	sbi    PORTC, CTS   ; return CTS to high state (indicating we are busy!)
	in     temp1, UDR   ; Read Byte in UART Data Register
	ret                 ;
;----------------------------------------------------------
Usart_TX:
	sbis	UCSRA, UDRE	; wait until UDR is empty before sending another byte
				; UDRE (Uart Data Register Empty) will be set
				; when ready to rec'v another byte
	rjmp	Usart_TX

Usart_TX1:
	sbic	PINC, RTS	; wait until terminal brings this pin low
				; when it is ready to Rec'v byte from avr
	rjmp	Usart_TX1

	out	UDR, temp1 	; Send byte in UART data register
	ret

 

The receive routine shuts down the data flow after every byte.

I have found this is the best way.

 

I have tried a usart circular buffer, however it still loses data. 

 

I think the problem is with Teraterm. 

I have tried Putty and others but they lack some the features that Teraterm has.

 

Any ideas would be appreciated.

 

Cheers

 

 

 

Last Edited: Wed. May 1, 2019 - 10:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The receive routine shuts down the data flow after every byte.

I have found this is the best way.

 

I have tried a usart circular buffer, however it still loses data. 

 

I haven't used HW flow control in a long time...

 

I seem to recall, however, that I'd typically use an interrupt driven ring buffer, and then set the water mark at 3/4 full, (or whatever).

You typically don't need to turn on and off the TxData for every byte.

Just stuff your buffer, then stop things while you process the data there within.

When the buffer hits 1/4 full, (or whatever), you re-enable the TxData.

 

That, however, shouldn't make a difference really in the overall operation, if you are really toggling the data flow after every byte.

Have you looked at the serial data, and the handshake lines, on an O'scope to confirm that what you think is taking place is actually occurring?

 

Next question:  What's the rush?

Pre-loading an EEPROM from a PC isn't usually a time critical task.

(If it is, then why are you even using a slow EEPROM as part of the system?)

 

Assuming you can slow the system down a bit, why not put a small delay in between each byte being shipped out of the PC?

(i.e. "Pacing", IIRC)

 

Start with a long pause between bytes, and verify that your data is then arriving and being stored (slowly) completely correctly.

Then shorten up the intra-byte delay.

If you know your EEPROM write time, then you will have a pretty good idea of the optimal delay, to allow the micro to process/write the data to the EEPROM, and have minimal stall time.

 

A project can never have too many LEDs.

 

I recall putting an LED on the ring buffer and/or the RxData routine.

You can then watch, either visually, or with an O'scope on the LED, the incoming data and the buffer status.

 

JC 

  

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Personally, I've always used the equivalent of XON/XOFF. What I do is have a buffer that will store say 32 bytes. When it is empty in the receiver, I send some specific character that causes the sender to pump out another 32 bytes. This way, the overhead is still pretty low and I do not have to depend on how the sender implements hardware flow control. 

 

Jim

 

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Use a file transfer protocol like XMODEM. This should address your problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:

I'd typically use an interrupt driven ring buffer, and then set the water mark at 3/4 full, (or whatever).

 

Even with the buffer it still does not work.

TeraTerm is the problem I am certain because Brays terminal works with the CTS/RTS signals.

 

 

DocJC wrote:

Assuming you can slow the system down a bit, why not put a small delay in between each byte being shipped out of the PC?

 

There is no hurry, however I'd like to figure it out.

If I implement a line delay of 100mS everything is fine, no data lost. I am ok with that except

this still does not explain why Teraterm is not responding to the CTS signal.

 

DocJC wrote:

You can then watch, either visually, or with an O'scope on the LED, the incoming data and the buffer status.

JC

 

 

I checked with a logic analyzer and the CTS is toggling when it's supposed to. I will try your suggestion using the LED.

thanks

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:

Personally, I've always used the equivalent of XON/XOFF. What I do is have a buffer that will store say 32 bytes. When it is empty in the receiver, I send some specific character that causes the sender to pump out another 32 bytes. This way, the overhead is still pretty low and I do not have to depend on how the sender implements hardware flow control. 

 

Jim

 

 

Anytime I have used this method some bytes (one or two bytes here or there) were lost unless I slow the sender down to 9600 baud or even slower.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then you have a bigger problem, somewhere. You should not loose any bytes. Do you check over-run flag bit in the UART? At 115K2 baud, N81, you have 86 uS to read and dispose of the character. That makes almost 690 instruction cycles at FCLK = 8MHz. You have that long after one byte is complete before the next byte has to be serviced. If you loose bytes, something is really wrong.

 

With the scheme I described, you can take forever to move those 32 bytes out of the buffer to where ever they need to go. The "request for a new data block" is not sent until all that stuff is finished. No reason to loose anything.

 

Jim

 

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since it works with Bray's Terminal, without losing any data, and you can't seem to find a PC terminal program that works well for you, perhaps it is just time to write your own PC User Interface program.

 

JC 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had to check to see if this was an old thread dragged back up, but no its current!

So if your code works ok with brays terminal, then it should work ok with any other that supports hardware handshaking.

In Teraterm, you go to setup menu, select serial port and set to hardware handshake.

This should put the PC into DTE mode, your AVR must be setup in DCE mode (modem), so in addition to RTS/CTS you must also set high DSR/CD!

Now when you raise CTS, the PC should send characters until you drop CTS!

If you are not doing anything with DSR/CD, that may explain why Teraterm is not acting correctly, as you have not properly emulated a modem (DCE) device.

Those two signals can be wired high if not currently connected, or "looped back" from DTR! i.e connect the DTR pin to both DSR and CD.

 

Jim

boy its been a looonnnggg time since I have needed to think about DTE/DCE comms.

 

 

 

 

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

Last Edited: Thu. May 2, 2019 - 02:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using rts/cts hardware flow control to prevent rx buffer overflow can be problematic, because

1) you have to figure out what it means first. It means different things to different people.

2) once you've figured out what it means, you can never be certain how quickly the other end will stop sending after you signal flow-off. Will it stop sending immediately (well, after any byte in progress) or will it stop a bit later after a few more bytes.

 

What it means to me, the way it has ended up beig used today, is that the receiving end drives RTS as an output, which is cross wired to the CTS input at the other end, much like you would cross wire tx at one end to rx at the other. So the receiving end outputs flow-on (which is low, assuming line level signals) if it is happy to receive, so it's easier to think of it as RTR (ready to receive) rather than RTS, and outputs flow-off (high) if it wants the other end to stop sending. The transmitting end will check its CTS before transmitting. I think that's what you are doing, other than at the AVR end you are calling RTS what I would call CTS!

 

Ultimately it might be more reliable to implement some kind of protocol to prevent rx buffer overflow rather than relying on hardware flow control. This could be very simple

eg. just have a big enough rx buffer!

or the transmitting end can only send one (or some max number of) byte(s) and then has to wait for a response, and so on.

 

Having said that, it does look a lot like the terminal application is simply not honouring the flow control, may just be a configuration issue, don't know.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The lack of a common understanding about how flow control SHOULD work is the very reason I avoid it. 

 

I always write both sides of the link, so I CAN control how it works. Never loose any bytes. For a while, I included a CRC8 with every block and had two different "gimme a new block" command, one for the next block, and one to resend the one just sent. Never had to use the latter. 

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Today I wrote a small vb program and implemented the hardware flow control.

 

My code works 100% not even one byte lost. I tried my ring buffer code as well, no data lost.

 

Just as a test, I inserted a 1mS delay between bytes and still no data lost @ 115200 baud,

so I know the flow control is working.

 

So there is definitely something broken with TeraTerm in terms of the hardware flow control setting.

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

Those two signals can be wired high if not currently connected, or "looped back" from DTR! i.e connect the DTR pin to both DSR and CD.

 

Tried this and it still does not work. Loses 16 bytes of data after every 16 bytes written.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried hyperterminal on an older PC, all is working.

 

Again it must be TeraTerm.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

you might try messing with these adjustments in device manager...there are similar ones for the "classic" serial  ports (non-usb)

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Thu. May 2, 2019 - 10:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

newbie123 wrote:

I tried hyperterminal on an older PC, all is working.

Again it must be TeraTerm.

 

Just to update this thread.

I received wonderful support from the software programmer.

He did tell me there was a problem.

 

How often these days do you ever get support for anything? Especially a free program!

Dealing with microsoft over the years I expect to receive no warranty, nothing, NADA!

Last Edited: Fri. Jun 7, 2019 - 02:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

d

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Last Edited: Mon. Jun 24, 2019 - 08:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Paulvdh wrote:

When using handshaking you have to keep in mind that the handshaking is not "instantly". After you tell the remote node to stop (with either hardware or software handshaking) you can still expect to have to be able to store upto 10 or so bytes before the line goes quiet.

 

This is WHY i don't use a circular buffer. If you look at the code I posted above, it stops the flow after every single byte. This way the program can take however long it needs to process the incoming data and there is no data loss.

 

This is working regardless of speed of the baudrate.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

newbie123 wrote:
This is WHY i don't use a circular buffer. If you look at the code I posted above, it stops the flow after every single byte

That's missing the point.

You might tell the other end to stop, but what if it doesn't stop straight away and it sends you another 2,3,4,8,10 etc. bytes before it stops.

If you only ever use it where you know the other end will stop instantly it's fine, but in general you could use it one day with a different host and that host doesn't behave the same.

So a circular buffer could still be useful. It could be quite small in this case, it just gives you some extra leeway if the other end does send you a few extra bytes while you're still off processing the first one.

Of course if it doesn't stop sending at all then you can still overflow your circular buffer so it won't fix everything.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

d

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Last Edited: Mon. Jun 24, 2019 - 08:56 AM