Digital filter and assembler code examples

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

BL instruction (subroutine call)

Post by pythoncoder » Mon Feb 16, 2015 8:19 am

It would be great to have this implemented. I gather subroutine call works as follows:

Code: Select all

	bl(foo) # jump to subroutine, return address goes into r14
	...
	label(foo)
	add(r0, r0, r0) # do something
	mov(pc, r14) # return
Peter Hinch
Index to my micropython libraries.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Post by Damien » Mon Feb 16, 2015 11:52 am

That's a neat idea: calling a subroutine within the actual function using a label. Are you requesting this feature, or proper subroutine calls to external entities?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Digital filter and assembler code examples

Post by pythoncoder » Mon Feb 16, 2015 12:47 pm

This feature would be fine for my purposes.
Peter Hinch
Index to my micropython libraries.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Post by Damien » Mon Feb 16, 2015 7:25 pm

Bx and bl now implemented. Along with ite and all its variations. Examples in the tests/inlineaam dir.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

A final thought?

Post by pythoncoder » Tue Feb 17, 2015 9:31 am

Excellent. Can I suggest that the assembler tutorial document includes a link to the relevant section of the wiki as this is where much of the relevant detail is located?

I think you've implemented a very usable subset. One thought for the future is implementing interrupt service routines in assembler. This may be a matter of figuring out how to do it and documenting it rather than changing MicroPython. I wonder if anyone has achieved this already?
Peter Hinch
Index to my micropython libraries.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Post by Damien » Tue Feb 17, 2015 9:42 pm

Registering an assembler function as a callback should work just fine. Eg timer.callback(asmfunc). It will have a small bit of overhead setting up the call.

I can link to the wiki, but even better might be to put the wiki stuff in the docs, since the docs are lacking with respect to the inline assembler.

PieMan
Posts: 6
Joined: Wed Feb 11, 2015 11:01 pm

Re: Digital filter and assembler code examples

Post by PieMan » Tue Feb 17, 2015 10:13 pm

Reading about "Accepting arguments" here: https://micropython.org/doc/tut-asm and here: http://wiki.micropython.org/platforms/b ... /assembler showed me how to write an ISR/callback in asm. The following code example works for me and I measure the call overhead to be about 3.5us. Calling a "normal" function which in turn calls an asm functions incurs a 9us call overhead (by my measurements).

Code: Select all

from pyb import Timer, Pin
import stm

# Waggle pin A2 (aka X3) on then off.
# A timer callback receives the timer obj as a parameter which is not used here.
@micropython.asm_thumb
def asm_pin_waggle(r0):
    movwt(r1, stm.GPIOA) # Port A
    movw(r2, 1<<2)       # A2
    strh(r2, [r1, stm.GPIO_BSRRL]) # Set high...
    strh(r2, [r1, stm.GPIO_BSRRH]) # then set low.

# Configure pin X3 (aka A2)
PinX3 = Pin(Pin.board.X3, Pin.OUT_PP)

# Setup a 100us 50:50 PWM on pin X2.
tim2 = Timer(2,prescaler=83,period=99,mode=Timer.DOWN)
ch2 = tim2.channel(2,Timer.PWM,pin=Pin('X2'))
ch2.pulse_width_percent(50)

# Have an ISR written in assembler called.
ch2.callback(asm_pin_waggle)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Digital filter and assembler code examples

Post by pythoncoder » Wed Feb 18, 2015 8:09 am

Very neat and much simpler than I'd imagined! This might amuse:

I'd been puzzling over how to enable an assembler function to handle more than three arrays, given the limit of three register arguments. The solution was obviously to use indirection but I couldn't see how. It proved to be trivial:

Code: Select all

# Return the address of an array (to put in another array)
@micropython.asm_thumb
def getaddress(r0):
    nop()
This allows you to populate an array with the addresses of other arrays. I've put this in the Wiki in case anyone else encounters this issue.
Peter Hinch
Index to my micropython libraries.

Post Reply