So it turns out the previous assembler version wasn't incrementing the counter the same way that the C version was.
So I coded up an inline assembler version which dies things more or less the same way as the C version, but my counter is still only reaching 10 million, so I'm not sure what's wrong.
Code: Select all
import pyb
import stm
import uctypes
run_buf = bytearray(1)
run_buf[0] = 1
def timer_irq(tim):
global run_buf
run_buf[0] = 0
@micropython.asm_thumb
def counter(r0): # r0 has address of run_buf
movwt(r1, stm.GPIOA) # LED(1) is A13
add(r1, stm.GPIO_BSRRL)
movw(r2, 1 << 13) # r2 has mask for setting LED
mov(r3, r2)
mov(r4, 16)
lsl(r3, r4) # r3 has mask for clearing LED
mov(r4, 0) # r4 is counter
# loop
label(loop)
ldrb(r3, [r0, 0])
cmp(r3, 1)
bne(endloop)
str(r2, [r1, 0])
add(r4, 1)
str(r3, [r1, 0])
b(loop)
# endloop
label(endloop)
mov(r0, r4) # return counter in r0
def main():
# Setup Timer2 to increment at 10 kHz
# Disable SysTick
stm.mem32[0xe000e010] = 0
t2 = pyb.Timer(2, prescaler=84000000 // 10000 - 1, period=9999, callback=timer_irq)
print('PSC =', stm.mem32[stm.TIM2 + stm.TIM_PSC])
count = counter(run_buf)
print('Counted: {:10,} (asm_thumb)'.format(count))
main()
I threw in the line to disable systick, which increased things a bit, but not much.
This is still a factor of 2 worse than the C example (I'll need to compile the C version and verify independently)