Rpi cheat sheet
Code
structure:
Main
program
(.text):
u
Ini:alize
Vector
Table
(IRQ/FIQ)
v
Init
the
stack/s
for
FIQ/IRQ
modes
w
Init
the
stack
for
SVC
mode
(SVC
mode
selected)
x
Configure
GPIOs
(I&O)
Tx
y
Configure
peripheral
interrup:on:
:mer/push-‐buLons)
Rx
z
Local
enabling
of
configured
interrupts
{Global
enabling
of
interrupts
(SVC
mode)
|Infinite
loop
(polling
of
device/s?)
IRQ/FIQ
Handler:
u
Push
registers
to
be
used
v
Source
of
interrup:on?
w
Perform
handler
work
depending
on
v
x
Clear
event
(no:fy
to
device
IRQ/FIQ
has
been
served)
y
Pop
registers
z
Return
from
handler
GPIO: configuration as I/O(1), write(2), read(3)
• 000:
Input
pin
• 001:
Output
pin
GPFSEL0-5 (3F20 0000) 1.
Configure:
GPIO9
as
Output
• 010-‐111:
Other
modes
X
FSEL9
FSEL8
FSEL7
FSEL6
FSEL5
FSEL4
FSEL3
FSEL2
FSEL1
FSEL0
001
GPSET0-1 (3F20 001C) 2.
Wri:ng
1:
Set
GPIO9
(turn
the
led
on)
SET31
SET30
SET29
SET28
SET27
SET26
SET25
SET24
SET23
SET22
SET21
SET20
SET19
SET18
SET17
SET16
SET15
SET14
SET13
SET12
SET11
SET10
SET9
SET8
SET7
SET6
SET5
SET4
SET3
SET2
SET1
SET0
1
GPCLR0-1 (3F20 0028) 2.
Wri:ng
0:
Clear
GPIO9
(turn
the
led
off)
CLR31
CLR30
CLR29
CLR28
CLR27
CLR26
CLR25
CLR24
CLR23
CLR22
CLR21
CLR20
CLR19
CLR18
CLR17
CLR16
CLR15
CLR14
CLR13
CLR12
CLR11
CLR10
CLR9
CLR8
CLR7
CLR6
CLR5
CLR4
CLR3
CLR2
CLR1
CLR0
1
3.
Read:
GPIO2
GPLEV0-1 (3F20 0034)
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
Rpi 3: change HYP mode to SVC mode
y
Step
0
.text
mrs r0,cpsr
mov r0, #0b11010011 @ Modo SVC, FIQ&IRQ desact
msr spsr_cxsf,r0
add r0,pc,#4
msr ELR_hyp,r0
eret
Example: Code for checking push button
(GPIO2) and turning led (GPIO9) on
.set GPBASE, 0x3F200000
.set GPFSEL0, 0x00
.set GPSET0, 0x1c
.set GPLEV0, 0x34
.text
ldr r0, =GPBASE x
Configure
GPIOs
(I&O)
/* guia bits xx999888777666555444333222111000 */
mov r1, #0b00001000000000000000000000000000
str r1, [r0, #GPFSEL0]
/* mask for testing GPIO2 */
mov r2, #0b00000000000000000000000000000100 |
Polling,
infinite
loop
bucle:
ldr r3, [r0, #GPLEV0]
tst r3, r2
bne bucle
/* guia bits 10987654321098765432109876543210
mov r1, #0b00000000000000000000001000000000
str r1, [r0, #GPSET0]
infi: b infi
Timer (polling example)
M3
M2
M1
M0
STBASE
STCS 3F20 3000 CS
3F20 3004 CLO
Ascending
counter
low
bytes
CHI
Ascending
counter
high
bytes
3F20 3008
(CHI:CLO
increments
each
microsecond)
STCLO 3F20 300C C0
Compare
registers:
if
any
one
of
them
is
equal
to
CLO,
STC1 3F20 3010 C1
then
corresponding
bit
Mx
in
CS
is
set
and
interrupt
is
3F20 3014 C2
provoked
(if
it
is
enabled).
C0
and
C3
are
used
by
the
C3
GPU
3F20 3018
Delay
loop
(polling)
ldr r0, =STBASE @ r0 is an input parameter (ST base address)
ldr r1, =500000 @ r1 is an input parameter (waiting time in microseconds)
espera: push {r4, r5} @ Save r4 and r5 in the stack
ldr r4, [r0, #STCLO] @ Load CLO timer
add r4, r1 @ Add waiting time -> this is our ending time
ret1: ldr r5, [r0, #STCLO] @ Enter waiting loop: load current CLO timer
cmp r5, r4 @ Compare current time with ending time
blo ret1 @ If lower, go back to read timer again
pop {r4, r5} @ Restore r4 and r5
bx lr @ Return from routine
IRQ (timer, push-button). Main program.
u
Ini2alize
Vector
Table
(IRQ)
y
Configure
push-‐buJon
interrup2on
(GPIO
2)
mov r0, #0
ldr
r0,=GPBASE
ADDEXC 0x18, irq_handler
mov
r1,
#0b00000000000000000000000000000100
str
r1,
[r0,
#GPFEN0]
v
Stack
init
for
IRQ
mode
mov r0, #0b11010010
z
Enable
push-‐buJon
interrup2on
(IRQ):
msr cpsr_c, r0
ldr
r0,
=INTBASE
mov sp, #0x8000
mov
r1,
#0b00000000000100000000000000000000
w
Stack
init
for
SVC
mode
/*
guia
bits
10987654321098765432109876543210*/
mov r0, #0b11010011
str
r1,
[r0,
#INTENIRQ2]
msr cpsr_c, r0
mov sp, #0x8000000
Enable
IRQ
1
(:mer)
3F00B210
(INTBASE+INTENIRQ1)
y
Configure
2mer
IRQ
ldr
r0,
=STBASE
ldr
r1,
[r0,
#STCLO]
add
r1,
#y
@y
microseconds
GPFEN0
(push-‐buLon
falling-‐edge
interrupt
configura:on,
GPIO
2)
str
r1,
[r0,
#STC1]
3F200058
(GPBASE+GPFEN0)
z
Enable
2mer
interrupt
by
comparator
C1:
ldr
r0,=INTBASE
mov
r1,
#0b0010
Enable
IRQ
2
(any
push-‐buLon
falling-‐edge
interrupt
enabling)
str
r1,[r0,#INTENIRQ1]
3F00B214
(INTBASE+INTENIRQ2)
IRQ
pending
2
{
Enable
IRQ
(SVC
mode):
mov
r1,
#0b01010011
msr
cpsr_c,
r1
20
IRQ (timer, push-button). Handler.
Timer:
u
Push
registers
to
be
used
Push-button:
push
{r0,
r1,
r2}
v
Source
of
:mer
interrup:on?:
v
Source
of
interrup:on?.
Check
if
push-‐buLon
(2)
was
pressed
ldr
r0,
=STBASE
ldr
r0,
=GPBASE
ldr
r2,
[r0,
#STCS]
ldr
r2,
[r0,
#GPEDS0]
ands
r2,
#0b0010
@C1?
ands
r2,
#0b00000000000000000000000000000100
...
...
ldr
r2,
[r0,
#STCS]
ands
r2,
#0b1000
@C3?
GPEDS0
(push-‐buLon
falling-‐edge
interrupt
no:fica:on)
20200040
(GPBASE+GPEDS0)
x
Clear
event
(2mer
interrupt
C1/C3)
x
Clear
event
(interrupt
by
push-‐buJon
(2)
)
(to
allow
a
new
interrupt):
(to
allow
a
new
interrupt):
ldr
r0,
=STBASE
ldr
r0,
=GPBASE
mov
r1,
#0b0010
@C1
mov
r1,
#0b00000000000000000000000000000100
str
r1,[r0,#STCS]
str
r1,
[r0,
#GPEDS0]
...
mov
r1,
#0b1000
@C3
str
r1,[r0,#STCS]
y
Pop
registers
pop
{r0,
r1,
r2}
z
Return
from
handler
subs
pc,
lr,
#4
Select FIQ Source = 7 bits à 128 sources
Using FIQ 0-31 represent 32 interruption sources of IRQ 1
32-63 represent 32 interruption sources of IRQ 2
64-95 represent 32 interruption sources of IRQ basic
3F00B20C
(INTBASE+INTFIQCON)
Enable
Source
Select
control
FIQ
FIQ
31
30
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
FIQ
29
8
z
Also
1
in
FIQ
Enable
• Enable
FIQ
for
C1
of
– • Enable
FIQ
for
C3
of
– Result:
0b10000001
à
0x81
SysTimer
SysTimer
– Bit
1
of
IRQ1
à
Code
1
– Bit
3
of
IRQ1
à
Code
3
– Also
1
in
FIQ
Enable
– Result:
0b10000011
à
0x83
z
Enable
push-‐buJon
interrup2on
(FIQ):
ldr
r0,
=INTBASE
• Enable
FIQ
for
GPIO_int3
u
Ini2alize
Vector
Table
mov
r1,
#0b10110100
(any
push
buLon
(FIQ)
str
r1,
[r0,
#INTFIQCON]
– Bit
20
of
IRQ2
à
Code
20+32
mov r0, #0 – Also
1
in
FIQ
Enable
ADDEXC 0x1C, irq_handler z
Enable
C3
interrup2on
(FIQ):
– Result:
0b10110100
à
0xB4
v
Stack
init
for
FIQ
mode
ldr
r0,
=INTBASE
mov
r0,
#0b11010001
mov
r1,
#0b10000011
msr
cpsr_c,
r0
str
r1,
[r0,
#INTFIQCON]
mov
sp,
#0x4000
{
Enable
FIQ
and
IRQ
(SVC
mode):
mov
r1,
#0b00010011
msr
cpsr_c,
r1
Example: Timer in IRQ and push button in FIQ
.include "inter.inc"
.text
ADDEXC 0x18, irq_handler
ADDEXC 0x1c, fiq_handler
mov r0, #0b11010001
msr cpsr_c, r0 Stack
init
for
FIQ
mode
mov sp, #0x4000
mov r0, #0b11010010
msr cpsr_c, r0 Stack
init
for
IRQ
mode
mov sp, #0x8000
mov r0, #0b11010011
msr cpsr_c, r0 Stack
init
for
SVC
mode
mov sp, #0x8000000
ldr r0, =GPBASE
mov r1, #0b00001000000000000000000000000000 Set
GPIO9
as
output
str r1, [r0, #GPFSEL0]
mov r1, #0b00000000000000000000000000000100
str r1, [r0, #GPFEN0] Enable
FE
ints
through
GPIO2
ldr r0, =STBASE
ldr r1, [r0, #STCLO] Program
:mer
to
add r1, #0x400000
str r1, [r0, #STC1] interrupt
in
4
seconds
ldr r0, =INTBASE
mov r1, #0b00000010 Enable
C1
interrup:on
str r1, [r0, #INTENIRQ1]
mov r1, #0b10110100
str r1, [r0, #INTFIQCON] Enable
FIQ
for
GPIO_int3
mov r0, #0b00010011
msr cpsr_c, r0 Set
SVC
mode
with
FIQ
and
IRQ
enabled
bucle: b bucle
9
Example: IRQ and FIQ handlers
fiq_handler:
push {r0, r1, r2}
ldr r0, =GPBASE
ldr r1, =onoff
ldr r2, [r1] Update
onoff
variable
eors r2, #1
str r2, [r1]
and
test
if
its
0
or
1
mov r1, #0b00000000000000000000001000000000
streq r1, [r0, #GPCLR0] Turn
on
or
off
red
led
strne r1, [r0, #GPSET0]
mov r1, #0b00000000000000000000000000000100
str r1, [r0, #GPEDS0] Clear
GPIO2
interrupt
pop {r0, r1, r2}
subs pc, lr, #4
irq_handler:
push {r0, r1, r2}
ldr r0, =GPBASE
ldr r1, =onoff
ldr r2, [r1] Update
onoff
variable
eors r2, #1
and
test
if
its
0
or
1
str r2, [r1]
mov r1, #0b00000000000000000000001000000000
strne r1, [r0, #GPSET0] Turn
on
or
off
red
led
streq r1, [r0, #GPCLR0]
ldr r0, =STBASE
mov r1, #0b0010 Clear
:mer
interrupt
str r1, [r0, #STCS]
A
variable
ldr r1, [r0, #STCLO]
Program
:mer
to
add r1, #0x400000
str r1, [r0, #STC1] interrupt
in
4
seconds
pop {r0, r1}
subs pc, lr, #4 10
onoff: .word 0