Hi,
Klaus Rudolph:
can someone assist me a bit to catch the problem and the background
please? :-)
sure :-)
Which controller and which registers on that controller(s) are affected.
It would be nice if someone points me to two or more different registers
on a single controller core which provide "new" SBI/CBI functionality.
Example: ATmega644, http://www.atmel.com/Images/doc2593.pdf
(other example: ATtiny25/45/85)
Initial datasheet revision date: 06/2005
Page 20, section "6.4 I/O Memory" (emphasis mine):
All ATmega644 I/Os and peripherals are placed in the I/O space. All I/O
locations may be
accessed by the LD/LDS/LDD and ST/STS/STD instructions, transferring data
between the 32
general purpose working registers and the I/O space. I/O Registers within the
address range
0x00 - 0x1F are *directly bit-accessible* using the SBI and CBI instructions.
In these registers, the
value of *single bits* can be checked by using the SBIS and SBIC instructions.
Have we more than an SBI/CBI issue? More instructions requiring rework?
AFAIK, it is only the SBI/CBI instruction. Affecting the PINx register
(port pin toggle feature, see below) and clearing of interrupt flags
(see below).
Datasheet page 67, section "12.2.2 Toggling the Pin":
Writing a logic one to PINxn toggles the value of PORTxn, independent on the
value of DDRxn.
Note that the SBI instruction can be used to *toggle one single bit* in a port.
Page 20, section "6.4 I/O Memory":
Some of the Status Flags are cleared by writing a logical one to them. Note
that, unlike most
other AVRs, the CBI and SBI instructions will only operate on the specified
bit, and can therefore
be used on registers containing such Status Flags. The CBI and SBI instructions
work with reg-
isters 0x00 to 0x1F only.
It would also be nice if the "new" functionality is described in a few
words and the wrong effect we currently have implemented. A direct
reference to datasheet is highly welcome.
Currently SBI/CBI are implemented as "read/modify/write" (as if
in/or/out instructions were used). However, this differs from a true
"bit-accessible I/O register".
Example: PINx toggle feature
DDRB = 0xff;
PORTB = 0xff;
PINB |= _BV(PB0); // sbi _SFR_IO_REG(PINB), 0
Expected behaviour:
PB0 toggles from 1 -> 0
PINB is a bit-accessible IO register. The SBI instruction behaves as if
0x01 had been written.
Simulavr behaviour:
All bits (PB7..PB0) toggle from 1 -> 0.
Simulavr emulates SBI as RMW:
- Read PINB: 0xff (each input stage=1)
- Modify: 0xff | 0x01 --> 0xff
- Write: 0xff --> PINB, == "PORTB ^= 0xff"
The PINx toggle feature can also be used to toggle pullups ("independent
on the value of DDRxn").
Similarly, SBI on an interrupt flag register with multiple interrupt
flags set, would also clear these other interrupt flags.
Another example: SBI on a non-interrupt bit would clear (i.e. write 1
to) an interrupt flag in the same register (because the interrupt flag
is read as 1, other bit is ORed, result with interrupt bit set is
written back).
Cheers,
panic
_______________________________________________
Simulavr-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/simulavr-devel