UDRE issues

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

Using mega128a & trying to spit out simple test...xtal 14.74x MHz, all initialized ok for 9600-8-n-1

			outreg ubrr0h, zero
            ldi temp, uart_speed   ;set to desired UART speed
            outreg ubrr0l, temp        
            outreg ucsr0a, zero
            ldi temp, (0<<rxen0)|(1<<txen0)|(0<<rxcie0)  ;enable rx,tx, isr functions
            outreg ucsr0b, temp
            ldi temp, 06
            outreg ucsr0c, temp

I have the following loop:

holup:	inreg temp, UCSR0A
		SBRS TEMP, UDRE0
		rjmp holup
		ldi temp, 'W'
		outreg UDR0, temp
		RJMP HOLUP

It tends to spit out garbage unless I add some sort of delay (then it works fine)...its as though udre is not working properly or the chars are too close together...they seems right on top of each other....should udre keep the stream spaced out enough? The level shifting looks good...never ran into this before..I hate to add delay without knowing, since this seems quite strange

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

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

Your code should work just fine. The mega128 has been in existence for about 10 years, so any problems would have emerged by now.

I am well aware that ASM programmers always like to do things their own way.

Have you tried using tabs between the opcode and operand?
Have you tried using uppercase for SFR names and bit-names?
Have you tried case consistency in labels?

I know that assemblers default to being case-insensitive. Humans are not naturally so inclined. And I for one, have serious difficulties with lowercase 'el'.

David.

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

I've retyped this about 20 times, thus looking messy now...spent several hours on investigation...nothing yet...seems like the PC program is loosing "lock" and getting garbage...but adding a small delay fixes everything up...may have to resort to that...just wondering if I'm overlooking something...never had this issue with mega88 and other parts, doing it the same way. Maybe I have a ground loop.

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

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

are you testing the correct bit?
maybe UDR takes a couple of cycles to reset?

add a few nops after you load udr to see.

crystal oscillator?
fuses set correctly?

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

My only guess is that your 'temp' register is getting corrupted in an ISR().

I also wonder why you have chosen SBRS instead of SBIS in the first place. But either approach should have the same effect. The UDRE0 bit will only clear when you write to the UDR0 register.

David.

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

Quote:
inreg temp, UCSR0A
Which assembler are you using?? I only know of in/out not inreg/outreg.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Quote:

ldi temp, (0<<rxen0)|(1<<txen0)|(0<<rxcie0) ;enable rx,tx, isr

Ummm--see bolded above...
Quote:

I only know of in/out not inreg/outreg.

Probably the same as LOAD and STORE from app note 001.
https://www.avrfreaks.net/index.p...
https://www.avrfreaks.net/index.p...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

here are the macros (friom the links provided)

 AVR {in/lds} - {out/sts} automatic selection macros 
; 
;   The device include file must be used to define SRAM_START 

; usage: InReg reg, addr 
.macro InReg 
    .if @1 < 0x40 
        in @0, @1 
    .elif ((@1 >= 0x60) && (@1 < SRAM_START)) 
        lds @0,@1 
    .else 
       .error "InReg: Invalid I/O register address" 
    .endif 
.endmacro 

; usage: OutReg addr, reg 
.macro OutReg 
    .if @0 < 0x40 
        out @0, @1 
    .elif ((@0 >= 0x60) && (@0 < SRAM_START)) 
        sts @0,@1 
    .else 
       .error "OutReg: Invalid I/O register address" 
    .endif 
.endmacro 
; 

My code code works fine with some delay added (just before the rjmp)...but my question is---should that be needed? I don't rememeber ever neededing to add manual delay before!!?? the sbrs is needed since when trying uart1, the registers are beyong the sbis range

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

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

