variable and ISR in assembler.

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
bymb13
Posts: 5
Joined: Tue Sep 26, 2017 5:24 pm

variable and ISR in assembler.

Post by bymb13 » Tue Sep 26, 2017 5:52 pm

Hi.
I am a newbie about MicroPython.
How to increment a variable during an ISR written in assembler?
Best Regards.

User avatar
pythoncoder
Posts: 1964
Joined: Fri Jul 18, 2014 8:01 am

Re: variable and ISR in assembler.

Post by pythoncoder » Wed Sep 27, 2017 7:05 am

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

User avatar
dhylands
Posts: 2501
Joined: Mon Jan 06, 2014 6:08 pm
Location: Shuswap, BC, Canada
Contact:

Re: variable and ISR in assembler.

Post by dhylands » Wed Sep 27, 2017 4:26 pm

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.

bymb13
Posts: 5
Joined: Tue Sep 26, 2017 5:24 pm

Re: variable and ISR in assembler.

Post by bymb13 » Wed Sep 27, 2017 7:08 pm

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)

bymb13
Posts: 5
Joined: Tue Sep 26, 2017 5:24 pm

Re: variable and ISR in assembler.

Post by bymb13 » Thu Sep 28, 2017 8:00 am

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 ?

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)

Post Reply