DISCLAIMER: I am no expert in Assembler or manipulating Raspberry Pi's, this blog entry only describes what worked for me.
Hey, first post, kinda forgot I created this blog.
I wanted to turn on the ACT LED on a Raspberry Pi B+ and make it blink, and found this 'Baking Pi' tutorial by Robert Mullins:
Problem is, it's not updated for the Pi B+, so of course everything couldn't be so perfect and it didn't work with this model. I had a hard time figuring out how to do this, and a lot of googling and forum reading, so why not blog it so maybe it's useful for someone else.
The first thing we need to know is that instead of working with pin 16, we need to use pin 47. So this changes some stuff, and with this model we actually do need to turn the pin ON. If you read the tutorial, it's the other way round for their model.
The good thing is that the GPIO controller's address is still 0x20200000, and the byte groups are the same:
GPIO Controller
Bytes Function
----------------------------
00 - 23 Function Select
28 - 35 Turn On Pin
40 - 47 Turn Off Pin
52 - 59 Pin Input
Yes, I changed some bytes from the chart in the OK01 lesson because it doesn't make any sense that, for example, group 1 goes from 00 to 24; that makes 25 bytes total, and each word in the processor is 4 bytes long, 4x8 = 24... you get my point. According to the BCM2835 manual, the ommited words are reserved.
Now, the tutorial explains pretty well the first part and the use of the mov, lsl and str commands, but when it begins to talk about the arguments for these commands, IMO it gets unnecesarily complicated, thus making it kind of hard to adapt it to our needs. Here is the first difference in code:
Tutorial B+
---------------------------------
mov r1,#1 mov r1,#1
lsl r1,#18 lsl r1,#21
str r1,[r0,#4] str r1,[r0,#16]
That's cool but... why? Let's take a look at the GPIO "Function Select" byte groups:
Bytes Pins
---------------------
00 - 03 00 - 09
04 - 07 10 - 19
08 - 11 20 - 29
12 - 15 30 - 39
16 - 19 40 - 49
20 - 23 50 - 53
Since we want to enable pin 47, we need bytes 16 to 19 (that's why the 16, it adds 16 bytes FROM the controllers address). We select the first byte from the word that our pin is associated to. Now, inside each word, 3 bytes are associated to each pin, something like this:
So, bit 21 is the first one of the 3-bit-group associated to pin 47. Remember this word is for pins 40 to 49. So what we want to do is put a "1" in the 21st bit. (that's why the 21). Got it? So the mov, lsl and str commands do this for us.
Once you understand that, the rest is pretty simple, specially for turning on and off, since these assign just one bit to every pin.
For turning the LED ON (or off, for the tutorial's model) we need to look at these byte groups:
Bytes Pins
-----------------
28 - 31 00 - 31
32 - 35 32 - 54
This is the code:
Tutorial B+
---------------------------------
mov r1,#1 mov r1,#1
lsl r1,#16 lsl r1,#15
str r1,[r0,#40] str r1,[r0,#32]
Pretty straightforward, we need to stand in byte 32 and add 15 bits, like this (yes I ommited bytes 34 and 35, but they are part of the word):
For turning the LED OFF (or on, for the tutorial's model) we need to look at these byte groups:
Bytes Pins
-------------------
40 - 43 00 - 31
44 - 47 32 - 54
This is the code:
Tutorial B+
---------------------------------
mov r1,#1 mov r1,#1
lsl r1,#16 lsl r1,#15
str r1,[r0,#28] str r1,[r0,#44]
Looks like this:
Remember that for turning the LED ON, in the tutorial they need to actually "turn it off". The next steps (loops and waiting) are the same as the tutorial. I downloaded OK02's solution, and the author seemed to be more efficient than what I did here, but for the sake of this small task it doesn't matter. Obviously it's good practice to always write efficient code :-)
If this helped you, let me know :)