Pages: [1]   Go Down
Author Topic: Addressing ATmega registers by number  (Read 1020 times)
0 Members and 1 Guest are viewing this topic.
Eindhoven
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I am aware I can address eg. DDRB register by name, but I want to access the registers by number, essentially reading /writing directly to an I/O register (eg. port 0x04 for DDRB).

I want to do this in a loop (*and* I want to be able to initiate it from the attached PC).

How can I read or write directly from/to an AVR's I/O register by number?
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 505
Posts: 31343
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

DDRB is a defined value that evaluates to 0x04.
So just use the number in place of the name.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8430
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

DDRB is a number, it's just been defined as a human-readable mnemonic.

Quote
port 0x04 for DDRB
Doesn't make sense, DDRB is one of the PORTB regs, there is no "port 0x04 for DDRB". Do you mean "pin 0x04"?

If you want to address ports using a number you could have an array of port addresses

Code:
byte ports [] = {DDRB, DDRA, PINx, PORTy...};

for (int i = 0, i < n; i++) {
    ports [i] = somevalue;

I think you should explain what you want to do not how you think it should be done.

_____
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Eindhoven
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Grumpy_Mike: How would I rewrite this:

Code:
  byte maskAnd = 0x07;
  byte maskEor = 0x73;
  DDRB = ( DDRB & maskAnd ) ^ maskEor;
  0x04 = ( 0x04 & maskAnd ) ^ maskEor;

Line 3 compiles just fine; Line 4 will not compile and would mean something entirely different than to manipulate controller registers.

@Graynomad: I want to be able to send an instruction from my PC to Arduino, saying "what is the current value of DDRB?" If I have to program all registers in an 'if' or 'case' statement, I will probably make many errors and the program will grow really quick in size.

If you check the datasheet of ATmega1280, you'll see DDRB is a register at I/O port 0x04. If you examine the disassembled machine code that is sent to the controller while programming it, you'll see writing to IO ports is simply reading an IO register. I do not mean pin 0x04.
« Last Edit: April 29, 2012, 09:34:09 am by jippie » Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8430
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Line 4 will not compile
I think that's because the lower registers (< 0x60) are addressed with a 0x20 offset for memory instructions and directly for IO instructions.

so DDRB = x actually writes to 0x24. You could try that address to see if it works.

The DDRx macro organises this for you.

Quote
If I have to program all registers in an 'if' or 'case' statement, I will probably make many errors and the program will grow really quick in size.
Try the above address adjustment, if it works just add 0x20 to all regs below 0x60.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Eindhoven
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Point taken about the + 0x20, but a line like:

0x24 = ....

will never compile. I need some way to tell the compiler to access the AVR's register, not the number. Any idea where I can find the DDRx macro? Maybe I can figure it out from the source codes.
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 121
Posts: 8430
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

On my system it's in C:\arduino-1.0\hardware\tools\avr

from iom328p.h
#define DDRB _SFR_IO8(0x04)

from sfr_defs.h
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Eindhoven
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void testje() {
  byte maskAnd = 0x00;
  byte maskEor = 0x73;
  byte regNum = 0x04;
  _SFR_IO8( regNum ) = ( _SFR_IO8( regNum ) & maskAnd ) ^ maskEor;
}
Compiles, I can test a bit with it smiley

Thnx
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 505
Posts: 31343
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Try using:-
Code:
  *(unsigned short *)0x04 = 0;
or what ever.
Logged

Eindhoven
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Grumpy_Mike: Compiles too! I was searching the source codes for what _SFR_IO8 exactly does, possibly it just does your little trick.

Thnx.
Logged

Offline Offline
Edison Member
*
Karma: 17
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To find out what exactly what code a bunch of macros generate, I like to just run the compiler with the -E switch
1. Turn on verbose mode (in preferences(1.0) or hold shift(0022))
2. Compile
3. Copy first line (from where is says blahbalh/avr-g++ to the next time it says it) into a command prompt/terminal
4. there should be a word "-c" in it. Change that to "-E"
5. After -o, there's a path to a file. Change the name to some thing like sketch.preprocessed (optional)
6. hit enter
7. read sketch.preprocessed, and scroll all the way to the bottom, where your sketch is
8. ???
9. PROFIT
Logged

Eindhoven
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
_SFR_IO8( regNum ) = ( _SFR_IO8( regNum ) & maskAnd ) ^ maskEor;

Code:
(*(volatile uint8_t *)((regNum) + 0x20)) = ( (*(volatile uint8_t *)((regNum) + 0x20)) & maskAnd ) ^ maskEor;

Cool! This little work instruction is useful information for troubleshooting and future reference smiley
Logged

Pages: [1]   Go Up
Jump to: