-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
feature/optional_i2c_bus #16671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature/optional_i2c_bus #16671
Conversation
Code size report:
|
ports/esp32/machine_i2c.c
Outdated
|
||
// Parse args | ||
enum { ARG_id, ARG_scl, ARG_sda, ARG_freq, ARG_timeout }; | ||
static const mp_arg_t allowed_args[] = { | ||
{ MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, | ||
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use { MP_QSTR_id, MP_ARG_INT, {.u_int = I2C_NUM_0} },
here to avoid the default and MP_OBJ_NULL
checks below.
Note: Retrieving the value then becomes mp_int_t i2c_id = args[ARG_id].u_int
ports/rp2/machine_i2c.c
Outdated
@@ -97,7 +97,7 @@ static void machine_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_prin | |||
mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { | |||
enum { ARG_id, ARG_freq, ARG_scl, ARG_sda, ARG_timeout }; | |||
static const mp_arg_t allowed_args[] = { | |||
{ MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, | |||
{ MP_QSTR_id, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still not ideal but I'd probably do:
#ifdef PICO_DEFAULT_I2C
{ MP_QSTR_id, MP_ARG_INT, {.u_int = PICO_DEFAULT_I2C} },
#else
{ MP_QSTR_id, MP_ARG_INT, {.u_int = -1} },
#endif
Rather than inline the checks below. Saves code.
(Not really sure why this was ever MP_ARG_OBJ
?)
It doesn't feel like this breaks the API, but it seems to break expectations on Pico since - afaict - machine.I2C()
will not give you a properly configured default I2C instance. (It doesn't handle PICO_DEFAULT_I2C_SCL_PIN
and PICO_DEFAULT_I2C_SDA_PIN
so I2C will wiggle into the void and thus your objective - portable code - wont quite be met?)
Edit crossed out erroneous statement: I2C gets initialised by since freq == 0
:
micropython/ports/rp2/machine_i2c.c
Lines 149 to 158 in 53f1a3a
if (n_args > 1 || n_kw > 0 || self->freq == 0) { | |
self->freq = args[ARG_freq].u_int; | |
i2c_init(self->i2c_inst, self->freq); | |
self->freq = i2c_set_baudrate(self->i2c_inst, self->freq); | |
self->timeout = args[ARG_timeout].u_int; | |
gpio_set_function(self->scl, GPIO_FUNC_I2C); | |
gpio_set_function(self->sda, GPIO_FUNC_I2C); | |
gpio_set_pulls(self->scl, true, 0); | |
gpio_set_pulls(self->sda, true, 0); | |
} |
I kinda like where you're going with this, though afaict it doesn't make Of course, to play devil's advocate here, your library shouldn't construct |
I actually quite like this idea. After all, you can already do things like
I think it will work on Pico. There are default pins for all I2C objects which should get configured the first time
I agree with this. A driver usually doesn't need to |
Oof I think I see how this works, falls through to the check for There is a comment saying as much 😆 but I can see why I missed that. |
Thank you for your feedback. I have made the suggested changes. Let me know if there's anything else I should do before this is merged. |
This commit gives the option to not pass an I2C Bus ID when creating a machine I2C object. If the ID is not provided, the default bus ID (which is `PICO_DEFAULT_I2C`) is used. This allows users to simply declare an I2C object with `machine.I2C()` without passing any arguments, thus creating an object with the default I2C ID, SCL, and SDA. Signed-off-by: Malcolm McKellips <malcolm.mckellips@sparkfun.com>
Similar to the previous commit, this allows constructing an I2C instance without specifying an ID. The default ID is I2C_NUM_0. Signed-off-by: Malcolm McKellips <malcolm.mckellips@sparkfun.com>
67f83c0
to
c143eb5
Compare
My experience with a XIAO C3 running with the GENERIC_C3 build: Using 1.24.1 release build,
I will look at what is causing the hang. Note that on the XIAO S3 both |
Summary
This pull request gives the option to not pass an I2C Bus ID when creating a machine I2C object on RP2 and ESP32. If the ID is not provided on RP2, the default bus ID (PICO_DEFAULT_I2C) is used. For ESP32, I2C_NUM_0 is used. This would allow users on both platforms to simply declare an I2C object with machine.I2C() without passing any arguments, thus creating an object with the default I2C ID, SCL, and SDA.
Our use case is a higher-level python driver that creates machine.I2C objects. We would like the driver to be portable to many different RP2 and ESP32 boards without having to explicitly specify these arguments.
Testing
Tested on RP2 with Raspberry Pi Pico W:
Tested on ESP32 with Sparkfun Thing Plus - ESP32 WROOM (Micro-B):
Trade-offs and Alternatives