I am trying to turn led on STM32F103 blue pill's PB1 port using bare metal assembly code. For the first step I want to initialize stack pointer in reset_handler subroutine and then execute LED related code. Enable RCC on APB2_ENR register, configure GPIO_CRL and GPIO_ODR registers respectively. The code is below, but seems that it doesn't work. Please advice what are the mistakes.
stack_size = 0x400
stack_start = 0x20000000+stack_size
gpiob_base = 0x40010C00
rcc_base = 0x40021000
rcc_apb2enr = rcc_base+0x18
gpio_crl = gpiob_base
gpiob_odr = gpiob_base+0x0C
.syntax unified
.cpu cortex-m3
.thumb
.global main
.global vtable
main:
; Enable RCC Clock on ABP2
LDR R0, =rcc_apb2enr
AND R0, #0x00000000
ORR R0, #0x4
STR R0, [rcc_apb2enr]
; Configure GPIO_CRL
LDR R0, #0x44444444 ; Registry reset value
STR R0, [gpio_crl] ; Reset register
LDR R0, #0x2
LDR R1, =gpio_crl ; Load register
ORR R1, R0 ; set bit 2 - on
STR R1, [gpio_crl]
; Configure GPIOB_ODR
LDR R0, #0x0 ; set reset value
STR R0, [gpiob_odr] ; reset register
LDR R0, #0x2
LDR R1, =gpiob_odr
ORR R1, R0
STR R1, [gpiob_odr]
vtable:
.word stack_start
.word reset_handler
reset_handler:
LDR R0, =stack_start
MOV SP, R0
You have mistaken loading a literal with loading from the address pointed to by the literal.
The value =rcc_apb2enr
means an address in ROM that is part of your program where you have stored the address of the register. You need to load this first, then load the value from the address pointed to by it. You can then write back to the same address.
Change the two instructions:
LDR R0, =rcc_apb2enr
...
... change the value of R0
...
STR R0, [rcc_apb2enr]
to something like:
LDR R0, =rcc_apb2enr
LDR R1, [R0]
...
...change the value of R1
...
STR R1, [R0]
(Also, your AND instruction is zeroing-out the previous contents of the enable register - this is probably not what you want. To enable something you only need to set bits.)