Cannot configure interupts of TIM6 on stm32f103 board
Does my NVIC configuration wrong?
Code:
@ stm32f103 timer & interrupt test by laper_s (from 2019-02-02) .thumb .cpu cortex-m3 .syntax unified .word 0x20005000 .word start + 1 b start .macro mov32 regnum,number movw \regnum,:lower16:\number movt \regnum,:upper16:\number .endm start: mov32 r1, 0x40021018 @ RCC_APB2ENR address mov32 r0, 0x10 @ enable GPIOC str r0, [r1] mov32 r1, 0x4002101c @ RCC_APB1ENR address mov32 r0, 0x10 @ enable TIM6 str r0, [r1] mov32 r1, 0x40011004 @ GPIOC_CRH mov32 r0, 0x44344444 @ set PC13 as 50 MHz PP output str r0, [r1] mov32 r1, 0xE000E104 @ NVIC_ISER1 ldr r0, [r1] orr r0, #0x00400000 @ enable interrupt #54 str r0, [r1] mov32 r1, 0x00000118 @ TIM6 interrupt address adr r0, tim6_interrupt_observer str r0, [r1] mov32 r1, 0x40001024 @ TIM6_CNT movw r0, 0x707 @ set counter strh r0, [r1] mov32 r1, 0x40001028 @ TIM6_PSC movw r0, 0x270f @ set prescaler strh r0, [r1] mov32 r1, 0x4000100c @ TIM6_DIER movw r0, 0x1 @ enable update interrupt strh r0, [r1] mov32 r1, 0x40001000 @ TIM6_CR1 ldrh r0, [r1] orr r0, 0x1 @ enable counter strh r0, [r1] .include "sysclk.inc" loop: b loop tim6_interrupt_observer: mov32 r1, 0x40001010 @ TIM6_SR movw r0, 0x0 @ clear interrupt flag str r0, [r1] mov32 r1, 0x4001100c @ GPIOC_ODR ldr r0, [r1] and r0, #0x2000 cmp r0, #0x2000 ite eq movweq r0, 0x0000 movwne r0, 0x2000 str r0, [r1] bx lr end: b end
Can anyone help me with that?
if I understand correctly vector table starting from 0x0000 0000 address
and I need to put address of my interrupt handler to pre-defined address for some interrupt
from datasheet: TIM6 interrupt allocated at 0x0000 0118 in vectors table
Vanhealsing said:Are you trying to write directly to flash memory?
flash starting from address 0x800 0000 and 0x0000 0118 must be address of internal periph of cortex, is not it?
You can't write directly to flash, you can only reprogram it with compiled binary image. Address of 0x118 seems to be in flash. After booting the microcontroller you can copy vector table to SRAM and then to change address in VTOR register to pointing to vector table in SRAM, after that you can write directly in SRAM vectors, in your case VTOR + 0x118. For example if you copy all vectors to addresses beginning from 0x1FFF0000, write 0x1FFF0000 to VTOR, then you can write the address of your interrupt handler to 0x1FFF0118. VTOR is Vector Table Offset Register.
ok, it's clear, thank you!
special thanks for the step by step instruction
My vectors table copy code:
copy_vectors_table: mov32 r1, 0x00000000 mov32 r2, 0x20000000 mov32 r3, #0 cvt_l0: ldr r0, [r1], #1 str r0, [r2], #1 add r3, #1 and r4, r3, #0xFFFFFFFF cmp r4, #76 bne cvt_l0
And VTOR config:
mov32 r1, 0xE000ED08 @ SCB_VTOR address mov32 r0, 0x20000000 @ address to new vectors table str r0, [r1] mov32 r1, 0x20000118 @ TIM6 interrupt address adr r0, tim6_interrupt_observer str r0, [r1]
no results
Is this only code you write to your board?
Full code:
@ stm32f103 timer & interrupt test by laper_s (from 2019-02-02) .thumb .cpu cortex-m3 .syntax unified .word 0x20005000 .word start + 1 b start .macro mov32 regnum,number movw \regnum,:lower16:\number movt \regnum,:upper16:\number .endm start: copy_vectors_table: mov32 r1, 0x00000000 mov32 r2, 0x20000000 mov32 r3, #0 cvt_l0: ldr r0, [r1], #1 str r0, [r2], #1 add r3, #1 and r4, r3, #0xFFFFFFFF cmp r4, #76 bne cvt_l0 mov32 r1, 0x40021018 @ RCC_APB2ENR address mov32 r0, 0x10 @ enable GPIOC str r0, [r1] mov32 r1, 0x4002101c @ RCC_APB1ENR address mov32 r0, 0x10 @ enable TIM6 str r0, [r1] mov32 r1, 0x40011004 @ GPIOC_CRH mov32 r0, 0x44344444 @ set PC13 as 50 MHz PP output str r0, [r1] mov32 r1, 0xE000E104 @ NVIC_ISER1 ldr r0, [r1] orr r0, #0x00400000 @ enable interrupt #54 str r0, [r1] mov32 r1, 0xE000ED08 @ SCB_VTOR address mov32 r0, 0x20000000 @ address to new vectors table str r0, [r1] mov32 r1, 0x20000118 @ TIM6 interrupt address adr r0, tim6_interrupt_observer str r0, [r1] mov32 r1, 0x40001024 @ TIM6_CNT movw r0, 0x707 @ set counter strh r0, [r1] mov32 r1, 0x40001028 @ TIM6_PSC movw r0, 0x270f @ set prescaler strh r0, [r1] mov32 r1, 0x4000100c @ TIM6_DIER movw r0, 0x1 @ enable update interrupt strh r0, [r1] mov32 r1, 0x40001000 @ TIM6_CR1 ldrh r0, [r1] orr r0, 0x1 @ enable counter strh r0, [r1] .include "sysclk.inc" loop: b loop tim6_interrupt_observer: mov32 r1, 0x40001010 @ TIM6_SR movw r0, 0x0 @ clear interrupt flag str r0, [r1] mov32 r1, 0x4001100c @ GPIOC_ODR ldr r0, [r1] and r0, #0x2000 cmp r0, #0x2000 ite eq movweq r0, 0x0000 movwne r0, 0x2000 str r0, [r1] bx lr
Dou you understand the difference between freestanding code (bare metal) and code executed in hosted environment (in an operating system environment)?
Because this is a board with microcontroller you have firstly to initialize important parts of microcontroller, e.g. load vector table, configure clocks, disable watchdog etc.
Try to look demo codes at st.com for your board.
>if I understand correctly vector table starting from 0x0000 0000 address
In the case of STM32, there is a boot loader in address 0x00000000, and flash is in 0x8000000. It is true that initial vector table is in address 0x0. However, before jumping into the application in flash, the bootloader program the VTOR to point to the one in flash. That's why in the application, the vector table starts from 0x8000000.