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
Currently there is an linker error when compiling with debug information.
This is only the case for dwarf (the default). Everything is fine with
stabs, thus allowing to debug and use all the other nice tools like
"objdump -S".
Since avr-libc 1.8.0 MCUSR is marked as poison as it was replaced by the
correct name MCUCSR.
Thus code still using the old MCUSR name does not compile anymore.
This commit replaces usages of former MCUSR by its new name MCUCSR and
modifies the alias fallback accordingly.
The border-router tries to transmit and do other stuff after turning
the radio off, and the radio driver didn't handle that very well.
With this fix, it's no longer necessary to reset the border router
after starting tunslip6.
The previous chip detection was inspired by the old IP65 driver code. For some reason it didn't work as expected. The new code is simpler and based on this statement in the chip datasheet: "The upper byte always reads as 33h and can be used to help determine the I/O location of the LAN91C96."
The problem with the current version of the code was that the condition at the end of the do...while loop at Timer A1 interrupt:
while((TACCR1 - TAR) > INTERVAL);
evaluates to false whenever TACCR1 == TAR.
Not incrementing TACCR1 in this case leads to Timer A1 interrupt not being called for 2 seconds, until TAR counter reaches TACCR1 again after an overflow.
The patch avoids this problem by changing the condition of the loop, and using CLOCK_LT macro to compare between time values.
The patch also attempts to fix another problem: a read of TAR register while it is being updated may return a lower value than the actual contents. To avoid that, the "read twice and compare results" idiom should be used. As the TAR register is updated by the actual hardware, it is of no importance whether it is read with interrupts disabled or enabled; the problem can occur in both contexts.