Created
August 14, 2015 21:05
-
-
Save BobBurns/a0ba8c4bdf09d094cea7 to your computer and use it in GitHub Desktop.
cylon eyes program in arm assembly for stm32L discovery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@ 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