jung6717 / arduino

Automatically exported from code.google.com/p/arduino
0 stars 0 forks source link

HardwareSerial not clearing U2Xn bit #47

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
EmilyJane from the arduino forums noted that the 3.3V 328P 8MHz arduinos
were communicating at 2X the specified bit rate.

e.g.
Serial.begin(9600);
Serial.print("string");  // would be transmitted at 19200 bps on 3.3V 328P 8MHz

The bootloader for the 3.3V 328P 8MHz is created with the flag
"-DDOUBLE_SPEED" which sets the U2Xn bit in UCSRnA register.

Instead of overhauling the bootloader, HardwareSerial.h/.cpp has been
altered to explicitly set the U2Xn bit in UCSRnA register to 0.

New HardwareSerial.h and HardwareSerial.cpp files attached.

Can also be downloaded from:
http://mediafire.com/Arduino under "HardwareSerial u2x fix"

b

Original issue reported on code.google.com by rogue.bh...@gmail.com on 25 Jun 2009 at 9:49

Attachments:

GoogleCodeExporter commented 9 years ago
For more information:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1245508129

Original comment by rogue.bh...@gmail.com on 26 Jun 2009 at 9:20

GoogleCodeExporter commented 9 years ago
It would make sense to setup everything for the serial port so this doesn't 
happen
again. For example, a firmware could set the parity bit in UCSRnC, which would 
put us
right back in this situation.

I propose that the begin() set all the serial port registers (UCSRnA, UCSRnB, 
UCSRnC,
UBRRnL, and UBRRnH)

The code I'm posting also incorporates the end() function ala
http://code.google.com/p/arduino/issues/detail?id=45

Since all those registers are getting set, I also added options for setting 
databits,
stopbits, and parity. All these options have defaults so that 
"Serial.begin(9600);"
works the same.

Original comment by gabebear@gmail.com on 3 Jul 2009 at 1:13

Attachments:

GoogleCodeExporter commented 9 years ago
Oh ya, the code I just posted also uses U2X mode if it is needed, this will 
allow
people to use baud rates twice as high.

Original comment by gabebear@gmail.com on 3 Jul 2009 at 2:19

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
This goes back to this change:
http://code.google.com/p/arduino/source/detail?r=581

The guy from sparkfun is correct, 57600baud @ 8Mhz has a 3.7% error rate 
without U2X
and has an error rate of 2.1% with U2X... 3.7 is unacceptable, and 2.1 is barely
acceptable.

The REAL way to set baud is with util/setbaud.h
http://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html , but it 
relies
on macros to calculate error-rate and the format is just kind of.... bleh.

http://www.wormfood.net/avrbaudcalc.php helps calculate the error rates. Half 
the
baud to get error rate with U2X.

I'm going to re-write begin() one more time to try to incorporate the error 
rates
into the ubbr calculations.

Original comment by gabebear@gmail.com on 3 Jul 2009 at 4:57

GoogleCodeExporter commented 9 years ago
Well, I updated HardwareSerial a LOT...
   - Final program size should be smaller and faster
   - more accurate baud-rate calculation
   - more options (parity, char size, stopbits, end)

This should-be a drop in replacement, the class still externally look the same.

Changes from version in SVN:
  1. uses U2X if it helps get correct baud rate
  2. sets all serial registers
  3. added options for setting
      - parity
      - data bits
      - stop bits
  4. inlined pretty much everything
  5. buffers now exist within class
  6. added end()

Reasoning:
  1. Some baud rates need to use U2X to use certain
       baud-rates. (i.e. 57600 baud on an 8MHz AVR)
  2. Not setting all registers was the root cause
       here. (U2X being left on accidentally)
  3. Parity, data bits, and stop bits are useful
  4. This shrinks the final hex file by a couple
       hundred bytes!!! and everything is faster
  5. Putting the buffers inside the class and
       having the interrupts access the 'Serial'
       objects just looks cleaner to me.
  6. The end() function gives you back pin0 and
       pin1 back if you no longer need the USART

Original comment by gabebear@gmail.com on 4 Jul 2009 at 7:02

Attachments:

GoogleCodeExporter commented 9 years ago
Hmm, thinking about it, the shrink in executable size probably isn't as much 
from
inlining functions, as it is from not initializing the read buffer.

There isn't any reason to initialize the read buffer to all zero, I just want 
to make
sure that the reasoning for changes is clear. Not initializing the read buffer 
won't
save you any RAM at run-time though.

Original comment by gabebear@gmail.com on 4 Jul 2009 at 7:23

GoogleCodeExporter commented 9 years ago
gabebear, I committed your baud rate setting code (including the selection of 
the U2X register).  The addition of 
the parity, data bit, and stop bit parameters to begin() should probably be 
discussed on the developers mailing 
list: http://mail.arduino.cc/mailman/listinfo/developers_arduino.cc as should 
the end() (or stop()) function.

Original comment by dmel...@gmail.com on 12 Jul 2009 at 3:03

GoogleCodeExporter commented 9 years ago
Hi! I can't understand everything is happening here, but I need to use an 
Arduino to read from the serial port at 1200baud, 7 data, 1 stop.

Since I found this "issue" I've been able to read it wright (Thank you!!) 
replacing the original HardwareSerial to the two files you have modified here, 
but I need to print it thru the web and now when I compile my Sketch with all 
the "web-things" in it there is an error saying 'class Client' has no member 
called 'print', and 'println' and the same with 'class File' because I'm 
logging it into an SD Card...

When I replace the "HardwareSerial" .cpp and .h with the original it compiles 
ok but, obviously, I cannot set the stop bit and the 7 data bits, so it's not 
working for me...

What should I do?

Thank you!!

Original comment by avi.barr...@gmail.com on 8 Jun 2011 at 9:38

GoogleCodeExporter commented 9 years ago
Uhm... I've solved it just subtracting 128 to each byte... for sure I will have 
to work more to solve the problem with the 7-O-1 temperature controller... 
Thanks for your work anyway!

Original comment by avi.barr...@gmail.com on 9 Jun 2011 at 12:04