Adam
Adam

Reputation: 41

Calculate GPIO address

GPIO_MODER Port mode register

Each pin uses two bits.

00 = input
01 = output

In an example they configure pins 15-8 as inputs and pins 7-0 as outputs.

@ arm assembly
LDR R0,=0x40020C00
LDR R1,=0x00005555
STR R1,[R0]
/* c */
*( (unsigned long *)0x40020C00) = 0x5555;

This is the first example in the chapter "General Purpose IO" and I am completely lost. I thought I had figured out how they got 0x00005555 but now I do not know. If each pin uses two bits and 01 is output I get 01 01 01 01 which is 0x55 and not 0x5555. They use 16 bits to get 0x5555 = 0101 0101 0101 0101 and I do not understand why.

Now to pins 15-8. Here I do not understand anything sadly. 00 is for input so I get 00 00 00 00. Then there is an offset 0x01 which I do not understand how it should be used.

Any help is greatly appreciated, I am in need of a more simpler example to understand I guess.


EDIT: So I mixed up the bits and pins, thanks NoTengoBattery. I understand 0101 0101 0101 0101 = 0x5555. But I still do not understand how I get to 0x40020C00 from 0000 0000 0000 0000.

Upvotes: 0

Views: 1305

Answers (2)

yano
yano

Reputation: 5265

It looks like you're getting lost converting binary to hex. Remember, every four bits can be expressed as a single hex character. The following is a breakdown of where they derive 0x5555 based on what you've described (I've split the whole register into two parts for my own sanity dealing with word wrap in this answer box, but imagine they're mashed together):

       |pin15|pin14|pin13|pin12|pin11|pin10|pin09|pin08|
bit    |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|
bin 0b |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
hex 0x |     0     |     0     |     0     |     0     |

       |pin07|pin06|pin05|pin04|pin03|pin02|pin01|pin00|
bit    |15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00|
bin 0b |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |
hex 0x |     5     |     5     |     5     |     5     |

Put is all together and you get 0x00005555. 0x40020C00 is apparently the address of this register. *( (unsigned long *)0x40020C00) casts 0x40020C00 to an unsigned long pointer, then dereferences that pointer to write 0x00005555 to that address with = 0x5555;.

Upvotes: 3

NoTengoBattery
NoTengoBattery

Reputation: 81

I think that your confusion comes from understanding the text, not the concept. You said:

... and pins 7-0 as outputs ...

That's 8 pins. After that, you said:

... and 01 is output I get 01 01 01 01 which is 0x55 ...

If you see how you separated it yourself, you are only considering 4 pins, not 8. If you consider 4 pins you are right, it's 0x55. If you consider 8 pins, its 0b0101010101010101 which is, indeed, 0x5555.

Upvotes: 3

Related Questions