Forum Update - Announcement about May 10th, 2018 update and your password.

Python P2 Loader

Here's a starting point for a possible Python P2 tool chain.
It converts an object file to the P2 base64 download protocol and loads @ 3Mbaid.
It's bare bones at present but things like multi P2 support can added as we move forward.
Give it a try!

Sample output
Python P2 loader V0.1 Ozpropdev 2018
Prop_Chk =  Prop_Ver E
HUBSET Ok, max clock speed enabled
Loading.......complete
Melbourne, Australia

Comments

  • 25 Comments sorted by Date Added Votes
  • jmgjmg Posts: 11,778
    ozpropdev wrote: »
    Here's a starting point for a possible Python P2 tool chain.
    Very nifty.....

    Can I suggest adding this line
    if reply != b'\r\n' :
      print("Unexpected RX=",reply)  # Supports easy loopback diagnostics 
    print("Prop_Chk = ",m[:-1].decode('utf-8'))  
    

    That then gives a useful message ( Unexpected RX= b'> Prop_Chk 0 0 0 0 ') when RX-TX is looped, for a com-link test.
    Useful for trouble shooting.

    I think there was some ROM command to change sysclk ? is it possible to use that to bump the baud to 12MBd ?
  • The code already sens the following command to switch to max sysclk
    > Prop_Clk 0 0 0 0 FF
    
    I'm preety sure my FPGA boards USB brifhe doesn't like >3Mbaud.
    I will check it again next time I fire it up.

    Melbourne, Australia
  • jmgjmg Posts: 11,778
    edited August 16 Vote Up0Vote Down
    ozpropdev wrote: »
    The code already sends the following command to switch to max sysclk
    > Prop_Clk 0 0 0 0 FF
    

    Ahh, yes. How does that react in a genuine P2 ?
    ozpropdev wrote: »
    I'm pretty sure my FPGA boards USB brifhe doesn't like >3Mbaud.
    I will check it again next time I fire it up.

    If it is FTDI, probably will not go > 3Mbd.

    Do you have a CP2102N board ? (or a FT2232H, or FT232H) (note: needs to be CP2102N, not older CP2102)

    I was idly testing your code on CP2102N, and whacked in 12MBd, expecting an error report... none came.
    So I assumed it has rounded to nearest legal Mbd (4MBd?).... nope, scope says it is sending at 12MBd (but with some gaps, of course, as the USB cannot sustain that ).

    I have tested CP2102N in the past, but usually in loop-back full duplex, which is tougher test than downloader use. There, 4MBd duplex was upper limit, needing HW handshake to never drop chars.

    So, I try some other test points, in the Python code
    # sp1.write(b'UUUUUUUUUUUUUUUUUUUU')   Test out A
    # echo      b'UUUU\xd5UUUUU\xd5UUU\xfd' 12MBd fails  12Md = see 40L = 8 bytes, then 3.7us, then 40L == 16U sent 
    # echo      b'UUUUUUUUUUUUUUUUUUUU'     8MBd manages short burst see 30L=6 bytes 3.6us then 30L(6b) then 2.6us then 6B then 2.6us then 10L = 20 bytes sent 20*10/33.62u = 5.948839Mbd average baud
    #sp1.write(b'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU')  test out B
    #     echo b'UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU' 6MBd
    
    # TX burst tests 6MBd  - 'U'*60 = 300 counts fine, 200Ch ok 2k ok 20k ok, 200k ok 2M = ok - wow.... - averages there 5.464MBd
    # TX burst tests 8MBd  - 'U'*2M = 10M edges  ok - wow.... - average there 2.870*2 = 5.74MBd, little gain above 6MBd 
    # TX burst tests 12MBd - 'U'*2M = 10M edges  ok, wow   - average    3.158*2 = 6.316MBd    Scope rough check 8/660n = 12121212 (11Mbd snaps to 12Mbd )
    # TX burst tests 24MBd - 'U'*2M = 10M edges  ok - wow.... - averages there 3.568*2 = 7.136MBd, scope says ?? ~8/330n = 24242424, but struggling with bandwidth...
    
    addit:
    # TX burst tests 3MBd   - 'U'*2M  -> 1500.4036*2 = 3.0008072MBd, so manages ~no gaps.
    # TX burst tests 4MBd   - 'U'*2M  -> 2000.3974*2 = 4.0007948MBd, so manages ~no gaps.
    # TX burst tests 4.8MBd - 'U'*2M  -> 2393.2875*2 = 4.786575MBd, so just adding extra stop bits.
    # TX burst tests 4.8MBd, 2 Stop - 'U'*2M  -> 2181.6115*2 = 4363.223 Predict 4800*10/11 = 4363.6363 - others are ~ 200ppm high, whislt this is ~100ppm low, so not quite sustained
    # TX burst tests 4.8MBd, 2 Stop, PARITY_MARK - now predicts 4MBd, & measures same as 4.00Mbd speed. This may be useful where bonus stop-bit time helps other code.
    # ie looks like 500k Bytes/sec is sustained, but 545.454k Bytes/sec comes in ~ 300ppm low.
    
    
    
    
    Confirms CP2102N has a virtual baud clock of 24MHz/N, and it can even make a decent fist of send at 24Mbd, (but has no hope of RX at that speed.)
    (It could maybe be used to confirm P2 serial Rx at 24MHz, or to generate test short pulses ~ 42ns steps, for smart pins testing )

    At 12MBd Rx also struggles, but at 8Mbd and below, short RX packets look to be ok - ie 60 chars at 6MBd looks fine (loopback)
    My earlier tests show under 4Mb full duplex loop back, but P2 download is not duplex, or even close, so things can push much faster, on a one way stream with short acks.

    This is sending a single, very large string (via sp1.write(b'U'*2000000)), but shows Python is no slouch - and that the CP2102N appears to not drop any chars TX of a 2M block, even at 6/8/12/24MBd Tx

    edit: added tests for 3M, 4M, 4.8MBd, as there may be some cases where gap-less send (no added stop bits) from PC to MCU is useful.
    These tests show 4.8M almost manages, with 0.28% slow-down, and 4.8M with 2 stop bits predicts 4.3636363 average, but comes up ~ 300ppm slow.
    2 Stop bits and PARITY_MARK is ok, gives the exact same byte-rate as 4MBd, but does buy added stop-bit margin.

    3M & 4M look to be gap-less, at ~ +200ppm on requested baud (CP2102N uses lock to USB frame, so does not give low-ppm errors on Baud that Xtal based UARTS do. )


    For P2 loader use (half duplex), CP2102N settings of 4.8M, 6M, 8M certainly look worth trying, should get close to ~1 sec for full P2 image, Base64 ?
  • jmgjmg Posts: 11,778
    edited August 17 Vote Up0Vote Down
    After a little experimenting, & web crawling, this works in Win10, to list the serial ports Curious to know if it works on other OS too ?
    import serial.tools.list_ports
    portlist = serial.tools.list_ports.comports()  
    for sp in portlist:
      print (sp.device,sp.description)
    # Typical list, Win10 is 
    # COM1 Communications Port (COM1)
    # COM3 Intel(R) Active Management Technology - SOL (COM3)
    # COM9 Silicon Labs CP210x USB to UART Bridge (COM9)
    # COM6 JLink CDC UART Port (COM6)
    
  • On Ubuntu:
    /// avsa242@desktop:~$ python jmg-serlist.py
    ('/dev/ttyS0', 'ttyS0')
    ('/dev/ttyUSB1', 'Propeller Flip Rev A')
    ('/dev/ttyUSB0', 'Propeller Activity Brd')
    
    

    Requires python-serial package in Ubuntu - may be named differently in other distros.
  • jmgjmg Posts: 11,778
    edited August 20 Vote Up0Vote Down
    ozpropdev wrote: »
    .... Give it a try!

    Sample output
    Python P2 loader V0.1 Ozpropdev 2018
    Prop_Chk =  Prop_Ver E
    HUBSET Ok, max clock speed enabled
    Loading.......complete
    

    Did you test this on a real-code download & run ok ?

    I've been playing about speeding the code up, and found some puzzles ... I have it ~2x faster, and think ~4x faster is possible..

    Puzzles:
    Your code seems to send one less char than predicted ?

    & also does not quite base64 encode how I anticipated.
    eg I find 0x14 maps onto U, so for my tests I want to send 'UUUU', which I make to be
    0x14+(0x14<<6)+(0x14<<12)+(0x14<<18) = 0x00514514 dropped into 24 bits, should send 'UUUU'
    - but your code needs this fill pattern to send 'UUUUUUUUUUUUUUU' (note 15U expected 16U ?)
    buff1 = [0x51,0x45,0x14]*4


  • Loader seems to be Ok here.
    Downloaded code runs Ok.
    Just download a 450K image with no issues.
    Melbourne, Australia
  • Ah, Ok I see the problem now.
    All the tested code I tried is not affected by the dropped bits at the end of the stream.
    I need to add a check at the end to empty the bit buffer.
    Good pick up jmg.
    Melbourne, Australia
  • jmgjmg Posts: 11,778
    edited August 20 Vote Up0Vote Down
    ozpropdev wrote: »
    Loader seems to be Ok here.
    Downloaded code runs Ok.
    Just download a 450K image with no issues.

    Ah, thanks, I went back to the example Chip gave, reshuffled my packing, and now I have my faster code below sending

    buff1 = [0xFB,0xF7,0x23,0xF6,0xFD,0xFB,0x23,0xF6,0x25,0x26,0x80,0xFF,0x28,0x80,0x66,0xFD,0xF0,0xFF,0x9F,0xFD]
    # Want : +/cj9v37I/YlJoD/KIBm/fD/n/0
    # Get : SendStr +/cj9v37I/YlJoD/KIBm/fD/n/0 Len() 27 = OK, takes 2 remainder branch
    Your original code does this
    # Get : SendStr +/cj9v37I/YlJoD/KIBm/fD/n/ Len() 26 - Missing '0' ?


    Speed Tests - original were a little slow in the Base64 prep area...
    # Len: 699051 Time to construct s: 1.088480
    # Len: 699051 Time to construct s: 0.999540
    # Len: 699051 Time to construct s: 0.988162

    improved code below : is now ~ 4x faster,
    # Fixed packing of build_txt_R3W4()
    # Len: 699056 Time to construct s: 0.252640
    # Len: 699056 Time to construct s: 0.248172
    # Len: 699056 Time to construct s: 0.256134

    expected transport times USB-UART (add to the prep time above)
    CP2102N 6~8MBd appx 699056/(5.5M/10) = 1.271s
    FT232H 12Mbd appx 699056/(12M/10) = 0.582s


    cBase64LUT = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        
    def build_txt_R3W4():  # much faster variant 
        r = ""
        idx = 0
        len_buff1 = len(buff1)
        rem3 = len_buff1 % 3         # split into triples  
        TopByte = len_buff1-1        # eg 0..11 for 12 bytes
        Last3Byte = len_buff1-rem3   # do fraction of triple  later
        if len_buff1 >= 3:
          while idx < Last3Byte:     # bytes are 0..len-1
            Wn = (buff1[idx] <<16) + (buff1[idx+1] <<8) + buff1[idx+2]   # 24 bits becomes 4 chars
            B64Quad = cBase64LUT[(Wn>>18) & 0x3f] + cBase64LUT[(Wn>>12) & 0x3f] + cBase64LUT[(Wn>>6) & 0x3f] + cBase64LUT[Wn & 0x3f]
            r = r + B64Quad  
            idx += 3
        # choices of 0,1,2 partial triples remaining    
        if rem3 == 1:              # 8 bits to send, needs 2 base64 
            Wn = buff1[TopByte]    # 1 top byte, send as 6.2 LEFT justified  [765432][10----]
            B64Quad = cBase64LUT[(Wn>>2) & 0x3f] + cBase64LUT[(Wn & 0x03)<<4]
            r = r + B64Quad       
        elif rem3 == 2:              # 16 bits to send, needs 3 base64 
            Wn = (buff1[TopByte-1]<<8) + buff1[TopByte]  # 2 top bytes, take 16, send as 6.6.4 LEFT justified [15.14.13.12.11.10][9.8.7.6.5.4][3.2.1.0--]
            B64Quad = cBase64LUT[(Wn>>10) & 0x3f] + cBase64LUT[(Wn>>4) & 0x3f] + cBase64LUT[(Wn & 0x0f) <<2]
            r = r + B64Quad  
        return r
    # Given this : buff1 = [0xFB,0xF7,0x23,0xF6,0xFD,0xFB,0x23,0xF6,0x25,0x26,0x80,0xFF,0x28,0x80,0x66,0xFD,0xF0,0xFF,0x9F,0xFD]
    # Want   :          +/cj9v37I/YlJoD/KIBm/fD/n/0
    #    Get : SendStr  +/cj9v37I/YlJoD/KIBm/fD/n/0 Len() 27
    
    # buff1 = [0x51,0x45,0x14]*174764   # Magic triple to base64 encode as UUUU, so can use Freq Counter to test times and dropouts....
    


    Can you confirm that works on some real downloads ?
  • ozpropdevozpropdev Posts: 2,162
    edited August 20 Vote Up0Vote Down
    Works great!
    Just had to add pre/postamble to stream.
    r = "> Prop_Txt 0 0 0 0 "
    …
      r += " ~"
    
    Melbourne, Australia
  • jmgjmg Posts: 11,778
    edited August 20 Vote Up0Vote Down
    ozpropdev wrote: »
    Works great!
    Just had to add pre/postamble to stream.

    Good to hear :)
    With modest tuning, this Python is looking quite useful. A final device should manage the 12MBd download, fingers crossed ?
    Just checked the code with FT232H,
    # PC Time to send at Baud  12000000   0.582612 s  (add above Prep time 0.2322 s to get total download overhead )
    Counter reports 6.00011MHz so 12.00022 Mbd,  
    Predicted 12M download time is  0.582546 s 
    FT2232H will be similar.
    

    If someone was doing production programming, there could be a case for allowing send of a pre-prepared Base64 file, to save (most of) that prep time.
  • jmg,

    In your code above you have:
    # Given this : buff1 = [0xFB,0xF7,0x23,0xF6,0xFD,0xFB,0x23,0xF6,0x25,0x26,0x80,0xFF,0x28,0x80,0x66,0xFD,0xF0,0xFF,0x9F,0xFD]
    # Want   :          +/cj9v37I/YlJoD/KIBm/fD/n/0
    #    Get : SendStr  +/cj9v37I/YlJoD/KIBm/fD/n/0 Len() 27[code]
    
    When I do this in javascript I get something slightly different:
    buff1 = [0xFB,0xF7,0x23,0xF6,0xFD,0xFB,0x23,0xF6,0x25,0x26,0x80,0xFF,0x28,0x80,0x66,0xFD,0xF0,0xFF,0x9F,0xFD]
    
    var encoded = new Buffer(buff1).toString('base64');
    console.log("buff1: ", encoded)
    console.log("Lenghth: ", encoded.length)
    
    Outputs:
    buff1:  +/cj9v37I/YlJoD/KIBm/fD/n/0=
    Lenghth:  28
    



  • jmgjmg Posts: 11,778
    Not sure what that means, I just took Chip's before and after example
    https://forums.parallax.com/discussion/comment/1384233/#Comment_1384233
    and stopped when I had equality.

    As a cross check, 20*8/6 = 26.666, so it should 'fit into' 27 chars.
  • Turns out that the extra "=" on the end of my output is there for padding.

    This padding may or may not be required depending on the variant of the base64 standard one is using.
    See here: https://en.wikipedia.org/wiki/Base64#Variants_summary_table

    The padding is mandatory for Base64 transfer encoding for MIME (RFC 2045). As used for encoding binary data, as we do here.

    This sounds like a bug.

    The Python base64 library agrees:
    import base64
    buff1 = bytearray.fromhex('FB F7 23 F6 FD FB 23 F6 25 26 80 FF 28 80 66 FD F0 FF 9F FD')
    print (base64.b64encode(buff1))
    
    Outputs:
    +/cj9v37I/YlJoD/KIBm/fD/n/0=
    






  • jmgjmg Posts: 11,778
    Heater. wrote: »
    Turns out that the extra "=" on the end of my output is there for padding.

    This padding may or may not be required depending on the variant of the base64 standard one is using.
    See here: https://en.wikipedia.org/wiki/Base64#Variants_summary_table

    The padding is mandatory for Base64 transfer encoding for MIME (RFC 2045). As used for encoding binary data, as we do here.

    This sounds like a bug.
    The 'gold standard' here is the P2 ROM, that is what needs to receive the host-generated strings.

  • If it works with the Prop then we are good to go.

    Though if it does not actually conform to the base64 standard we should not call it that.

    I betting the Prop PROM does not care about that padding and that it will accept output from Javascript or Python base64 encoders or others.

    Have you actually tried using Python's base64 module?

    Actually I was wondering why you hand coded that encoder. I would have expected the built in one to be much faster.
  • The "=" looks like a good idea to me. Would be nice to use
    But, I suppose the " ~" at the end makes it so you don't need it.

    I searched and found how to do this in Visual Studio:
    #include "stdafx.h"
    #include "atlenc.h"
    
    int main ( ) 
    {
       BYTE Source[] = {"\t To be encoded. \n"};
       char Dest[1024];
       int DestLen = 1024;
       BOOL rc = Base64Encode (Source, sizeof (Source), Dest, &DestLen);
       Dest[DestLen] = '\0'; // append null
       // this creates the string CSBUbyBiZSBlbmNvZGVkLiAKAA==
       return 0;
    }
    
    Prop Info and Apps: http://www.rayslogic.com/
  • jmgjmg Posts: 11,778
    Heater. wrote: »
    If it works with the Prop then we are good to go.
    I betting the Prop PROM does not care about that padding and that it will accept output from Javascript or Python base64 encoders or others.

    The ROM seems to exit on first not=base64 char, and I guess extra '=' are tolerated.
    Easy enough to try, but it also looks easy enough (see below) to strip any trailing '=' at the host side.
    I think it gives either none, or '=' or '==' as appended packer ?
    Heater. wrote: »
    Have you actually tried using Python's base64 module?
    Actually I was wondering why you hand coded that encoder. I would have expected the built in one to be much faster.
    No, I was partly assuming the hand-coding I started from, was required because P2 was different enough..

    checking this
    from base64 import b64encode
    SendAry = b64encode(bytes(buff1)).rstrip(b'=') 
    
    seems to remove any trailing '=' packers, and yes, the built in one is significantly faster, slashes prep time from ~230ms to ~ 10ms
  • I seem to recall that @JMG pleaded for a 'nonstandard' BASE64 encoding skipping U for autobaud...

    https://forums.parallax.com/discussion/comment/1391790/#Comment_1391790

    Not sure if this was implemented or not but that might be a issiue.

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • jmgjmg Posts: 11,778
    msrobots wrote: »
    I seem to recall that @JMG pleaded for a 'nonstandard' BASE64 encoding skipping U for autobaud...
    Not sure if this was implemented or not but that might be a issiue.
    No, Chip uses a standard char set in P2 ROM, and creates a lookup table for decode speed, which then makes the 'simpler tests' point moot.

    'Standard' base64 looks to use a 65 char-set, with the '=' as a packer. The P2 ROM I think exits base64 decode if it see's '=', but you can also use .rstrip(b'='), as above on the host side.

    The latest P2 Autobaud revisions of '> ' use an advanced char edge ratio test, (tFF,tH) via the smart pins, which are almost as precise as 'U', but can be trapped in a mid-stream capture.

    ie if you send a continually repeating
    "> Prop_Chk 0 0 0 0 "+"> Prop_Chk 0 0 0 0 "+"> Prop_Chk 0 0 0 0 "+"> Prop_Chk 0 0 0 0 "...
    that can Exit-reset and Autobaud fine, no matter what phase the reset release has.

    Other MCUs cannot quite manage that ....

  • T ChapT Chap Posts: 3,790
    edited August 21 Vote Up0Vote Down
    I’m curious why you’d use the 2102 that requires a driver when you are building your own loader that you could add An HID no driver feature. For example the CP2110.

    “CP210x devices can generally provide a higher throughput than the CP2110. The CP2110 is limited to 1 x 64 byte packet per 1 millisecond, while the CP210x will generally have multiple 64 byte packets per 1 millisecond. “

    Maybe this is an issue
  • jmgjmg Posts: 11,778
    edited August 22 Vote Up0Vote Down
    T Chap wrote: »
    I’m curious why you’d use the 2102 that requires a driver when you are building your own loader that you could add An HID no driver feature. For example the CP2110.

    “CP210x devices can generally provide a higher throughput than the CP2110. The CP2110 is limited to 1 x 64 byte packet per 1 millisecond, while the CP210x will generally have multiple 64 byte packets per 1 millisecond. “

    Maybe this is an issue

    Speed is always an issue :)

    64 bytes/ms is ~64k Bytes/s, whilst the CP2102N here is hitting ~550k Bytes/s with Python (FT232H hits 1.2MB/s)

    - but you are right, HID is driver-less and could appeal to some, even at the lower speeds, so a HID variant certainly sounds possible/useful.

    Google finds some Python HID hits- has anyone done HID with Python ?

    Addit: Found time to do some Rx tests, with a FT2232H 'standing in' for a P2 - sending high speed UART data to a CP2102N
    # CP2102N RX burst Tests - no handshake enabled, looking for packet size tolerance. HW buffers mean smaller packets are 'easier' than larger ones.
    # RX burst tests 4MBd 8.N.1   - 'U'*100   = fine 
    # RX burst tests 4MBd 8.N.1   - 'U'*1000  = fine 
    # RX burst tests 4MBd 8.N.1   - 'U'*2000  = fine 
    # RX burst tests 4MBd 8.N.1   - 'U'*3000  = XX Rx Over Ctr 1 @ Rx.Count 5994 Rx Over Ctr 2 @ Rx.Count 8967
    # RX burst tests 4MBd 8.N.1   - 'U'*4000  = XX drops to 3834 
    # RX burst tests 4MBd 8.N.1   - 'U'*10000 = XX drops to 9058 chars
    
    # RX burst tests 6MBd 8.N.1   - 'U'*100   = fine 
    # RX burst tests 6MBd 8.N.1   - 'U'*500   = fine 
    # RX burst tests 6MBd 8.N.1   - 'U'*600   = fine ie quite close to the HW buffer size here 
    # RX burst tests 6MBd 8.N.1   - 'U'*750   = XX Rx Over Ctr 1 @ Rx.Count 1896 Rx Over Ctr 2 @ Rx.Count 2536
    # RX burst tests 6MBd 8.N.1   - 'U'*1000  = XX Rx Over Ctr 1 @ Rx.Count 1896 Rx Over Ctr 2 @ Rx.Count 2536
    
    # RX burst tests 8MBd 8.N.1  - 'U'*10    = fine (1 stop bit)
    # RX burst tests 8MBd 8.N.2  - 'U'*64    = fine (note needs bump to 2 stop bits)
    # RX burst tests 8MBd 8.N.2  - 'U'*128   = fine
    # RX burst tests 8MBd 8.N.2  - 'U'*256   = fine
    # RX burst tests 8MBd 8.N.2  - 'U'*512   = fine
    # RX burst tests 8MBd 8.N.2  - 'U'*750   = XX Rx Over Ctr 1 @ Rx.Count 704
    # RX burst tests 8MBd 8.M.2  - 'U'*750   = XX Rx Over Ctr 1 @ Rx.Count 704
    # RX burst tests 8MBd 8.M.2  - 'U'*700   = XX better, 4 ok before Over Ctr 1 @ Rx.Count 2792
    # RX burst tests 8MBd 8.N.1  - 'U'*64    = XX 63,125 - one stop bit is not enough.
    # RX burst tests 8MBd 8.N.1  - 'U'*100   = XX 97,195 
    
    TX was given above, and looks fine to 2M block sends. ~ 550k Bytes/sec stream speeds.
    RX is tougher, and here looks like 2 stop bits allows moderate packets from the P2, and some simple pause-code should save needing HW handshake lines.
  • jmgjmg Posts: 11,778
    ozpropdev wrote: »
    Works great!
    Just had to add pre/postamble to stream.

    Can you test/merge this change, from above ?
    from base64 import b64encode
    SendAry = b64encode(bytes(buff1)).rstrip(b'=') 
    # add pre/postamble & send...
    

    If that works ok, try one with the .rstrip(b'=') removed - that then leaves the 0/1/2 packer '=' appended.
  • b64encode works fine.
    P2 seems to ignore the '=' character.
        sp1.write(b'> Prop_Txt 0 0 0 0 ')
        sp1.write(b64encode(bytes(buff1)))
        sp1.write(b'~')  #run code
    

    Eezy peezy :)

    Melbourne, Australia
  • jmgjmg Posts: 11,778
    edited August 23 Vote Up0Vote Down
    ozpropdev wrote: »
    b64encode works fine.
    P2 seems to ignore the '=' character.
    ..
    Eezy peezy :)
    Great, I like Simple and Fast at the same time :)
    That brings total Download times down to this ballpark, for a full 512k image download to P2 of
    CP2102N 6~8MBd appx 699056/(5.5M/10) = 1.271s + 10ms
    FT232H 12Mbd appx 699056/(12M/10) = 0.582s + 10ms
    (tbd is the actual Baud a P2 chip can support, when switched to faster sysCLK)
    FWIR ~2Mbd was spec'd at 20MHz min, so 80M (FPGA) should manage ~ 8Mbd and > 120MHz should support 12MBd downloads.

    Do you have a FT232H/FT2232H there, you can test at 6M/8M/12M on the 80M FPGA setup ?


    And a reference comparison, spotted over in AVR forums, is this comment from someone testing their
    MplabX 5.05, and the ATMEL X-plained Mini 328p

    "..was disappointed to see write speeds for about a minute for a 20k plus file size. That compares to about 50 seconds for Atmel Studio 7"

    hmm... their 50~60s for 20k, is going to make P2 download look very snappy indeed, to Atmel users :)



Sign In or Register to comment.