Age | Commit message (Collapse) | Author |
|
The flush() method blocks until all characters in the serial buffer have
been written to the uart _and_ transmitted. This is checked by waiting
until the "TXC" (TX Complete) bit is set by the UART, signalling
completion. This bit is cleared by write() when adding a new byte to the
buffer and set by the hardware after tranmission ends, so it is always
guaranteed to be zero from the moment the first byte in a sequence is
queued until the moment the last byte is transmitted, and it is one from
the moment the last byte in the buffer is transmitted until the first
byte in the next sequence is queued.
However, the TXC bit is also zero from initialization to the moment the
first byte ever is queued (and then continues to be zero until the first
sequence of bytes completes transmission). Unfortunately we cannot
manually set the TXC bit during initialization, we can only clear it. To
make sure that flush() would not (indefinitely) block when it is called
_before_ anything was written to the serial device, the "transmitting"
variable was introduced.
This variable suggests that it is only true when something is
transmitting, which isn't currently the case (it remains true after
transmission is complete until flush() is called, for example).
Furthermore, there is no need to keep the status of transmission, the
only thing needed is to remember if anything has ever been written, so
the corner case described above can be detected.
This commit improves the code by:
- Renaming the "transmitting" variable to _written (making it more
clear and following the leading underscore naming convention).
- Not resetting the value of _written at the end of flush(), there is
no point to this.
- Only checking the "_written" value once in flush(), since it can
never be toggled off anyway.
- Initializing the value of _written in both versions of _begin (though
it probably gets initialized to 0 by default anyway, better to be
explicit).
|
|
The actual interrupt vectors are of course defined as before, but they
let new methods in the HardwareSerial class do the actual work. This
greatly reduces code duplication and prepares for one of my next commits
which requires the tx interrupt handler to be called from another
context as well.
The actual content of the interrupts handlers was pretty much identical,
so that remains unchanged (except that store_char was now only needed
once, so it was inlined).
Now all access to the buffers are inside the HardwareSerial class, the
buffer variables can be made private.
One would expect a program size reduction from this change (at least
with multiple UARTs), but due to the fact that the interrupt handlers
now only have indirect access to a few registers (which previously were
just hardcoded in the handlers) and because there is some extra function
call overhead, the code size on the uno actually increases by around
70 bytes. On the mega, which has four UARTs, the code size decreases by
around 70 bytes.
|
|
Previously, the constants to use for the bit positions of the various
UARTs were passed to the HardwareSerial constructor. However, this
meant that whenever these values were used, the had to be indirectly
loaded, resulting in extra code overhead. Additionally, since there is
no instruction to shift a value by a variable amount, the 1 << x
expressions (inside _BV and sbi() / cbi()) would be compiled as a loop
instead of being evaluated at compiletime.
Now, the HardwareSerial class always uses the constants for the bit
positions of UART 0 (and some code is present to make sure these
constants exist, even for targets that only have a single unnumbered
UART or start at UART1).
This was already done for the TXC0 constant, for some reason. For the
actual register addresses, this approach does not work, since these are
of course different between the different UARTs on a single chip.
Of course, always using the UART 0 constants is only correct when the
constants are actually identical for the different UARTs. It has been
verified that this is currently the case for all targets supported by
avr-gcc 4.7.2, and the code contains compile-time checks to verify this
for the current target, in case a new target is added for which this
does not hold. This verification was done using:
for i in TXC RXEN TXEN RXCIE UDRIE U2X UPE; do echo $i; grep --no-filename -r "#define $i[0-9]\? " /usr/lib/avr/include/avr/io* | sed "s/#define $i[0-9]\?\s*\(\S\)\+\s*\(\/\*.*\*\/\)\?$/\1/" | sort | uniq ; done
This command shows that the above constants are identical for all uarts
on all platforms, except for TXC, which is sometimes 6 and sometimes 0.
Further investigation shows that it is always 6, except in io90scr100.h,
but that file defines TXC0 with value 6 for the UART and uses TXC with
value 0 for some USB-related register.
This commit reduces program size on the uno by around 120 bytes.
|
|
operator bool()
|
|
This allows users to create subclasses.
Closes: #947
|
|
This removes the need for doing an extra pointer dereference on every
access to the buffers, shrinking the code by around 100 bytes.
The members for these buffers must be public for now, since the
interrupt handlers also need to access them. These can later be made
private again.
Furthermore, the struct ring_buffer was removed. This allows the all
head and tail pointers to be put into the HardwareSerial struct before
the actual buffers, so the pointers all end up in the first 32 bytes of
the struct that can be accessed using a single instruction (ldd).
References: #947
|
|
Otherwise, you get an error when compiling for processors with no serial port because the header file is always compiled.
See, for an example of the problem: https://github.com/damellis/attiny/issues/8
|
|
|
|
Before, the UMSELn1 bit was being to set to 1, putting the UART into a reserved mode. Now, we only set the high (0x80) bit to 1 for the ATmega8, which is needed to access UCSRnC (whose i/o address is shared with UBRRH).
Also, no longer bitwise-or the new config with the existing register value, because we're actually configuring all the settings in the register. (We're not using UCPOL, but it's supposed to be 0 in asynchronous mode.)
|
|
|
|
Serial.begin() parameter to set data bits, parity, stop bits.
|
|
http://code.google.com/p/arduino/issues/detail?id=1020
|
|
http://code.google.com/p/arduino/issues/detail?id=1019
|
|
http://code.google.com/p/arduino/issues/detail?id=1006
|
|
http://code.google.com/p/arduino/issues/detail?id=871
|
|
New Serial.begin(baud, config);
|
|
Adding advanced begin (); with the ability to specify the length of bits, parity, stop bits.
|
|
Adding advanced begin (); with the ability to specify the length of bits, parity, stop bits.
|
|
is ready to send data.
Mostly useful for Leonardo - simple way to test whether the port is actually opened by an application and ready to receive data. For Serial objects attached to real UARTs always returns true.
|
|
diskloader_reboot"
This reverts commit df9835efafd13685251749bc210c0b96a18a96a5, reversing
changes made to ec45af8bfa9222a807c075dd1db4b5aa798bba03.
Conflicts:
hardware/arduino/variants/mega/pins_arduino.h
libraries/Ethernet/examples/PachubeClientString/PachubeClientString.ino
|
|
begin(long) -> begin(unsigned long)
|
|
Mark Sproul's patches, via Christian Maglie.
http://code.google.com/p/arduino/issues/detail?id=315
|
|
|
|
another stream might need more than 255 bytes).
|
|
|
|
|
|
|
|
- moving back to multple cores per platform
- using target instead of platform
- moving per-board and per-programmer preferences out of Preferences.java and into a new Target class
- adding a new "target" preference
- support for platform:value values in board preferences for bootloader path and core
- XXX: need to support platform:value syntax for board upload.using preferences.
|
|
|
|
Mini 328). Fixing some indentation.
|
|
Compiler have been integrated with changes to the Sketch.
Compilation still has problems (Thread error on success, and can't handle non-pde files in a sketch).
Modified the Mac OS X make.sh to copy the hardware, avr tools, and example over.
Removing some of the antlr stuff.
Disabling the Commander (command-line execution) for now.
Added Library, LibraryManager, and Target.
Added support for prefixed preferences (e.g. for boards and programmers).
|