From cbe5fdd279b9c7327b2cdb3d90bc9bfb4b904a27 Mon Sep 17 00:00:00 2001 From: NikhitaR-IFX Date: Mon, 24 Jul 2023 18:58:08 +0530 Subject: [PATCH] ports/psoc6: Refactor ADC WIP. Signed-off-by: NikhitaR-IFX --- ports/psoc6/modules/machine/machine_adc.c | 147 ++++++++++++++---- ports/psoc6/modules/machine/machine_adc.h | 4 +- .../psoc6/modules/machine/machine_adcblock.c | 32 ++-- .../psoc6/modules/machine/machine_adcblock.h | 21 ++- ports/psoc6/modules/machine/modmachine.c | 1 + 5 files changed, 155 insertions(+), 50 deletions(-) diff --git a/ports/psoc6/modules/machine/machine_adc.c b/ports/psoc6/modules/machine/machine_adc.c index daf87d94d599..7960301498df 100644 --- a/ports/psoc6/modules/machine/machine_adc.c +++ b/ports/psoc6/modules/machine/machine_adc.c @@ -7,6 +7,7 @@ #include "modmachine.h" #include "pins.h" #include "machine_adc.h" +#include "machine_adcblock.h" #include "cybsp.h" #include "cyhal.h" @@ -16,7 +17,7 @@ #define IS_GPIO_VALID_ADC_PIN(gpio) ((gpio == CYHAL_NC_PIN_VALUE) || ((gpio >= 80) && (gpio <= 87))) -cyhal_adc_t adc_obj; + bool adc_init_flag = false; /******************************************************************************/ @@ -24,10 +25,98 @@ bool adc_init_flag = false; 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; +} + +// 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++) + { + if (pin == adc_block_pin_map[i].pin) { + return adc_block_pin_map[i].channel; + } + } + return -1; +} + +// 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; + } + + 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); + + } + // return(adc_channels[adc_channel_no]); + // return mp_const; +} + + // 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->adc_pin, self->block->ch, self->sample_ns); + // machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in); + // mp_printf(print, "", self->pin, self->block->ch, self->sample_ns); return; } @@ -37,46 +126,51 @@ machine_adc_obj_t *adc_init_helper(uint32_t sampling_time, uint32_t pin, uint8_t if (!IS_GPIO_VALID_ADC_PIN(pin)) { mp_raise_ValueError(MP_ERROR_TEXT("Invalid ADC Pin")); } - cyhal_adc_channel_t adc_channel_obj; + 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. - // uint32_t adc_block_id = get_adc_block(pin); + uint16_t adc_block_id = get_adc_block_id(pin); + printf("\n ADC Block ID: %d\n", adc_block_id); - // TODO: get or construct (if not yet constructed) the associated block + 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 = construct_or_get_existing(adc_block_id); + machine_adcblock_obj_t *adc_block = get_adc_block(adc_block_id); + printf("\nADC Bits: %d\n", adc_block[0].id); - //TODO: Before creating the ADC object, check if for the associated block + // 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. - // machine_adc_obj_t *o = get_adc_channel(adc_block, pin); - - // TODO: (Review) If not existing, now we can create the adc object - // Configure the ADC channel - 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 - }; + cyhal_adc_channel_t *adc_channel_obj1; + configure_adc_channel(adc_obj, adc_channel_obj1, pin, adc_channel_no, sampling_time); - // Initialize channel - cyhal_adc_channel_init_diff(&adc_channel_obj, &adc_obj, pin, CYHAL_ADC_VNEG, &channel_config); + printf("\nAcquisition time A: %ld\n", adc_channel_obj1->minimum_acquisition_ns); // Create ADC Object machine_adc_obj_t *o = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type); - o->adc_pin = pin; - o->block = adc_block; + 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); + // adc_block_allocate_adc_channel(adc_block, o); return o; } @@ -116,14 +210,15 @@ 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->block->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->block->adc_chan_obj)); + printf("\n WORK DUMBO \n"); + 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 fb4e33c2e415..0fff9e6bde60 100644 --- a/ports/psoc6/modules/machine/machine_adc.h +++ b/ports/psoc6/modules/machine/machine_adc.h @@ -5,10 +5,10 @@ typedef struct _machine_adc_obj_t { mp_obj_base_t base; - machine_adcblock_obj_t *block; + 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); diff --git a/ports/psoc6/modules/machine/machine_adcblock.c b/ports/psoc6/modules/machine/machine_adcblock.c index bbc004830a55..2b12f8a7f1f7 100644 --- a/ports/psoc6/modules/machine/machine_adcblock.c +++ b/ports/psoc6/modules/machine/machine_adcblock.c @@ -7,31 +7,21 @@ #include "pins.h" #include "machine_adc.h" +machine_adcblock_obj_t *adc_block[MAX_BLOCKS] = {NULL}; +cyhal_adc_channel_t *adc_channels[MAX_CHANNELS] = {NULL}; -#define ADCBLOCK0 (0) -#define ADCBLOCK_CHANNEL_MAX (1) - -STATIC machine_adblock_obj_t * acd_block[MAX_BLOCKS] = {NULL}; - -typedef struct -{ - uint16_t block_id; - uint16_t channel; - uint16_t pin; -}acd_block_channel_pin_map_t; - -STATIC const acd_block_channel_pin_map_t adc_block_pin_map[] = { +const adc_block_channel_pin_map_t adc_block_pin_map[] = { {ADCBLOCK0, 0, PIN_P10_0}, {ADCBLOCK0, 1, PIN_P10_1}, {ADCBLOCK0, 2, PIN_P10_2}, {ADCBLOCK0, 3, PIN_P10_3}, {ADCBLOCK0, 4, PIN_P10_4}, {ADCBLOCK0, 5, PIN_P10_5} -}; //will belong to only a particular bsp +}; // will belong to only a particular bsp 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->adc_id, self->bits); + mp_printf(print, "ADCBlock(%u, bits=%u)", self->id, self->bits); } STATIC mp_obj_t machine_adcblock_make_new(const mp_obj_type_t *type, size_t n_pos_args, size_t n_kw_args, const mp_obj_t *all_args) { @@ -58,10 +48,10 @@ 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) + // 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 + // 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; @@ -71,7 +61,7 @@ STATIC mp_obj_t machine_adcblock_make_new(const mp_obj_type_t *type, size_t n_po return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t machine_adcblock_connect(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +/*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; if (n_pos_args == 2) { @@ -80,7 +70,7 @@ STATIC mp_obj_t machine_adcblock_connect(size_t n_pos_args, const mp_obj_t *pos_ if (mp_obj_is_int(pos_args[1])) { channel = mp_obj_get_int(pos_args[1]); if (channel <= 7) { - self->adc_pin = ch_pin_obj[channel].pin; + self->adc_pin = adc_block_pin_map[channel].pin; } } // TODO: generalize for (block, channel, pin) structure @@ -115,10 +105,10 @@ STATIC mp_obj_t machine_adcblock_connect(size_t n_pos_args, const mp_obj_t *pos_ //TODO: allocate it in the right channel index of the array. } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_adcblock_connect_obj, 2, machine_adcblock_connect); - +*/ STATIC const mp_rom_map_elem_t machine_adcblock_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&machine_adcblock_connect_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); diff --git a/ports/psoc6/modules/machine/machine_adcblock.h b/ports/psoc6/modules/machine/machine_adcblock.h index e359c8a1dd43..2d0786306cc9 100644 --- a/ports/psoc6/modules/machine/machine_adcblock.h +++ b/ports/psoc6/modules/machine/machine_adcblock.h @@ -5,12 +5,31 @@ #define DEFAULT_ADC_BITS 12 #define ADC_BLOCK_CHANNEL_MAX 6 +#define ADCBLOCK0 (0) +#define ADCBLOCK_CHANNEL_MAX (1) +#define MAX_BLOCKS (1) +#define MAX_CHANNELS (6) + +#include "pins.h" typedef struct _machine_adcblock_obj_t { mp_obj_base_t base; 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; + uint16_t channel; + 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 diff --git a/ports/psoc6/modules/machine/modmachine.c b/ports/psoc6/modules/machine/modmachine.c index 063a67e28c77..a39be4fcfda5 100644 --- a/ports/psoc6/modules/machine/modmachine.c +++ b/ports/psoc6/modules/machine/modmachine.c @@ -258,6 +258,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, + { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) },