Skip to content

Instantly share code, notes, and snippets.

@BobBurns
Created August 14, 2015 21:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BobBurns/a0ba8c4bdf09d094cea7 to your computer and use it in GitHub Desktop.
Save BobBurns/a0ba8c4bdf09d094cea7 to your computer and use it in GitHub Desktop.
cylon eyes program in arm assembly for stm32L discovery
@ cylon eyes for stm32L discovery
@ uses lcd software driver 1/4 duty 1/3 bias
@ how to compile and flash:
@ arm-none-eabi-as -mcpu=cortex-m3 cylon_eyes.s -o cylon_eyes.o
@ arm-none-eabi-ld -v -T stm32.ld -nostartfiles -o cylon_eyes.elf cylon_eyes.o
@ arm-none-eabi-objcopy -O binary cylon_eyes.elf cylon_eyes.bin
@ then from st-link (https://github.com/texane/stlink)
@ ./st-flash write ../first_arm/cylon_eyes.bin 0x08000000
.thumb
.syntax unified
@ Equates
count .req r7
.equ STACKINIT, 0x20005000
.equ RCC, 0x40023800 @ RCC base address
.equ _AHBRSTR, 0x10 @ reset register
.equ _AHBENR, 0x1C @ enable clock
.equ _APB1ENR, 0x24 @ enable pwr lcd clock
.equ _APB2ENR, 0x14 @ for syscfg
.equ _AHBLPENR, 0x28 @ enable low power
.equ _CSR, 0x34 @ control status reg
.equ GPIOA, 0x40020000
.equ GPIOB, 0x40020400
.equ GPIOC, 0x40020800
.equ GPIOD, 0x40020C00
.equ _MODER, 0x00 @ port B mode
.equ _OTYPER, 0x04 @ type push-pull
.equ _OSPEEDR, 0x08 @ port pin clock speed
.equ _PUPDR, 0x0C @ pull-up pull-down
.equ _ODR, 0x14 @ output data
.equ _AFRL, 0x20
.equ _AFRH, 0x24 @ alternate function reg
.equ PWR_CR, 0x40007000 @ power cr for bu write disable
.equ LCD, 0x40002400
.equ _CR, 0x00
.equ _FCR, 0x04
.equ LCD_SR, 0x08 @status reg for enable bits
.equ _COM0, 0x14
.equ _COM1, 0x1C
.equ _COM2, 0x24
.equ _COM3, 0x2C
.equ RTC, 0x40002800
.equ RTC_WPR, 0x24
.equ LEDDELAY, 400000
.section .data
commap0:
.word 0x00000001, 0x00000004, 0x00000100, 0x00000400, 0x00001000, 0x00004000
commap1:
.word 0x20000000, 0x08000000, 0x02000000, 0x00200000, 0x00080000, 0x00010000
.section .text
.org 0
@ Vectors
vectors:
.word STACKINIT
.word _start + 1
.word _nmi_handler + 1
.word _hard_fault + 1
.word _memory_fault + 1
.word _bus_fault + 1
.word _usage_fault + 1
_start:
@ power interface clock enable
ldr r6, =RCC
ldr r5, [r6, _APB1ENR]
mov r4, 0x01
orr r5, r5, r4, lsl 28 @pwr enable bit 28
str r5, [r6, _APB1ENR]
@ disable rtc write protection
ldr r6, = PWR_CR
ldr r5, [r6]
mov r4, 0x01
orr r5, r5, r4, lsl 8 @DBP bit 8
str r5, [r6]
@ enable LSI clock
ldr r6, =RCC
ldr r5, [r6, _CSR]
mov r4, 0x02
orr r5, r5, r4, lsl 16 @ RTCSEL select LSI as RTC clock 1:0
str r5, [r6, _CSR]
ldr r5, [r6, _CSR]
mov r4, 0x01
orr r5, r5, r4, lsl 22 @ RTCEN
str r5, [r6, _CSR]
ldr r6, = RTC
mov r5, 0xca
str r5, [r6, RTC_WPR] @write 0xca and 0x53 to disable protection
mov r5, 0x53
str r5, [r6, RTC_WPR]
@ enable the clock of LCD
ldr r6, =RCC
ldr r5, [r6, _APB1ENR]
mov r3, 1
orr r5, r5, r3, lsl 9
str r5, [r6, _APB1ENR]
@ enable syscfg?
ldr r5, [r6, _APB2ENR]
mov r4, 0x01
orr r5, r5, r4
str r5, [r6, _APB2ENR]
@ enable LSI and wait until LSI is ready
ldr r5, [r6, _CSR]
orr r5, r5, 0x01 @ LSION
str r5, [r6, _CSR]
lsirdy_lp:
ldrb r5, [r6, _CSR]
tst r5, 0x02
beq lsirdy_lp
@ select lsi as lcd clock source
ldr r5, [r6, _CSR]
mvn r4, 0x00
movt r4, 0xfffd
and r5, r5, r4
str r5, [r6, _CSR]
ldr r5, [r6, _CSR]
mov r4, 0x00
movt r4, 0x0002
orr r5, r5, r4
str r5, [r6, _CSR] @reset and set rtcsel_lsi like book
ldr r5, [r6, _CSR]
mov r3, 0x01
orr r5, r5, r3, lsl 22
str r5, [r6, _CSR]
@ enable write protection
ldr r6, =PWR_CR
ldr r5, [r6]
mvn r4, 0
movt r4, 0xfffe
and r5, r5, r4
str r5, [r6]
@**** end init sequence ****
ldr r6, =RCC
@***** Configure LCD GPIO as Alternative Functions ****
@ enable clock on GPIO ABC
ldr r5, [r6, _AHBENR]
orr r5, r5, 0x07
str r5, [r6, _AHBENR]
@ setup af mode on GPIOA 1,2,3,8,9,10,15
ldr r6, = GPIOA
ldr r5, [r6, _MODER]
mov r4, 0x00A8
movt r4, 0x800A
orr r5, r5, r4
str r5, [r6, _MODER]
@ GPIOA set AF 1011
mov r4, 0xbb
mov r5, r4, lsl 8
movt r5, 0
orr r5, r5, 0xb0
@ ldr r5, = 0x0000BBB0
str r5, [r6, _AFRL] @ low register
mov r4, 0xbb
mov r5, r4, lsl 4
orr r5, r5, 0x0b
movt r5, 0xb000
@ ldr r5, = 0xB0000BBB
str r5, [r6, _AFRH] @ high register
@ setup af mode on GPIOB 3,4,5,8,9,10,11,12,13,14,15
ldr r6, = GPIOB
ldr r5, [r6, _MODER]
@ ldr r4, = 0xAAAA0A80
mov r3, 0xA8
mov r4, r3, lsl 0x04
movt r4, 0xaaaa
orr r5, r5, r4
str r5, [r6, _MODER]
@ GPIOB set AF 1011
@ ldr r5, = 0x00BBB000
mov r3, 0x0b
mov r4, r3, lsl 0x0c
movt r4, 0x00BB
str r4, [r6, _AFRL]
@ ldr r5, = 0xBBBBBBBB
mov r3, 0xbb
mov r4, r3, lsl 0x08
orr r4, r4, 0xbb
movt r4, 0xbbbb
str r4, [r6, _AFRH]
@ setup af mode on GPIOC 0,1,2,3,6,7,8,9,10,11
ldr r6, = GPIOC
ldr r5, [r6, _MODER]
@ ldr r4, = 0x00AAA0AA
mov r3, 0xa0
mov r4, r3, lsl 0x08
orr r4, r4, 0xaa
movt r4, 0x00aa
orr r5, r5, r4
str r5, [r6, _MODER]
@ GPIOC set AF 1011
@ ldr r5, = 0xBB00BBBB
mov r3, 0xbb
mov r4, r3, lsl 0x08
orr r4, r4, 0xbb
movt r4, 0xbb00
str r4, [r6, _AFRL]
@ ldr r5, = 0x0000BBBB
mov r3, 0xbb
mov r4, r3, lsl 0x08
orr r4, r4, 0xbb
str r4, [r6, _AFRH]
@********* LCD Configuration *******
@ set bias 1/3, duty 1/4
@ bias 6:5 = 1:0 = 0x40
ldr r6, = LCD
ldr r5, [r6, _CR]
mov r4, 0x40
orr r5, r5, r4
str r5, [r6, _CR]
@ duty 4:2 = 011 = 0x0C
ldr r5, [r6, _CR]
mov r4, 0x0C
orr r5, r5, r4
str r5, [r6, _CR]
@ configure CC of LCD_FCR to max value 111
ldr r5, [r6, _FCR]
mov r4, 0x07
orr r5, r5, r4, lsl 10
str r5, [r6, _FCR]
@ configure PON to 111
ldr r5, [r6, _FCR]
mov r4, 0x70
orr r5, r5, r4
str r5, [r6, _FCR]
@ enable mux segment of LCD_CR
ldr r5, [r6, _CR]
mov r4, 0x80
orr r5, r5, r4
str r5, [r6, _CR]
@ select internal voltage on VSEL
ldr r5, [r6, _CR]
mvn r4, 2
movt r4, 0xffff
and r5, r5, r4
str r5, [r6, _CR]
@ wait until FCRSF flag is set
fcrsf_lp:
ldrb r5, [r6, LCD_SR]
tst r5, 0x20
beq fcrsf_lp
@ enable lcd
ldr r5, [r6, _CR]
mov r4, 0x01
orr r5, r5, r4
str r5, [r6, _CR]
enr_lp:
ldrb r5, [r6, LCD_SR]
tst r5, 0x01
beq enr_lp
rdy_lp:
ldrb r5, [r6, LCD_SR]
tst r5, 0x10
beq rdy_lp
@ set up addressing
ldr r2, =commap0
ldr r3, =commap1
mov count, 5
ldr r6, =LCD @ r6 is always lcd during loop
@ check UDR bit loop until clear
bl udr_rdy
@ now we can modify lcd ram
move_rt:
ldr r0, [r2], 4
str r0, [r6, _COM0]
ldr r1, [r3], 4
str r1, [r6, _COM1]
ldr r5, [r6, LCD_SR]
mov r4, 0x04
orr r5, r5, r4 @set UDR bit
str r5, [r6, LCD_SR]
bl udd_rdy
bl udr_rdy
bl delay1
mvn r0, r0
mvn r1, r1 @ not to clear
ldr r5, [r6, _COM0]
and r5, r5, r0
str r5, [r6, _COM0]
ldr r5, [r6, _COM1]
and r5, r5, r1
str r5, [r6, _COM1]
ldr r5, [r6, LCD_SR]
mov r4, 0x04
orr r5, r5, r4 @ set UDR bit in lcd sr
str r5, [r6, LCD_SR]
bl udd_rdy
bl udr_rdy
subs count, 1
bgt move_rt
mov count, 5
move_lt:
ldr r0, [r2], -4
str r0, [r6, _COM0]
ldr r1, [r3], -4
str r1, [r6, _COM1]
ldr r5, [r6, LCD_SR]
mov r4, 0x04
orr r5, r5, r4 @set UDR bit
str r5, [r6, LCD_SR]
bl udd_rdy
bl udr_rdy
bl delay1
mvn r0, r0
mvn r1, r1 @ not to clear
ldr r5, [r6, _COM0]
and r5, r5, r0
str r5, [r6, _COM0]
ldr r5, [r6, _COM1]
and r5, r5, r1
str r5, [r6, _COM1]
ldr r5, [r6, LCD_SR]
mov r4, 0x04
orr r5, r5, r4 @ set UDR bit in lcd sr
str r5, [r6, LCD_SR]
bl udd_rdy
bl udr_rdy
subs count, 1
bgt move_lt
mov count, 5
b move_rt
@ *************** subroutines *******************
udr_rdy:
ldrb r5, [r6, LCD_SR]
tst r5, 0x04
bne udr_rdy
bx lr
udd_rdy:
ldrb r5, [r6, LCD_SR]
tst r5, 0x08
beq udd_rdy
bx lr
delay1:
ldr r8, = LEDDELAY
d_lp:
subs r8, 1
bne d_lp
bx lr
@ if any int gets triggered, just loop
_dummy:
_nmi_handler:
_hard_fault:
_memory_fault:
_bus_fault:
_usage_fault:
add r0, 1
add r1, 1
b _dummy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment