I would like to save and restore GPIO registers on the stack for certain reasons. For this I wrote a small test program, which is not compiled without errors. Where is the problem? Why are the two registers "PORTB" and "DDRB" unknown?
The error messages (Arduino IDE 2.1, Arduino UNO): C:\Users\Rudol\AppData\Local\Temp\cccgm7Sb.ltrans0.ltrans.o: In function loop':* *D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:40: undefined reference to DDRB' D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:40: undefined reference to PORTB'* *D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:50: undefined reference to PORTB' D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:50: undefined reference to `DDRB' collect2.exe: error: ld returned 1 exit status
exit status 1
Compilation error: exit status 1
... and my Sketch:
/*================================================================
UNO/Nano (ATMEGA328P): Test push/pop with assembler instructions
================================================================*/
//==== Arduino-Standard: setup() ==========================
void setup() {
pinMode(13,OUTPUT); // Signal: Prozessor is running
digitalWrite(13,HIGH);
delay(2000);
Serial.begin(115200);
while(!Serial) delay(10);
Serial.println("Test push / pop GPIO");
}
//==== Arduino-Standard: loop() ===========================
void loop() {
//---- Save DDRB and PORTB con Stack ----
asm volatile
(
"PUSH R20 \n"
"IN R20,DDRB \n"
"PUSH R20 \n"
"IN R20,PORTB \n"
"PUSH R20 \n"
);
digitalWrite(13,LOW);
delay(250);
//---- Restore PORTB / DDRB from stack ----
asm volatile
(
"POP R20 \n"
"OUT PORTB, R20 \n"
"POP R20 \n"
"OUT DDRB, R20 \n"
"POP R20 \n"
);
delay(250);
}
Sorry, I have reduced my Sketch to a minimum and forgot to change the LED.on(); It is now corrected to pinMode/digitalWrite..
To all other answers: I have often seen the port manipulation like "PORTB = ...". The problem must be in relation with PUSH and POP!
PORTB and DDRB are not defined at assembly level; they are C preprocessor symbols.
To access them via "asm" C statements, you'd normally do something like:
asm("in r20, %0" : : "I" (_SFR_IO_ADDR(PORTD)) );
(Described in the cookbook 6v6gt linked.)
It has nothing to do with the use of PUSH and POP.
The internet suggests that a #define __AVR__(your processor)__ is missing or out-dated... and that will have the pre-defined DDRB, et c. that are causing the error(s).
Thank you everyone for your contributions. But after x attempts with all possible variants I do without "asm(...) and stay with the register names that are understood in the sketch by C/C++.