Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ports/psoc6/modules/machine/machine_adc: WIP refactor relationship. #70

Merged
merged 2 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 30 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,64 @@

#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);
extern machine_adc_obj_t *adc_block_allocate_new_pin(machine_adcblock_obj_t *adc_block, uint32_t pin);

/******************************************************************************/
// 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 = adc_block_allocate_new_pin(adc_block, pin);
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 +99,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 +114,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
144 changes: 127 additions & 17 deletions ports/psoc6/modules/machine/machine_adcblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
#include "modmachine.h"

#include "machine_adcblock.h"
#include "pins.h"
#include "machine_adc.h"
#include "pins.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 +20,128 @@ 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_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);

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 +152,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 +168,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
Loading