Skip to content

Commit

Permalink
ports/psoc6/modules/machine/machine_adc: WIP refactor relationship.
Browse files Browse the repository at this point in the history
Signed-off-by: enriquezgarc <[email protected]>
  • Loading branch information
jaenrig-ifx committed Jul 25, 2023
1 parent 0305be0 commit 22856c1
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 155 deletions.
155 changes: 29 additions & 126 deletions ports/psoc6/modules/machine/machine_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, "<ADC Pin=%u, Channel=%d, sampling_time_ns=%ld>", self->pin, self->block->ch, self->sample_ns);
return;
machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "<ADC Pin=%u, ADCBlock_id=%d, sampling_time_ns=%ld>", 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;
}
Expand All @@ -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);
}
Expand All @@ -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);

Expand Down
4 changes: 1 addition & 3 deletions ports/psoc6/modules/machine/machine_adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
136 changes: 119 additions & 17 deletions ports/psoc6/modules/machine/machine_adcblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -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);
Expand All @@ -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);

Expand All @@ -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) {
Expand Down
Loading

0 comments on commit 22856c1

Please sign in to comment.