Micropython for P2

2456

Comments

  • twm47099 wrote: »
    Ken,
    What happened to Blockly? Doesn't that use (or compile to) C?
    Tom

    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
  • Roy Eltham wrote: »
    Ken,
    I highly recommend getting behind ersmith's fastspin. It's kind of everything in one for both P1 and P2.

    Can you point me to the best starting thread for fastspin? I see several threads.

    Thanks, Ken

  • Roy Eltham wrote: »
    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.
  • ersmith wrote: »
    [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.
  • Ken Gracey wrote: »
    localroger wrote: »
    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.
  • Roy Eltham wrote: »
    Ken,
    I highly recommend getting behind ersmith's fastspin. It's kind of everything in one for both P1 and P2.

    Ditto

    Terry's Workbench

    Feel the need for speed between your PC's com port and Prop?
    Try the FTDI 245 and the FullDuplexParallel Object.
    Check out my spin driver for the Parallax "96 x 64 Color OLED Display Module" Product ID: 28087
    22FPS video from the P2 on the Parallax "96 x 64 Color OLED Display Module" https://www.youtube.com/watch?v=ja84rf38QHM
  • 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:
    import pyb
    p=pyb.Pin(56)
    p.mode(0x4c)
    p.xval(16000)
    p.yval(858993)
    p.makeoutput()
    
  • Thank you Eric!
    Fired it up briefly and excited to see the >>> prompt coming from a P2. :)
    Melbourne, Australia
  • me likey :smiley:
    Stockholm, Sweden
    I am only an egg -- Stranger in a Strange land, Robert A. Heinlein
  • This is a great addition, Eric. Looking forward to trying it this week
  • TubularTubular Posts: 3,649
    edited 2019-03-18 - 03:23:52
    Ok its really nice to be able to interact with smartpins. However i haven't been able to read back an input yet.

    I can do
    Pin(56).makeinput()
    

    however calling
    Pin(56).read()
    
    seems to lock things up, requiring a new session. Is there another way to retrieve input state?
  • Tubular wrote: »
    Ok its really nice to be able to interact with smartpins. However i haven't been able to read back an input yet.

    I can do
    Pin(56).makeinput()
    

    however calling
    Pin(56).read()
    
    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).

  • Thanks Eric for the fix.
    I will try a bunch of tests to day. :)
    Melbourne, Australia
  • Here's a screen shot from version 3 yesterday. The smartpin 56 is doing async serial TX being driven from MicroPython

    Look forward to having a look at v4 this Thurs if not sooner

    800 x 480 - 83K
  • and yes thanks for doing the fix on the read instruction
  • jmgjmg Posts: 13,787
    Tubular wrote: »
    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 ?

  • Lets just say MicroPython is powerful.

    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)
  • jmgjmg Posts: 13,787
    Tubular wrote: »
    (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).

  • Let me do some more tests later. I notice there are millis and usec counters implemented for timing things...
  • AFAIK Eric's implementation of Micropython is not optimized for P2 yet.
    I believe it's using an emulator of another core(RISC-V?).
    Early days.... :)

    @ersmith
    V4 is working nicely.

    Melbourne, Australia
  • 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??

    Melbourne, Australia
  • 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.
  • I've updated the first post with a more recent version with the GC debug message removed and some improvements to the millis() and micros() counters.
  • ersmith wrote: »
    I've updated the first post with a more recent version with the GC debug message removed and some improvements to the millis() and micros() counters.
    Thanks Eric. V5 working nicely.

    Melbourne, Australia
  • That .read() now works great, many thanks Eric.

    Noticed things are a bit faster too
  • ozpropdevozpropdev Posts: 2,540
    edited 2019-03-23 - 01:42:59
    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
    Melbourne, Australia
  • ozpropdev wrote: »
    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).

    Regards,
    Eric
  • ozpropdevozpropdev Posts: 2,540
    edited 2019-03-23 - 02:21:08
    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
    >>> 
    

    Melbourne, Australia
Sign In or Register to comment.