Skip to content

Commit

Permalink
ports/psoc6: Refactor ADC WIP.
Browse files Browse the repository at this point in the history
Signed-off-by: NikhitaR-IFX <[email protected]>
  • Loading branch information
NikhitaR-IFX authored and jaenrig-ifx committed Jul 25, 2023
1 parent 8645852 commit cbe5fdd
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 50 deletions.
147 changes: 121 additions & 26 deletions ports/psoc6/modules/machine/machine_adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "modmachine.h"
#include "pins.h"
#include "machine_adc.h"
#include "machine_adcblock.h"

#include "cybsp.h"
#include "cyhal.h"
Expand All @@ -16,18 +17,106 @@

#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;

/******************************************************************************/
// 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;
}

// 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, "<ADC Pin=%u, Channel=%d, sampling_time_ns=%ld>", self->adc_pin, self->block->ch, self->sample_ns);
// 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;
}

Expand All @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions ports/psoc6/modules/machine/machine_adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
32 changes: 11 additions & 21 deletions ports/psoc6/modules/machine/machine_adcblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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);

Expand Down
21 changes: 20 additions & 1 deletion ports/psoc6/modules/machine/machine_adcblock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions ports/psoc6/modules/machine/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) },
Expand Down

0 comments on commit cbe5fdd

Please sign in to comment.