Assembler, GPIO, 31bit integers?

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
PinkInk
Posts: 65
Joined: Tue Mar 11, 2014 3:42 pm

Assembler, GPIO, 31bit integers?

Post by PinkInk » Sat Jul 12, 2014 3:51 pm

*Somewhere* I think I read that micropython implements 31 bit integers, but I can't recall where, is this correct? (recall something about the most significant bit indicating to the gc whether it's a pointer or a number)

In pursuit of a temporary PWM fix, via embedded assembler, I am trying to push a 32bit number into GPIOA.GPIO_MODER address (trying, for test purposes, to implement PWM on pyb.LED(2) which, according to some comments in led.c, is on GPIOA 15 ... which seems to be born out by inspecting GPIOA.GPIO_ODR when switching it on and off) ... but the assembler interpreter doesn't like it;

Code: Select all

>>> @micropython.asm_thumb
... def alter():
...   movwt(r0, stm.GPIOA)
...   movwt(r1, 0x100aaa00)
...   strh(r1, [r0, stm.GPIO_AFR1])
...   movwt(r1, 0xa9600000)
...   strh(r1, [r0, stm.GPIO_MODER])
...
SyntaxError: 'movwt' expects an integer
The value is less than 4 bytes, but is 32 bits long;

Code: Select all

>>> 0xa9600000<0xffffffff
True
>>> bin(0xa9600000)
'0b10101001011000000000000000000000'
>>> len(bin(0xa9600000)[2:])
32
In fact, it appears that movwt doesn't like anything longer than 30bits;

Code: Select all

>>> len(bin(0x3fffffff)[2:])
30
>>> @micropython.asm_thumb
... def alter():
...   movwt(r0, stm.GPIOA)
...   movwt(r1, 0x100aaa00)
...   strh(r1, [r0, stm.GPIO_AFR1])
...   movwt(r1, 0x3fffffff)
...   strh(r1, [r0, stm.GPIO_MODER])
...
>>> len(bin(0x3fffffff+1)[2:])
31
>>> @micropython.asm_thumb
... def alter():
...   movwt(r0, stm.GPIOA)
...   movwt(r1, 0x100aaa00)
...   strh(r1, [r0, stm.GPIO_AFR1])
...   movwt(r1, 0x3fffffff+1)
...   strh(r1, [r0, stm.GPIO_MODER])
...
SyntaxError: 'movwt' expects an integer
If I take a very deep breath, count on all fingers and toes (and those of a couple of volunteers), I *think* I can probably work around this by using two movw operations and incrementing the memory address target ... but I think I may be missing something much more obvious ... am I?

pfalcon
Posts: 1155
Joined: Fri Feb 28, 2014 2:05 pm

Re: Assembler, GPIO, 31bit integers?

Post by pfalcon » Sat Jul 12, 2014 4:25 pm

*Somewhere* I think I read that micropython implements 31 bit integers, but I can't recall where, is this correct?
Not quite, uPy implements 2 integer types - small and long ints, smalls are indeed 31-bit signed ints, but longs ints are at least 33 signed bits.
In fact, it appears that movwt doesn't like anything longer than 30bits;
All Python ints are signed, so there's always signed bit to keep in extra bit.
If I take a very deep breath, count on all fingers and toes (and those of a couple of volunteers), I *think* I can probably work around this by using two movw operations
Raw ARM assembler doesn't allow to load a 32-bit immediate value at all. Pair of commands mov + movt is used to load low, then high 16 bits. That would be natural workaround for uPy too, assuming it supports such separate commands (if not, please submit bug). Your original issue is that convenience "movwt" command doesn't support long ints, it's surely a bug, please submit it too.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/

PinkInk
Posts: 65
Joined: Tue Mar 11, 2014 3:42 pm

Re: Assembler, GPIO, 31bit integers?

Post by PinkInk » Sun Jul 13, 2014 4:32 pm

Thanks, I reported the movwt issue ...

uPy appears to support a subset of the commands required for these operations i.e. it supports mov and movt ... but the limitations of what it currently exposes come up pretty quickly (particularly in relation to absence of more useful variants of commands that take register, register arguments, rather than register, value args) ... and I'm only 2 days into learning assembler ...

However, emitinlinethumb.c is clearly work in progress, core Python functionality is more important, and I'm sure it'll be gotten round to in time.

pfalcon
Posts: 1155
Joined: Fri Feb 28, 2014 2:05 pm

Re: Assembler, GPIO, 31bit integers?

Post by pfalcon » Sun Jul 20, 2014 7:43 pm

> However, emitinlinethumb.c is clearly work in progress, core Python functionality is more important, and I'm sure it'll be gotten round to in time.

That's true, but priority also depends on whether something is actually used. So, please keep sharing your experiences with assembler and report bugs - that will help making sure it gets it share of attention in devel plans.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/

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

Re: Assembler, GPIO, 31bit integers?

Post by Damien » Thu Jan 07, 2016 5:01 pm

This issue is now fixed: the convenience function movwt can now accept 32-bit integer arguments (including constants like stm.GPIOA).

Post Reply