Shop OBEX P1 Docs P2 Docs Learn Events
Micropython for P2 - Page 19 — Parallax Forums

Micropython for P2

11719212223

Comments

  • roglohrogloh Posts: 5,495
    edited 2024-05-28 09:40

    @Rayman said:
    Btw also think seeing that what is taken over here is the hardware version of i2c.

    But one can also activate the soft i2c. That relies on a Pins module, but looks like @ersmith has implemented that in his pyb modules. So, if didn’t need pull-ups, looks like that is almost out of the box ready.

    If you look at machine_pin.c in my native P2 variant you'll see the new "machine" way to do things which supports machine.Pin objects. This should be compatible with the SOFT I2C stuff. Or at least it was back in 1.13. This should be able to work with optional internal pull ups configured on the pin (implemented using P2 drive modes). You'll also probably need some of what is in modmachine.c/h related to Pin functionality.

  • RaymanRayman Posts: 14,325

    @rogloh Ok, think have machine.Pin working. Slight distraction from working on I2C...
    Had to change your gpio.c around to use riscvp2 way.
    Seems could use compiler directives to have both ways there though...

    Here's the thing you need to add to modmachine.c to make it work:

    #define MICROPY_PY_MACHINE_EXTRA_GLOBALS \
        { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, \
    
  • RaymanRayman Posts: 14,325

    I'm not really liking this machine.I2C() way of doing things...
    Seems like it slows things down a lot with this self stuff, also they add in variable length arguments to the functions for no apparent reason...

    There's a read_mem() function which looks reasonable, just the self thing.
    Then, there's the exposed function:

    STATIC mp_obj_t machine_i2c_readfrom_mem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
        enum { ARG_addr, ARG_memaddr, ARG_n, ARG_addrsize };
        mp_arg_val_t args[MP_ARRAY_SIZE(machine_i2c_mem_allowed_args)];
        mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
            MP_ARRAY_SIZE(machine_i2c_mem_allowed_args), machine_i2c_mem_allowed_args, args);
    
        // create the buffer to store data into
        vstr_t vstr;
        vstr_init_len(&vstr, mp_obj_get_int(args[ARG_n].u_obj));
    
        // do the transfer
        int ret = read_mem(pos_args[0], args[ARG_addr].u_int, args[ARG_memaddr].u_int,
            args[ARG_addrsize].u_int, (uint8_t *)vstr.buf, vstr.len);
        if (ret < 0) {
            mp_raise_OSError(-ret);
        }
    
        return mp_obj_new_bytes_from_vstr(&vstr);
    }
    MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_readfrom_mem_obj, 1, machine_i2c_readfrom_mem);
    

    That seems to do a lot of work to turn the variable length arguments into fixed length arguments.
    But, maybe this is all very fast and serves some purpose that I don't get...

  • roglohrogloh Posts: 5,495
    edited 2024-05-28 23:57

    @Rayman said:
    That seems to do a lot of work to turn the variable length arguments into fixed length arguments.
    But, maybe this is all very fast and serves some purpose that I don't get...

    Yeah I know what you mean. In general I don't typically question the actual MP implementation or these conventions and treated most of it as a black box. Without knowing their design reasons up front and the evolution of this project over time, it's not going to be simple to figure it all out unless you dig quite deep. I don't think Python's execution efficiency was necessarily their top priority everywhere - perhaps flexibility/portability/expandability could have outweighed that here. But unnecessary bloating is not good either for sizing the application to suit small micros.

  • RaymanRayman Posts: 14,325

    @Tubular If you do talk to the Micropython guys, you might mention that the I2C.scan() that we are doing here, based on the @JonnyMac way, with grid is much better than what they have and easy to implement...

  • TubularTubular Posts: 4,653

    Yeah lets find out what they were thinking. I know they spent a fair bit of effort trying to make things same-ish across the ports, perhaps that was the main driver. Sometimes the backstory is contained in the github discussion of the change request where it changed.

  • TubularTubular Posts: 4,653

    Ray (and everyone) - if you haven't already seen it check out this curated MP collection that mcauser keeps updating
    https://awesome-micropython.com/

  • RaymanRayman Posts: 14,325

    Think see how it works now, looking at STM32 example.
    Seems we use the locals_dict from micropython version of machine_i2c.c and then use the MP_DEFINE_CONST_OBJ_TYPE to implement our own version of make_new, print, and transfer.
    The transfer() does all the actual work.

    Only drawback is that seems stuck using their version of scan(). Unless, we replace it with our code.
    Probably not supposed to do that, but might anyway. Or, perhaps call ours scan2() or something...

  • TubularTubular Posts: 4,653

    Yep if possible do the scan2 or scanjm or whatever, so we can show side by side on same system and espound the benefits

  • RaymanRayman Posts: 14,325

    just started actual testing of I2C with LIS3DH accelerometer. But, seems we are missing the "time" module and not sure why...
    Guessing this is something we need to implement in the port?

  • RaymanRayman Posts: 14,325

    Ok, think I'd be close to saying i2c is working if only had time to slow things down.
    But, this code appears to work... Modified to change how I2C is invoked and with time stuff commented out.
    Also, can't reboot the lis3dh with out a time delay after..

    Suppose can add some delay into p2 module and use that instead...

  • roglohrogloh Posts: 5,495

    @Rayman said:
    just started actual testing of I2C with LIS3DH accelerometer. But, seems we are missing the "time" module and not sure why...
    Guessing this is something we need to implement in the port?

    The "time" module stuff is a built in feature of MP so in theory it's mostly present when included but it looks like they've changed the way it's implemented in the lower level. Seems you now need a port specific modtime.c file to be present in the port folder and some additional settings in the mpconfigport.h file (like below for STM32) as well as the mp_hal_ticks_us function related to getting ticks in microseconds etc. It should be possible for the 64 bit P2 counter to be used to report microseconds since boot up for ticks however without an actual RTC you won't be able to implement a proper calendar time.

    #define MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME (1)
    #define MICROPY_PY_TIME_TIME_TIME_NS (1)
    #define MICROPY_PY_TIME_INCLUDEFILE "ports/stm32/modtime.c"

    There should already be some other code available from Eric's RISC-V and my native P2 machine port variant for the other time delay API stuff in that module too you could utilize if you are putting together a proper modtime.c and updated mphalport.c file for this later MP version's requirements.

  • RaymanRayman Posts: 14,325

    @rogloh thanks. definitely need to figure that out. For now, added a waitus() to p2 module and can verify that i2c is working with lis3dh at least. I2c seems a bit fragile at the moment though so definitely needs more testing. But, big win for now for sure.

  • msrobotsmsrobots Posts: 3,709

    i think @ersmith put something into flex-c to support linux time by adding a current datetime diff to the 64 bit cnt while using p2load to load a program, not sure if this may help here

  • RaymanRayman Posts: 14,325
    edited 2024-06-01 17:54

    So, seems need to do something like this in mpconfigport:

    #define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES)

  • RaymanRayman Posts: 14,325

    Ok, got time, but not under machine...

     help("modules")
    __main__          hashlib           micropython       struct 
    array             heapq             os                sys                       
    binascii          io                p2                time                      
    builtins          json              pyb_pin                                     
    collections       machine           pyb_sdcard                                  
    gc                math              re   
    
  • RaymanRayman Posts: 14,325

    Ok, LIS3DH accelerometer code works just about as is now. Just the I2C() invocation is changed, think ...

    One think I'm noticing now is that there's no way to quit a program like this...
    started it with:
    execfile("test_lis3dh.py")
    Some places say CTRL-something should exit, but nothing works...

  • roglohrogloh Posts: 5,495

    @Rayman said:
    One think I'm noticing now is that there's no way to quit a program like this...
    started it with:
    execfile("test_lis3dh.py")
    Some places say CTRL-something should exit, but nothing works...

    I'd imagine that the program either needs to exit or needs to take input so you can press ^C or ^D etc to quit/restart MP. Unless there is interrupt driven serial IO or the IO is non-blocking polled and buffered automatically in the middle of MP's normal processing loop running the executed program there'd be no way to abort by looking for a ^C character in the middle of the program that is not itself already waiting on input.

    If you look in micropython/shared/runtime/pyexec.c you'll see the REPL processing loop code which does look for special characters like ^C & ^D etc to interrupt execution. But when you invoke the execfile statement other things happen, so you'd have to track that particular sequence down to see how it processes any input data. It seems to call parse_compile_execute with different flags in different situations and the mp_hal_set_interrupt_char routine is called to specify the "interrupt" character in different cases. You'd probably have to search down wherever this special character is being detected and see if it is part of the processing loop when execfile is invoked.

  • RaymanRayman Posts: 14,325
    edited 2024-06-02 17:25

    This code for 9DOF sensor ICM-20948 seems to be working over I2C:
    https://github.com/jposada202020/MicroPython_ICM20948

    but, there might be something that I don't understand...
    Had to rename the driver "icm20948.py" to "micropython_icm20948.py". This seems strange...
    Maybe if it's in a properly named folder wouldn't have to?
    Also seems need to create a "micropython_icm20948" folder and put "i2c_helpers.py" in it.

    Also, had to change the printout for some reason. This code seems to be using some format that isn't supported for some reason here:

        #print(f"x: {accx}m/s², y: {accy},m/s² z: {accz}m/s²")
        #print(f"x: {gyrox}°/s, y: {gyroy}°/s, z: {gyroz}°/s")
        print("x: %0.2f m/s², y: %0.2f m/s², z: %0.2f m/s²" % (accx,accy,accz))
        print("x: %0.2f °/s, y: %0.2f °/s, z: %0.2f °/s" % (gyrox,gyroy,gyroz))
    
  • RaymanRayman Posts: 14,325

    Just noticed the ² and ° symbols don't seem to work with the VGA driver... Wonder if it's worth or possible to fix that...

  • RaymanRayman Posts: 14,325

    Also posted the source code to bottom of page here:
    https://www.rayslogic.com/Propeller2/upy/micropython.html

  • TubularTubular Posts: 4,653

    Looks like they just released MP 1.23 including the dynamic usb and openamp support

  • RaymanRayman Posts: 14,325
    edited 2024-06-02 23:07

    Interesting… openamp looks to be similar to something I know openmp, but for microcontrollers I guess

    Not sure the asymmetric part makes sense with P2 though…

  • roglohrogloh Posts: 5,495
    edited 2024-06-03 00:19

    Openamp for MP does seem useful if it gives us a framework for other firmware to be loaded onto other COGs. The ancillary endpoint API stuff that comes along with it could be good too as it provides an in-built path for messaging between MicroPython and the other spawned COGs allowing control and data to be passed between a COG and MP. The COG side could potentially see this as a buffered mailbox. Additionally being able to optionally load binaries from a filesystem into COGs looks especially useful and is more dynamic and capable than requiring them all statically built into the entire executable image itself.

    UPDATE: here's the link to their API for openamp
    https://docs.micropython.org/en/latest/library/openamp.html

  • RaymanRayman Posts: 14,325

    Got 1.23 to compile. Just had to add this to basically all the port files:

    #define STATIC static

    662 x 80 - 6K
  • ElectrodudeElectrodude Posts: 1,649
    edited 2024-06-03 15:58

    @Rayman said:
    Got 1.23 to compile. Just had to add this to basically all the port files:

    #define STATIC static

    Isn't there some common header that's already included by everything that you can add that to?

  • RaymanRayman Posts: 14,325

    Might be able to put it in Propeller2.h, but is not really a P2 thing, don't think. I'm open to suggestions...

  • RaymanRayman Posts: 14,325

    Maybe Propeller2.h makes sense after all.
    These are the files:

    1011 x 26 - 12K
  • roglohrogloh Posts: 5,495

    @Rayman said:
    Might be able to put it in Propeller2.h, but is not really a P2 thing, don't think. I'm open to suggestions...

    Here is the related check-in they did for this recently:
    https://github.com/micropython/micropython/commit/decf8e6a8bb940d5829ca3296790631fcece7b21
    I think it would be best to try to follow the same approach for consistency. By #defining STATIC to avoid the change is sort of working around the problem. They used a convenient "git ls-files | egrep .. | xargs sed ..." script command to change a large number of files which should save time. You might just want to apply it to the P2 port specific folder files instead of everything, by running it within the P2 port folder.

Sign In or Register to comment.