From c45b4658703bb1e0f9e83b9b451d33d005246f84 Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Tue, 25 Jul 2023 16:05:20 +0200 Subject: [PATCH 1/2] ports/psoc6/modules/machine/machine_adc: WIP refactor relationship. Signed-off-by: enriquezgarc --- ports/psoc6/modules/machine/machine_adc.c | 155 ++++-------------- ports/psoc6/modules/machine/machine_adc.h | 4 +- .../psoc6/modules/machine/machine_adcblock.c | 136 +++++++++++++-- .../psoc6/modules/machine/machine_adcblock.h | 15 +- 4 files changed, 155 insertions(+), 155 deletions(-) diff --git a/ports/psoc6/modules/machine/machine_adc.c b/ports/psoc6/modules/machine/machine_adc.c index bafd5cc41359..558b7209045b 100644 --- a/ports/psoc6/modules/machine/machine_adc.c +++ b/ports/psoc6/modules/machine/machine_adc.c @@ -17,160 +17,63 @@ #define IS_GPIO_VALID_ADC_PIN(gpio) ((gpio == CYHAL_NC_PIN_VALUE) || ((gpio >= 80) && (gpio <= 87))) - -bool adc_init_flag = false; +extern int16_t get_adc_block_id(uint32_t pin); +extern machine_adc_obj_t *adc_block_get_pin_adc_obj(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); /******************************************************************************/ // MicroPython bindings for machine.ADC const mp_obj_type_t machine_adc_type; -// Get adc block id associated to input pin -uint16_t get_adc_block_id(uint32_t pin) { - // printf("\n Size of adc_block_pin_map: %d", sizeof(adc_block_pin_map)/sizeof(adc_block_pin_map[0])); - 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; -} +static inline machine_adc_obj_t *adc_init_new(machine_adcblock_obj_t *adc_block, uint32_t pin, uint32_t sampling_time) { -// Helper function to get channel number provided the pin is given -uint16_t get_adc_channel_number(uint32_t pin) { - for (int i = 0; i < sizeof(adc_block_pin_map); i++) + machine_adc_obj_t *o = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); + const cyhal_adc_channel_config_t channel_config = { - if (pin == adc_block_pin_map[i].pin) { - return adc_block_pin_map[i].channel; - } - } - return -1; -} + .enable_averaging = false, + .min_acquisition_ns = sampling_time, // TODO: if existing, can we change its configuration (sampling rate?) + .enabled = true + }; -// Get or construct (if not yet constructed) the associated block instance given its adc block id -// ToDo: Needs refactoring to adapt if multiple adc blocks are allowed -machine_adcblock_obj_t *get_adc_block(uint16_t adc_block_id) { - // Check if block instance is created before. If it is, then return the adc_block associated to adc_id - // Else create a block instance and return the same - if (*adc_block != NULL) { // Block already created - for (int i = 0; i < MAX_BLOCKS; i++) - { - return (adc_block[i]->id == adc_block_id) ? adc_block[i] : NULL; - } - } else { // If block not created - machine_adcblock_obj_t *adc_block_new = mp_obj_malloc(machine_adcblock_obj_t, &machine_adcblock_type); - adc_block_new->id = adc_block_id; - adc_block_new->bits = DEFAULT_ADC_BITS; - // Update the master adc_block to sync adc_block creation across classes - adc_block[0] = adc_block_new; - printf("\n Block created! \n"); - - return adc_block_new; - } + cyhal_adc_channel_init_diff(&(o->adc_chan_obj), &(adc_block->adc_block_obj), pin, CYHAL_ADC_VNEG, &channel_config); + // TODO: handle error return - return NULL; -} -// cyhal_adc_channel_t *adc_channel_obj -void configure_adc_channel(cyhal_adc_t adc_obj, cyhal_adc_channel_t *adc_channel_obj, uint32_t pin, uint16_t adc_channel_no, uint32_t sampling_time) { - // TODO: (Review) If not existing, now we can create the adc object - // Configure the ADC channel !!internal - // If channel does no exist, only then create one - // printf("\nADC Channel OBJ add 1: %ld\n", *adc_channels[adc_channel_no]); - // cyhal_adc_channel_t adc_channel_obj; - if (adc_channels[adc_channel_no] != NULL) { // channel already available. So return the created channel - printf("\nChannel already available!\n"); - - // cyhal_adc_channel_t t = *adc_channels[adc_channel_no]; - - adc_channel_obj = adc_channels[adc_channel_no]; - - printf("\nACQ Time 1: %ld\n", (*adc_channels[adc_channel_no]).minimum_acquisition_ns); - printf("\nACQ Time 1A: %ld\n", adc_channel_obj->minimum_acquisition_ns); - - } else { // Channel not created already. Create new one here - - printf("\nChannel is being created!\n"); - // cyhal_adc_channel_t adc_channel_obj; - const cyhal_adc_channel_config_t channel_config = - { - .enable_averaging = false, - .min_acquisition_ns = sampling_time, // TODO: if existing, can we change its configuration (sampling rate?) - .enabled = true - }; - // Initialize channel - cyhal_adc_channel_init_diff(adc_channel_obj, &adc_obj, pin, CYHAL_ADC_VNEG, &channel_config); - - - // Update channel created in master list - adc_channels[adc_channel_no] = adc_channel_obj; - printf("\nACQ Time 2: %ld\n", (*adc_channels[adc_channel_no]).minimum_acquisition_ns); - printf("\nACQ Time 2: %ld\n", adc_channel_obj->minimum_acquisition_ns); + o->pin = pin; + o->block = adc_block; + o->sample_ns = sampling_time; - } - // return(adc_channels[adc_channel_no]); - // return mp_const; + return o; } - // 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->ch, self->sample_ns); - return; + machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "", self->pin, self->block, self->sample_ns); } // ADC initialization helper function -machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin, uint8_t bits) { +machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin) { // Get GPIO and check it has ADC capabilities. if (!IS_GPIO_VALID_ADC_PIN(pin)) { mp_raise_ValueError(MP_ERROR_TEXT("Invalid ADC Pin")); } - cyhal_adc_t adc_obj; - // cyhal_adc_channel_t adc_channel_obj; - // Initialize the ADC block (required only once per execution) - if (!adc_init_flag) { - cyhal_adc_init(&adc_obj, pin, NULL); - adc_init_flag = true; - } - // TODO: get the adcblock for a given pin. - uint16_t adc_block_id = get_adc_block_id(pin); + int16_t adc_block_id = get_adc_block_id(pin); printf("\n ADC Block ID: %d\n", adc_block_id); if (adc_block_id == -1) { mp_raise_ValueError(MP_ERROR_TEXT("No associated ADC Block for specified pin!")); } - // TODO: get or construct (if not yet constructed) the associated block - // instance given its adc block id - machine_adcblock_obj_t *adc_block = get_adc_block(adc_block_id); - printf("\nADC Bits: %d\n", adc_block[0].id); - - // Get channel number provided the pin is given. Required mapping in case channel to pin are not default. - uint16_t adc_channel_no = get_adc_channel_number(pin); - printf("\n Channel no. : %d\n", adc_channel_no); - - // TODO: Before creating the ADC object, check if for the associated block - // there is already a adc object (channel) created - // it will return null if not existing. - cyhal_adc_channel_t *adc_channel_obj1; - configure_adc_channel(adc_obj, adc_channel_obj1, pin, adc_channel_no, sampling_time); - - printf("\nAcquisition time A: %ld\n", adc_channel_obj1->minimum_acquisition_ns); + machine_adcblock_obj_t *adc_block = adc_block_init_helper(adc_block_id, DEFAULT_ADC_BITS); + printf("\nADC Bits: %d\n", adc_block->bits); - // Create ADC Object - machine_adc_obj_t *o = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); + machine_adc_obj_t *o = adc_block_get_pin_adc_obj(adc_block, pin); - o->pin = pin; - o->block = adc_block; - o->sample_ns = sampling_time; - o->adc_chan_obj = adc_channel_obj1; - - printf("\nAcquisition time B: %ld\n", o->adc_chan_obj->minimum_acquisition_ns); - - // TODO: (Review) Register the object in the corresponding block - // adc_block_allocate_adc_channel(adc_block, o); + if (o == NULL) { + o = adc_init_new(adc_block, pin, sampling_time); + } return o; } @@ -195,7 +98,7 @@ STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, s // 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->pin_addr, DEFAULT_ADC_BITS); + machine_adc_obj_t *o = adc_init_helper(sampling_time, adc_pin_obj->pin_addr); return MP_OBJ_FROM_PTR(o); } @@ -210,14 +113,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_block_obj, machine_adc_block); // read_u16() STATIC mp_obj_t machine_adc_read_u16(mp_obj_t self_in) { machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(cyhal_adc_read_u16(self->adc_chan_obj)); + return MP_OBJ_NEW_SMALL_INT(cyhal_adc_read_u16(&(self->adc_chan_obj))); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_u16_obj, machine_adc_read_u16); // read_uv STATIC mp_obj_t machine_adc_read_uv(mp_obj_t self_in) { machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(cyhal_adc_read_uv(self->adc_chan_obj)); + return MP_OBJ_NEW_SMALL_INT(cyhal_adc_read_uv(&(self->adc_chan_obj))); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_adc_read_uv_obj, machine_adc_read_uv); diff --git a/ports/psoc6/modules/machine/machine_adc.h b/ports/psoc6/modules/machine/machine_adc.h index 0fff9e6bde60..a802e8aae8e5 100644 --- a/ports/psoc6/modules/machine/machine_adc.h +++ b/ports/psoc6/modules/machine/machine_adc.h @@ -8,9 +8,7 @@ typedef struct _machine_adc_obj_t { machine_adcblock_obj_t *block; uint32_t pin; uint32_t sample_ns; - cyhal_adc_channel_t *adc_chan_obj; + cyhal_adc_channel_t adc_chan_obj; } machine_adc_obj_t; -extern machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin1, uint8_t bits); - #endif // MICROPY_INCLUDED_MACHINE_ADC_H diff --git a/ports/psoc6/modules/machine/machine_adcblock.c b/ports/psoc6/modules/machine/machine_adcblock.c index afee3f6e890a..b0831a9d6190 100644 --- a/ports/psoc6/modules/machine/machine_adcblock.c +++ b/ports/psoc6/modules/machine/machine_adcblock.c @@ -5,10 +5,10 @@ #include "machine_adcblock.h" #include "pins.h" -#include "machine_adc.h" + +extern machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin); machine_adcblock_obj_t *adc_block[MAX_BLOCKS] = {NULL}; -cyhal_adc_channel_t *adc_channels[MAX_CHANNELS] = {NULL}; const adc_block_channel_pin_map_t adc_block_pin_map[] = { {ADCBLOCK0, 0, PIN_P10_0}, @@ -19,6 +19,121 @@ const adc_block_channel_pin_map_t adc_block_pin_map[] = { {ADCBLOCK0, 5, PIN_P10_5} }; // will belong to only a particular bsp +static inline bool is_valid_id(uint8_t adc_id) { + if (adc_id >= MAX_BLOCKS) { + return false; + } + + return true; +} + +static inline machine_adcblock_obj_t *adc_block_get_allocated(uint8_t adc_block_id) { + for (uint8_t i = 0; i < MAX_BLOCKS; i++) + { + if (adc_block[i] != NULL) { + if (adc_block[i]->id == adc_block_id) { + return adc_block[i]; + } + } + } + + return NULL; +} + +static inline uint8_t adc_block_get_free_block() { + uint8_t i; + for (i = 0; i < MAX_BLOCKS; i++) + { + if (adc_block[i] == NULL) { + break; + } + } + + return i; +} + +static inline uint32_t adc_block_get_any_assoc_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; + } + } + + return 0; // there should always an associated pin for block... +} + +static inline machine_adcblock_obj_t *adc_block_init_new(uint16_t adc_block_id, uint8_t bits) { + uint8_t free_index = adc_block_get_free_block(); + // TODO: Associate id to index to simplify. Block always exists then, only is it inited or not. + 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; + + cyhal_adc_init(&(adc_block[free_index]->adc_block_obj), adc_block_get_any_assoc_pin(adc_block_id), NULL); + // TODO: handle return of cyhal + + printf("\n Block created! \n"); + + return adc_block[free_index]; + } + + return NULL; +} + +// Get adc block id associated to input pin +int16_t get_adc_block_id(uint32_t pin) { + // printf("\n Size of adc_block_pin_map: %d", sizeof(adc_block_pin_map)/sizeof(adc_block_pin_map[0])); + 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; +} + +// Helper function to get channel number provided the pin is given +int16_t get_adc_channel_number(uint32_t pin) { + for (int i = 0; i < sizeof(adc_block_pin_map); i++) + { + if (pin == adc_block_pin_map[i].pin) { + return adc_block_pin_map[i].channel; + } + } + return -1; +} + +machine_adc_obj_t *adc_block_get_channel_obj(machine_adcblock_obj_t *adc_block, uint8_t channel) { + return adc_block->channel[channel]; +} + +machine_adc_obj_t *adc_block_get_pin_adc_obj(machine_adcblock_obj_t *adc_block, uint32_t pin) { + + int16_t adc_channel_no = get_adc_channel_number(pin); + + return adc_block->channel[adc_channel_no]; +} + +machine_adcblock_obj_t *adc_block_init_helper(uint8_t adc_id, uint8_t bits) { + + if (!is_valid_id(adc_id)) { + mp_raise_TypeError(MP_ERROR_TEXT("Specified ADC id not supported")); + } + + machine_adcblock_obj_t *adc_block = adc_block_get_allocated(adc_id); + + if (adc_block == NULL) { + adc_block = adc_block_init_new(adc_id, bits); + } + + if (adc_block == NULL) { + mp_raise_TypeError(MP_ERROR_TEXT("ADC Blocks not available. Fully allocated")); + } + + return adc_block; +} + STATIC void machine_adcblock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_adcblock_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "ADCBlock(%u, bits=%u)", self->id, self->bits); @@ -29,10 +144,7 @@ STATIC mp_obj_t machine_adcblock_make_new(const mp_obj_type_t *type, size_t n_po // Get ADC ID uint8_t adc_id = mp_obj_get_int(all_args[0]); - // TODO: check if this id is a valid/available genertically - if (adc_id != 0) { - mp_raise_TypeError(MP_ERROR_TEXT("Specified ADC id not supported. Currently only block 0 is configured!")); - } + mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw_args, all_args + n_pos_args); @@ -48,17 +160,7 @@ 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!")); } - // TODO: check if the object already exists (the instance object) - // if the corresponding index in the array isnĀ“t NULL - - // TODO: If not construct the object - machine_adcblock_obj_t *self = mp_obj_malloc(machine_adcblock_obj_t, &machine_adcblock_type); - self->id = adc_id; - self->bits = bits; - // TODO: initialize chan array to NULL - // self->adc_chan_obj = {NULL}; - - return MP_OBJ_FROM_PTR(self); + return MP_OBJ_FROM_PTR(adc_block_init_helper(adc_id, bits)); } /*STATIC mp_obj_t machine_adcblock_connect(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { diff --git a/ports/psoc6/modules/machine/machine_adcblock.h b/ports/psoc6/modules/machine/machine_adcblock.h index 2d0786306cc9..17e4820a4335 100644 --- a/ports/psoc6/modules/machine/machine_adcblock.h +++ b/ports/psoc6/modules/machine/machine_adcblock.h @@ -1,7 +1,7 @@ #ifndef MICROPY_INCLUDED_MACHINE_ADCBLOCK_H #define MICROPY_INCLUDED_MACHINE_ADCBLOCK_H -// #include "drivers/machine/psoc6_adc.h" +// These should go into the specific BSP #define DEFAULT_ADC_BITS 12 #define ADC_BLOCK_CHANNEL_MAX 6 @@ -11,16 +11,17 @@ #define MAX_CHANNELS (6) #include "pins.h" + +typedef struct _machine_adc_obj_t machine_adc_obj_t; /* Forward declaration of adc_obj */ + typedef struct _machine_adcblock_obj_t { mp_obj_base_t base; + cyhal_adc_t adc_block_obj; uint8_t id; uint8_t bits; - // machine_adc_obj_t *channel[ADC_BLOCK_CHANNEL_MAX]; + machine_adc_obj_t *channel[ADC_BLOCK_CHANNEL_MAX]; } machine_adcblock_obj_t; -extern machine_adcblock_obj_t *adc_block[MAX_BLOCKS]; -extern cyhal_adc_channel_t *adc_channels[MAX_CHANNELS]; - typedef struct { uint16_t block_id; @@ -28,8 +29,4 @@ typedef struct uint32_t pin; }adc_block_channel_pin_map_t; -extern const adc_block_channel_pin_map_t adc_block_pin_map[MAX_CHANNELS]; - - -extern void machine_adcblock_init_helper(machine_adcblock_obj_t *self, uint8_t id, uint8_t bits, cyhal_adc_channel_t adc_chan_obj); #endif // MICROPY_INCLUDED_MACHINE_ADCBLOCK_H From d4ee26d3226b14540466845ad26a47842537948d Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Thu, 27 Jul 2023 11:52:23 +0200 Subject: [PATCH 2/2] ports/psoc6/modules/machine/machine_adc: Allocaed channel in ADC block. Signed-off-by: enriquezgarc --- ports/psoc6/modules/machine/machine_adc.c | 3 ++- ports/psoc6/modules/machine/machine_adcblock.c | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ports/psoc6/modules/machine/machine_adc.c b/ports/psoc6/modules/machine/machine_adc.c index 558b7209045b..bf6147a7ed3c 100644 --- a/ports/psoc6/modules/machine/machine_adc.c +++ b/ports/psoc6/modules/machine/machine_adc.c @@ -20,6 +20,7 @@ extern int16_t get_adc_block_id(uint32_t pin); extern machine_adc_obj_t *adc_block_get_pin_adc_obj(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_pin(machine_adcblock_obj_t *adc_block, uint32_t pin); /******************************************************************************/ // MicroPython bindings for machine.ADC @@ -28,7 +29,7 @@ const mp_obj_type_t machine_adc_type; static inline machine_adc_obj_t *adc_init_new(machine_adcblock_obj_t *adc_block, uint32_t pin, uint32_t sampling_time) { - machine_adc_obj_t *o = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); + machine_adc_obj_t *o = adc_block_allocate_new_pin(adc_block, pin); const cyhal_adc_channel_config_t channel_config = { .enable_averaging = false, diff --git a/ports/psoc6/modules/machine/machine_adcblock.c b/ports/psoc6/modules/machine/machine_adcblock.c index b0831a9d6190..3ef09c633929 100644 --- a/ports/psoc6/modules/machine/machine_adcblock.c +++ b/ports/psoc6/modules/machine/machine_adcblock.c @@ -4,6 +4,7 @@ #include "modmachine.h" #include "machine_adcblock.h" +#include "machine_adc.h" #include "pins.h" extern machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin); @@ -108,6 +109,13 @@ machine_adc_obj_t *adc_block_get_channel_obj(machine_adcblock_obj_t *adc_block, return adc_block->channel[channel]; } +machine_adc_obj_t *adc_block_allocate_new_pin(machine_adcblock_obj_t *adc_block, uint32_t pin) { + int16_t adc_channel_no = get_adc_channel_number(pin); + adc_block->channel[adc_channel_no] = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); + + return adc_block->channel[adc_channel_no]; +} + machine_adc_obj_t *adc_block_get_pin_adc_obj(machine_adcblock_obj_t *adc_block, uint32_t pin) { int16_t adc_channel_no = get_adc_channel_number(pin);