Study Web

Week 7

ASM Programming: Turning on an LED (Part

COS10004 Computer Systems · Lecture 7.5 ASM Programming: Turning on an LED (Part

2) – the GPIO chip

FIRST WE WIRE IT UP

See https://www.youtube.com/watch?v=Rd9kvVs1lSQ for my tutorial on wiring this circuit

We “write” bits to the LED via this pin

See https://www.youtube.com/watch?v=Rd9kvVs1lSQ for my tutorial on wiring this circuit

This is the ground pin

We “write” bits to the LED via this pin

See https://www.youtube.com/watch?v=Rd9kvVs1lSQ for my tutorial on wiring this circuit

TURNING ON AN LED

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

TURNING ON AN LED

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

What about these numbers?

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

Where did they come from

mov r1,#1 And what do they mean ?
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register These numbers all refer to

settings and programming of

mov r1,#1 the GPIO registers.
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register To understand this part of the

Code we need to understand loop$: what the GPIO chip is, and b loop$;loop forever how we interface with it to read to and write from the GPIO header pins.

GPIO

  • The General Purpose Input/Output chip
  • The GPIO chip has 54 registers which can be read, set high or set low.
  • They are referred to as GPIO0, GPIO1 …
  • Some are connected to physical pins on the R Pi board
  • Others are connected to hardware on the board.

GPIO LAYOUT FOR RPI 2B, 3B AND 4

SETTING A HARDWARE PIN ON

  • Establish which GPIO is associated with the Pin.
  • Find the associated “function” register and set appropriate bits to indicate your intention to write to that GPIO
  • Find the appropriate “write” register and set the output bit to 1.
  • Establish which GPIO is associated with the Pin.
  • Find the associated “function” register and set appropriate bits to indicate your intention to write to that GPIO
  • Find the appropriate “write” register and set the output bit to 1.

OK – BACK TO THIS FLASHY LED THING

We “write” bits to the LED via this pin

This is the ground pin

We “write” bits to the LED via this pin

SO WHICH GPIO REGISTER?

  • Now locate the “writing” pin in the diagram GPIO register
  • Now locate the “writing” pin in the diagram GPIO register
  • It is GPIO18
  • So the LED is controlled via

GPIO18.

  • The pin has to be pulled up to turn on LED.
  • But some other things need to happen first

BASE ADDRESS AND GPIO OFFSET

  • In our ASM program we will need to access the correct GPIO registers and set specific bits.
  • We first need to know where in memory the location of these registers are.
  • Specifically we need to know:
  • The BASE address: for all memory we need to access
  • The GPIO offset: the number of bytes from the base address from which GPIO registers start.
  • For RPi 2B/3B/3B+: BASE = $3F000000; $ means HEX

GPIO_OFFSET=$200000

  • For RPi 4:

BASE = $FE000000

GPIO_OFFSET=$200000

PSEUDOCODE

  • store location of GPIO (BASE + GPIOADDR) in r0
  • Enable “writing” for GPIO18 (our LED)
  • we need to set certain bits in the “function” register to program GPIO18 for writing
  • Set output of GPIO18
  • Light on: set bit in the appropriate “write 1” register
  • Light off: set bit in the appropriate “write 0” register
  • loop forever

FYI: TURN PWR LED OFF (B+, 2 ONLY)

  • store location of GPIO (BASE + GPIOADDR) in r0
  • enable output function on GPIO35 (red LED)
  • r1 set to 2^15
  • store r1 into [r0 + 12] #dereferences value in r0+12
  • set output of GPIO35 (32 + 3) (turn PWR light off!)
  • r1 set to 2^3 or
  • store r1 into [r0 +44];pull low(light off) 40+4
  • store r1 into [r0 +32];pull high(light on) 32 = 28+4
  • loop forever

But Chris!

How do you know what bits to set for a particular GPIO?

start of the BASE+ Each pin programmed by a GPIO (RPi 2/3). Add 3-bit number. Those this address to 1. SELECT FUNCTION numbers are packed into everything in the 30 bits of each word

GPIO

Add 4 bytes (1 word) each time we go above 30 bits (10 GPIO pins)

3 registers control Each pin programmed writing 0, writing 1 by a 1-bit number. 32

or reading each 2. SET VALUE (R/W) numbers are packed pin. into 32 bits of each word.

Some GPIO pins need to be sent a 0 to turn the pin on, others need a 1 to turn on.

PSEUDOCODE

  • store location of GPIO (BASE + GPIO_OFFSET) in r0
  • Enable “writing” for GPIO18 (our LED)
  • Set the 24th bit of r1 (ie r1 = 2^24 or 0x800000)
  • store r1 into [r0 + 4];dereferences value in r0+4
  • set output of GPIO18
  • r1 set to 2^18 or
  • store r1 into [r0 + 28] (light on)
  • loop forever

SO NOW BACK TO THE CODE TO SEE THIS!

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

SO NOW BACK TO THE CODE TO SEE THIS!

BASE = $FE000000 ; $ means HEX Enable “writing” for GPIO18
GPIO_OFFSET=$200000 (our LED)

th

mov r0,BASE • Set the 24 bit of r1
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000 • store r1 into [r0 + 4]

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

SO NOW BACK TO THE CODE TO SEE THIS!

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000
Write “1” to GPIO18 by:
mov r1,#1 • Setting the 18th bit to 1 in
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24 r1
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register • store r1 into memoery
location [r0 + 28]
mov r1,#1 • This turns the LED on
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

SO NOW BACK TO THE CODE TO SEE THIS!

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

Loop forever so we do not loop$: b loop$;loop forever “fall off the cliff”!

WHY THE LOOP AT THE END?

  • Computer endlessly follows a continuous instruction cycle until switched off
  • A special register known as the Program Counter (PC) keeps track of the next instruction to execute
  • PC is a digital counter:
  • It blindly increments automatically after each instruction (but has no idea what its pointing to!)
  • Also set by branch instructions like “b” which jump control to a new instruction address
  • The infinite loop stops the PC addressing locations that are not part of the program
  • Keeps it in an infinite holding pattern

DESIGN PATTERN FOR OUR ASM

  1. Set BASE address, GPIO_OFFSET address, put in r0
BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000
mov r0,BASE
orr r0,GPIO_OFFSET
  1. Select GPIO by shifting 1 (using lsl) to required position (within 32-bit number)
  2. lsl r1,#21
  3. if more than 32, subtract 32 and add 4 (4 bytes) to offset
  4. Select action by storing selection in appropriate register by adding register offset to GPIO base address
  5. str r1,[r0,#32];or 32+offset

DESIGN PATTERNS…

  • Step 0 would only be done once – setting up the hardware, constants.
  • Repeat steps 1 and 2 for each new action:
  • program a GPIO (for input, output, other functions) (registers 0-27)
  • Pull a register high (registers 28-31)
  • Pull a register low (registers 32-

HOW TO RUN IT YOURSELF

  • Launch FASMARM from where ever you installed it (just an exe file)

WRITE THE CODE INTO THE EDITOR

; means comment

COMPILE

  • Save
  • Run / Compile (Ctrl + F9)
  • Read any errors and fix
  • Successful compilation

COPY TO SD

  • Copy <filename>.bin to your correctly formatted micro SD card
  • Rename <filename>.bin to kernel7.img
  • Wait or dismount card
  • Remove card (and adapter)
  • Plug micro SD card into Pi
  • Power-on Pi
  • Be amazed!

THE LAB

  • You’re going to do this!
  • You will also have more opportunities to get your head around the GPIO programming:
  • We will be doing this for a few weeks!

SUMMARY

  • Assembly language is the lowest level of human readable programming
  • Extremely close to native machine code
  • RISC versus CISC instruction sets define major differences between CPU architectures:
  • ARM is RISC, Intel is CISC
  • ARM asm basics
  • GPIO interface
  • Oh yeah.. AND we wired up and turned on an LED!