simulavr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Simulavr-devel] SBI vs. PINx and interrupt flag registers


From: Michael Hennebry
Subject: [Simulavr-devel] SBI vs. PINx and interrupt flag registers
Date: Mon, 19 Jun 2017 07:14:38 +0000 (UTC)

In old AVRs, the hardware implemented SBI instructions as a RMW.

In current AVRs, SBI instructions cause single-bit writes.
The difference is important for current PINx and interrupt flag registers.
For current PINx registers, writing a one to a PINx bit
causes the corresponding PORTx bit to toggle.
For an interrupt flag bit, writing a one to it sets it to zero.
In both cases, writing a zero has no effect.

I suspect the practical thing to do is
give each IO register an sbi and cbi method.
They could all be implemented as a simple read-modify-store,
a store or a complicated read-modify-store.
Note that "read" means just get the value in the register,
do not produce any of the side-effects, if any, associated with a load.
"Store" means store, as in STS or OUT.

In most cases, a simple read-modify-will do the trick:
Store old |= (1<<b) or old &= ~(1<<b) .
In the case of a flag-only or modern PINx register, store (1<<b) or 0.
The complicated case is a register that contains both flag bits and ordinary 
bits.
In that case, store (old & ~F) | (1<<b) or old & ~F & ~(1<<b).
b is the bit position and F is a mask indicating the locations of the flag bits.

Note that this is a separate issue from how
compilers handle PINx |= (1<<b) on modern AVRs.
Often, though not always, it should clear every bit in PORTx.
Usually, though not always, compilers convert it into an SBI instruction.
This is usually (always?) wrong, but usually what was desired.
The correct method is for the toolchain to provide a mechanism
for C users to explicitly generate the desired SBI instruction.



Michael Hennebry


reply via email to

[Prev in Thread] Current Thread [Next in Thread]