Hi.
I am a newbie about MicroPython.
How to increment a variable during an ISR written in assembler?
Best Regards.
variable and ISR in assembler.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: variable and ISR in assembler.
As far as I know there is no support for writing ISRs in assembler. A Python ISR can call assembler code but that clearly isn't what you're after. To do what you want you'll need to dig quite deeply into the chip programming manual. Unless someone else has cracked this one. It would be good to have a solution.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: variable and ISR in assembler.
Unfortunately, the ISR vectors are stored in flash, so they're kind of "hard-baked". To support runtime pluggable ISRs requires that a particular ISR store a vector in RAM which can then be modified at runtime, which is how timer ISRs and pin-changed ISRs work.
Technically, there is a register called VTOR which is the vector table offset register. You could allocate an appropriately aligned block of SRAM, copy the vector table there and then update VTOR to point to it, and then be able to change ISR vectors dynamically, but you're pretty much on your own if you decide to tread down this path.
Technically, there is a register called VTOR which is the vector table offset register. You could allocate an appropriately aligned block of SRAM, copy the vector table there and then update VTOR to point to it, and then be able to change ISR vectors dynamically, but you're pretty much on your own if you decide to tread down this path.
Re: variable and ISR in assembler.
Thank you for your answers.
I badly expressed my problem. Sorry.
For a project using a transducer of ultrasounds, I try to generate a periodic frame (Tf = 10 s).
Each of the frame includes N pulses at 40 kHz.
The PA13 pin (red led) is used for the test with a scope.
The Timer 4 is programmed for an interruption every 10 seconds.
The Timer 2 is programmed for an interruption every 12.5 microseconds.
The variable n serves to count the interruptions from Timer 2.
->! Here N = 4 pulses !<-
__! _______ ________ ________ ______..._______! __...
!________! !________! !________! !________! !________!
! n = 1 ! n = 2 ! n = 3 n = 4 n = 5 n = 6 n = 7 n = 8 => n = 0 ! n = 1
! ! ! !
->! 12.5µs !<- ! !
! ! !
->! 25.0µs (40 kHz) !<- !
! !
!<--------------------------------- 10.0s (0.1Hz) ------------------------------------------------------------->!
^ ^ ^ ^ ^ ^ ^ ^ ^
ISR ISR ISR ISR ISR ISR ISR ISR ISR
TIMER4 TIMER2 TIMER2 TIMER2 TIMER2 TIMER2 TIMER2 TIMER2 TIMER4
Start Stop Start
ISR ISR ISR
TIMER2 TIMER2 TIMER2
Can we write of the assembler code as that one ?
How we can get back the address of n ?
(They are my first lines of code, so bear with me...)
# *** code *******************************************************
# variable n, 0 by default
n = 0
# ISR TIMER 2 ****************************************************
@micropython.asm_thumb
def asm_red_led_toggle() :
# toggle ......................................................
movw(r0, 1 << 13) # r0 = 0x2000
movwt(r1, stm.GPIOA)
ldrh(r2, [r1, stm.GPIO_ODR])
eor(r0, r2)
strh(r0, [r1, stm.GPIO_ODR])
# n = n + 1 ...................................................
movwt(r1, address_of_n) # r1 = address of n (how to do it?)
ldrw(r2, [r1, 0]) # r2 = n
movwt(r0, 1) # r0 = 0x00000001
add(r2, r0, r2) # r2 = n + 1
# n = 8 ? .....................................................
movwt(r0, 8) # r0 = 0x00000008
cmp(r0, r2) # r2 = 8 ?
beq(Stop_isr_timer2)
strw(r0, [r1, 0]) # save n
b(End)
# yes : stop ISR TIMER2 .......................................
label(Stop_isr_timer2)
movw(r0, 1) # r0 = 0x0001
mvn(r0, r0) # r0 = 0xFFFE
movwt(r1, stm.TIM2)
ldrh(r2, [r1, stm.TIM_CR1]) # r2 = TIM2_CR1
and_(r0, r2) # bit TIM2_CR1.CEN = 0b
strh(r0, [r1, stm.TIM_CR1]) # TIM2_CR1 = r2
eor(r0, r0) # r0 = 0
strw(r0, [r1, 0]) # save n = 0
label(End)
I badly expressed my problem. Sorry.
For a project using a transducer of ultrasounds, I try to generate a periodic frame (Tf = 10 s).
Each of the frame includes N pulses at 40 kHz.
The PA13 pin (red led) is used for the test with a scope.
The Timer 4 is programmed for an interruption every 10 seconds.
The Timer 2 is programmed for an interruption every 12.5 microseconds.
The variable n serves to count the interruptions from Timer 2.
->! Here N = 4 pulses !<-
__! _______ ________ ________ ______..._______! __...
!________! !________! !________! !________! !________!
! n = 1 ! n = 2 ! n = 3 n = 4 n = 5 n = 6 n = 7 n = 8 => n = 0 ! n = 1
! ! ! !
->! 12.5µs !<- ! !
! ! !
->! 25.0µs (40 kHz) !<- !
! !
!<--------------------------------- 10.0s (0.1Hz) ------------------------------------------------------------->!
^ ^ ^ ^ ^ ^ ^ ^ ^
ISR ISR ISR ISR ISR ISR ISR ISR ISR
TIMER4 TIMER2 TIMER2 TIMER2 TIMER2 TIMER2 TIMER2 TIMER2 TIMER4
Start Stop Start
ISR ISR ISR
TIMER2 TIMER2 TIMER2
Can we write of the assembler code as that one ?
How we can get back the address of n ?
(They are my first lines of code, so bear with me...)
# *** code *******************************************************
# variable n, 0 by default
n = 0
# ISR TIMER 2 ****************************************************
@micropython.asm_thumb
def asm_red_led_toggle() :
# toggle ......................................................
movw(r0, 1 << 13) # r0 = 0x2000
movwt(r1, stm.GPIOA)
ldrh(r2, [r1, stm.GPIO_ODR])
eor(r0, r2)
strh(r0, [r1, stm.GPIO_ODR])
# n = n + 1 ...................................................
movwt(r1, address_of_n) # r1 = address of n (how to do it?)
ldrw(r2, [r1, 0]) # r2 = n
movwt(r0, 1) # r0 = 0x00000001
add(r2, r0, r2) # r2 = n + 1
# n = 8 ? .....................................................
movwt(r0, 8) # r0 = 0x00000008
cmp(r0, r2) # r2 = 8 ?
beq(Stop_isr_timer2)
strw(r0, [r1, 0]) # save n
b(End)
# yes : stop ISR TIMER2 .......................................
label(Stop_isr_timer2)
movw(r0, 1) # r0 = 0x0001
mvn(r0, r0) # r0 = 0xFFFE
movwt(r1, stm.TIM2)
ldrh(r2, [r1, stm.TIM_CR1]) # r2 = TIM2_CR1
and_(r0, r2) # bit TIM2_CR1.CEN = 0b
strh(r0, [r1, stm.TIM_CR1]) # TIM2_CR1 = r2
eor(r0, r0) # r0 = 0
strw(r0, [r1, 0]) # save n = 0
label(End)
Re: variable and ISR in assembler.
After shaping of the text...
Thank you for your answers.
I badly expressed my problem. Sorry.
For a project using a transducer of ultrasounds, I try to generate a periodic frame (Tf = 10 s).
Each of the frame includes N pulses at 40 kHz.
The PA13 pin (red led) is used for the test with a scope.
The Timer 4 is programmed for an interruption every 10 s.
The Timer 2 is programmed for an interruption every 12.5 µs.
The variable n serves to count the interruptions from Timer 2.
https://www.dropbox.com/s/php5uvmtn2wj3 ... n.gif?dl=0
Can we write of the assembler code as that one ?
How we can get back the address of n ?
Thank you for your answers.
I badly expressed my problem. Sorry.
For a project using a transducer of ultrasounds, I try to generate a periodic frame (Tf = 10 s).
Each of the frame includes N pulses at 40 kHz.
The PA13 pin (red led) is used for the test with a scope.
The Timer 4 is programmed for an interruption every 10 s.
The Timer 2 is programmed for an interruption every 12.5 µs.
The variable n serves to count the interruptions from Timer 2.
https://www.dropbox.com/s/php5uvmtn2wj3 ... n.gif?dl=0
Can we write of the assembler code as that one ?
How we can get back the address of n ?
Code: Select all
# *** code *******************************************************
# variable n, 0 by default
n = 0
# ISR TIMER 2 ****************************************************
@micropython.asm_thumb
def asm_red_led_toggle() :
# toggle ......................................................
movw(r0, 1 << 13) # r0 = 0x2000
movwt(r1, stm.GPIOA)
ldrh(r2, [r1, stm.GPIO_ODR])
eor(r0, r2)
strh(r0, [r1, stm.GPIO_ODR])
# n = n + 1 ...................................................
movwt(r1, address_of_n) # r1 = address of n (how to do it?)
ldrw(r2, [r1, 0]) # r2 = n
movwt(r0, 1) # r0 = 0x00000001
add(r2, r0, r2) # r2 = n + 1
# n = 8 ? .....................................................
movwt(r0, 8) # r0 = 0x00000008
cmp(r0, r2) # r2 = 8 ?
beq(Stop_isr_timer2)
strw(r0, [r1, 0]) # save n
b(End)
# yes : stop ISR TIMER2 .......................................
label(Stop_isr_timer2)
movw(r0, 1) # r0 = 0x0001
mvn(r0, r0) # r0 = 0xFFFE
movwt(r1, stm.TIM2)
ldrh(r2, [r1, stm.TIM_CR1]) # r2 = TIM2_CR1
and_(r0, r2) # bit TIM2_CR1.CEN = 0b
strh(r0, [r1, stm.TIM_CR1]) # TIM2_CR1 = r2
eor(r0, r0) # r0 = 0
strw(r0, [r1, 0]) # save n = 0
label(End)