Ken,
I highly recommend getting behind ersmith's fastspin. It's kind of everything in one for both P1 and P2.
I second that! With fastspin you get Spin, BASIC, C, and PASM and it is likely that the C support could compile MicroPython. The only difficulty is fastspin's lack of separate compilation and linking and that is mostly a problem if you want to use the standard MicroPython build system. It would probably be possible to create a new Makefile for fastspin to get around that problem.
[As you correctly surmised, the main code is running under a Risc-V emulator, but that has very little overhead -- as long as a routine fits in the 512 byte L1 cache (best) or 4K L2 cache (next best) it'll basically run as fast as native P2 code, because in fact it is native P2 code at that point (it's JIT compiled from Risc-V to P2).
I guess the next step would be to JIT compile the MicroPython opcodes. This would require a way to escape from the Risc-V interpreter into native PASM but I suppose that wouldn't be too hard.
@"Roy Eltham" and @"David Betz" : Thank you for your support, and for your help in debugging fastspin and improving it.
@"Ken Gracey" : I think the thread Roy pointed at is probably the best place to discuss fastspin. I'll be happy to answer any of your questions.
As for micropython:
At the moment it's implemented in C. I have not at all tried to look into the internals of the interpreter to see how hard it would be to interpret the bytecodes differently. It's probably a big project.
Micropython does seem to have a built in assembler for some architectures, so presumably it has a way to escape into native code. That would probably be easier to hook into than changing the bytecode interpreter.
Working in industry I have never seen micropython used, but I have four different platforms from various manufacturers that now run Lua.
Python is quickly becoming the top programming language for education. I'm really not sure about the industry uses either, but educational sales are the primary source of revenue for Parallax. For the Propeller 2, we are currently considering Spin/PASM as the primary language for commercial products and Python for education.
I'm watching this discussion closely, along with others.
Ken Gracey
Point taken about Python in education -- I noticed that when my Dad bought the Great Courses how-to-program course, it focused on Python.
I know that Lua is designed from scratch to sit on a firmware base written in C, to provide convenient scripting for embedded devices whose firmware is C based. I suspect the same is true of microPython, so if we get one going getting the other is probably just a matter of getting someone who knows the dev chain to compile it.
But there is also the issue of having a standard, which has been a problem for P1 since the push to C. It was hard to beat the low bar to startup set by the PropTool, and knowing that it would support any object you chose to investigate in the obex was very convenient. It should be similar with on-top-of-C scripting languages like Lua; once you load the pre-compiled kernal, the scripting language just works. There is even a free web service that will build you an ESP8266 Lua / NodeMCU firmware image with your web-click selection of modules built in so you don't have to figure out the toolchain yourself. I could see something that really working for either Propeller because of the mixes of software emulated hardware that are possible. Alas, putting something like that together is out of my wheelhouse.
I see the advantage for penetration of getting C for the pro users of other platforms, but I've personally learned to run for my life when I hear the phrase "tool chain." I don't know what the best solution is for Parallax but whatever course you decide will be standard, I'll figure it out.
Not sure how much interest there is, but I've updated the micropython in the first post with a new version that has some smartpin primitives. For example, to blink a pin using smartpin functionality:
Here's a screen shot from version 3 yesterday. The smartpin 56 is doing async serial TX being driven from MicroPython
Looks nice. What sort of speed can MicroPython achieve ? - ie if you crank the baudrate way up, how spaced are the characters if printed one at a time ?
Of course, because the smartpin is performing the serial i/o, you can have almost any baudrate you like.
(check the scope timebase in the screenshot if you really must know. But I don't think the speed or lack thereof is a huge problem right at the moment)
(check the scope timebase in the screenshot if you really must know. But I don't think the speed or lack thereof is a huge problem right at the moment)
I already did that, but 14400 baud is glacial, and almost anything could keep up with that... so it does not reveal much, except show that MicroPython can manage 14400 baud (with smart pin).
Here's a sample P2 micropython example that configures 16 smartpins in async tx mode and then sends a ID string out on each one.
#P2 Micropython Async Tx smartpin setup test
#ozpropdev - March 2019
import pyb
def init_tx(px,baudrate):
p = pyb.Pin(px)
p.mode(0x7c) #async tx
x = 160000000 // baudrate
p.xval((x << 16) + 7)
p.makeoutput()
return p
def strout(p,m):
for c in m:
p.yval(ord(c))
while(True):
if p.read() == 1:
break
#build pin list
tx = []
for z in range(16,32): #pins 16 to 31
tx.append(init_tx(z,115200))
print("List of pins")
for z in tx:
print(z,end=" ")
print()
#send "PIN(nn)" to pins in list
while(True):
for z in tx:
strout(z,str(z))
This seems to work fine except every ~15 seconds the terminal receives a message in this format.
GC: total: 32256, used: 1936, free: 30320
No. of 1-blocks: 16, 2-blocks: 1, max blk sz: 41, max free sz: 1831
Anyone have any ideas what's happening.
Am I trashing a heap or stack??
The GC message you're seeing is just some debug code that's printing whenever garbage collection happens (python regularly needs to do this, it's normal). I'll take it out, but it doesn't indicate any problem in your code.
Hi Eric.
One issue I've encountered is a 31 bit limitation when writing smartpin registers.
An overflow error is thrown.
Not sure if implementing micropythons long integers would help here, or a modified type is required.
Thoughts?
Cheers
Brian
Hi Eric.
One issue I've encountered is a 31 bit limitation when writing smartpin registers.
An overflow error is thrown.
Not sure if implementing micropythons long integers would help here, or a modified type is required.
Thoughts?
Cheers
Brian
Hi Brian! I tried implementing the long integers, but they still didn't work with the smartpin code, so unfortunately some additional work will be required. For now the smartpin registers are restricted so that the upper two bits (bits 31 and 30) have to be the same, either both 0 (a positive number) or both 1 (a negative number).
Hi Eric
I came up with a hack to get around the 32 bit value passing that ironically used smartpins themselves to do the trick.
Basically I've set up three smartpns in repository mode as an interface to a utility cog to handle passing the values in 16 bit chunks.
'Micropython smartpin 32 bit variable hack
'Version 0.1 23rd Marcg 2019 - ozpropdev
dat org
'move micropython image to address $0 and launch in cog #7
upython_boot loc ptra,#\@upython
mov ptrb,#0
rep @loader,##(up_end-upython) >> 2
rdlong pa,ptra++
wrlong pa,ptrb++
loader coginit #7,#0
'configure smartpins 0..2 in repository mode
wrpin #2,#0 'value reposutory
wrpin #2,#1 'pin number
wrpin #2,#2 'command
or dira,#7 'enable smartpins
'Check for activity in repository registers
main testp #0 wc 'has repository been updated
if_c shl val,#16 'shift in new 16 bit word
if_c rdpin pa,#0
if_c setword val,pa,#0
testp #2 wc 'new command?
if_nc jmp #main
rdpin spn,#1 'get smartpin number
rdpin pb,#2 'command
skipf pb
wrpin val,spn '%110
wxpin val,spn '%101
wypin val,spn '%011
jmp #main
val long 0
spn long 0
orgh
upython file "upython_v5.binary"
up_end
and here's samle test code and results
RiscV P2 JIT
MicroPython v1.10-198-g70cf38707 on 2019-03-19; P2-Eval-Board with p2-cpu
Type "help()" for more information.
>>>
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import pyb
===
=== _wrpin = 6
=== _wxpin = 5
=== _wypin = 3
===
=== val=pyb.Pin(0)
=== spn=pyb.Pin(1)
=== cmd=pyb.Pin(2)
===
=== def show_states(p):
=== p.off()
=== print("Off state = ",p.read())
=== p.on()
=== print("On state = ",p.read())
===
===
=== led = pyb.Pin(24)
=== show_states(led)
=== #Invert pin IN state
=== val.xval(0x8000)
=== val.xval(0)
=== spn.xval(24) #smartpin number
=== cmd.xval(_wrpin)
=== print(":Inverted IN state")
=== show_states(led)
===
Off state = 0
On state = 1
:Inverted IN state
Off state = 1
On state = 0
>>>
Comments
Nothing happened to BlocklyProp. It's the primary system we promote and support for education.
For P2, though, we're keeping our options open. We could produce Blockly with Python code generation.
Ken Gracey
Can you point me to the best starting thread for fastspin? I see several threads.
Thanks, Ken
This is the main thread for it where he posts updates/releases.
http://forums.parallax.com/discussion/164187/fastspin-compiler-for-p2-assembly-spin-basic-and-c-in-one-compiler
I second that! With fastspin you get Spin, BASIC, C, and PASM and it is likely that the C support could compile MicroPython. The only difficulty is fastspin's lack of separate compilation and linking and that is mostly a problem if you want to use the standard MicroPython build system. It would probably be possible to create a new Makefile for fastspin to get around that problem.
@"Ken Gracey" : I think the thread Roy pointed at is probably the best place to discuss fastspin. I'll be happy to answer any of your questions.
As for micropython:
At the moment it's implemented in C. I have not at all tried to look into the internals of the interpreter to see how hard it would be to interpret the bytecodes differently. It's probably a big project.
Micropython does seem to have a built in assembler for some architectures, so presumably it has a way to escape into native code. That would probably be easier to hook into than changing the bytecode interpreter.
Point taken about Python in education -- I noticed that when my Dad bought the Great Courses how-to-program course, it focused on Python.
I know that Lua is designed from scratch to sit on a firmware base written in C, to provide convenient scripting for embedded devices whose firmware is C based. I suspect the same is true of microPython, so if we get one going getting the other is probably just a matter of getting someone who knows the dev chain to compile it.
But there is also the issue of having a standard, which has been a problem for P1 since the push to C. It was hard to beat the low bar to startup set by the PropTool, and knowing that it would support any object you chose to investigate in the obex was very convenient. It should be similar with on-top-of-C scripting languages like Lua; once you load the pre-compiled kernal, the scripting language just works. There is even a free web service that will build you an ESP8266 Lua / NodeMCU firmware image with your web-click selection of modules built in so you don't have to figure out the toolchain yourself. I could see something that really working for either Propeller because of the mixes of software emulated hardware that are possible. Alas, putting something like that together is out of my wheelhouse.
I see the advantage for penetration of getting C for the pro users of other platforms, but I've personally learned to run for my life when I hear the phrase "tool chain." I don't know what the best solution is for Parallax but whatever course you decide will be standard, I'll figure it out.
Ditto
Fired it up briefly and excited to see the >>> prompt coming from a P2.
I can do
however calling seems to lock things up, requiring a new session. Is there another way to retrieve input state?
Sorry, the .read() method had a bug. That should be fixed in v4 (updated zip in the first post).
I will try a bunch of tests to day.
Look forward to having a look at v4 this Thurs if not sooner
Of course, because the smartpin is performing the serial i/o, you can have almost any baudrate you like.
(check the scope timebase in the screenshot if you really must know. But I don't think the speed or lack thereof is a huge problem right at the moment)
I already did that, but 14400 baud is glacial, and almost anything could keep up with that... so it does not reveal much, except show that MicroPython can manage 14400 baud (with smart pin).
I believe it's using an emulator of another core(RISC-V?).
Early days....
@ersmith
V4 is working nicely.
This seems to work fine except every ~15 seconds the terminal receives a message in this format. Anyone have any ideas what's happening.
Am I trashing a heap or stack??
Noticed things are a bit faster too
One issue I've encountered is a 31 bit limitation when writing smartpin registers.
An overflow error is thrown.
Not sure if implementing micropythons long integers would help here, or a modified type is required.
Thoughts?
Cheers
Brian
Hi Brian! I tried implementing the long integers, but they still didn't work with the smartpin code, so unfortunately some additional work will be required. For now the smartpin registers are restricted so that the upper two bits (bits 31 and 30) have to be the same, either both 0 (a positive number) or both 1 (a negative number).
Regards,
Eric
I came up with a hack to get around the 32 bit value passing that ironically used smartpins themselves to do the trick.
Basically I've set up three smartpns in repository mode as an interface to a utility cog to handle passing the values in 16 bit chunks.
and here's samle test code and results