add timeout keyword to I2C - for bitbangio - ignored for busio
This commit is contained in:
parent
ce5eae1c76
commit
d6c26942a5
|
@ -41,7 +41,7 @@
|
|||
#define ATTEMPTS 2
|
||||
|
||||
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency) {
|
||||
const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout) {
|
||||
Sercom* sercom = NULL;
|
||||
uint8_t sercom_index;
|
||||
uint32_t sda_pinmux = 0;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "pins.h"
|
||||
#include "nrf.h"
|
||||
|
||||
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency) {
|
||||
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency, uint32_t timeout ) {
|
||||
if (scl->pin == sda->pin) {
|
||||
mp_raise_ValueError("Invalid pins");
|
||||
}
|
||||
|
|
|
@ -275,9 +275,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException)
|
|||
MP_DEFINE_EXCEPTION(UnboundLocalError, NameError)
|
||||
*/
|
||||
MP_DEFINE_EXCEPTION(OSError, Exception)
|
||||
#if MICROPY_PY_BUILTINS_TIMEOUTERROR
|
||||
MP_DEFINE_EXCEPTION(TimeoutError, OSError)
|
||||
#endif
|
||||
/*
|
||||
MP_DEFINE_EXCEPTION(BlockingIOError, OSError)
|
||||
MP_DEFINE_EXCEPTION(ChildProcessError, OSError)
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "lib/utils/context_manager_helpers.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
//| .. currentmodule:: bitbangio
|
||||
//|
|
||||
//| :class:`I2C` --- Two wire serial protocol
|
||||
|
@ -49,6 +50,7 @@
|
|||
//| :param ~microcontroller.Pin scl: The clock pin
|
||||
//| :param ~microcontroller.Pin sda: The data pin
|
||||
//| :param int frequency: The clock frequency of the bus
|
||||
//| :param int timeout: The maximum clock stretching timeout in microseconds
|
||||
//|
|
||||
STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
@ -57,11 +59,12 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args,
|
|||
self->base.type = &bitbangio_i2c_type;
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
|
||||
enum { ARG_scl, ARG_sda, ARG_frequency };
|
||||
enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
@ -69,7 +72,7 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args,
|
|||
assert_pin(args[ARG_sda].u_obj, false);
|
||||
const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj);
|
||||
const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj);
|
||||
shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int);
|
||||
shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ extern const mp_obj_type_t bitbangio_i2c_type;
|
|||
extern void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self,
|
||||
const mcu_pin_obj_t * scl,
|
||||
const mcu_pin_obj_t * sda,
|
||||
uint32_t frequency);
|
||||
uint32_t frequency,
|
||||
uint32_t us_timeout);
|
||||
|
||||
extern void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self);
|
||||
extern bool shared_module_bitbangio_i2c_deinited(bitbangio_i2c_obj_t *self);
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
//| :param ~microcontroller.Pin scl: The clock pin
|
||||
//| :param ~microcontroller.Pin sda: The data pin
|
||||
//| :param int frequency: The clock frequency in Hertz
|
||||
//| :param int timeout: The maximum clock stretching timeut - only for bitbang
|
||||
//|
|
||||
STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
@ -63,11 +64,12 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
|||
self->base.type = &busio_i2c_type;
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
|
||||
enum { ARG_scl, ARG_sda, ARG_frequency };
|
||||
enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
@ -77,7 +79,7 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
|||
assert_pin_free(scl);
|
||||
const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj);
|
||||
assert_pin_free(sda);
|
||||
common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int);
|
||||
common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@ extern const mp_obj_type_t busio_i2c_type;
|
|||
extern void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
const mcu_pin_obj_t * scl,
|
||||
const mcu_pin_obj_t * sda,
|
||||
uint32_t frequency);
|
||||
uint32_t frequency,
|
||||
uint32_t timeout);
|
||||
|
||||
extern void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self);
|
||||
extern bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self);
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
*/
|
||||
|
||||
#include "shared-bindings/bitbangio/I2C.h"
|
||||
|
||||
#include "py/mperrno.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
@ -34,7 +34,6 @@
|
|||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "shared-module/bitbangio/types.h"
|
||||
|
||||
#define I2C_STRETCH_LIMIT 255
|
||||
|
||||
STATIC void delay(bitbangio_i2c_obj_t *self) {
|
||||
// We need to use an accurate delay to get acceptable I2C
|
||||
|
@ -48,11 +47,16 @@ STATIC void scl_low(bitbangio_i2c_obj_t *self) {
|
|||
|
||||
STATIC void scl_release(bitbangio_i2c_obj_t *self) {
|
||||
common_hal_digitalio_digitalinout_set_value(&self->scl, true);
|
||||
uint32_t count = self->us_timeout;
|
||||
delay(self);
|
||||
// For clock stretching, wait for the SCL pin to be released, with timeout.
|
||||
for (int count = I2C_STRETCH_LIMIT; !common_hal_digitalio_digitalinout_get_value(&self->scl) && count; --count) {
|
||||
for (; !common_hal_digitalio_digitalinout_get_value(&self->scl) && count; --count) {
|
||||
common_hal_mcu_delay_us(1);
|
||||
}
|
||||
if(count==0) { /// raise exception on timeout
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError,
|
||||
"Clock Stretching Timeout."));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void sda_low(bitbangio_i2c_obj_t *self) {
|
||||
|
@ -142,7 +146,10 @@ STATIC bool read_byte(bitbangio_i2c_obj_t *self, uint8_t *val, bool ack) {
|
|||
void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self,
|
||||
const mcu_pin_obj_t * scl,
|
||||
const mcu_pin_obj_t * sda,
|
||||
uint32_t frequency) {
|
||||
uint32_t frequency,
|
||||
uint32_t us_timeout) {
|
||||
|
||||
self->us_timeout = us_timeout;
|
||||
self->us_delay = 500000 / frequency;
|
||||
if (self->us_delay == 0) {
|
||||
self->us_delay = 1;
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef struct {
|
|||
digitalio_digitalinout_obj_t scl;
|
||||
digitalio_digitalinout_obj_t sda;
|
||||
uint32_t us_delay;
|
||||
uint32_t us_timeout;
|
||||
volatile bool locked;
|
||||
} bitbangio_i2c_obj_t;
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#include "py/nlr.h"
|
||||
|
||||
void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
|
||||
const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t freq) {
|
||||
shared_module_bitbangio_i2c_construct(&self->bitbang, scl, sda, freq);
|
||||
const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t freq, uint32_t timeout) {
|
||||
shared_module_bitbangio_i2c_construct(&self->bitbang, scl, sda, freq, timeout);
|
||||
}
|
||||
|
||||
bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) {
|
||||
|
|
Loading…
Reference in New Issue