diff --git a/ports/psoc6/main.c b/ports/psoc6/main.c index db2efd58cbe1a..9641fe25d1e94 100644 --- a/ports/psoc6/main.c +++ b/ports/psoc6/main.c @@ -26,6 +26,8 @@ #include "shared/runtime/pyexec.h" #include "extmod/modnetwork.h" +#include "modules/machine/machine_pin_phy.h" + #if MICROPY_PY_NETWORK #include "cybsp_wifi.h" #include "cy_wcm.h" @@ -54,7 +56,8 @@ extern void machine_init(void); extern void machine_deinit(void); extern void network_init(void); extern void network_deinit(void); -extern void adcblock_deinit(void); +extern void mod_pin_deinit(void); +extern void mod_adc_block_deinit(void); void mpy_task(void *arg); @@ -174,7 +177,9 @@ void mpy_task(void *arg) { // Deinitialize modules machine_deinit(); - adcblock_deinit(); + mod_pin_deinit(); + mod_adc_block_deinit(); + mod_pin_phy_deinit(); #if MICROPY_PY_NETWORK mod_network_deinit(); network_deinit(); diff --git a/ports/psoc6/modules/machine/machine_adc.c b/ports/psoc6/modules/machine/machine_adc.c index c091a2ab4e02b..5e57bd94130c2 100644 --- a/ports/psoc6/modules/machine/machine_adc.c +++ b/ports/psoc6/modules/machine/machine_adc.c @@ -12,31 +12,15 @@ #include "cyhal.h" #include "cy_pdl.h" -#define IS_GPIO_VALID_ADC_PIN(gpio) ((gpio == CYHAL_NC_PIN_VALUE) || ((gpio >= 80) && (gpio <= 87))) +extern machine_adcblock_obj_t *adc_block_obj_find(mp_obj_t pin); +extern machine_adcblock_obj_t *adc_block_obj_init(mp_obj_t pin); +extern machine_adc_obj_t *adc_block_channel_find(machine_adcblock_obj_t *adc_block, mp_obj_t pin); +extern machine_adc_obj_t *adc_block_channel_alloc(machine_adcblock_obj_t *adc_block, mp_obj_t pin); +extern void adc_block_channel_free(machine_adcblock_obj_t *acd_block, machine_adc_obj_t *channel); -extern int16_t adc_block_get_block_id_for_pin(uint32_t pin); -extern machine_adc_obj_t *adc_block_retrieve_adc_obj_for_pin(machine_adcblock_obj_t *adc_block, uint32_t pin); -extern machine_adcblock_obj_t *adc_block_init_helper(uint8_t adc_id, uint8_t bits); -extern machine_adc_obj_t *adc_block_allocate_new_channel_for_pin(machine_adcblock_obj_t *adc_block, uint32_t pin); +void adc_obj_init(machine_adc_obj_t *adc, machine_adcblock_obj_t *adc_block, mp_obj_t pin_name, uint32_t sampling_time) { + machine_pin_phy_obj_t *adc_pin_phy = pin_phy_realloc(pin_name, PIN_PHY_FUNC_ADC); -/******************************************************************************/ -// MicroPython bindings for machine.ADC - -const mp_obj_type_t machine_adc_type; - -// Private helper function to check if ADC Block ID is valid -static inline bool _is_gpio_valid_adc_pin(uint32_t pin) { - if ((pin == CYHAL_NC_PIN_VALUE) || ((pin >= 80) && (pin <= 87))) { - return true; - } - - return false; -} - -// Public helper function to handle new ADC channel creation and initialization -machine_adc_obj_t *adc_create_and_init_new_channel_obj(machine_adcblock_obj_t *adc_block, uint32_t pin, uint32_t sampling_time) { - - machine_adc_obj_t *adc_channel = adc_block_allocate_new_channel_for_pin(adc_block, pin); const cyhal_adc_channel_config_t channel_config = { .enable_averaging = false, @@ -44,47 +28,45 @@ machine_adc_obj_t *adc_create_and_init_new_channel_obj(machine_adcblock_obj_t *a .enabled = true }; - cy_rslt_t status = cyhal_adc_channel_init_diff(&(adc_channel->adc_chan_obj), &(adc_block->adc_block_obj), pin, CYHAL_ADC_VNEG, &channel_config); + cy_rslt_t status = cyhal_adc_channel_init_diff(&(adc->adc_chan_obj), &(adc_block->adc_obj), adc_pin_phy->addr, CYHAL_ADC_VNEG, &channel_config); if (status != CY_RSLT_SUCCESS) { mp_raise_TypeError(MP_ERROR_TEXT("ADC Channel Initialization failed!")); } - adc_channel->pin = pin; - adc_channel->block = adc_block; - adc_channel->sample_ns = sampling_time; - - return adc_channel; + adc->pin_phy = adc_pin_phy; + adc->block = adc_block; + adc->sample_ns = sampling_time; } -// Main helper function to create and initialize ADC -machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin) { - if (!_is_gpio_valid_adc_pin(pin)) { - mp_raise_ValueError(MP_ERROR_TEXT("Invalid ADC Pin")); - } - - int16_t adc_block_id = adc_block_get_block_id_for_pin(pin); +void adc_obj_deinit(machine_adc_obj_t *adc) { + cyhal_adc_channel_free(&(adc->adc_chan_obj)); + pin_phy_free(adc->pin_phy); +} - if (adc_block_id == -1) { - mp_raise_ValueError(MP_ERROR_TEXT("No associated ADC Block for specified pin!")); +machine_adc_obj_t *machine_adc_make_init(uint32_t sampling_time, mp_obj_t pin_name) { + machine_adc_obj_t *adc; + + machine_adcblock_obj_t *adc_block = adc_block_obj_find(pin_name); + if (adc_block == NULL) { + adc_block = adc_block_obj_init(pin_name); + } else { + adc = adc_block_channel_find(adc_block, pin_name); + if (adc != NULL) { + adc->sample_ns = sampling_time; + return adc; + } } - // Initialize ADC Block - machine_adcblock_obj_t *adc_block = adc_block_init_helper(adc_block_id, DEFAULT_ADC_BITS); - - // Retrieve associated channel (ADC obj) for pin - machine_adc_obj_t *o = adc_block_retrieve_adc_obj_for_pin(adc_block, pin); - - if (o == NULL) { - o = adc_create_and_init_new_channel_obj(adc_block, pin, sampling_time); - } + adc = adc_block_channel_alloc(adc_block, pin_name); + adc_obj_init(adc, adc_block, pin_name, sampling_time); - return o; + return adc; } // machine_adc_print() STATIC void machine_adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "", self->pin, self->block->id, self->sample_ns); + mp_printf(print, "", self->pin_phy->addr, self->block->id, self->sample_ns); } // ADC(id) @@ -102,16 +84,23 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, all_args + 1, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - machine_pin_phy_obj_t *adc_pin_obj = pin_phy_alloc(all_args[0], PIN_PHY_FUNC_ADC); - // Get user input sampling time uint32_t sampling_time = args[ARG_sample_ns].u_int; - machine_adc_obj_t *o = adc_init_helper(sampling_time, adc_pin_obj->addr); + machine_adc_obj_t *o = machine_adc_make_init(sampling_time, all_args[0]); return MP_OBJ_FROM_PTR(o); } +// deinit() +STATIC mp_obj_t machine_adc_deinit(mp_obj_t self_in) { + machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); + adc_obj_deinit(self); + adc_block_channel_free(self->block, self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_deinit_obj, machine_adc_deinit); + // block() STATIC mp_obj_t machine_adc_block(mp_obj_t self_in) { const machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -134,6 +123,7 @@ STATIC mp_obj_t machine_adc_read_uv(mp_obj_t self_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_uv_obj, machine_adc_read_uv); STATIC const mp_rom_map_elem_t machine_adc_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_adc_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_read_u16), MP_ROM_PTR(&machine_adc_read_u16_obj) }, { MP_ROM_QSTR(MP_QSTR_read_uv), MP_ROM_PTR(&machine_adc_read_uv_obj) }, { MP_ROM_QSTR(MP_QSTR_block), MP_ROM_PTR(&machine_adc_block_obj) }, diff --git a/ports/psoc6/modules/machine/machine_adc.h b/ports/psoc6/modules/machine/machine_adc.h index a802e8aae8e5e..4df04cfff6a1b 100644 --- a/ports/psoc6/modules/machine/machine_adc.h +++ b/ports/psoc6/modules/machine/machine_adc.h @@ -6,7 +6,7 @@ typedef struct _machine_adc_obj_t { mp_obj_base_t base; machine_adcblock_obj_t *block; - uint32_t pin; + machine_pin_phy_obj_t *pin_phy; uint32_t sample_ns; cyhal_adc_channel_t adc_chan_obj; } machine_adc_obj_t; diff --git a/ports/psoc6/modules/machine/machine_adcblock.c b/ports/psoc6/modules/machine/machine_adcblock.c index b6dcea0475648..39a65c49c844b 100644 --- a/ports/psoc6/modules/machine/machine_adcblock.c +++ b/ports/psoc6/modules/machine/machine_adcblock.c @@ -6,8 +6,8 @@ #include "machine_adcblock.h" #include "machine_adc.h" -extern machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin); -extern machine_adc_obj_t *adc_create_and_init_new_channel_obj(machine_adcblock_obj_t *adc_block, uint32_t pin, uint32_t sampling_time); +extern void adc_obj_init(machine_adc_obj_t *adc, machine_adcblock_obj_t *adc_block, mp_obj_t pin_name, uint32_t sampling_time); +extern void adc_obj_deinit(machine_adc_obj_t *adc); machine_adcblock_obj_t *adc_block[MAX_BLOCKS] = {NULL}; @@ -23,6 +23,39 @@ const adc_block_channel_pin_map_t adc_block_pin_map[] = { /******************************************************************************/ // MicroPython bindings for machine.ADC +// Private helper function to get channel number for provided pin +int16_t _get_adc_channel_number_for_pin(uint32_t pin) { + for (int i = 0; i < (sizeof(adc_block_pin_map) / sizeof(adc_block_pin_map[0])); i++) + { + if (pin == adc_block_pin_map[i].pin) { + return adc_block_pin_map[i].channel; + } + } + return -1; +} + +// Private helper function to get pin number for provided channel no. +int16_t _get_adc_pin_number_for_channel(uint16_t channel) { + for (int i = 0; i < (sizeof(adc_block_pin_map) / sizeof(adc_block_pin_map[0])); i++) + { + if (channel == adc_block_pin_map[i].channel) { + return adc_block_pin_map[i].pin; + } + } + return -1; +} + +// Public helper function to get adc block id associated to input pin +int16_t _get_block_id_for_pin(uint32_t pin) { + for (int i = 0; i < (sizeof(adc_block_pin_map) / sizeof(adc_block_pin_map[0])); i++) + { + if (pin == adc_block_pin_map[i].pin) { + return adc_block_pin_map[i].block_id; + } + } + return -1; +} + // Private helper function to check if ADC Block ID is valid static inline bool _is_valid_id(uint8_t adc_id) { if (adc_id >= MAX_BLOCKS) { @@ -32,8 +65,11 @@ static inline bool _is_valid_id(uint8_t adc_id) { return true; } -// Private helper function to allocate ADC Block provided it's ID -static inline machine_adcblock_obj_t *_get_existing_adc_block_by_id(uint8_t adc_block_id) { +static inline machine_adcblock_obj_t *_adc_block_obj_find(uint8_t adc_block_id) { + if (!_is_valid_id(adc_block_id)) { + mp_raise_TypeError(MP_ERROR_TEXT("Specified ADC id not supported")); + } + for (uint8_t i = 0; i < MAX_BLOCKS; i++) { if (adc_block[i] != NULL) { @@ -46,22 +82,44 @@ static inline machine_adcblock_obj_t *_get_existing_adc_block_by_id(uint8_t adc_ return NULL; } -// Private helper function to get ADC Block not created yet and is supported by hardware - returned as id/index -static inline uint8_t _get_free_adc_block_id() { - uint8_t i; - for (i = 0; i < MAX_BLOCKS; i++) +static inline machine_adcblock_obj_t *_adc_block_obj_alloc() { + for (uint8_t i = 0; i < MAX_BLOCKS; i++) { if (adc_block[i] == NULL) { - break; + adc_block[i] = mp_obj_malloc(machine_adcblock_obj_t, &machine_adcblock_type); + return adc_block[i]; } } - return i; + return NULL; } +static inline void _adc_block_obj_free(machine_adcblock_obj_t *adc_block_ptr) { + for (uint8_t i = 0; i < MAX_BLOCKS; i++) + { + if (adc_block[i] == adc_block_ptr) { + adc_block[i] = NULL; + } + } +} + +machine_adc_obj_t *adc_block_channel_alloc(machine_adcblock_obj_t *adc_block, mp_obj_t pin) { + int pin_addr = mp_hal_get_pin_obj(pin); + int16_t adc_channel_no = _get_adc_channel_number_for_pin(pin_addr); + adc_block->channel[adc_channel_no] = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); + return adc_block->channel[adc_channel_no]; +} + +void adc_block_channel_free(machine_adcblock_obj_t *adc_block, machine_adc_obj_t *adc) { + for (uint8_t i = 0; i < ADC_BLOCK_CHANNEL_MAX; i++) { + if (adc_block->channel[i] == adc) { + adc_block->channel[i] = NULL; + } + } +} // Private helper function to get any associated pin to the given ADC Block id -static inline uint32_t _get_any_pin_for_adc_block_id(uint16_t adc_block_id) { +static inline uint32_t _adc_block_get_any_pin(uint16_t adc_block_id) { for (uint8_t i = 0; i < MAX_CHANNELS; i++) { if (adc_block_pin_map[i].block_id == adc_block_id) { return adc_block_pin_map[i].pin; @@ -72,97 +130,68 @@ static inline uint32_t _get_any_pin_for_adc_block_id(uint16_t adc_block_id) { } // Private helper function to create and initialize new ADC Block -static inline machine_adcblock_obj_t *_create_and_init_new_adc_block(uint16_t adc_block_id, uint8_t bits) { - uint8_t free_index = _get_free_adc_block_id(); - if (free_index <= MAX_BLOCKS) { - adc_block[free_index] = mp_obj_malloc(machine_adcblock_obj_t, &machine_adcblock_type); - adc_block[free_index]->id = adc_block_id; - adc_block[free_index]->bits = bits; - - cy_rslt_t status = cyhal_adc_init(&(adc_block[free_index]->adc_block_obj), _get_any_pin_for_adc_block_id(adc_block_id), NULL); - if (status != CY_RSLT_SUCCESS) { - mp_raise_TypeError(MP_ERROR_TEXT("ADC Initialization failed!")); - } - - return adc_block[free_index]; +static void _adc_block_obj_init(machine_adcblock_obj_t *adc_block, uint16_t adc_block_id, uint8_t bits) { + cy_rslt_t status = cyhal_adc_init(&(adc_block->adc_obj), _adc_block_get_any_pin(adc_block_id), NULL); + if (status != CY_RSLT_SUCCESS) { + mp_raise_TypeError(MP_ERROR_TEXT("ADC Initialization failed!")); } - return NULL; + adc_block->id = adc_block_id; + adc_block->bits = bits; } -// Private helper function to get channel number for provided pin -int16_t _get_adc_channel_number_for_pin(uint32_t pin) { - for (int i = 0; i < (sizeof(adc_block_pin_map) / sizeof(adc_block_pin_map[0])); i++) - { - if (pin == adc_block_pin_map[i].pin) { - return adc_block_pin_map[i].channel; +static void _adc_block_obj_deinit(machine_adcblock_obj_t *adc_block) { + // Includes all channels deinitialization and deallocation + for (uint8_t i = 0; i < ADC_BLOCK_CHANNEL_MAX; i++) { + if (adc_block->channel[i] != NULL) { + adc_obj_deinit(adc_block->channel[i]); + adc_block_channel_free(adc_block, adc_block->channel[i]); } } - return -1; + cyhal_adc_free(&(adc_block->adc_obj)); } -// Private helper function to get pin number for provided channel no. -int16_t _get_adc_pin_number_for_channel(uint16_t channel) { - for (int i = 0; i < (sizeof(adc_block_pin_map) / sizeof(adc_block_pin_map[0])); i++) - { - if (channel == adc_block_pin_map[i].channel) { - return adc_block_pin_map[i].pin; - } - } - return -1; -} +machine_adcblock_obj_t *machine_adcblock_make_init(uint8_t adc_id, uint8_t bits) { + machine_adcblock_obj_t *adc_block = _adc_block_obj_find(adc_id); -// Public helper function to get adc block id associated to input pin -int16_t adc_block_get_block_id_for_pin(uint32_t pin) { - for (int i = 0; i < (sizeof(adc_block_pin_map) / sizeof(adc_block_pin_map[0])); i++) - { - if (pin == adc_block_pin_map[i].pin) { - return adc_block_pin_map[i].block_id; + // No existing adc_block for given id. Create new one. + if (adc_block == NULL) { + adc_block = _adc_block_obj_alloc(); + if (adc_block == NULL) { + mp_raise_TypeError(MP_ERROR_TEXT("ADC Blocks not available. Fully allocated")); } + _adc_block_obj_init(adc_block, adc_id, bits); } - return -1; -} -// Not Used currently -/*machine_adc_obj_t *adc_block_get_channel_obj(machine_adcblock_obj_t *adc_block, uint8_t channel) { - return adc_block->channel[channel]; -}*/ - -// Public helper function to allocate a new channel for provided pin. -machine_adc_obj_t *adc_block_allocate_new_channel_for_pin(machine_adcblock_obj_t *adc_block, uint32_t pin) { - int16_t adc_channel_no = _get_adc_channel_number_for_pin(pin); - adc_block->channel[adc_channel_no] = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); - - return adc_block->channel[adc_channel_no]; + return adc_block; } -// Public helper function to retrieve the associated channel (adc object) for given pin -machine_adc_obj_t *adc_block_retrieve_adc_obj_for_pin(machine_adcblock_obj_t *adc_block, uint32_t pin) { +machine_adcblock_obj_t *adc_block_obj_find(mp_obj_t pin) { + int pin_addr = mp_hal_get_pin_obj(pin); + int adc_block_id = _get_block_id_for_pin(pin_addr); - int16_t adc_channel_no = _get_adc_channel_number_for_pin(pin); + if (adc_block_id == -1) { + mp_raise_ValueError(MP_ERROR_TEXT("No associated ADC Block for specified pin!")); + } - return adc_block->channel[adc_channel_no]; + return _adc_block_obj_find(adc_block_id); } -// Main helper function to initialize an ADC Block -machine_adcblock_obj_t *adc_block_init_helper(uint8_t adc_id, uint8_t bits) { +machine_adcblock_obj_t *adc_block_obj_init(mp_obj_t pin) { + int pin_addr = mp_hal_get_pin_obj(pin); + int adc_block_id = _get_block_id_for_pin(pin_addr); - if (!_is_valid_id(adc_id)) { - mp_raise_TypeError(MP_ERROR_TEXT("Specified ADC id not supported")); - } - - machine_adcblock_obj_t *adc_block = _get_existing_adc_block_by_id(adc_id); - - // No existing adc_block for given id. Create new one. - if (adc_block == NULL) { - adc_block = _create_and_init_new_adc_block(adc_id, bits); + if (adc_block_id == -1) { + mp_raise_ValueError(MP_ERROR_TEXT("No associated ADC Block for specified pin!")); } - if (adc_block == NULL) { - mp_raise_TypeError(MP_ERROR_TEXT("ADC Blocks not available. Fully allocated")); - } + return machine_adcblock_make_init(adc_block_id, DEFAULT_ADC_BITS); +} - return adc_block; +machine_adc_obj_t *adc_block_channel_find(machine_adcblock_obj_t *adc_block, mp_obj_t pin) { + int pin_addr = mp_hal_get_pin_obj(pin); + int16_t adc_channel_no = _get_adc_channel_number_for_pin(pin_addr); + return adc_block->channel[adc_channel_no]; } // machine_adcblock_print() @@ -193,31 +222,40 @@ STATIC mp_obj_t machine_adcblock_make_new(const mp_obj_type_t *type, size_t n_po mp_raise_TypeError(MP_ERROR_TEXT("Invalid bits. Current ADC configuration supports only 12 bits resolution!")); } - return MP_OBJ_FROM_PTR(adc_block_init_helper(adc_id, bits)); + return MP_OBJ_FROM_PTR(machine_adcblock_make_init(adc_id, bits)); } +// ADCBlock deinit() +STATIC mp_obj_t machine_adcblock_deinit(mp_obj_t self_in) { + machine_adcblock_obj_t *self = MP_OBJ_TO_PTR(self_in); + _adc_block_obj_deinit(self); + _adc_block_obj_free(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adcblock_deinit_obj, machine_adcblock_deinit); + // ADCBlock connect() STATIC mp_obj_t machine_adcblock_connect(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { machine_adcblock_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); uint8_t channel = -1; uint32_t pin = 0; + mp_obj_t pin_name; if (n_pos_args == 2) { // If channel only specified : If mp_obj_is_int is true, then it is channel if (mp_obj_is_int(pos_args[1])) { channel = mp_obj_get_int(pos_args[1]); pin = _get_adc_pin_number_for_channel(channel); + pin_name = pin_name_by_addr(mp_obj_new_int(pin)); } else { - machine_pin_phy_obj_t *adc_pin_obj = pin_phy_alloc(pos_args[1], PIN_PHY_FUNC_ADC); - pin = adc_pin_obj->addr; - channel = _get_adc_channel_number_for_pin(pin); + pin_name = pos_args[1]; } } else if (n_pos_args == 3) { channel = mp_obj_get_int(pos_args[1]); uint32_t exp_pin = _get_adc_pin_number_for_channel(channel); - machine_pin_phy_obj_t *adc_pin_obj = pin_phy_alloc(pos_args[2], PIN_PHY_FUNC_ADC); - pin = adc_pin_obj->addr; + pin_name = pos_args[2]; + pin = mp_hal_get_pin_obj(pin_name); if (exp_pin != pin) { mp_raise_TypeError(MP_ERROR_TEXT("Wrong pin specified for the mentioned channel")); } @@ -225,27 +263,18 @@ STATIC mp_obj_t machine_adcblock_connect(size_t n_pos_args, const mp_obj_t *pos_ mp_raise_TypeError(MP_ERROR_TEXT("Too many positional args")); } - machine_adc_obj_t *o = adc_block_retrieve_adc_obj_for_pin(self, pin); - if (o == NULL) { - o = adc_create_and_init_new_channel_obj(self, pin, DEFAULT_ADC_ACQ_NS); + machine_adc_obj_t *adc = adc_block_channel_find(self, pin_name); + if (adc == NULL) { + adc = adc_block_channel_alloc(self, pin_name); + adc_obj_init(adc, self, pin_name, DEFAULT_ADC_ACQ_NS); } - return o; + return adc; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_adcblock_connect_obj, 2, machine_adcblock_connect); -void adcblock_deinit(void) { - - for (uint8_t i = 0; i < MAX_BLOCKS; i++) { - if (adc_block[i] != NULL) { - cyhal_adc_free(&adc_block[i]->adc_block_obj); - adc_block[i] = NULL; - } - } - -} - STATIC const mp_rom_map_elem_t machine_adcblock_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_adcblock_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&machine_adcblock_connect_obj) }, }; STATIC MP_DEFINE_CONST_DICT(machine_adcblock_locals_dict, machine_adcblock_locals_dict_table); @@ -258,3 +287,11 @@ MP_DEFINE_CONST_OBJ_TYPE( print, machine_adcblock_print, locals_dict, &machine_adcblock_locals_dict ); + +void mod_adc_block_deinit(void) { + for (uint8_t i = 0; i < MAX_BLOCKS; i++) { + if (adc_block[i] != NULL) { + machine_adcblock_deinit(adc_block[i]); + } + } +} diff --git a/ports/psoc6/modules/machine/machine_adcblock.h b/ports/psoc6/modules/machine/machine_adcblock.h index 8e398a99142c2..9e5c6727d9d93 100644 --- a/ports/psoc6/modules/machine/machine_adcblock.h +++ b/ports/psoc6/modules/machine/machine_adcblock.h @@ -17,7 +17,7 @@ typedef struct _machine_adc_obj_t machine_adc_obj_t; /* Forward declaration of a typedef struct _machine_adcblock_obj_t { mp_obj_base_t base; - cyhal_adc_t adc_block_obj; + cyhal_adc_t adc_obj; uint8_t id; uint8_t bits; machine_adc_obj_t *channel[ADC_BLOCK_CHANNEL_MAX]; @@ -30,5 +30,5 @@ typedef struct uint32_t pin; }adc_block_channel_pin_map_t; -void adcblock_deinit(void); +void mod_adc_block_deinit(void); #endif // MICROPY_INCLUDED_MACHINE_ADCBLOCK_H diff --git a/ports/psoc6/modules/machine/machine_pin.c b/ports/psoc6/modules/machine/machine_pin.c index d9c55a4647696..01938fb1d68f4 100644 --- a/ports/psoc6/modules/machine/machine_pin.c +++ b/ports/psoc6/modules/machine/machine_pin.c @@ -24,7 +24,8 @@ typedef struct _machine_pin_io_obj_t { #define MAX_PIN_IO MP_ARRAY_SIZE(machine_pin_phy_obj) machine_pin_io_obj_t *pin_io[MAX_PIN_IO] = {NULL}; -static inline machine_pin_io_obj_t *pin_io_allocate(void) { +static inline machine_pin_io_obj_t *pin_io_allocate(mp_obj_t pin_name) { + machine_pin_phy_obj_t *pin_phy = pin_phy_realloc(pin_name, PIN_PHY_FUNC_DIO); uint16_t i; for (i = 0; i < MAX_PIN_IO; i++) { if (pin_io[i] == NULL) { @@ -32,9 +33,20 @@ static inline machine_pin_io_obj_t *pin_io_allocate(void) { } } pin_io[i] = mp_obj_malloc(machine_pin_io_obj_t, &machine_pin_type); + pin_io[i]->pin_phy = pin_phy; + return pin_io[i]; } +static inline void pin_io_free(machine_pin_io_obj_t *pin) { + pin_phy_free(pin->pin_phy); + for (uint16_t i = 0; i < MAX_PIN_IO; i++) { + if (pin_io[i] == pin) { + pin_io[i] = NULL; + } + } +} + // Pin.print() STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mplogger_print("machine pin print\n"); @@ -217,15 +229,11 @@ mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, mp_arg_check_num(n_args, n_kw, 1, 6, true); - machine_pin_phy_obj_t *pin_phy = pin_phy_realloc(args[0], PIN_PHY_FUNC_DIO); - - machine_pin_io_obj_t *self = pin_io_allocate(); + machine_pin_io_obj_t *self = pin_io_allocate(args[0]); if (self == NULL) { return mp_const_none; } - self->pin_phy = pin_phy; - // go into param arg parsing if args apart from "id" are provided (for ex. pin.Mode, pin.PULL etc) if (n_args > 1 || n_kw > 0) { // pin mode given, so configure this GPIO @@ -274,12 +282,12 @@ MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_obj_init_obj, 1, machine_pin_obj_init); STATIC mp_obj_t machine_pin_obj_deinit(mp_obj_t self_in) { machine_pin_io_obj_t *self = MP_OBJ_TO_PTR(self_in); cyhal_gpio_free(self->pin_phy->addr); + pin_io_free(self); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_deinit_obj, machine_pin_obj_deinit); - // Pin.toggle() STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) { machine_pin_io_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -335,6 +343,14 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { }; STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); +void mod_pin_deinit() { + for (uint8_t i = 0; i < MAX_PIN_IO; i++) { + if (pin_io[i] != NULL) { + machine_pin_obj_deinit(pin_io[i]); + } + } +} + STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { (void)errcode; machine_pin_io_obj_t *self = self_in; diff --git a/ports/psoc6/modules/machine/machine_pin.h b/ports/psoc6/modules/machine/machine_pin.h index ca9db8a3f4f11..4fd411532646a 100644 --- a/ports/psoc6/modules/machine/machine_pin.h +++ b/ports/psoc6/modules/machine/machine_pin.h @@ -4,5 +4,6 @@ #include #include "machine_pin_phy.h" +void mod_pin_deinit(); #endif // MICROPY_INCLUDED_MACHINE_PIN_H diff --git a/ports/psoc6/modules/machine/machine_pin_phy.c b/ports/psoc6/modules/machine/machine_pin_phy.c index 11ab84a4e797d..9384a5dabb51b 100644 --- a/ports/psoc6/modules/machine/machine_pin_phy.c +++ b/ports/psoc6/modules/machine/machine_pin_phy.c @@ -126,8 +126,13 @@ machine_pin_phy_obj_t machine_pin_phy_obj[] = { int pin_find(mp_obj_t pin) { int wanted_pin = -1; if (mp_obj_is_small_int(pin)) { - // Pin defined by the index of pin table - wanted_pin = mp_obj_get_int(pin); + int pin_addr = mp_obj_get_int(pin); + for (int i = 0; i < MP_ARRAY_SIZE(machine_pin_phy_obj); i++) { + if (machine_pin_phy_obj[i].addr == pin_addr) { + wanted_pin = i; + break; + } + } } else if (mp_obj_is_str(pin)) { // Search by name size_t slen; @@ -147,6 +152,15 @@ int pin_find(mp_obj_t pin) { return wanted_pin; } +mp_obj_t pin_name_by_addr(mp_obj_t pin) { + if (mp_obj_is_int(pin)) { + const char *name = machine_pin_phy_obj[pin_find(pin)].name; + return mp_obj_new_str(name, strlen(name)); + } else { + return NULL; // expecting a int as input + } +} + // helper function to translate pin_name(string) into machine_pin_io_obj_t->pin_addr int pin_addr_by_name(mp_obj_t pin) { if (mp_obj_is_str(pin)) { @@ -200,11 +214,12 @@ machine_pin_phy_obj_t *pin_phy_realloc(mp_obj_t pin_name, machine_pin_phy_func_t } void pin_phy_free(machine_pin_phy_obj_t *pin_phy) { - // machine_pin_phy_func_t current_func = pin_phy->allocated_func; pin_phy->allocated_func = PIN_PHY_FUNC_NONE; +} - // TODO: each module should provide its own instance deinitialization - // We can not just free the physical_pin, without deiniting its corresponding - // peripheral object - // machine_mod_deinit[func](pin_phy); + +void mod_pin_phy_deinit(void) { + for (int i = 0; i < MP_ARRAY_SIZE(machine_pin_phy_obj); i++) { + pin_phy_free(&machine_pin_phy_obj[i]); + } } diff --git a/ports/psoc6/modules/machine/machine_pin_phy.h b/ports/psoc6/modules/machine/machine_pin_phy.h index ef9215f8e7721..194cb5cb44054 100644 --- a/ports/psoc6/modules/machine/machine_pin_phy.h +++ b/ports/psoc6/modules/machine/machine_pin_phy.h @@ -26,8 +26,11 @@ 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); void pin_phy_free(machine_pin_phy_obj_t *obj); +void mod_pin_phy_deinit(void); + // Function Prototypes to support interaction between c<->py int pin_find(mp_obj_t obj); +mp_obj_t pin_name_by_addr(mp_obj_t pin); int pin_addr_by_name(mp_obj_t obj); #define PIN_P0_0 CYHAL_GET_GPIO(CYHAL_PORT_0, 0)// !< Port 0 Pin 0