After many hours of fiddling I found that the waveforms look fine. If you connect/disconnect the terminal program (using BRAY's), sometimes it reads correctly and sometimes not (rcv all good chars or rcv all the same wrong chars)---this was quite perplexing.

Turns out, it "locks on" the stream and will either lock on properly or not. You can connect/disconnect the program to see this happening. No wonder I was going in circles.

Found out the if I cycle power to my cpu board (a bit of a pain), the terminal & my program always work perfectly!!!!!! No delays neeeded.

It appears the terminal program just does not like being "turned on" if a steady data stream is already in progress. This I did not know!!! Beware!!

When in doubt cycle the power.

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

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

An UART is just that: Asynchronous.

If you have continuous back-to-back transmissions then you can obviously get out of sync.

But genuine asynchronous detects the start bit, and aligns itself properly. And of course sets Framing error, Parity etc accordingly.

Are you saying that your 'test' program was sending continuous W's? And that Brays was not always catching the start bits?

David.

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

you can see the program above yourself...just a test sending out WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW to check the wiring, usb converter, rs232 shifter, baudrate, etc,dip switches, uart setups, proper connections, etc, etc.

However, activating Bray's (and perhaps others) terminal AFTER this is running often (not always) fails---giving the wrong character say ~~~~~~~~~~~~~~~ !!! quite maddening.

As noted, cycling power (while the terminal is already running) always gives the correct result!!!!

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

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

Maybe you should have an occasional pause in your test program (100ms after every 10 characters?) to allow Brays to catch up/resync?

It's a less than perfect world we live in....

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

Well the solution is obvious. You introduce a periodic BREAK.

Personally, I do not find continuous "WWWWWWWW..." very useful. Sending a human readable string is so much more convenient for humans.

You would find exactly the same symptoms from any other AVR, PIC, ARM, 8051 ...

A 'W' is 0111010101. RS232 transmits LSB first.

Valid start bits:
0111010101  0x57 'W'
0101010111  0xD5
0101011101  0x75 'u'
0101110101  0x5D
0111010101  0x57 ... i.e. back to start again

You will have to look up what char 0x5D is.
It is a stroke of luck that each valid Start bit is accompanied by a valid Stop bit. So you will never get a Framing error!

David.

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

Quote:

you can see the program above yourself...just a test sending out WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW to check the wiring, usb converter, rs232 shifter, baudrate,

Then why not send 'U' characters like we all do, so you can look at the square-wave bit stream and measure bit widths, etc.?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
Then why not send 'U' characters like we all do, so you can look at the square-wave bit stream and measure bit widths, etc.?

I was sending 'U', but then wanted to send something asymmetric to help with the debugging...made no sense at all ..everything looked good...a 5 minute check turned into a 5 hour debug. Just need to cycle the power!!
Terminal does not like being started in the middle of a steady stream. Now we know!!

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

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

You have not grasped the point.
You need to allow the receiver to detect a valid Start bit. It is nothing to do with power-cycling or inappropriate states.

You are providing a bit-stream that has four possible perfectly legal byte values. It will be completely random when you switch on your terminal, and which start bit it locks onto.

David.

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

Quote:
You need to allow the receiver to detect a valid Start bit

I didn't realize I needed to do anything special...... thought it would rcv automatically...never heard of needing to stop sending in order to rcv properly! thought any stream would be picked up correctly...guess not...but you are correct---rs232 is not completely self-synchronizing.

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

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

Quote:

thought any stream would be picked up correctly...

Think about the 'U' that we discussed above. If you stuff on UDRE it will be an unbroken square wave, 50% duty cycle, at 8-n-1.

So, if you start at any point in that 10-bit character frame, it could sync at 5 different places.

Note that it would indeed cure your symptom, as you would see 'U's at the receiver. Solves your "~~~ instead of WWW" situation. That should be sufficient to you, as you seem to want to address the symptom rather than the cause.

I think two stop bits would force an eventual re-sync, due to the 11-bit frame.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

I am happy now that I know there was no problem with the processor or my uart config/setup...I've done this exact thing many times with no problem whatsoever...so must have been lucky all these years!

I was really concerend that the UDRE in this chip worked differently (since this usart has soem form of extra buffering) If I could not rely on the UDRE signal to send out the next char, then what would be the use in monitoring it? I guess even though it says (via UDRE)its ready to accept another char, one might want to add a small delay if startup sync is questionable.

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

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

You still have not grasped it.

Any UART will start when it receives ANY Start bit. The only way that you can ensure that it syncs on the correct 0 bit, is to have at least 10 bit-time's of 1 (idle).

The mega128 is no different to any UART of any device from any maker.

It is your PC that is not synchronising because it does not know which 0 bit is a start bit.

If you reset your AVR after Brays has started running, you will be fine. Resetting Brays after the AVR is running will not synchronise on W's. (unless you are lucky)

No-one uses synchronous comms any more. But this is even more critical to start at a byte boundary.

David.

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

Quote:
No-one uses synchronous comms any more.

Well, we've been talking about asynchronous comms (rs-232) anyhow. And SPI is a form of synchronous comm.

:P

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