* Only enable TX by default.
* Add some magic for RX handling. When an input handler is registered:
* Automatically enable RX-related and interrupts
* Automatically lock the SERIAL PD on under all power modes
* Automatically enable the UART clock under sleep and deep sleep
* Automatically undo all of the above when the input handler becomes NULL
* As a result, modules / examples that need UART RX no longer need to clock the UART and manipulate the SERIAL PD. They simply have to specify an input handler
* Don't automatically power on the UART whenever the CM3 is active
* Before accessing the UART, make sure it is powered and clocked
* Avoid falling edge glitches
* Fix garbage characters / Explicitly wait for UART TX to complete
* Implement new style of PD locks
* Use our own shutdown sequence rather than the one provided by cc26xxware
* Shutdown from within the interrupt that requested it. This allows shutdown to take place even if the code is stuck in a loop somewhere else
* Improve DCDC/GLDO/uLDO switching logic
* Explicitly handle oscillators and retentions
Instead of using a separate data structure to request that a PD remain powered during deep sleep,
we do the same within the main LPM data structure through an additional field.
This allows us to maintain only one linked list of LPM modules and overall improves code clarity
This tutorial was written for the older implementation of CoAP, and
while it may be possible to update it, the directions include URLs and
repos that no longer exist, so it's better to just remove it.
Only the interrupt flags that have been handled must be cleared.
Otherwise, if a new interrupt occurs after the interrupt statuses are
read and before they are cleared, then it is discarded without having
been handled. This issue was particularly likely with two interrupt
trigger conditions occurring on different pins of the same port in a
short period of time.
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
Power-up interrupts do not always update the regular interrupt status.
Because of that, in order not to miss power-up interrupts, the ISR must
handle both the regular and the power-up interrupt statuses.
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
Introduce new useful GPIO macros to:
- get the raw interrupt status of a port,
- get the masked interrupt status of a port,
- get the power-up interrupt status of a port.
These macros are cleaner and less error-prone than raw register access
code copied all over the place.
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
Behave just like the CS8900A driver: Both the CS8900A and the LAN91C96 dynamically share a buffer for received packets and packets to be send. If the chip is exposed to a network with a lot of broadcasts the shared buffer might fill quicker with received packets than the 6502 reads them (via polling). So we might need to drop some received packets in order to be able to send anything at all.
OR-ing an offset to a base address instead of adding it is dangerous
because it can only work if the base address is aligned enough for the
offset.
Moreover, if the base address or the offset has a value unknown at
compile time, then the assembly instructions dedicated to 'base +
offset' addressing on most CPUs can't be emitted by the compiler because
this would require the alignment of the base address against the offset
to be known in order to optimize 'base | offset' into 'base + offset'.
In that case, the compiler has to emit more instructions in order to
compute 'base | offset' on most CPUs, e.g. on ARM, which means larger
binary size and slower execution.
Hence, replace all occurrences of 'base | offset' with 'base + offset'.
This must become a coding rule.
Here are the results for the cc2538-demo example:
- Compilation of uart_init():
* before:
REG(regs->base | UART_CC) = 0;
200b78: f446 637c orr.w r3, r6, #4032 ; 0xfc0
200b7c: f043 0308 orr.w r3, r3, #8
200b80: 2200 movs r2, #0
200b82: 601a str r2, [r3, #0]
* now:
REG(regs->base + UART_CC) = 0;
200b7a: 2300 movs r3, #0
200b7c: f8c4 3fc8 str.w r3, [r4, #4040] ; 0xfc8
- Size of the .text section:
* before: 0x4c7c
* now: 0x4c28
* saved: 84 bytes
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
Hardware init function profit a great deal from being inlined if the
given parameters are constant -- which is the common use-case, we could
probably call this for all timers and still have less overhead. The
hwtimer_pwm_ini (which calls hwtimer_ini) gets completely computed at
compile-time resulting only in the register settings of hwtimer_ini.
This is now possible because we get rid of static storage for the
max_ticks and instead compute this in hwtimer_pwm_max_ticks from the
timer register settings.
Some platforms are missing timer channels, this is now left to the
(missing) preprocessor definitions on those platforms, no
platform-specific defines needed anymore.
Also fix usage of timer counter register 3 (hardcoded) in
cpu/avr/dev/clock.c -- this code isn't used on many platforms as it
requires a very special quartz clock frequency but this now also uses
the platform timer specification.
We can now directly compile arduino sketches (.pde) files.
Arduino compatible analogWrite works now.
But there is still a long way to go, serial I/O and timer stuff (delay,
millis etc) currently don't work (not tested but I don't expect this to
work).
It can be used in an arduino sketch or in a normal contiki program.
We get a PWM frequency of 490.2 Hz (a period of 2.040 ms), that's
Arduino compatible. If you need different frequencies see native timer
usage in examples/osd/pwm-example
In a contiki program you have to call arduino_pwm_timer_init to
initialize the timer before pwm works. The arduino sketch wrapper
already does this.
For running a sketch, see examples/osd/arduino-sketch