diff --git a/ports/psoc6/modules/machine/machine_i2c.c b/ports/psoc6/modules/machine/machine_i2c.c index 4c971d6b293db..08b10c527c9f0 100644 --- a/ports/psoc6/modules/machine/machine_i2c.c +++ b/ports/psoc6/modules/machine/machine_i2c.c @@ -15,26 +15,22 @@ // port-specific includes #include "modmachine.h" +#include "machine_pin_phy.h" #include "mplogger.h" #define DEFAULT_I2C_FREQ (400000) -#define MICROPY_HW_I2C_SCL (CYBSP_I2C_SCL) -#define MICROPY_HW_I2C_SDA (CYBSP_I2C_SDA) #define PSOC_I2C_MASTER_MODE (CYHAL_I2C_MODE_MASTER) typedef struct _machine_i2c_obj_t { mp_obj_base_t base; cyhal_i2c_t i2c_obj; uint8_t i2c_id; - uint8_t scl; - uint8_t sda; + machine_pin_phy_obj_t *scl; + machine_pin_phy_obj_t *sda; uint32_t freq; } machine_i2c_obj_t; STATIC cy_rslt_t i2c_init(machine_i2c_obj_t *machine_i2c_obj) { - // free first in case object has been initialized before - cyhal_i2c_free(&machine_i2c_obj->i2c_obj); - // Define the I2C master configuration structure cyhal_i2c_cfg_t i2c_master_config = { @@ -44,25 +40,45 @@ STATIC cy_rslt_t i2c_init(machine_i2c_obj_t *machine_i2c_obj) { }; // Initialize I2C master, set the SDA and SCL pins and assign a new clock - cy_rslt_t result = cyhal_i2c_init(&machine_i2c_obj->i2c_obj, machine_i2c_obj->sda, machine_i2c_obj->scl, NULL); + cy_rslt_t result = cyhal_i2c_init(&machine_i2c_obj->i2c_obj, machine_i2c_obj->sda->addr, machine_i2c_obj->scl->addr, NULL); return result == CY_RSLT_SUCCESS ? cyhal_i2c_configure(&machine_i2c_obj->i2c_obj, &i2c_master_config) : result; } -STATIC cy_rslt_t i2c_read(cyhal_i2c_t *i2c_obj, uint16_t addr, uint8_t *buf, size_t len, uint32_t timeout, bool send_stop) { - return cyhal_i2c_master_read(i2c_obj, addr, buf, len, timeout, send_stop); +STATIC inline void i2c_sda_alloc(machine_i2c_obj_t *i2c_obj, mp_obj_t pin_name) { + machine_pin_phy_obj_t *sda = pin_phy_realloc(pin_name, PIN_PHY_FUNC_I2C); + + if (sda == NULL) { + size_t slen; + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SDA pin (%s) not found !"), mp_obj_str_get_data(pin_name, &slen)); + } + + i2c_obj->sda = sda; +} + +STATIC inline void i2c_sda_free(machine_i2c_obj_t *i2c_obj) { + pin_phy_free(i2c_obj->sda); } -STATIC cy_rslt_t i2c_write(cyhal_i2c_t *i2c_obj, uint16_t addr, uint8_t *buf, size_t len, uint32_t timeout, bool send_stop) { - return cyhal_i2c_master_write(i2c_obj, addr, buf, len, timeout, send_stop); +STATIC inline void i2c_scl_alloc(machine_i2c_obj_t *i2c_obj, mp_obj_t pin_name) { + machine_pin_phy_obj_t *scl = pin_phy_realloc(pin_name, PIN_PHY_FUNC_I2C); + + if (scl == NULL) { + size_t slen; + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SCL pin (%s) not found !"), mp_obj_str_get_data(pin_name, &slen)); + } + + i2c_obj->scl = scl; } -extern mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj); +STATIC inline void i2c_scl_free(machine_i2c_obj_t *i2c_obj) { + pin_phy_free(i2c_obj->scl); +} STATIC void machine_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "I2C(%u, freq=%u, scl=%u, sda=%u)", self->i2c_id, self->freq, self->scl, self->sda); + mp_printf(print, "I2C(%u, freq=%u, scl=%u, sda=%u)", self->i2c_id, self->freq, self->scl->addr, self->sda->addr); } @@ -89,34 +105,19 @@ mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n } machine_i2c_obj_t *self = mp_obj_malloc(machine_i2c_obj_t, &machine_i2c_type); - self->base.type = &machine_i2c_type; self->i2c_id = i2c_id; - // get scl & Sda pins & configure them + // get scl & sda pins & configure them if (args[ARG_scl].u_obj != mp_const_none) { - int scl = mp_hal_get_pin_obj(args[ARG_scl].u_obj); - - if (self->scl == -1) { - size_t slen; - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SCL pin (%s) not found !"), mp_obj_str_get_data(args[ARG_scl].u_obj, &slen)); - } - - self->scl = scl; + i2c_scl_alloc(self, args[ARG_scl].u_obj); } else { - self->scl = MICROPY_HW_I2C_SCL; + mp_raise_TypeError(MP_ERROR_TEXT("SCL pin must be provided")); } - if (args[ARG_sda].u_obj != mp_const_none) { - int sda = mp_hal_get_pin_obj(args[ARG_sda].u_obj); - - if (self->sda == -1) { - size_t slen; - mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("SDA pin (%s) not found !"), mp_obj_str_get_data(args[ARG_sda].u_obj, &slen)); - } - self->sda = sda; + i2c_sda_alloc(self, args[ARG_sda].u_obj); } else { - self->sda = MICROPY_HW_I2C_SDA; + mp_raise_TypeError(MP_ERROR_TEXT("SDA pin must be provided")); } self->freq = args[ARG_freq].u_int; @@ -130,6 +131,12 @@ mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n return MP_OBJ_FROM_PTR(self); } +STATIC void machine_i2c_deinit(mp_obj_base_t *self_in) { + machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + cyhal_i2c_free(&(self->i2c_obj)); + i2c_sda_free(self); + i2c_scl_free(self); +} STATIC int machine_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t len, uint8_t *buf, unsigned int flags) { machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -138,7 +145,7 @@ STATIC int machine_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t le uint32_t timeout = 0; if ((flags & MP_MACHINE_I2C_FLAG_READ) == MP_MACHINE_I2C_FLAG_READ) { - result = i2c_read(&self->i2c_obj, addr, buf, len, timeout, send_stop); + result = cyhal_i2c_master_read(&self->i2c_obj, addr, buf, len, timeout, send_stop); if (result != CY_RSLT_SUCCESS) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("cyhal_i2c_master_read failed with return code %lx !"), result); @@ -148,7 +155,7 @@ STATIC int machine_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t le } else { // handle scan type bus checks and send stop if (buf == NULL) { - result = i2c_write(&self->i2c_obj, addr, buf, 0, 50, send_stop); + result = cyhal_i2c_master_write(&self->i2c_obj, addr, buf, 0, 50, send_stop); if ((result != CY_RSLT_SUCCESS)) { // these 2 errors occur if nothing is attached to sda/scl, but they are pulled-up (0xaa2004) or not pulled-up (0xaa2003). @@ -162,8 +169,7 @@ STATIC int machine_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t le return len; } else { - result = i2c_write(&self->i2c_obj, addr, buf, len, timeout, send_stop); - + result = cyhal_i2c_master_write(&self->i2c_obj, addr, buf, len, timeout, send_stop); if (result != CY_RSLT_SUCCESS) { mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("cyhal_i2c_master_write failed with return code %lx !"), result); } @@ -175,6 +181,7 @@ STATIC int machine_i2c_transfer(mp_obj_base_t *self_in, uint16_t addr, size_t le STATIC const mp_machine_i2c_p_t machine_i2c_p = { + .deinit = machine_i2c_deinit, .transfer_single = machine_i2c_transfer, .transfer = mp_machine_i2c_transfer_adaptor }; diff --git a/ports/psoc6/modules/machine/machine_pin_phy.h b/ports/psoc6/modules/machine/machine_pin_phy.h index 194cb5cb44054..ec5c318fb1753 100644 --- a/ports/psoc6/modules/machine/machine_pin_phy.h +++ b/ports/psoc6/modules/machine/machine_pin_phy.h @@ -22,8 +22,8 @@ typedef struct _machine_pin_phy_obj_t { extern machine_pin_phy_obj_t machine_pin_phy_obj[PIN_PHY_NUM_MAX]; bool pin_phy_is_alloc(machine_pin_phy_obj_t *obj); -machine_pin_phy_obj_t *pin_phy_alloc(mp_obj_t addr, machine_pin_phy_func_t func); -machine_pin_phy_obj_t *pin_phy_realloc(mp_obj_t addr, machine_pin_phy_func_t func); +machine_pin_phy_obj_t *pin_phy_alloc(mp_obj_t pin_name, machine_pin_phy_func_t func); +machine_pin_phy_obj_t *pin_phy_realloc(mp_obj_t pin_name, machine_pin_phy_func_t func); void pin_phy_free(machine_pin_phy_obj_t *obj); void mod_pin_phy_deinit(void);