Accessing hardware from native .mpy code

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
pro100vald
Posts: 3
Joined: Sun Dec 26, 2021 8:48 pm

Accessing hardware from native .mpy code

Post by pro100vald » Sun Dec 26, 2021 9:03 pm

Hello! I need to integrate existing C code into my MicroPython project. I`ve already determined that the most suitable option for me would be a dynamically loaded .mpy module. The C code should manage a chip via the I2C protocol, so I`m looking for any way to access I2C hardware from .mpy module. It is possible to just include port-specific .h and .c files and use the hardware directly, however, I`m wondering, if there is a way to use MicroPython built-in I2C library?

User avatar
OlivierLenoir
Posts: 126
Joined: Fri Dec 13, 2019 7:10 pm
Location: Picardie, FR

Re: Accessing hardware from native .mpy code

Post by OlivierLenoir » Mon Dec 27, 2021 5:38 am

Can you give us the i2c device reference you're using?
For i2c you can start with this documentation.

pro100vald
Posts: 3
Joined: Sun Dec 26, 2021 8:48 pm

Re: Accessing hardware from native .mpy code

Post by pro100vald » Mon Dec 27, 2021 7:03 am

Can you give us the i2c device reference you're using?
I need to integrate the USB power delivery control library for the FUSB302 PHY. You can find it there:
https://github.com/ReclaimerLabs/USB_PD
For i2c you can start with this documentation.
This documentation link is for the Python side of MicroPython, however, I`m working with the native C code. MicroPython allows usage of native C via this feature. I`ve successfully got this example up and running, as well as other native module examples from the MicroPython SDK. However, none of them demonstrate how to access the hardware.

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: Accessing hardware from native .mpy code

Post by karfas » Mon Dec 27, 2021 2:09 pm

I don't see differences between "code accessing hardware" and "code moving memory content around".
If you have working C/Assembler code already talking to your hardware - great, go ahead! Most likely you will need some interface code to micropython.

However, as your application doesn't look time critical, a few reads+writes over the I2C bus can be done in micropython as well.
This looks much simpler to me than a mixed C/Native Code/Micropython approach.

Regards,
Thomas
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

pro100vald
Posts: 3
Joined: Sun Dec 26, 2021 8:48 pm

Re: Accessing hardware from native .mpy code

Post by pro100vald » Mon Dec 27, 2021 2:26 pm

karfas wrote:
Mon Dec 27, 2021 2:09 pm
I don't see differences between "code accessing hardware" and "code moving memory content around".
If you have working C/Assembler code already talking to your hardware - great, go ahead! Most likely you will need some interface code to micropython.

However, as your application doesn't look time critical, a few reads+writes over the I2C bus can be done in micropython as well.
This looks much simpler to me than a mixed C/Native Code/Micropython approach.

Regards,
Thomas
Indeed, there is no difference between accessing hardware and accessing memory, and there is no barrier for me to just write the I2C module registers directly. However, it seems more reasonable to use the MicroPython's HAL, as this provides numerous benefits. The problem is, that there is little to none documentation regarding native C API, so thats why I`m asking this question on the forum, while keeping direct register shuffling as a backup plan.

User avatar
karfas
Posts: 193
Joined: Sat Jan 16, 2021 12:53 pm
Location: Vienna, Austria

Re: Accessing hardware from native .mpy code

Post by karfas » Wed Dec 29, 2021 9:50 am

pro100vald wrote:
Mon Dec 27, 2021 2:26 pm
it seems more reasonable to use the MicroPython's HAL, as this provides numerous benefits. The problem is, that there is little to none documentation regarding native C API, so thats why I`m asking this question on the forum, while keeping direct register shuffling as a backup plan.
The HAL for I2C isn't much more than an interface for sending and receiving I2C messages.
You can look up the code in the micropython source (e.g. ports/esp32/machine_i2c.c).

I still don't understand why you would like to mix native code in a .mpy to get the benefits of uPy HAL abstractions.
This contradicts itself a little, I think.

Regarding the docs: these look (together with the examples) sufficient for me, provided you can read, write and understand C code.
A few hours of debugging might save you from minutes of reading the documentation! :D
My repositories: https://github.com/karfas

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Accessing hardware from native .mpy code

Post by deshipu » Sat Jan 01, 2022 11:15 pm

pro100vald wrote:
Mon Dec 27, 2021 2:26 pm
Indeed, there is no difference between accessing hardware and accessing memory, and there is no barrier for me to just write the I2C module registers directly. However, it seems more reasonable to use the MicroPython's HAL, as this provides numerous benefits. The problem is, that there is little to none documentation regarding native C API, so thats why I`m asking this question on the forum, while keeping direct register shuffling as a backup plan.
I have been there myself, and the only advice I can give to you is to not use the native .mpy feature for this, and instead compile your custom module into the firmware, using the usual MicroPython functions as normal. Then perhaps make a pull request to include it (with an option flag) in the MicroPython itself. Just prepare to wait very patiently for any reviews on it — a couple of years at least.

The thing is, the native mpy code can only use the handful of functions that have been explicitly listed in a table in the compiled MicroPython firmware, and nothing else. It's useful for making functions that need to run fast, or for linking to third-party C libraries, but not for any hardware manipulation. As far as I can tell, the best you can do is to have your native function fill a buffer, that you can then send over i2c on the Python side.

Post Reply