Skip to content

Commit

Permalink
ports/psoc6/../machine_i2c.c: Added deinit and pin phy refactor.
Browse files Browse the repository at this point in the history
Signed-off-by: enriquezgarc <enriquezgarcia.external@infineon.com>
  • Loading branch information
jaenrig-ifx committed Oct 12, 2023
1 parent 1aef1f0 commit a67660d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 44 deletions.
2 changes: 2 additions & 0 deletions ports/psoc6/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ extern void network_init(void);
extern void network_deinit(void);
extern void mod_pin_deinit(void);
extern void mod_adc_block_deinit(void);
extern void mod_i2c_deinit(void);

void mpy_task(void *arg);

Expand Down Expand Up @@ -179,6 +180,7 @@ void mpy_task(void *arg) {
machine_deinit();
mod_pin_deinit();
mod_adc_block_deinit();
mod_i2c_deinit();
mod_pin_phy_deinit();
#if MICROPY_PY_NETWORK
mod_network_deinit();
Expand Down
121 changes: 79 additions & 42 deletions ports/psoc6/modules/machine/machine_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,46 @@

// port-specific includes
#include "modmachine.h"
#include "machine_pin_phy.h"
#include "mplogger.h"

#define MAX_I2C 10 // TODO: Change as per bsp?
#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);
machine_i2c_obj_t *i2c_obj[MAX_I2C] = { NULL };

static inline machine_i2c_obj_t *i2c_obj_alloc() {
for (uint8_t i = 0; i < MAX_I2C; i++)
{
if (i2c_obj[i] == NULL) {
i2c_obj[i] = mp_obj_malloc(machine_i2c_obj_t, &machine_i2c_type);
return i2c_obj[i];
}
}

return NULL;
}

static inline void i2c_obj_free(machine_i2c_obj_t *i2c_obj_ptr) {
for (uint8_t i = 0; i < MAX_I2C; i++)
{
if (i2c_obj[i] == i2c_obj_ptr) {
i2c_obj[i] = NULL;
}
}
}

STATIC cy_rslt_t i2c_init(machine_i2c_obj_t *machine_i2c_obj) {
// Define the I2C master configuration structure
cyhal_i2c_cfg_t i2c_master_config =
{
Expand All @@ -44,28 +64,47 @@ 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);
}


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) {
mplogger_print("%q constructor invoked\n", MP_QSTR_I2C);
enum { ARG_id, ARG_freq, ARG_scl, ARG_sda };
Expand All @@ -88,35 +127,20 @@ mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2C id '%d' not supported !"), i2c_id);
}

machine_i2c_obj_t *self = mp_obj_malloc(machine_i2c_obj_t, &machine_i2c_type);
self->base.type = &machine_i2c_type;
machine_i2c_obj_t *self = i2c_obj_alloc();
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;
Expand All @@ -130,6 +154,13 @@ 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);
i2c_obj_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);
Expand All @@ -138,7 +169,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);
Expand All @@ -148,7 +179,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).
Expand All @@ -162,8 +193,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);
}
Expand All @@ -173,13 +203,12 @@ 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
};


MP_DEFINE_CONST_OBJ_TYPE(
machine_i2c_type,
MP_QSTR_I2C,
Expand All @@ -189,3 +218,11 @@ MP_DEFINE_CONST_OBJ_TYPE(
protocol, &machine_i2c_p,
locals_dict, &mp_machine_i2c_locals_dict
);

void mod_i2c_deinit() {
for (uint8_t i = 0; i < MAX_I2C; i++) {
if (i2c_obj[i] != NULL) {
machine_i2c_deinit((mp_obj_base_t *)(i2c_obj[i]));
}
}
}
4 changes: 2 additions & 2 deletions ports/psoc6/modules/machine/machine_pin_phy.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit a67660d

Please sign in to comment.