Shop OBEX P1 Docs P2 Docs Learn Events
FlexGUI 4.3.1: Program your P2 in Spin, BASIC, or C — Parallax Forums

FlexGUI 4.3.1: Program your P2 in Spin, BASIC, or C

ersmithersmith Posts: 5,900
edited 2020-08-15 20:36 in Propeller 2
The latest version of FlexGUI is available at:

https://github.com/totalspectrum/flexgui/releases/.

Get the "flexgui.zip" file from the latest release, and unpack it anywhere convenient (it should be a location that you have read/write access to, e.g. your desktop, rather than a system folder like "Program Files"). Both Windows and Macintosh binaries are included with this release.

NOTE: FlexGUI is not in any way affiliated with Parallax, and please do not direct any questions about it to Parallax support.

FlexGUI supports programming both the P1 and the P2, in BASIC, Spin, and C, and also comes with interfaces for Python, Forth, and Lisp programming (those last 3 languages rely on an interpreter to run on the P2, rather than compiling the code directly). The Spin support comes in two flavors: Spin 1 with extensions (if the file has a .spin suffix) and Spin 2 with extensions (if it has a .spin2 suffix). Either one can be compiled for either P1 or P2. There's not a lot of difference between them, mostly it's in the operators, e.g. to use the keyword operators like FRAC you'll have to use .spin2.

It's very easy to get started with FlexGUI. Just run flexgui.exe (or flexgui.tcl for the Mac). You'll see a window open. Type something like:
print "hello from the P2"
into the window, then press the "Compile & Run on P2" button. It'll prompt you for a name to save the file as (it needs to save the file before compiling); enter something like "hello.bas", since this is a BASIC program. You'll then get a terminal window popping open with the "hello from the P2" message. If you prefer C or Spin, you can also enter those languages instead; just name the file appropriately with a ".c" or ".spin" extension.

This release has a lot of improvements compared to earlier versions of FlexGUI. The BASIC language has many more operators and built-in functions (thanks in part to contributions by @JRoark ) and now supports multiple assignment and functions which return multiple values. The Spin language supports more of Chip's proposed Spin2 syntax, including method pointers. There have been many bug fixes, especially in the C compiler.

