Interrupt based time. Adjust tick cost every 1 minute and when timer-0 is reconfigured (the time precision affected when timer-0 reconfigured). Keep all time in nanoseconds.
It is always implemented exactly the same way (as an uint8) so there is
no reason to implement it in each target separately.
This also makes it easier to add some documentation to it.
These stubs don't really belong there: attiny currently doesn't directly
support I2C at all (although it has hardware to support a software
implementation).
All the AVRs that I've looked at had the same pin/port structure, with
the possible states being input/floating, input/pullup, low, and high
(with the same PORT/DDR registers). The main difference is the number of
available ports and pins. To reduce the amount of code and avoid
duplication (and thus errors) I decided to centralize this, following
the design used by the atmega2560 but while using a trick to save
tracking a few registers.
In the process, I noticed that the Pin.Get() function was incorrect on
the atmega2560 implementation. It is now fixed in the unified code.
* machine/uart: add core support for multiple UARTs by allowing for multiple RingBuffers
* machine/uart: complete core support for multiple UARTs
* machine/uart: no need to store pointer to UART, better to treat like I2C and SPI
* machine/uart: increase ring buffer size to 128 bytes
* machine/uart: improve godocs comments and use comma-ok idiom for buffer Put/Get methods
Don't store addresses in the values of registers, this leads to problems
with char arrays (among others). Instead, do it like it's done in C with
raw addresses cast to struct pointers.
This commit also splits gen-device.py, as AVR and ARM have very
different ideas of what a register is. It's easier to just keep them
separate.
This requires support in LLVM, as AVR support is still experimental. For
example, in bindings/go/build.sh, add
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR to cmake_flags.