Skip to content

Instantly share code, notes, and snippets.

@whaleygeek
Created March 20, 2024 21:33
Show Gist options
  • Save whaleygeek/2ff467983b79c322b3d7a1764938d9d9 to your computer and use it in GitHub Desktop.
Save whaleygeek/2ff467983b79c322b3d7a1764938d9d9 to your computer and use it in GitHub Desktop.
# (c) 2024 David Whale - 20/03/2024
# ARM thumb assembly language that reads button A
from microbit import *
from micropython import const
REG_GPIO_P0 = const(0x50000000)
REG_GPIO_IN = const(REG_GPIO_P0 + 0x510)
BUTTON_A_PIN = const(14) # P0_14 of the nRF5x GPIO block
@micropython.asm_thumb
def button_a_pressed():
movwt(r0, REG_GPIO_IN) # r0 = REG_GPIO_IN GPIO input register address
ldr(r0, [r0, 0]) # r0 = mem[r0] read GPIO pin states
movw(r1, BUTTON_A_PIN) # r1 = BUTTON_A_PIN bit number we are interested in
lsr(r0, r1) # r0 = r0 >> r1 right shift our bit down to bit 0
mov(r1, 1) # r1 = 1
and_(r0, r1) # r0 = r0 & r1 mask out all other bits except bit 0
eor(r0,r1) # r0 = r0 ^ r1 invert the bit, low=pressed, high=released
# value in r0 at the end, is the value returned back to python
while True:
if button_a_pressed():
display.show(Image.YES)
else:
display.show(Image.NO)
@whaleygeek
Copy link
Author

micro:bit pin mappings here: https://tech.microbit.org/hardware/edgeconnector/

Use the "MCU" column in the table to work out which bit numbers in which port registers are actually mapped to which features (as the numbers on the big picture are not the actual chip identifies that you w
Screenshot 2024-03-20 at 22 02 46
ill find in the NRF5x data sheet.

@whaleygeek
Copy link
Author

@whaleygeek
Copy link
Author

The MicroPython thumb assembly instructions are documented here: https://docs.micropython.org/en/latest/reference/asm_thumb2_index.html

The simulator at python.microbit.org won't run the assembly instructions, but it does flash and run fine on the micro:bit even though there are lots of red marks over it all!
Screenshot 2024-03-20 at 22 10 26

@whaleygeek
Copy link
Author

whaleygeek commented Mar 20, 2024

MakeCode shims mentioned here, that can call assembly language code from javascript code: https://forum.makecode.com/t/using-assembler-routines-in-both-js-and-c/2155

MakeCode extensions here (neopixel is a good example as it has assembly code in it as well): https://makecode.com/extensions

.asm files can't be added at present: microsoft/pxt-microbit#4426

@whaleygeek
Copy link
Author

whaleygeek commented Mar 20, 2024

Screenshot 2024-03-20 at 22 48 15

This shows the output/binary mode, which also shows the hex codes that represent each assembly instruction, as they would be assembled into memory by an assembler tool.

@whaleygeek
Copy link
Author

The red underlining in the python.microbit.org editor for the asm lines can be removed with this fix:

microbit-foundation/python-editor-v3#774 (comment)

@whaleygeek
Copy link
Author

whaleygeek commented Mar 26, 2024

42 in ASCII is a '*', this prints ABC then *BC, the assembly program has stored a 42 in the first memory location of the buffer data. id(b) is the bytearray address, the third longword32 of that memory holds the address of the actual buffer data.

# pyright: reportGeneralTypeIssues=false, reportUndefinedVariable=false
from machine import mem8, mem32

@micropython.asm_thumb
def ultimate_answer(r0):
    mov(r1,42)
    strb(r1,[r0,0])

b = bytearray(b'ABC')
print("before", b)
ITEMS_ADDR = mem32[id(b)+(4*3)]

ultimate_answer(ITEMS_ADDR)
print("after", b)

@whaleygeek
Copy link
Author

Screenshot 2024-03-26 at 21 39 44

@whaleygeek
Copy link
Author

Screenshot 2024-03-26 at 21 43 07

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment