Shop OBEX P1 Docs P2 Docs Learn Events
FlexProp: a complete programming system for P2 (and P1) - Page 32 — Parallax Forums

FlexProp: a complete programming system for P2 (and P1)

1293032343554

Comments

  • Got the Proploader to work for my environment, Windows.

    Had to add a sleep function to the receive section. On my system the receive was running to fast and only got 1 character before returning. By adding a sleep(1) it returned all 14 characters and I was able to load the P2 every time with no failures.

        SetCommTimeouts(serial->hSerial, &serial->timeouts);
        Sleep(1);
        if (!ReadFile(serial->hSerial, buf, len, &dwBytes, NULL)) {
    

    Wifi loader does not work with my Wifi unit. I don't have the latest firmware with the load p2 function on it.
    I use a simpler method:

    GET /propeller/reset HTTP/1.1\r\n\r\n
    

    I send this command to the Wifi module and then just open a telnet port and send the image data over that port which is needed after that to talk the application as it starts up. Easy Peasy.

    Mike

  • @RS_Jim said:
    Questions? when running flexprop is there anyway to tell what version is running?

    The version is shown in the Help > About... dialog.

    Second question, is there anyway to get formatting (like serial position) into the terminal?

    I'm not quite sure what you mean by this. If you mean to control the cursor position, both the ANSI and PST terminals have control sequences for this, although they are different. The built in ANSI terminal only supports a subset of ANSI control codes. If you know what codes you need that are missing I'd be happy to add them. Otherwise, you could select Options > Use External Terminal to run the loader in a "real" ANSI terminal (like xterm).

  • @hinv said:
    Ever thought about adding Android to the platform list?

    I can barely support what's there already. But I'm happy to accept pull requests...

    I would also like to make a contribution to your cause, but I don't do patreon, and I'm usually broke on the dollar side of things. Got a Bitcoin Cash address?

    Unforuntately accepting any kind of crypto would be very difficult for me, tax-wise, so for now PayPal and Patreon are my only options... but thanks for asking!

  • @iseries said:
    Got the Proploader to work for my environment, Windows.

    Had to add a sleep function to the receive section. On my system the receive was running to fast and only got 1 character before returning. By adding a sleep(1) it returned all 14 characters and I was able to load the P2 every time with no failures.

        SetCommTimeouts(serial->hSerial, &serial->timeouts);
        Sleep(1);
        if (!ReadFile(serial->hSerial, buf, len, &dwBytes, NULL)) {
    

    Thanks, I'll try that. It does seem to be a timing problem, since it works on some systems but not on others.

    Wifi loader does not work with my Wifi unit. I don't have the latest firmware with the load p2 function on it.
    I use a simpler method:

    GET /propeller/reset HTTP/1.1\r\n\r\n
    

    I send this command to the Wifi module and then just open a telnet port and send the image data over that port which is needed after that to talk the application as it starts up. Easy Peasy.

    That sounds interesting. Is the source for your loader available anywhere?

    Thanks,
    Eric

  • I wrote the code in C# but what you have with the latest firmware is more fool proof.

        hdrCnt = snprintf((char *)buffer, sizeof(buffer), "\
    POST /propeller/load?baud-rate=%d&reset-pin=%d&response-size=%d&response-timeout=1000 HTTP/1.1\r\n\
    Content-Length: %d\r\n\
    \r\n",
                          loaderBaudRate, m_resetPin, responseSize, imageSize);
    

    Using @VonSzarvas code you just pack up a request and send it to the Wifi module to be loaded.

    I reuse the code for the P1 to send a request to the Wifi module to reset the P2 and then using the telnet connection on port 22 to send the program to the P2 just as if it were connected serially.

                tcpClient = new TcpClient();
                Telnet = new TcpClient();
                tcpClient.Connect(esp.IP);
                esp.IP.Port = 23;
                Telnet.Connect(esp.IP);
                Telnet.NoDelay = true;
                TS = Telnet.GetStream();
                NS = tcpClient.GetStream();
                b = Encoding.UTF8.GetBytes("GET /propeller/reset HTTP/1.1\r\n\r\n");
                NS.Write(b, 0, b.Length);
                Thread.Sleep(50);
                b = Encoding.UTF8.GetBytes(Program.PropChk);
                TS.Write(b, 0, b.Length);
                if (NS.DataAvailable)
                {
                    i = NS.Read(data, 0, data.Length);
                    s = Encoding.UTF8.GetString(data, 0, i);
                    //Console.WriteLine(s);
                }    
                Thread.Sleep(50);
                if (TS.DataAvailable)
                {
                    i = TS.Read(data, 0, data.Length);
                    s = Encoding.UTF8.GetString(data, 0, i);
                    //Console.WriteLine(s);
                }
                i = data[11];
                NS.Close();
                if ((i < 'A') || (i > 'G'))
                {
                    Console.WriteLine("No Propeller Found!");
                    TS.Close();
                    return;
                }
    
                /*
                 * Send Base64 Encoding Program
                */
                b = Encoding.UTF8.GetBytes(Program.PropTxt);
                TS.Write(b, 0, b.Length);
    
                s = Convert.ToBase64String(program);
                b = Encoding.UTF8.GetBytes(s);
                TS.Write(b, 0, b.Length);
                s = " ~";
                b = Encoding.UTF8.GetBytes(s);
                TS.Write(b, 0, b.Length);
                Console.WriteLine("Program Loaded");
    

    The nice thing is that the program is already connected to the telnet port and can see the serial data from the P2 right away.

    This I think is confusing to some people as there is no baud rate between the PC and the Wifi module, but there is between the P2 and the Wifi module. If that baud rate does not match the Wifi module, then there is no way the data gets to the PC.

    WiFi Loader

    The problem with my method is the baud rate is the same for loading as is the terminal connection which can be slow.

    Mike

  • hinvhinv Posts: 1,252

    @ersmith said:

    @hinv said:
    Ever thought about adding Android to the platform list?

    I can barely support what's there already. But I'm happy to accept pull requests...

    I can understand that. You do a really good job. I'm impressed, and I'm tempted because I used to do a bit of Tcl/Tk.

    I would also like to make a contribution to your cause, but I don't do patreon, and I'm usually broke on the dollar side of things. Got a Bitcoin Cash address?

    Unforuntately accepting any kind of crypto would be very difficult for me, tax-wise, so for now PayPal and Patreon are my only options... but thanks for asking!

    AFAIK, if you don't sell the asset, or trade it for another, there is no tax consequences. Also, if you manage your keys well, which is pretty easy with today's wallets, dystopian governments like we recently saw in Canada can't take it from you.

  • RS_JimRS_Jim Posts: 1,748
    edited 2022-02-25 15:38

    Eric re position xy:
    ```
    PUB Position(x, y)
    ' Position cursor at column x, row y (from top-left)
    y++ ' Without this, (1, 1) is considered
    x++ ' upper-left/home position instead of
    CSI() ' the more common (0, 0)
    Dec(y)
    Char(";")
    Dec(x)
    Char("f")
    PRI CSI()
    ' Command Sequence Introducer
    Str(string(ESC, LBRACKET))

    I dug this code out of avisa42's ansi code library. Is there anyway I can drop that into the flexprop terminal?
    Sorry about the formatting, forum code formatting doesnot seem to be working.

    Jim

  • @RS_Jim said:
    Eric re position xy:

    PUB Position(x, y)
    ' Position cursor at column x, row y (from top-left)
        y++                                                     ' Without this, (1, 1) is considered
        x++                                                     '   upper-left/home position instead of
        CSI()                                                   '   the more common (0, 0)
        Dec(y)
        Char(";")
        Dec(x)
        Char("f")
    PRI CSI()
    ' Command Sequence Introducer
        Str(string(ESC, LBRACKET))
    

    I dug this code out of avisa42's ansi code library. Is there anyway I can drop that into the flexprop terminal?

    Changing the Char("f") to Char("H") should do the trick. "f" is a less common escape sequence which seems to do basically the same thing as "H".

    Another option is to select "Use external terminal" from the Options menu.

    Sorry about the formatting, forum code formatting doesnot seem to be working.

    Jim

  • RaymanRayman Posts: 13,721

    @ersmith Is there a quick way to make this work?

    // Compiler-independent means of expressing structure packing.
    #if defined(_MSC_VER)
    #define BEGIN_PACKED_STRUCT __pragma(pack(push, 1))
    #define END_PACKED_STRUCT __pragma(pack(pop))
    #define PACKED_STRUCT1
    #define PACKED_STRUCT2
    #elif defined(__GNUC__) || defined(__clang__)
    #define BEGIN_PACKED_STRUCT
    #define END_PACKED_STRUCT
    #define PACKED_STRUCT1 __attribute__((packed))
    #define PACKED_STRUCT2
    #elif defined(__CC_ARM)
    #define BEGIN_PACKED_STRUCT
    #define END_PACKED_STRUCT
    #define PACKED_STRUCT1
    #define PACKED_STRUCT2 __packed
    #else
    #error Unknown compiler; structure packing not configured
    #endif
    
  • @Rayman: No, unfortunately FlexC does not support packed structs.

  • RaymanRayman Posts: 13,721

    I didn't realize the usual way to do structures was to make all elements the same size as the largest element.

    Something to keep in mind…

  • Hi,

    I have been using FlexProp for a while, and recently updated Flexprop. (About says 5.9.9) When I attempt to 'Compile & Run on P1' I get an application error popup with the following contents:

    invalid command name "::TkTerm::RunInWindow"
    invalid command name "::TkTerm::RunInWindow"
    while executing
    "::TkTerm::RunInWindow $cmdstr"
    (procedure "doJustRun" line 22)
    invoked from within
    "doJustRun """
    (procedure "doCompileRun" line 5)
    invoked from within
    "doCompileRun"
    invoked from within
    ".toolbar.compileRun invoke "
    invoked from within
    ".toolbar.compileRun instate !disabled { .toolbar.compileRun invoke } "
    invoked from within
    ".toolbar.compileRun instate pressed { .toolbar.compileRun state !pressed; .toolbar.compileRun instate !disabled { .toolbar.compileRun invoke } } "
    (command bound to event)

    What can I do?

    Thanks!

  • @"R Baggett" : Are you on Linux? If so, I think you need to re-install FlexProp. Remove all old config files with:

    rm -f ~/.flexprop*
    

    Delete your ~/flexprop directory (or wherever you installed from), check-out a fresh copy from git, and follow the instructions for Linux to build and install.

  • I don't know if you have tested this code or even if you have an esp8266 module, but I think this code doesn't work for a P2.

    in module: int WiFiProp2Connection::loadImage

        hdrCnt = snprintf((char *)buffer, sizeof(buffer), "\
    POST /propeller/load?baud-rate=%d&reset-pin=%d&response-size=%d&response-timeout=1000 HTTP/1.1\r\n\
    Content-Length: %d\r\n\
    \r\n",
                          loaderBaudRate, m_resetPin, responseSize, imageSize);
    

    This looks like the P1 loader.

    Mike

  • @ersmith said:
    @"R Baggett" : Are you on Linux? If so, I think you need to re-install FlexProp. Remove all old config files with:

    rm -f ~/.flexprop*
    

    Delete your ~/flexprop directory (or wherever you installed from), check-out a fresh copy from git, and follow the instructions for Linux to build and install.

    Yep, Ubuntu, and that fixed it!

    Thanks!

  • @iseries said:
    in module: int WiFiProp2Connection::loadImage

        hdrCnt = snprintf((char *)buffer, sizeof(buffer), "\
    POST /propeller/load?baud-rate=%d&reset-pin=%d&response-size=%d&response-timeout=1000 HTTP/1.1\r\n\
    Content-Length: %d\r\n\
    \r\n",
                          loaderBaudRate, m_resetPin, responseSize, imageSize);
    

    This looks like the P1 loader.

    Thanks, Mike. There were two loadImage methods in the code I started from, but only one of them (the other one) seems to actually be used.

  • Windows and Mac binaries for FlexProp 5.9.9 are available from github now. I've reverted to using loadp2 for serial downloads, which should improve reliability for those. proploader is still used for WiFi connections.

    Besides this improvement, there are a number of bug fixes in the compiler.

  • Does this mean that you can have propplug plugged in, and the WiFi adapter plugged in at the same time. Then you would manually select which port to use? Hopefully flexprop would select which loader to use.

    Ray

  • @Rsadeika said:
    Does this mean that you can have propplug plugged in, and the WiFi adapter plugged in at the same time. Then you would manually select which port to use? Hopefully flexprop would select which loader to use.

    Ray

    No, not if it's using the same P2 pins.

  • @ersmith FlexProp 5.9.9-final is a winner for me. It cured a bunch of strange compiler behaviors and I can now download and flash again. Winner, winner, chicken dinner! 👍

  • Found some bugs:

    _TLS is defined twice.
    in localtim.c

    #if defined(__linux__) || defined(__FLEXC__)
    struct TLS {
      struct tm time_temp;
    } foo;
    struct TLS *_TLSx = &foo;
    
    #else
    

    and in threads.h

    #if defined(__propeller__) && defined(__GNUC__)
    #define _TLSDECL(x) extern __attribute__((cogmem)) x
    #else
    #define _TLSDECL(x) extern x
    #endif
    
    _TLSDECL( _thread_state_t *_TLS );
    

    This happens when you use asctime()

    Also in time.h

    int settimeofday(const struct timeval *tv, const void *unused) _IMPL("libc/time/settimeofday.c");
    

    I think it's should be this which works.

    int settimeofday(const struct timeval *tv, const void *unused) _IMPL("libc/time/gettimeofday.c");
    

    Enhancement:
    dirent.h add these

    #define ATTR_READ_ONLY  0x01
    #define ATTR_HIDDEN     0x02
    #define ATTR_SYSTEM     0x04
    #define ATTR_VOLUME_ID  0x08
    #define ATTR_DIRECTORY  0x10
    #define ATTR_ARCHIVE    0x20
    
    struct dirent {
        char d_name[_NAME_MAX]; /** long file name **/
        unsigned long d_off;
        unsigned long d_ino;
        unsigned long d_type; /** directory entry type (ATTR_)**/
        unsigned long d_date; /** date year from 1980 (15:9), month (8:5), day (4:0) **/
        unsigned long d_time; /** time hour (15:11), minutes (10:5), seconds (4:0) **/
        unsigned long d_size; /** file size **/
    };
    

    Fatfs is returning this information and might as well use it since it will help with finding files and sizes....

    Also VS code will show those comments after the definitions.

    Mike

  • Wuerfel_21Wuerfel_21 Posts: 4,331
    edited 2022-03-07 21:10

    Hey kids, want some candy?

    Through the immense power of multi-level procrastination, a new compiler optimization has materialized on my GitHub. Benchmarks say 15% more speends (only realistic if your code has a lot of multiply/divide). But it's probably still full of bugs and I'm too lazy to find all of them. And Eric seems busy, idk, hasn't even commented on the previous PR yet. Probably doing something actually important.

    Anyways, that's where y'all come in. I've attached a beta build of the compiler which you may try out (or build it from the PR branch source if you can/want/need to). Report if it explodes your code. If not, enjoy the speends.
    (Note: if it does infact break, try it with -O1,~cordic-reorder to see if it's the reorder feature itself or one of the other random changes I made)

  • Ada: is this re-optimized beta for all languages? (I’m looking at you, FlexBASIC! Lol)

  • @JRoark said:
    Ada: is this re-optimized beta for all languages? (I’m looking at you, FlexBASIC! Lol)

    Should be, all this stuff happens at the IR level. Though I only really tested it with Spin.

  • Trick question: what gets printed?

    CON _CLKFREQ = 200_000_000
    VAR long x,y,z
    PUB main() | a,b
        x := 100
        y := 3
        a := x*y
        b := y*y
        debug(udec(b))
    

    That's right, 300. Of course.

    I've attached another beta build, with the fix for this nonsense, the new optimizations and some even newer optimizations.

  • Thanks for these changes, Ada! I haven't had a chance to review them all yet (I'm very busy with "real" work) but hope to do so soon.

  • pik33pik33 Posts: 2,342

    Can the Flexprop detect if it is second (or the next) instance of it started and display a warning - "beware, I am a second instance, do you really want to run it?"

  • @pik33 said:
    Can the Flexprop detect if it is second (or the next) instance of it started and display a warning - "beware, I am a second instance, do you really want to run it?"

    I don't know how to do that in Tcl. It would probably also annoy some users who like to run multiple copies of Flexprop (one for their P1 and one for their P2).

  • pik33pik33 Posts: 2,342
    edited 2022-03-15 21:41

    Maybe. I lost a lot of work (several times!) because of the second, accidentally opened instance of Flexprop. Both opened with the same set of files which they automatically open, partially hidden by a P2 manual in the browser or something like this. The result: edit in one instance, save from another, close both, the work lost. There were a lot more times when I managed to notice this and close the proper instance before the harm is done. Sometimes it is hard to find which of it is proper if the edited file was long enough. - they both look exactly the same. Hide them for a moment with another window and there is a problem.
    Maybe if not warn, a Lazarus approach can be used: the second (and next) instance starts empty so there is no danger of edit the file in one instance and save from another unless you want to.

  • One of my favorite text editors solves this problem by looking at the file date whenever the window gets focus (again). If the date is newer than when it was originally opened the editor warns you that the file has been changed externally and asks if you want to re-load it. Some editors keep a write lock on open files so you can only open it a second time in read-only mode. That's the safest way but it can also be anoying because you can't rename or move the file to create a backup while it's open.

Sign In or Register to comment.