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

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

14951535455

Comments

  • I shouldn't post questions until I try a few things first. This seems to work.

    loadp2 -SINGLE -b 230400 cdemo.binary -t

    Now off to writing real code!

  • Okay, one more question for tonight. How do I write my program to flash so it runs on reset? I don't see an option to do that with loadp2.

  • evanhevanh Posts: 16,032
    edited 2023-09-08 03:36

    @"David Betz" said:
    Okay, one more question for tonight. How do I write my program to flash so it runs on reset? I don't see an option to do that with loadp2.

    I've not used FlexProp to know if it has any automation for this but Loadp2 comes with a Spin2 written programmer/loader program "P2ES_flashloader.spin2" that can either be compiled together with the target program or have the binaries concatenated by Loadp2.

  • @"David Betz" said:
    That produced cdemo.binary which I tried to load with proploader but that gave me an error saying it wasn't a propeller binary. Should I be using loadp2?

    The proploader that comes with FlexProp can speak to P2s, but it needs a -2 argument t> @"David Betz" said:

    Okay, one more question for tonight. How do I write my program to flash so it runs on reset? I don't see an option to do that with loadp2.

    There's no single command for that, but you can use an auxiliary program to do this, as Evan mentioned. The FlexProp GUI will automate this for you, and you can look at the commands it generates to see how to do it on the command line.

    Great to see you back, David!

  • @ersmith said:

    Okay, one more question for tonight. How do I write my program to flash so it runs on reset? I don't see an option to do that with loadp2.

    There's no single command for that, but you can use an auxiliary program to do this, as Evan mentioned. The FlexProp GUI will automate this for you, and you can look at the commands it generates to see how to do it on the command line.

    Is this because there is no way to build this support into the loaders? That is too bad. It was nice to be able to just tack on -e to a P1 loader command to write to the EEPROM. Is there no way to do that for the P2?

    Great to see you back, David!

    I've been lurking all along but the Parallax Labor Day sale got me to buy a P2-EC32MB module. The work on the retro basic interpreter here got me interested in trying to revive my old P1 basic interpreter using the 32MB RAM. Who knows how far I'll get.

  • @"David Betz" said:

    @ersmith said:

    Okay, one more question for tonight. How do I write my program to flash so it runs on reset? I don't see an option to do that with loadp2.

    There's no single command for that, but you can use an auxiliary program to do this, as Evan mentioned. The FlexProp GUI will automate this for you, and you can look at the commands it generates to see how to do it on the command line.

    Is this because there is no way to build this support into the loaders? That is too bad. It was nice to be able to just tack on -e to a P1 loader command to write to the EEPROM. Is there no way to do that for the P2?

    I'm sure it could be done, but nobody has taken the time to do it. Most users use GUIs these days, so having an awkward command line doesn't seem to be as big a deal. But I'm always happy to get pull requests for my version of loadp2!

  • @ersmith said:
    But I'm always happy to get pull requests for my version of loadp2!

    Maybe I’ll take a shot at it!

  • RaymanRayman Posts: 14,758

    @"David Betz" If you can use the flexprop GUI, would probably make things easier... It's cross platform...

  • @Rayman said:
    @"David Betz" If you can use the flexprop GUI, would probably make things easier... It's cross platform...

    I'm not really a GUI guy but if I used one I'd like to use Visual Studio Code. Has that been made to work with P1 and/or P2? I've used it for Arduino and the ESP32 and it seems to work quite well.

  • AribaAriba Posts: 2,690

    @ersmith said:

    @Ariba said:

    @ersmith said:

    - Added VFS layer for Parallax flash file system
    

    Thanks Eric

    It looks like the VFS layer for Parallax flash file system does not fully work.
    If I try to open more than one file, strange things happen. You can see the effect in the shell example, if you try to copy a file inside the /pfs file system.
    This will open one file for read and one for write.
    Also if you open only 1 file for read, the first 2 characters of the file seem to not be read correct.

    At the end I need to open 4 files, 2 for read and 2 for write. Will this be supported by the VFS layer, if I increase the MAX_FILES_OPEN to 4 files in the 'FlashFileSystem_16MB_eh.spin2' file?

    Andy

    Aargh, yes, the VFS layer is unaware of the file system limitation. I'll try to hook some error checking up. I think increasing MAX_FILES_OPEN should do what you need, but I'm not sure of that.

    Eric,
    The problem with the read of first 2 characters has to do with a Unicode test in the example I tried. It reads the first 2 chars and then makes a fseek(0) which is not implemented in this VFS layer.
    But the real problem is that you can't work with more than 1 open file. If I open a second file the whole Filesystem gets haywire.
    Here is a simple example. With the commented out fgetc() of the 2nd file, it works. If you comment in the line, nothing works anymore, the first file reads only garbage.

    #include <stdio.h>
    #include <sys/vfs.h>
    
    void main()
    {
        int e, i, c;
        FILE *file1, *file2;
        char txt1[64], txt2[64];
    
        e = mount("/pfs", _vfs_open_parallaxfs());   //parallax flash fs
        printf("pfs mount: %d\n", e);
        if(e < 0) return;
        chdir("/pfs");
    
        file1 = fopen("test.txt","w");
        for(i=0; i<63; i++) fputc(i+64, file1);
        fclose(file1);
    
        file1 = fopen("test.txt","r");
        file2 = fopen("test.txt","r");
    
        for(i=0; i<63; i++) {
          c = fgetc(file1);
          if(c < 0) break;
          txt1[i] = c;
    //      txt2[i] = fgetc(file2);;
        }
        printf("%s",txt1);
        printf("%s",txt2);
        fclose(file1);        
        fclose(file2);        
        printf("\n done\n");
    }
    

    A similar Spin2 program that uses the Parallax File System direct (without VFS-Layer) works in FlexProp and PropTool.

    Andy

  • ElectrodudeElectrodude Posts: 1,660
    edited 2023-09-09 03:04

    @ersmith said:

    @"David Betz" said:

    @ersmith said:

    Okay, one more question for tonight. How do I write my program to flash so it runs on reset? I don't see an option to do that with loadp2.

    There's no single command for that, but you can use an auxiliary program to do this, as Evan mentioned. The FlexProp GUI will automate this for you, and you can look at the commands it generates to see how to do it on the command line.

    Is this because there is no way to build this support into the loaders? That is too bad. It was nice to be able to just tack on -e to a P1 loader command to write to the EEPROM. Is there no way to do that for the P2?

    I'm sure it could be done, but nobody has taken the time to do it. Most users use GUIs these days, so having an awkward command line doesn't seem to be as big a deal. But I'm always happy to get pull requests for my version of loadp2!

    My solution to all the cryptic arguments is a generic P2 Makefile that remembers all the details for me. Then I can compile and flash the EEPROM with just make PORT=/dev/p2es_0 myProgName_eeprom. I can try to remember to post it eventually.

  • @Ariba : thanks for your bug report! I tested some direct I/O in the Parallax FS, but didn't test stdio fgetc/fputc, so of course those were broken :(. They should be fixed now in github.

  • AribaAriba Posts: 2,690

    Thank you Eric
    It works now very well! Also with 4 open files when I set the MAX_OPEN_FILES in the spin file to 4.
    Is there a way to overwrite Constants in included Spin files from C, like in Spin?

    I have implemented a Seek methode in the FlashFileSystem now. But need to test it a bit more.

    Andy

  • @"David Betz" said:

    @Rayman said:
    @"David Betz" If you can use the flexprop GUI, would probably make things easier... It's cross platform...

    I'm not really a GUI guy but if I used one I'd like to use Visual Studio Code. Has that been made to work with P1 and/or P2? I've used it for Arduino and the ESP32 and it seems to work quite well.

    https://forums.parallax.com/discussion/173429/visual-studio-code-supports-p2-development-on-windows-mac-linux-yes-rpi
    https://github.com/ironsheep/P2-vscode-extensions

  • @Ariba said:
    Thank you Eric
    It works now very well! Also with 4 open files when I set the MAX_OPEN_FILES in the spin file to 4.
    Is there a way to overwrite Constants in included Spin files from C, like in Spin?

    Yes, in the struct using it's possible to pass parameters to override constants. However, the Parallax file system Spin code is buried several layers deep in the file system, so it's hard to change directly. I've just checked in a change to use a global define PFS_MAX_FILES_OPEN to control this. PFS_MAX_FILES_OPEN may be set either on the command line, or via #pragma exportdef inside any of your .c files:

    #define PFS_MAX_FILES_OPEN 4
    #pragma exportdef PFS_MAX_FILES_OPEN
    

    I have implemented a Seek methode in the FlashFileSystem now. But need to test it a bit more.

    That would be great to have!

  • @dnalor said:

    @"David Betz" said:

    @Rayman said:
    @"David Betz" If you can use the flexprop GUI, would probably make things easier... It's cross platform...

    I'm not really a GUI guy but if I used one I'd like to use Visual Studio Code. Has that been made to work with P1 and/or P2? I've used it for Arduino and the ESP32 and it seems to work quite well.

    https://forums.parallax.com/discussion/173429/visual-studio-code-supports-p2-development-on-windows-mac-linux-yes-rpi
    https://github.com/ironsheep/P2-vscode-extensions

    I'll try it. I assume it will work for C code as well as Spin2.

  • @"David Betz" said:

    I'll try it. I assume it will work for C code as well as Spin2.

    I don't know. Maybe not.

  • I'm using FlexC, and unsure how to deal with Spin's multiple returns from, for example, when I access the Spin object with:

    _struct __using("flash_fs.spin2") ffs;_
    and call
    _ffs.serial_number()_

    I get these compiler errors.

    ///flash_fs.spin2:211: error: Variable sn_hi must be placed in memory (probably due to an @ expression) and hence cannot be accessed in inline assembly
    ///flash_fs.spin2:211: error: Variable sn_lo must be placed in memory (probably due to an @ expression) and hence cannot be accessed in inline assembly

    I know FlexC already has filesystem support, but this multiple return issue has hit me elsewhere, too. I'll do a pull request with updated FlexC docs, if I'm not simply overlooking the docs that exist.

  • ersmithersmith Posts: 6,068
    edited 2023-09-14 18:56

    @ngeneer : The problem isn't multiple returns, it's a conflict in the inline assembly language. FlexSpin prefers to keep values in registers, but the flash_fs code uses @ so that forces them into HUB -- but putting them in HUB makes them inaccessible to inline assembly, which is also used in that serial_number() function. I have a work around for this which I've checked into the FlexSpin repository (github.com/totalspectrum/spin2cpp). I've attached the modified version here, although beware that there are still some regression test failures in this so I'm not quite sure that it works -- basic file copies and read/write seem OK though.

    As for how to use the multiple return values, in this case just use 64 bit value (like long long sernum) to pick up both of the values returned by the method:

    long long sernum = ffs.serial_number();
    

    You could also use a struct with two members for this purpose.

  • @ersmith said:
    long long sernum = ffs.serial_number();

    dyanmite! thank you. I'll give that .spin a spin.

  • RaymanRayman Posts: 14,758

    @ersmith Still trying to get this ICM-20948 C code to work...

    Found one thing that is definitely wrong here:

         uint8_t sensor_id = convert_to_generic_ids[sensortype];
    
         for (int i = 0; i < 20; i++)
         {
             printf("ID[%d] = %d\n", i, convert_to_generic_ids[i]);
         }
    

    The array convert_to_generic_ids[] is all messed up. Don't really see why... It's defined like this:

    static uint8_t convert_to_generic_ids[INV_ICM20948_SENSOR_MAX] = {
      INV_SENSOR_TYPE_ACCELEROMETER,
      INV_SENSOR_TYPE_GYROSCOPE,
      INV_SENSOR_TYPE_RAW_ACCELEROMETER,
      INV_SENSOR_TYPE_RAW_GYROSCOPE,
      INV_SENSOR_TYPE_UNCAL_MAGNETOMETER,
      INV_SENSOR_TYPE_UNCAL_GYROSCOPE,
      INV_SENSOR_TYPE_BAC,
      INV_SENSOR_TYPE_STEP_DETECTOR,
      INV_SENSOR_TYPE_STEP_COUNTER,
      INV_SENSOR_TYPE_GAME_ROTATION_VECTOR,
      INV_SENSOR_TYPE_ROTATION_VECTOR,
      INV_SENSOR_TYPE_GEOMAG_ROTATION_VECTOR,
      INV_SENSOR_TYPE_MAGNETOMETER,
      INV_SENSOR_TYPE_SMD,
      INV_SENSOR_TYPE_PICK_UP_GESTURE,
      INV_SENSOR_TYPE_TILT_DETECTOR,
      INV_SENSOR_TYPE_GRAVITY,
      INV_SENSOR_TYPE_LINEAR_ACCELERATION,
      INV_SENSOR_TYPE_ORIENTATION,
      INV_SENSOR_TYPE_B2S
    };
    

    Printing out the array (as listed above) shows very wrong values:

    ID[0] = 208
    ID[1] = 243
    ID[2] = 201
    ID[3] = 224
    ID[4] = 1
    ID[5] = 4
    ID[6] = 32
    ID[7] = 33
    ID[8] = 14
    ID[9] = 16
    ID[10] = 26
    ID[11] = 18
    ID[12] = 19
    ID[13] = 15
    ID[14] = 11
    ID[15] = 20
    ID[16] = 2
    ID[17] = 17
    ID[18] = 25
    ID[19] = 22
    

    Here are some of the values:

    /** @brief Sensor type identifier definition
     */
    enum inv_sensor_type {
        INV_SENSOR_TYPE_RESERVED                     = 0 ,  /**< Reserved ID: do not use */
        INV_SENSOR_TYPE_ACCELEROMETER                = 1 ,  /**< Accelerometer */
        INV_SENSOR_TYPE_MAGNETOMETER                 = 2 ,  /**< Magnetic field */
        INV_SENSOR_TYPE_ORIENTATION                  = 3 ,  /**< Deprecated orientation */
        INV_SENSOR_TYPE_GYROSCOPE                    = 4 ,  /**< Gyroscope */
        INV_SENSOR_TYPE_LIGHT                        = 5 ,  /**< Ambient light sensor */
        INV_SENSOR_TYPE_PRESSURE                     = 6 ,  /**< Barometer */
        INV_SENSOR_TYPE_TEMPERATURE                  = 7 ,  /**< Temperature */
        INV_SENSOR_TYPE_PROXIMITY                    = 8 ,  /**< Proximity */
        INV_SENSOR_TYPE_GRAVITY                      = 9 ,  /**< Gravity */
        INV_SENSOR_TYPE_LINEAR_ACCELERATION          = 10,  /**< Linear acceleration */
        INV_SENSOR_TYPE_ROTATION_VECTOR              = 11,  /**< Rotation vector */
        INV_SENSOR_TYPE_HUMIDITY                     = 12,  /**< Relative humidity */
        INV_SENSOR_TYPE_AMBIENT_TEMPERATURE          = 13,  /**< Ambient temperature */
        INV_SENSOR_TYPE_UNCAL_MAGNETOMETER           = 14,  /**< Uncalibrated magnetic field */
        INV_SENSOR_TYPE_GAME_ROTATION_VECTOR         = 15,  /**< Game rotation vector */
    

    This line is giving the wrong value:
    uint8_t sensor_id = convert_to_generic_ids[sensortype];

    sensortype is 9, so the return value should be 15, but it's 16.

  • RaymanRayman Posts: 14,758

    I think was able to call the offending code without having the actual chip attached.
    Hope this helps.

  • RaymanRayman Posts: 14,758

    In case anyone is wondering what the ICM-20948 is...

    It's a very good 9DOF sensor chip. The special thing about it is that is has an onboard FPGA to do the sensor fusion calculations.
    Unfortunately, code for the FPGA has to be uploaded every time you cycle power.

    Most of the example code out there doesn't use the FPGA at all.
    But, this one does.
    Also see that Sparkfun used this code to come up with there own version.
    Wish I started from that, but this should be good, once working...

  • RaymanRayman Posts: 14,758

    @ersmith Just noticed that it's like the ID[] array is off by one long.
    looks like if I did: convert_to_generic_ids[i+4]
    would get the right answer...

  • @Rayman : thank you for the bug report. Unfortunately I'm not able to reproduce any problem here. When I insert some code at the beginning of main() to print the values of the convert_to_generic_ids[] array, everything looks correct:

    // inserted code in main.c, just after the clock frequency is printed
        for (int i = 0; i < 8; i++) {
            printf("convert_to_generic_ids[%d] = %d\n", i, convert_to_generic_ids[i]);
        }
    ...
    output:
    convert_to_generic_ids[0] = 1
    convert_to_generic_ids[1] = 4
    convert_to_generic_ids[2] = 32
    convert_to_generic_ids[3] = 33
    convert_to_generic_ids[4] = 14
    convert_to_generic_ids[5] = 16
    convert_to_generic_ids[6] = 26
    convert_to_generic_ids[7] = 18
    

    When I ran the code you sent it errored out with a Bad WHOAMI value. I manually set the whoami variable to 0xEA and that let it get further, and again, it printed the array of values without any issue.

    Which version of flexprop/flexspin are you using? There were some problems with variable sizes in some older versions. The most recent release is 6.4.0, and the current source code is 6.5.0-beta.

  • RaymanRayman Posts: 14,758

    It might be old version…
    I’ll check thanks

  • RaymanRayman Posts: 14,758

    @ersmith You are right, my version was 6.1. All better with 6.4.

  • @ersmith Is is possible that in version 6.4.0 the return vars of a method are not being preset to 0 (false). I have this simple method for stuffing characters into a buffer.

    pub enqueue(c) : done 
    
    '' Add c to input buffer
    '' -- returns true when terminating char encountered
    
      case c
        0, tchar :                                                  ' terminating char?
          buffer[bidx] := 0                                         '  end buffer
          return true
    
        8 :                                                         ' backspace?
          if (bidx > 0)                                             '  if something in buffer
            buffer[--bidx] := 0                                     '  erase last
    
        other :
          if (bidx < BUF_SIZE-2)                                    ' room in buffer?
            if (alphacase == LOWER)                                 '  check case settings
              c := lcase(c)
            elseif (alphacase == UPPER)
              c := ucase(c)
            buffer[bidx++] := c                                     '  add new character
    
      return false                                                  ' added for FlexProp
    

    When I was re-testing today this method was always returning true (!0) after each character when using FlexProp (without the last line).

  • They ought to be, but there may be something going awry. If it works when you replace return true with done := true, that's probably the case...

  • Wuerfel_21Wuerfel_21 Posts: 5,107
    edited 2023-09-23 17:30

    (Also, please, for codegen bugs, post complete examples that actually compile as written. This one's missing the lcase/ucase functions and some other definitions. These all can affect whether a bug triggers or not)

    EDIT: infact, I cannot reproduce this issue at all. Either it's already been fixed (try 6.5.0, just released) or the stuff I had to fill in doesn't match yours enough to cause the issue). Or maybe your surrounding code only calls enqueue once and it gets inlined there and that's where it goes funny, etc etc.

    EDIT 2: Reproduces on 6.4.0, so it indeed is already fixed, just get the new version.

Sign In or Register to comment.