In the GUI, the Help menu has been expanded to allow easy access to language references. It's now possible to set the command output font in the "Editor Options..." menu, and there's also an option there to automatically reload files if they are changed in an external editor (e.g. if you're using the PropTool to edit Spin files but want to program them to your P2). The "Special" menu has options for downloading MicroPython, FORTH, or Lisp programs. The "Serial" menu now has an option for setting the baud rate. Under "Commands" are options for programming the flash; the "Flash program" can also be changed to an SD card loader to allow programming of binaries to SD cards.

Have fun, and please report any problems you run into either here or on the github issues page.
«13456

Comments

  • One minor issue I have noticed is that P2 programs are a little slow starting up on Windows if the serial port is set to "Find port automatically" (the default). For faster turn-around time select the COM port to use manually.
  • JRoarkJRoark Posts: 1,214
    edited 2020-01-20 17:30
    @ersmith has been busy!
    On the FlexBASIC-side of the house, a quick look through the manual shows we have a bunch of new toys to play with.

    The new functions available are: BIN$(), COS(), Decuns$(), Delete$(), EXP(), HEX$(), Insert$(), Instr$(), InstrREV$(), LOG(), Oct$(), PinRND(), _Reboot(), SHR aka >>, SHL aka <<, Sin(), Tan(), WaitX(), WRPin(), WXPin(), WYPin()

    We also have a new emerging datatype: LongInt and ULongInt (64 bits!, early support)

    It's going to be a fun day!...

    EDIT: HA! Eric included an "easter egg" in the form of "\include\libsys\stringlibp2.bas". If you INCLUDE this in your code like this:
    #INCLUDE  "\include\libsys\stringlibp2.bas"
    
    ...then you also get these new functions: LCase$(), LPad$(), LTrim$(), Reverse$(), RPad$(), RTrim$(), Space$(), Trim$(), UCase$()
  • Bravo! I have to stop printing the reference guides. You update too often. I killed a lot of trees. :)
  • Thanks for all all the hard work ersmith. That was a ton of github commits since the last release.

    I recall seeing a starting clock frequency calculator. Basically Chip's idea to give a frequency and have it calculate the dividers and multipliers internally and set it during program startup.
  • whicker wrote: »
    I recall seeing a starting clock frequency calculator. Basically Chip's idea to give a frequency and have it calculate the dividers and multipliers internally and set it during program startup.

    Sorry, yes, I forgot to put that in the release notes -- the Spin compiler in P2 now works like Chip's Spin2, and can calculate a starting mode based on the desired clock frequency and input frequency (the input frequency defaults to 20MHz). Most of the Spin samples have been ported to use that method of setting the clock.
  • Does anyone have an RC clock that is ~20MHz? My boards are closer to 24-25MHz. Maybe the default needs to be higher...unless 20MHz is actually more common in production?
  • It's supposed to be about 24 MHz so that at worst case conditions it is still above 20 MHz.
    It is supply voltage, temperature, and batch sensitive.
  • Ok, I actually misread the above post from Eric, it mentions input frequency defaults. This is probably an external crystal not the RC one. I initially read it and thought it was relying on the internal RC clock being 20MHz.
  • rogloh wrote: »
    Ok, I actually misread the above post from Eric, it mentions input frequency defaults. This is probably an external crystal not the RC one. I initially read it and thought it was relying on the internal RC clock being 20MHz.

    Right, I was referring to the calculation of the PLL mode setting bits. Just as Chip described for his Spin2 compiler, fastspin will take a block like:
    CON
      _clkfreq = 180_000_000
      _xinfreq = 12_000_000
    
    and figure out the bits to use in hubset to set the clock to the desired frequency (and set this at boot time). If _xinfreq is not given it defaults to 20 MHz.

    RCFAST is a different kettle of fish, but calculating the mode value for that is easy since it's just 0x0 :).

  • ersmith wrote: »
    Right, I was referring to the calculation of the PLL mode setting bits. Just as Chip described for his Spin2 compiler, fastspin will take a block like:
    CON
      _clkfreq = 180_000_000
      _xinfreq = 12_000_000
    
    and figure out the bits to use in hubset to set the clock to the desired frequency (and set this at boot time). If _xinfreq is not given it defaults to 20 MHz.

    Any chance of getting a similar functionality in FlexBASIC? This could be very useful.

  • JRoark wrote: »
    ersmith wrote: »
    Right, I was referring to the calculation of the PLL mode setting bits. Just as Chip described for his Spin2 compiler, fastspin will take a block like:
    CON
      _clkfreq = 180_000_000
      _xinfreq = 12_000_000
    
    and figure out the bits to use in hubset to set the clock to the desired frequency (and set this at boot time). If _xinfreq is not given it defaults to 20 MHz.

    Any chance of getting a similar functionality in FlexBASIC? This could be very useful.

    A 100% chance :) FlexBASIC has the same feature, but you have to use const instead:
    const _clkfreq = 180_000_000
    const _xinfreq = 12_000_000
    
  • Schweet! I must have missed that little gem in the once-over I gave manual.
  • I've updated the FlexGUI release to 4.1.1. This is a bugfix release, with a minor improvement to the P2 optimizer. The changes are:

    fastspin
    - Fixed Spin REV operator to match PNut's Spin2 definition.
    - Optimize some P2 moves into BMASK or DECOD instructions
    - Allow the word "asm" to be used as a label in Spin
    - Allow use of _ in integers in BASIC DATA/READ

    loadp2
    - Reduced the timeout used when searching for a P2 (if a comm port is explicitly given then the behavior should be the same as before)

    flexgui
    - Fixed a packaging bug where some demo files were missing
    - Fixed a problem with the "Spin" help menu item
  • In the current flexgui (on macOS :-), selecting the Language Help menus doesn't display the Help docs (Spin, C, BASIC), though it does display the GUI Help doc.
    In the console:
    % wish flexgui.tcl 
    The file /Users/altergator/flexgui/doc/basic.html does not exist.
    The file /Users/altergator/flexgui/doc/c.html does not exist.
    The file /Users/altergator/flexgui/doc/spin.html does not exist.
    
    Looking through the Makefile, I don't see anything that produces and copies .html files to the flexgui doc directory. I do see the .md files and something about pandoc. Is that supposed to create the .html's? After installing pandoc, I get an error about pdflatex... Are PDFs supposed to be created? The .md files are copied to flexgui's doc directory, should they be opened when the Help menus are selected?
    pandoc --metadata-file=pandoc.yml -s --toc -f gfm -t latex -o spin2cpp/Fastspin.pdf spin2cpp/Fastspin.md
    pdflatex not found. Please select a different --pdf-engine or install pdflatex.
    
    Currently installing MacTeX to see if that solves the problem...

    dgately

  • OK, so installing pandoc & MacTeX, allows make to complete, successfully... Selecting the Help menu for each language brings up the correct webpage for language help. Not sure why the Makefile needed pandoc & MacTeX, just to access the URLs of a few webpages.


    dgately
  • The Makefile needed to create the HTML from .md files, which is what it uses pandoc for.

    The most recent FlexGUI .zip file has Mac binaries, so if you run into a problem building anything you could always install the binary :). But it sounds like you have things sorted out now.
  • ersmith wrote: »
    The Makefile needed to create the HTML from .md files, which is what it uses pandoc for.

    The most recent FlexGUI .zip file has Mac binaries, so if you run into a problem building anything you could always install the binary :). But it sounds like you have things sorted out now.
    I want to make sure that the project builds on macOS, because I have the macOS server that builds within David Zemon's TeamCity Propeller projects build services... Right now, flexgui is not building automatically on that server, so I'm about to debug that issue and want to make sure I can build flexgui manually.

    dgately

  • I've updated the flexgui release to 4.1.2. This is mainly a bug fix version, although the GUI does have one new feature (hyperlinks for include files). I've started to add some basic simpletools support for C, but that is in very early stages now (just the first tutorial works).

    The flexgui.zip file includes both Windows and MacOSX binaries, and is available from my Patreon page or from:

    https://github.com/totalspectrum/flexgui/releases
  • roglohrogloh Posts: 5,122
    edited 2020-02-03 02:47
    After upgrading to the bundled loadp2 in the latest flexgui 4.1.2 (which is v0.041) I am seeing frequent timeout issues on my Mac (OS X 10.10.5) Doing Compile & Run download attempts in flexgui, maybe 25-33% of the time when I repeatedly press the button, I get this output and it fails..

    ERROR: timeout waiting for initial checksum: got -1

    I had a very solid P2 download when using older tools (my loadp2 was v 0.017 IIRC) prior to using this later version. What's changed with these timeouts since then? It would be good to have a reliable download tool working again. Something is timing out too soon by the looks of it, or the downloader is not starting up correctly every time. Loader baud rate is just the default (i.e. was not setup in loadp2 command string).

    Here's the relevant code in the download sequence...the code appears to either not be waiting long enough for the response, the auto baud space character is sent too soon (50ms wait not enough for the COG to be ready?), or received too late, or the P2 reset is not working. Not sure what else would cause it. I think if a wait_drain() is added after the transmission of the "~" and before the 50ms sleep it might be better, so we know that the ~ has been sent out the wire and received by the COG before we send the auto baud char and expect a response. This would remove any serial buffering lag affecting the transaction. It's a better way to go than put in hardcoded 50ms delays etc. Same probably goes for the 10ms sleeps in the retries.
    Roger.

        tx((uint8_t *)"> Prop_Hex 0 0 0 0", 18);
        txstring((uint8_t *)MainLoader1_bin, MainLoader1_bin_len);
        txval(clock_mode);
        txval(flag_bits());
        tx((uint8_t *)"~", 1);
        
        {
            int retry;
            // receive checksum, verify it's "@@ "
            msleep(50);
            tx_raw_byte(' ');
            for (retry = 0; retry < 5; retry++) {
                // send autobaud character
                tx_raw_byte(' ');
                msleep(10);
                num = rx_timeout((uint8_t *)buffer, 3, 200);
                if (num == 3) break;
            }
            if (num != 3) {
                printf("ERROR: timeout waiting for initial checksum: got %d\n", num);
                promptexit(1);
            }
            if (buffer[0] != '@' || buffer[1] != '@') {
                printf("ERROR: got incorrect initial chksum: %c%c%c (%02x %02x %02x)\n", buffer[0], buffer[1], buffer[2], buffer[0], buffer[1], buffer[2]);
                promptexit(1);
            }
        }
    
  • Sorry you're having these timeout issues. Does the problem still happen if you do not have an SD card inserted (SD card presence changes the timing of the bootup sequence significantly)? And does it happen if you explicitly set the serial port rather than relying on auto detection?
  • I have only tried without the SD. Interestingly I have found if I set the serial port loader to 2000000 I didn't seem to get it to fail quite as often as shown in the captured loops of 50 download iterations below [ which was actually 49 because the loop condition started from 1 instead of 0. Yeah I'm a C-programmer :smile: ]

    First batch is with the loader default download rate, second is with it set to 2000000 which is visibly faster to download.

    So maybe the download rate has something to do with it? I noticed that the flexgui defaults only set the operational baud rate (-b) in the command line not the loader rate (-l) so perhaps the default download rate is different now via flexgui. This was without the auto detection variable in play.

    Sometimes the errors seem to bunch up and then there are periods where it is not behaving as bad. I wonder if it might be background OS CPU load activity affecting the timeout...though my MAC is about 97% idle. When it kicks in it seems pretty bad.
    RLs-MacBook-Pro:bin roger$ for (( i=1; i<50; i++ )); do echo -n "$i " && ./orig.loadp2.mac ../../reSoundAlfaExamples/Ahle2_reSoundSamplePlayback/main.binary -p /dev/cu.usbserial-DN43U3VJ && echo SUCCESS; done
    1 SUCCESS
    2 ERROR: timeout waiting for initial checksum: got -1
    3 SUCCESS
    4 SUCCESS
    5 SUCCESS
    6 ERROR: timeout waiting for initial checksum: got -1
    7 SUCCESS
    8 ERROR: timeout waiting for initial checksum: got -1
    9 ERROR: timeout waiting for initial checksum: got -1
    10 SUCCESS
    11 SUCCESS
    12 SUCCESS
    13 ERROR: timeout waiting for initial checksum: got -1
    14 SUCCESS
    15 SUCCESS
    16 SUCCESS
    17 SUCCESS
    18 SUCCESS
    19 SUCCESS
    20 SUCCESS
    21 SUCCESS
    22 SUCCESS
    23 SUCCESS
    24 SUCCESS
    25 SUCCESS
    26 SUCCESS
    27 SUCCESS
    28 SUCCESS
    29 SUCCESS
    30 SUCCESS
    31 SUCCESS
    32 SUCCESS
    33 SUCCESS
    34 SUCCESS
    35 ERROR: timeout waiting for initial checksum: got -1
    36 SUCCESS
    37 SUCCESS
    38 SUCCESS
    39 SUCCESS
    40 SUCCESS
    41 SUCCESS
    42 SUCCESS
    43 SUCCESS
    44 SUCCESS
    45 SUCCESS
    46 SUCCESS
    47 SUCCESS
    48 SUCCESS
    49 SUCCESS
    RLs-MacBook-Pro:bin roger$ for (( i=1; i<50; i++ )); do echo -n "$i " && ./orig.loadp2.mac -l2000000 ../../reSoundAlfaExamples/Ahle2_reSoundSamplePlayback/main.binary -p /dev/cu.usbserial-DN43U3VJ && echo SUCCESS; done
    1 SUCCESS
    2 SUCCESS
    3 SUCCESS
    4 SUCCESS
    5 SUCCESS
    6 SUCCESS
    7 SUCCESS
    8 SUCCESS
    9 SUCCESS
    10 SUCCESS
    11 SUCCESS
    12 SUCCESS
    13 ERROR: timeout waiting for initial checksum: got -1
    14 SUCCESS
    15 SUCCESS
    16 SUCCESS
    17 SUCCESS
    18 SUCCESS
    19 SUCCESS
    20 SUCCESS
    21 SUCCESS
    22 SUCCESS
    23 SUCCESS
    24 SUCCESS
    25 SUCCESS
    26 SUCCESS
    27 SUCCESS
    28 SUCCESS
    29 SUCCESS
    30 SUCCESS
    31 SUCCESS
    32 SUCCESS
    33 SUCCESS
    34 SUCCESS
    35 SUCCESS
    36 SUCCESS
    37 SUCCESS
    38 SUCCESS
    39 SUCCESS
    40 SUCCESS
    41 SUCCESS
    42 SUCCESS
    43 SUCCESS
    44 ERROR: timeout waiting for initial checksum: got -1
    45 SUCCESS
    46 SUCCESS
    47 SUCCESS
    48 SUCCESS
    49 SUCCESS
    
  • roglohrogloh Posts: 5,122
    edited 2020-02-03 19:53
    Here's a longer run of 100 iterations each. The slower default loader is still worse, though not by as much. Results were 9% failure rate for 2Mbps vs 18% failure for default rate. Also there was another error type printed here, which may shed more light perhaps...? It looks like the "G" from the chip revision is coming in late and being interpreted as a part of a checksum. It may be that the code may not be waiting long enough for any serial pipeline delay and getting results later than expected. Flush/drain may be required somewhere or increased timeouts.

    64 SUCCESS
    65 ERROR: timeout waiting for initial checksum: got -1
    66 Warning: Unknown version , assuming CHIP
    ERROR: got incorrect initial chksum: G
    (47 0d 0a)


    RLs-MacBook-Pro:bin roger$ for (( i=1; i<=100; i++ )); do echo -n "$i " && ./orig.loadp2.mac -l2000000 ../../reSoundAlfaExamples/Ahle2_reSoundSamplePlayback/main.binary -p /dev/cu.usbserial-DN43U3VJ && echo SUCCESS; done
    1 SUCCESS
    2 SUCCESS
    3 SUCCESS
    4 SUCCESS
    5 SUCCESS
    6 SUCCESS
    7 SUCCESS
    8 SUCCESS
    9 ERROR: timeout waiting for initial checksum: got -1
    10 SUCCESS
    11 SUCCESS
    12 SUCCESS
    13 SUCCESS
    14 SUCCESS
    15 SUCCESS
    16 SUCCESS
    17 SUCCESS
    18 ERROR: timeout waiting for initial checksum: got -1
    19 SUCCESS
    20 SUCCESS
    21 ERROR: timeout waiting for initial checksum: got -1
    22 SUCCESS
    23 SUCCESS
    24 SUCCESS
    25 SUCCESS
    26 SUCCESS
    27 SUCCESS
    28 SUCCESS
    29 ERROR: timeout waiting for initial checksum: got -1
    30 SUCCESS
    31 SUCCESS
    32 SUCCESS
    33 SUCCESS
    34 SUCCESS
    35 SUCCESS
    36 SUCCESS
    37 SUCCESS
    38 SUCCESS
    39 SUCCESS
    40 SUCCESS
    41 SUCCESS
    42 SUCCESS
    43 SUCCESS
    44 SUCCESS
    45 SUCCESS
    46 SUCCESS
    47 SUCCESS
    48 SUCCESS
    49 SUCCESS
    50 SUCCESS
    51 SUCCESS
    52 SUCCESS
    53 SUCCESS
    54 SUCCESS
    55 SUCCESS
    56 SUCCESS
    57 SUCCESS
    58 SUCCESS
    59 SUCCESS
    60 SUCCESS
    61 SUCCESS
    62 ERROR: timeout waiting for initial checksum: got -1
    63 SUCCESS
    64 SUCCESS
    65 SUCCESS
    66 ERROR: timeout waiting for initial checksum: got -1
    67 SUCCESS
    68 SUCCESS
    69 SUCCESS
    70 ERROR: timeout waiting for initial checksum: got -1
    71 SUCCESS
    72 ERROR: timeout waiting for initial checksum: got -1
    73 ERROR: timeout waiting for initial checksum: got -1
    74 SUCCESS
    75 SUCCESS
    76 SUCCESS
    77 SUCCESS
    78 SUCCESS
    79 SUCCESS
    80 SUCCESS
    81 SUCCESS
    82 SUCCESS
    83 SUCCESS
    84 SUCCESS
    85 SUCCESS
    86 SUCCESS
    87 SUCCESS
    88 SUCCESS
    89 SUCCESS
    90 SUCCESS
    91 SUCCESS
    92 SUCCESS
    93 SUCCESS
    94 SUCCESS
    95 SUCCESS
    96 SUCCESS
    97 SUCCESS
    98 SUCCESS
    99 SUCCESS
    100 SUCCESS
    RLs-MacBook-Pro:bin roger$ for (( i=1; i<=100; i++ )); do echo -n "$i " && ./orig.loadp2.mac  ../../reSoundAlfaExamples/Ahle2_reSoundSamplePlayback/main.binary -p /dev/cu.usbserial-DN43U3VJ && echo SUCCESS; done
    1 SUCCESS
    2 SUCCESS
    3 ERROR: timeout waiting for initial checksum: got -1
    4 SUCCESS
    5 SUCCESS
    6 ERROR: timeout waiting for initial checksum: got -1
    7 SUCCESS
    8 SUCCESS
    9 SUCCESS
    10 SUCCESS
    11 SUCCESS
    12 SUCCESS
    13 ERROR: timeout waiting for initial checksum: got -1
    14 SUCCESS
    15 SUCCESS
    16 SUCCESS
    17 SUCCESS
    18 SUCCESS
    19 SUCCESS
    20 SUCCESS
    21 SUCCESS
    22 SUCCESS
    23 SUCCESS
    24 SUCCESS
    25 SUCCESS
    26 SUCCESS
    27 SUCCESS
    28 SUCCESS
    29 SUCCESS
    30 SUCCESS
    31 SUCCESS
    32 SUCCESS
    33 SUCCESS
    34 SUCCESS
    35 SUCCESS
    36 SUCCESS
    37 SUCCESS
    38 ERROR: timeout waiting for initial checksum: got -1
    39 SUCCESS
    40 SUCCESS
    41 SUCCESS
    42 ERROR: timeout waiting for initial checksum: got -1
    43 SUCCESS
    44 SUCCESS
    45 SUCCESS
    46 SUCCESS
    47 SUCCESS
    48 SUCCESS
    49 SUCCESS
    50 SUCCESS
    51 SUCCESS
    52 ERROR: timeout waiting for initial checksum: got -1
    53 ERROR: timeout waiting for initial checksum: got -1
    54 SUCCESS
    55 SUCCESS
    56 ERROR: timeout waiting for initial checksum: got -1
    57 SUCCESS
    58 SUCCESS
    59 SUCCESS
    60 SUCCESS
    61 SUCCESS
    62 SUCCESS
    63 SUCCESS
    64 SUCCESS
    65 ERROR: timeout waiting for initial checksum: got -1
    66 Warning: Unknown version , assuming CHIP
    ERROR: got incorrect initial chksum: G
     (47 0d 0a)
    67 ERROR: timeout waiting for initial checksum: got -1
    68 SUCCESS
    69 SUCCESS
    70 SUCCESS
    71 ERROR: timeout waiting for initial checksum: got -1
    72 ERROR: timeout waiting for initial checksum: got -1
    73 ERROR: timeout waiting for initial checksum: got -1
    74 SUCCESS
    75 SUCCESS
    76 SUCCESS
    77 SUCCESS
    78 SUCCESS
    79 SUCCESS
    80 SUCCESS
    81 SUCCESS
    82 ERROR: timeout waiting for initial checksum: got -1
    83 SUCCESS
    84 SUCCESS
    85 SUCCESS
    86 SUCCESS
    87 SUCCESS
    88 SUCCESS
    89 SUCCESS
    90 SUCCESS
    91 ERROR: timeout waiting for initial checksum: got -1
    92 SUCCESS
    93 SUCCESS
    94 SUCCESS
    95 ERROR: timeout waiting for initial checksum: got -1
    96 ERROR: timeout waiting for initial checksum: got -1
    97 SUCCESS
    98 SUCCESS
    99 SUCCESS
    100 SUCCESS
    
  • I made a change that I thought may help. It seemed to get the failure rate down to 12% for the default case, and 2% for the fast case. I reached 78 good downloads in a row for the latter and by then I'd thought I'd fixed it, but had 2 failures after this. Still an interesting result. There still must be other factors in play.
    diff --git a/loadp2.c b/loadp2.c
    index e541f3c..2d16722 100644
    --- a/loadp2.c
    +++ b/loadp2.c
    @@ -523,11 +523,13 @@ int loadfile(char *fname, int address)
         {
             int retry;
             // receive checksum, verify it's "@@ "
    +        wait_drain();
             msleep(50);
             tx_raw_byte(' ');
             for (retry = 0; retry < 5; retry++) {
                 // send autobaud character
                 tx_raw_byte(' ');
    +            wait_drain();
                 msleep(10);
                 num = rx_timeout((uint8_t *)buffer, 3, 200);
                 if (num == 3) break;
    

    Raw results:
    RLs-MacBook-Pro:bin roger$ for (( i=1; i<=100; i++ )); do echo -n "$i " && ./loadp2.mac  ../../reSoundAlfaExamples/Ahle2_reSoundSamplePlayback/main.binary -p /dev/cu.usbserial-DN43U3VJ && echo SUCCESS; done
    1 SUCCESS
    2 SUCCESS
    3 SUCCESS
    4 ERROR: timeout waiting for initial checksum: got -1
    5 SUCCESS
    6 SUCCESS
    7 SUCCESS
    8 SUCCESS
    9 SUCCESS
    10 SUCCESS
    11 SUCCESS
    12 SUCCESS
    13 SUCCESS
    14 ERROR: timeout waiting for initial checksum: got -1
    15 ERROR: timeout waiting for initial checksum: got -1
    16 SUCCESS
    17 SUCCESS
    18 SUCCESS
    19 SUCCESS
    20 SUCCESS
    21 SUCCESS
    22 SUCCESS
    23 SUCCESS
    24 SUCCESS
    25 SUCCESS
    26 SUCCESS
    27 SUCCESS
    28 SUCCESS
    29 SUCCESS
    30 SUCCESS
    31 SUCCESS
    32 SUCCESS
    33 SUCCESS
    34 SUCCESS
    35 SUCCESS
    36 SUCCESS
    37 SUCCESS
    38 SUCCESS
    39 SUCCESS
    40 SUCCESS
    41 SUCCESS
    42 SUCCESS
    43 SUCCESS
    44 SUCCESS
    45 SUCCESS
    46 SUCCESS
    47 ERROR: timeout waiting for initial checksum: got -1
    48 SUCCESS
    49 SUCCESS
    50 SUCCESS
    51 SUCCESS
    52 SUCCESS
    53 SUCCESS
    54 ERROR: timeout waiting for initial checksum: got -1
    55 SUCCESS
    56 SUCCESS
    57 SUCCESS
    58 SUCCESS
    59 ERROR: timeout waiting for initial checksum: got -1
    60 SUCCESS
    61 SUCCESS
    62 SUCCESS
    63 ERROR: timeout waiting for initial checksum: got -1
    64 SUCCESS
    65 SUCCESS
    66 ERROR: timeout waiting for initial checksum: got -1
    67 SUCCESS
    68 SUCCESS
    69 SUCCESS
    70 SUCCESS
    71 ERROR: timeout waiting for initial checksum: got -1
    72 SUCCESS
    73 ERROR: timeout waiting for initial checksum: got -1
    74 SUCCESS
    75 SUCCESS
    76 SUCCESS
    77 SUCCESS
    78 SUCCESS
    79 SUCCESS
    80 SUCCESS
    81 SUCCESS
    82 SUCCESS
    83 SUCCESS
    84 ERROR: timeout waiting for initial checksum: got -1
    85 SUCCESS
    86 SUCCESS
    87 SUCCESS
    88 SUCCESS
    89 SUCCESS
    90 SUCCESS
    91 ERROR: timeout waiting for initial checksum: got -1
    92 SUCCESS
    93 SUCCESS
    94 SUCCESS
    95 SUCCESS
    96 SUCCESS
    97 SUCCESS
    98 SUCCESS
    99 SUCCESS
    100 SUCCESS
    RLs-MacBook-Pro:bin roger$ for (( i=1; i<=100; i++ )); do echo -n "$i " && ./loadp2.mac -l2000000  ../../reSoundAlfaExamples/Ahle2_reSoundSamplePlayback/main.binary -p /dev/cu.usbserial-DN43U3VJ && echo SUCCESS; done
    1 SUCCESS
    2 SUCCESS
    3 SUCCESS
    4 SUCCESS
    5 SUCCESS
    6 SUCCESS
    7 SUCCESS
    8 SUCCESS
    9 SUCCESS
    10 SUCCESS
    11 SUCCESS
    12 SUCCESS
    13 SUCCESS
    14 SUCCESS
    15 SUCCESS
    16 SUCCESS
    17 SUCCESS
    18 SUCCESS
    19 SUCCESS
    20 SUCCESS
    21 SUCCESS
    22 SUCCESS
    23 SUCCESS
    24 SUCCESS
    25 SUCCESS
    26 SUCCESS
    27 SUCCESS
    28 SUCCESS
    29 SUCCESS
    30 SUCCESS
    31 SUCCESS
    32 SUCCESS
    33 SUCCESS
    34 SUCCESS
    35 SUCCESS
    36 SUCCESS
    37 SUCCESS
    38 SUCCESS
    39 SUCCESS
    40 SUCCESS
    41 SUCCESS
    42 SUCCESS
    43 SUCCESS
    44 SUCCESS
    45 SUCCESS
    46 SUCCESS
    47 SUCCESS
    48 SUCCESS
    49 SUCCESS
    50 SUCCESS
    51 SUCCESS
    52 SUCCESS
    53 SUCCESS
    54 SUCCESS
    55 SUCCESS
    56 SUCCESS
    57 SUCCESS
    58 SUCCESS
    59 SUCCESS
    60 SUCCESS
    61 SUCCESS
    62 SUCCESS
    63 SUCCESS
    64 SUCCESS
    65 SUCCESS
    66 SUCCESS
    67 SUCCESS
    68 SUCCESS
    69 SUCCESS
    70 SUCCESS
    71 SUCCESS
    72 SUCCESS
    73 SUCCESS
    74 SUCCESS
    75 SUCCESS
    76 SUCCESS
    77 SUCCESS
    78 SUCCESS
    79 ERROR: timeout waiting for initial checksum: got -1
    80 SUCCESS
    81 SUCCESS
    82 SUCCESS
    83 SUCCESS
    84 SUCCESS
    85 ERROR: timeout waiting for initial checksum: got -1
    86 SUCCESS
    87 SUCCESS
    88 SUCCESS
    89 SUCCESS
    90 SUCCESS
    91 SUCCESS
    92 SUCCESS
    93 SUCCESS
    94 SUCCESS
    95 SUCCESS
    96 SUCCESS
    97 SUCCESS
    98 SUCCESS
    99 SUCCESS
    100 SUCCESS
    
  • jmgjmg Posts: 15,140
    rogloh wrote: »
    ...
    Here's the relevant code in the download sequence...the code appears to either not be waiting long enough for the response, the auto baud space character is sent too soon (50ms wait not enough for the COG to be ready?), or received too late, or the P2 reset is not working. Not sure what else would cause it. I think if a wait_drain() is added after the transmission of the "~" and before the 50ms sleep it might be better, so we know that the ~ has been sent out the wire and received by the COG before we send the auto baud char and expect a response. This would remove any serial buffering lag affecting the transaction. It's a better way to go than put in hardcoded 50ms delays etc. Same probably goes for the 10ms sleeps in the retries.
    Roger.

        tx((uint8_t *)"> Prop_Hex 0 0 0 0", 18);
        txstring((uint8_t *)MainLoader1_bin, MainLoader1_bin_len);
        txval(clock_mode);
        txval(flag_bits());
        tx((uint8_t *)"~", 1);
        
        {
            int retry;
            // receive checksum, verify it's "@@ "
            msleep(50);
            tx_raw_byte(' ');
            for (retry = 0; retry < 5; retry++) {
                // send autobaud character
                tx_raw_byte(' ');
                msleep(10);
                num = rx_timeout((uint8_t *)buffer, 3, 200);
                if (num == 3) break;
            }
            if (num != 3) {
                printf("ERROR: timeout waiting for initial checksum: got %d\n", num);
                promptexit(1);
            }
            if (buffer[0] != '@' || buffer[1] != '@') {
                printf("ERROR: got incorrect initial chksum: %c%c%c (%02x %02x %02x)\n", buffer[0], buffer[1], buffer[2], buffer[0], buffer[1], buffer[2]);
                promptexit(1);
            }
        }
    

    Is that using the P2 boot loader ?
    I see a comment about autobaud, but the P2 boot autobaud is ">" not " " ?
    Does change of clock mode also send a new autobaud char ? (should be before any other chars, but after P2 has had time to change speed )

    General Chip comments have suggested to use autobaud refresh, but I'm not sure how critical that is, as the P2 oscillators are quite stable ( < 1% short term ?)
    Maybe it actually does matter, and the slower downloads mean more time to drift, so have lower yields ?
    What size is your download ?
  • No this is using Eric's latest modifications to loadp2 with new features. I think the boot application that is initially downloaded in CHIP mode (MainLoader1.spin2) is also a little different now with the various extensions Eric has been adding.

    The downloaded image file size in the above cases was 288384 bytes.
  • Here's the MainLoader1.spin2 file in all it's glory jmg, if anything stands out...
    CON
    		tx_pin = 62
    		rx_pin = 63
    		dbg_pin = 56
    		
    		FLAGBIT_ZERO = $1		' if set, zero HUB memory
    		FLAGBIT_PATCHED = $2		' if set, clock frequency was patched into binary
      '' smart pin modes
      ser_txmode       = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output
      ser_rxmode       = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input  enabled for smart input
    		
    DAT		org
    
    begin		hubset	clkmode_			'set up oscillator 
                    waitx   ##25_000_000/100        'wait >10 ms
                    or      clkmode_, #3             'enable XI+PLL mode
                    hubset  clkmode_                 'enable oscillator
    		test	flagbits, #FLAGBIT_ZERO wz
    	if_z	jmp	#skipzero
    		'' zero out memory
    		wrfast	#0,#0
    		mov	pb, ##$7c000/16
    zeroloop
    		wflong	zeros
    		wflong	zeros
    		wflong	zeros
    		wflong	zeros
    		djnz	pb, #zeroloop
    		rdfast	#0,#0			' wait for last byte to be written
    skipzero
    
    restart		
    		'' set up uart smart pins
    		'' we don't know for sure what the frequency is, so use
    		'' auto baud rate detection for this
    		dirl	#rx_pin
    		dirl	#tx_pin
    
    		call	#autobaud
    		mov     pa, waitbit	' autobaud set waitbit
    		shl	pa, #16
    		or      pa, #7	' set for 8 bits
    		wrpin   ##ser_txmode, #tx_pin
    		wxpin   pa, #tx_pin
    		dirh    #tx_pin
    		wrpin   ##ser_rxmode, #rx_pin
    		wxpin   pa, #rx_pin
    		dirh    #rx_pin
    
    		'' try to receive a space
    		'' if it works, autobaud is OK, otherwise re-try
    .space
    		testp	#rx_pin wc
    	if_nc	jmp	#.space
    		rdpin	rxbyte, #rx_pin
    		shr	rxbyte, #24
    		cmp	rxbyte, #$20 wz
    	if_nz	jmp	#restart
    	
    		'' send 0 to host to indicate we are ready
    setup
    		mov	chksum, #0
    		call	#send_chksum
    
    read_file
    		mov	chksum, #0
    		'' read file address
    		call	#ser_rx_long
    		mov	loadaddr, rxlong
    
    		'' if first time through, set starting address
    		cmp	startaddr, ##-1 wz
    	if_z	mov	startaddr, loadaddr
    	
    		'' read file size
    		call	#ser_rx_long
    		mov	filesize, rxlong
    		wrfast	#0,loadaddr		'ready to write entire memory starting at address
    		nop		       		' give time to settle
    		
    .mainloop
    		call	#ser_rx
    		wfbyte	rxbyte			'write to hub
    		add	chksum, rxbyte
    
    		djnz	filesize,#.mainloop	'loop until all bytes received
    
                    rdfast  #0,#0                   'wait for last byte to be written
    
    		'' respond to host
    		call	#send_chksum
    
    		'' check host response
    		'' if they send "+" then look for another file
    		call	 #ser_rx
    		cmp	 rxbyte, #"+" wz
    	if_z	jmp	 #read_file
    	
    		waitx	##80_000_000/10		' short pause to ensure sync
    		
    		'' shut down smart pins
    		dirl	#tx_pin
    		dirl	#rx_pin
    		wrpin	#0, #tx_pin
    		wrpin	#0, #rx_pin
    		
    		' switch back to rcfast mode, maybe
    		' if the binary was patched with -PATCH then we skip this
    		test	flagbits, #FLAGBIT_PATCHED wz
    	if_nz	jmp	#start_cog		 ' patched, so start right now
    		' go back to rcfast mode
    		andn	 clkmode_, #3
    		hubset	 clkmode_
    		hubset	 #0
    start_cog
    		waitx	 ##25_000_000/10
    		coginit	#0,startaddr		'launch cog 0 from starting address
    
    send_chksum
    		mov	temp, chksum
    		shr	temp, #4
    		and	temp, #$f
    		add	temp, #"@"
    		call	#ser_tx
    		mov	temp, chksum
    		and	temp, #$f
    		add	temp, #"@"
    		call	#ser_tx
    		mov	temp, #" "
    		jmp	#ser_tx
    		
    ser_tx
    		wypin	temp, #tx_pin
    		waitx	#20
    .txflush
    		testp	#tx_pin wc
    	if_nc	jmp	#.txflush
    		ret
    
    ' receive a byte from serial
    ser_rx
    		testp	#rx_pin wc
    	if_nc	jmp	#ser_rx
    		rdpin	rxbyte, #rx_pin
    	_ret_	shr	rxbyte, #24
    
    ' receive a long from serial
    ser_rx_long
      	    	call	#ser_rx
    		mov	rxlong, rxbyte
    		call	#ser_rx
    		shl	rxbyte, #8
    		or	rxlong, rxbyte
    		call	#ser_rx
    		shl	rxbyte, #16
    		or	rxlong, rxbyte
    		call	#ser_rx
    		shl	rxbyte, #24
    	_ret_	or	rxlong, rxbyte
    
    ' automatically detect baud rate
    ' based on length of shortest 1 or 0
    ' we see next
    
    autobaud
    		dirl	#rx_pin
    		waitx	##1000
    		mov	mask, ##(1<<(rx_pin-32))
    		mov	port, #1
    
        		test port, #1 wc	' set C to distinguish INA/OUTA
        		test port, #2 wz    ' set Z (match on =)
    		
                    setpat mask, #0	' wait for pin lo (start bit)
        		waitpat
    		setpat mask, mask	' wait for pin hi (first 1)
    		waitpat
    		getct a
        		setpat mask, #0	' wait for pin lo again (following 0)
        		waitpat
        		getct b
    		setpat mask,mask	' wait for pin hi again (end of 0 sequence)
    		waitpat
    		getct waitbit
    
    		sub   waitbit, b
    		sub   b, a
    		fle   waitbit, b
    		mov   a, waitbit
    		shl   a, #3
    		waitx a
    		
    		ret
    		
    zeros
    		long	0
    startaddr	long	-1			'starting address
    waitbit		long	99999
    
    		orgf	$100
    clkmode_	res	1			'clock mode
    flagbits	res	1			'flag bits, see definitions above
    loadaddr	res	1			'address for load
    filesize	res	1			'binary file size in bytes
    count		res	1
    rxbyte		res	1			'received byte
    rxlong		res	1			'received longword
    temp		res	1
    chksum		res	1
    mask		res	1
    port		res	1
    a		res	1
    b		res	1
    
    
  • jmgjmg Posts: 15,140
    rogloh wrote: »
    The downloaded image file size in the above cases was 288384 bytes.
    If the yield changes with file size, that could suggest baud-drift effects, if size has no effect it may be turn-around delay variations.

  • Yes I should try a different file size to see what that does.

    Also it's a lot slower but just got 100 resets in a row working fine with -SINGLE and the current 4.1.2 loadp2 codebase without my other wait_drain() modifications. That way uses the inbuilt loader and takes a different path in the software. So it looks like the timeout error is only related to this new protocol invented for new features etc. Something new in the MainLoader1.Spin2 file or the C file has got out of whack and causing timeouts, at least on my Mac, perhaps Linux too though the serial software pipeline in the OS could be different there vs the Mac implementation.
  • rogloh,

    I'm also running on a MacBook Pro, but not seeing any loader failures. This is with loadp2 version 0.042 built on my Mac today (Feb 3 2020)... Your failures may not be caused by loadp2 itself. There may be some other system-related issue that you are seeing? Bad USB cable?
    % for (( i=1; i<50; i++ )); do echo -n "$i " && loadp2 main.binary -p /dev/cu.usbserial-DN43WMDD && echo SUCCESS; done
    1 SUCCESS
    2 SUCCESS
    3 SUCCESS
    4 SUCCESS
    5 SUCCESS
    6 SUCCESS
    7 SUCCESS
    8 SUCCESS
    9 SUCCESS
    10 SUCCESS
    11 SUCCESS
    12 SUCCESS
    13 SUCCESS
    14 SUCCESS
    15 SUCCESS
    16 SUCCESS
    17 SUCCESS
    18 SUCCESS
    19 SUCCESS
    20 SUCCESS
    21 SUCCESS
    22 SUCCESS
    23 SUCCESS
    24 SUCCESS
    25 SUCCESS
    26 SUCCESS
    27 SUCCESS
    28 SUCCESS
    29 SUCCESS
    30 SUCCESS
    31 SUCCESS
    32 SUCCESS
    33 SUCCESS
    34 SUCCESS
    35 SUCCESS
    36 SUCCESS
    37 SUCCESS
    38 SUCCESS
    39 SUCCESS
    40 SUCCESS
    41 SUCCESS
    42 SUCCESS
    43 SUCCESS
    44 SUCCESS
    45 SUCCESS
    46 SUCCESS
    47 SUCCESS
    48 SUCCESS
    49 SUCCESS
    


    dgately
  • roglohrogloh Posts: 5,122
    edited 2020-02-03 23:57
    Interesting dgately. How does you machine compare? I have OS X 10.10.5 with a 2.9 GHz Intel Core i5 dual core CPU:
    Intel(R) Core(TM) i5-5287U CPU @ 2.90GHz

    Looking at the MainLoader1.Spin2 code in some more detail here is the fix I've found that I now think solves the issue...using it I now have 100% success with the download at both 2Mbps and the default (which I think might be 921600bps). This was with 100 iterations each.

    What seems to be happening is that on my machine the two space characters being transmitted from the loadp2 code get buffered together (one space initially then the first one from the retry loop) and are arriving back to back on the P2 and in the PASM code the 8 bit waitx delay after auto baud means that the smartpin rx is not always ready for the 2nd space to arrive and it can get missed. Adding a wait_drain() in the right spot plus a 1ms delay solves it.

    A slower machine that introduces longer gaps into the serial transmission between these space characters, or one with no buffering, may not see this problem.

    From MainLoader1.spin2:

    ' automatically detect baud rate
    ' based on length of shortest 1 or 0
    ' we see next

    autobaud
    dirl #rx_pin
    waitx ##1000
    mov mask, ##(1<<(rx_pin-32))
    mov port, #1

    test port, #1 wc ' set C to distinguish INA/OUTA
    test port, #2 wz ' set Z (match on =)

    setpat mask, #0 ' wait for pin lo (start bit)
    waitpat
    setpat mask, mask ' wait for pin hi (first 1)
    waitpat
    getct a
    setpat mask, #0 ' wait for pin lo again (following 0)
    waitpat
    getct b
    setpat mask,mask ' wait for pin hi again (end of 0 sequence)
    waitpat
    getct waitbit

    sub waitbit, b
    sub b, a
    fle waitbit, b
    mov a, waitbit
    shl a, #3
    waitx a

    ret

    diff --git a/loadp2.c b/loadp2.c
    index e541f3c..c03da76 100644
    --- a/loadp2.c
    +++ b/loadp2.c
    @@ -523,11 +523,15 @@ int loadfile(char *fname, int address)
         {
             int retry;
             // receive checksum, verify it's "@@ "
    +        wait_drain();
             msleep(50);
             tx_raw_byte(' ');
    +        wait_drain();
    +        msleep(1);
             for (retry = 0; retry < 5; retry++) {
                 // send autobaud character
                 tx_raw_byte(' ');
    +            wait_drain();
                 msleep(10);
                 num = rx_timeout((uint8_t *)buffer, 3, 200);
                 if (num == 3) break;
    
Sign In or Register to comment.