I’m writing an assembly ‘library’ for a new application (I’ve written them before), but I guess this is the first time I’ve used sbi, sbic, sbis, etc in one. If I write
sbi PORTD, PD7
the assembler complains with
Error: number must be positive and less than 32
If I replace PORTD with its I/O address 0x0b, everything assembles OK. So it recognizes the bit numbers (PD7), but gets the value for PORTD wrong. I would suspect that it may be using its memory-space address (0x2b) instead of the I/O address.
I’m using Arduino v1.0.3 and an EtherMega board (ATmega2560).
In my library .S file I have
#include <avr/io.h>
I would expect this to be a common complaint, but I can’t seem to get a handle on it with google and forum searches.
To confirm that this is where the values are really coming from, I altered the #define of PD7 to have a value of 3. I then recompiled my sketch, and the line
sbi 0x0b, PD7 then compiled as
142: 5b 9a sbi 0x0b, 3 ; 11
From this it would appear that the assembler thinks that PORTD has a value of 0x2b, despite the values contained in iomxx0_1.h
Yep. SBI and CBI can only access the ports whose address is lower than 0x1f - on a 2560 that includes portA through portG. The “in” and “out” instruction can access address below 0x3F (there are no GPIO ports between 1F and 3F)
The “high” ports like portL can only be access with load/store instructions, which means that the closest you can get to “sbi” is a sequence that uses 5 clock cycles and a temporary register:
ldd reg, PORTL
ori reg, (1<<bit)
std PORTL, reg
A good reason to program in C, instead of assembler
Thanks!!!
Yeah, I was just trying to reuse some source code from someone else that had a .S code, but I was able to move the relevant part to the C side and it worked the same.