nrf5/adc: Updating adc module and hal with a new interface. No need for keeping peripheral base address in structure when there is only one peripheral (nrf51).

This commit is contained in:
Glenn Ruben Bakke 2017-01-12 17:20:08 +01:00
parent 24abb69eec
commit 6c54ed9a09
4 changed files with 72 additions and 101 deletions

View File

@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Glenn Ruben Bakke
* Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -40,6 +40,37 @@ typedef struct _machine_adc_obj_t {
ADC_HandleTypeDef *adc;
} machine_adc_obj_t;
ADC_HandleTypeDef ADCHandle0 = {.config.channel = 2};
ADC_HandleTypeDef ADCHandle1 = {.config.channel = 3};
ADC_HandleTypeDef ADCHandle2 = {.config.channel = 4};
ADC_HandleTypeDef ADCHandle3 = {.config.channel = 5};
ADC_HandleTypeDef ADCHandle4 = {.config.channel = 6};
ADC_HandleTypeDef ADCHandle5 = {.config.channel = 7};
STATIC const machine_adc_obj_t machine_adc_obj[] = {
{{&machine_adc_type}, &ADCHandle0},
{{&machine_adc_type}, &ADCHandle1},
{{&machine_adc_type}, &ADCHandle2},
{{&machine_adc_type}, &ADCHandle3},
{{&machine_adc_type}, &ADCHandle4},
{{&machine_adc_type}, &ADCHandle5},
};
STATIC int adc_find(mp_obj_t id) {
// given an integer id
int adc_id = mp_obj_get_int(id);
int adc_idx = adc_id - 2;
if (adc_idx >= 0 && adc_idx <= MP_ARRAY_SIZE(machine_adc_obj)
&& machine_adc_obj[adc_idx].adc != NULL) {
return adc_idx;
}
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"ADC(%d) does not exist", adc_id));
}
/// \method __str__()
/// Return a string describing the ADC object.
STATIC void machine_adc_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) {
@ -60,64 +91,36 @@ enum {
STATIC mp_obj_t machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
static const mp_arg_t allowed_args[] = {
{ ARG_NEW_PIN, MP_ARG_REQUIRED | MP_ARG_INT },
{ ARG_NEW_PIN, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1) } },
};
// parse args
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
machine_adc_obj_t *s = m_new_obj(machine_adc_obj_t);
s->base.type = type;
int adc_id = adc_find(args[ARG_NEW_PIN].u_obj);
const machine_adc_obj_t *self = &machine_adc_obj[adc_id];
mp_int_t channel_num;
if (args[ARG_NEW_PIN].u_int > 0) {
channel_num = args[ARG_NEW_PIN].u_int;
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"Channel number not set"));
}
s->adc->init.channel = channel_num;
hal_adc_init(ADC_BASE, &s->adc->init);
return MP_OBJ_FROM_PTR(s);
return MP_OBJ_FROM_PTR(self);
}
/// \method init()
mp_obj_t machine_adc_init(mp_obj_t self_in) {
hal_adc_start(ADC_BASE);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_machine_adc_init_obj, machine_adc_init);
/// \method deinit()
mp_obj_t machine_adc_deinit(mp_obj_t self_in) {
hal_adc_stop(ADC_BASE);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_machine_adc_deinit_obj, machine_adc_deinit);
/// \method value()
/// Read adc level.
mp_obj_t machine_adc_value(mp_obj_t self_in) {
return MP_OBJ_NEW_SMALL_INT(hal_adc_value(ADC_BASE));
machine_adc_obj_t *self = self_in;
return MP_OBJ_NEW_SMALL_INT(hal_adc_channel_value(&self->adc->config));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_machine_adc_value_obj, machine_adc_value);
/// \method battery_level()
/// Get battery level in percentage.
mp_obj_t machine_adc_battery_level(void) {
return MP_OBJ_NEW_SMALL_INT(hal_adc_battery_level(ADC_BASE));
return MP_OBJ_NEW_SMALL_INT(hal_adc_battery_level());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_machine_adc_battery_level_obj, machine_adc_battery_level);
STATIC const mp_map_elem_t machine_adc_locals_dict_table[] = {
// instance methods
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&mp_machine_adc_init_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&mp_machine_adc_deinit_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&mp_machine_adc_value_obj },
// class methods

View File

@ -70,75 +70,60 @@ static uint8_t battery_level_in_percent(const uint16_t mvolts)
return battery_level;
}
void hal_adc_init(HAL_ADC_Type * p_instance, hal_adc_init_t const * p_adc_init) {
while (p_instance->ENABLE && p_instance->BUSY)
{
// spin loop if another user is in progress of sampling
}
p_instance->INTENSET = ADC_INTENSET_END_Msk;
p_instance->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos)
uint16_t hal_adc_channel_value(hal_adc_config_t const * p_adc_conf) {
ADC_BASE->INTENSET = ADC_INTENSET_END_Msk;
ADC_BASE->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos)
| (ADC_CONFIG_INPSEL_AnalogInputTwoThirdsPrescaling << ADC_CONFIG_INPSEL_Pos)
| (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)
| (hal_adc_input_lookup[p_adc_init->channel])
| (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
}
| (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)
| (hal_adc_input_lookup[p_adc_conf->channel])
| (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
void hal_adc_start(HAL_ADC_Type * p_instance) {
p_instance->ENABLE = ADC_ENABLE_ENABLE_Enabled;
}
ADC_BASE->EVENTS_END = 0;
ADC_BASE->ENABLE = ADC_ENABLE_ENABLE_Enabled;
void hal_adc_stop(HAL_ADC_Type * p_instance) {
p_instance->ENABLE = ADC_ENABLE_ENABLE_Disabled;
}
ADC_BASE->EVENTS_END = 0;
ADC_BASE->TASKS_START = 1;
uint8_t hal_adc_value(HAL_ADC_Type * p_instance) {
p_instance->EVENTS_END = 0;
p_instance->TASKS_START = 1;
while (!p_instance->EVENTS_END) {
while (!ADC_BASE->EVENTS_END) {
;
}
uint8_t adc_result = p_instance->RESULT;
uint8_t adc_result;
p_instance->EVENTS_END = 0;
p_instance->TASKS_STOP = 1;
ADC_BASE->EVENTS_END = 0;
adc_result = ADC_BASE->RESULT;
ADC_BASE->TASKS_STOP = 1;
return adc_result;
}
uint8_t hal_adc_battery_level(HAL_ADC_Type * p_instance) {
p_instance->INTENSET = ADC_INTENSET_END_Msk;
p_instance->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos)
uint16_t hal_adc_battery_level(void) {
ADC_BASE->INTENSET = ADC_INTENSET_END_Msk;
ADC_BASE->CONFIG = (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos)
| (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos)
| (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)
| (ADC_CONFIG_PSEL_Disabled << ADC_CONFIG_PSEL_Pos)
| (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
p_instance->EVENTS_END = 0;
p_instance->ENABLE = ADC_ENABLE_ENABLE_Enabled;
ADC_BASE->EVENTS_END = 0;
ADC_BASE->ENABLE = ADC_ENABLE_ENABLE_Enabled;
p_instance->EVENTS_END = 0;
p_instance->TASKS_START = 1;
ADC_BASE->EVENTS_END = 0;
ADC_BASE->TASKS_START = 1;
while (!p_instance->EVENTS_END) {
while (!ADC_BASE->EVENTS_END) {
;
}
uint8_t adc_result;
uint16_t batt_lvl_in_milli_volts;
p_instance->EVENTS_END = 0;
adc_result = p_instance->RESULT;
p_instance->TASKS_STOP = 1;
ADC_BASE->EVENTS_END = 0;
adc_result = ADC_BASE->RESULT;
ADC_BASE->TASKS_STOP = 1;
batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS;
return battery_level_in_percent(batt_lvl_in_milli_volts);
}
#endif // HAL_ADC_MODULE_ENABLED

View File

@ -59,25 +59,17 @@ typedef enum {
*/
typedef struct {
hal_adc_channel_t channel;
} hal_adc_init_t;
} hal_adc_config_t;
/**
* @brief ADC handle Structure definition
*/
typedef struct __ADC_HandleTypeDef
{
void *instance; /* ADC register base address */
hal_adc_init_t init; /* ADC initialization parameters */
typedef struct __ADC_HandleTypeDef {
hal_adc_config_t config; /* ADC config parameters */
} ADC_HandleTypeDef;
void hal_adc_init(HAL_ADC_Type * p_instance, hal_adc_init_t const * p_adc_init);
uint16_t hal_adc_channel_value(hal_adc_config_t const * p_adc_conf);
void hal_adc_start(HAL_ADC_Type * p_instance);
void hal_adc_stop(HAL_ADC_Type * p_instance);
uint8_t hal_adc_value(HAL_ADC_Type * p_instance);
uint8_t hal_adc_battery_level(HAL_ADC_Type * p_instance);
uint16_t hal_adc_battery_level(void);
#endif // HAL_ADC_H__

View File

@ -29,20 +29,11 @@
#ifdef HAL_ADCE_MODULE_ENABLED
void hal_adc_init(HAL_ADC_Type * p_instance, hal_adc_init_t const * p_adc_init) {
}
void hal_adc_start(HAL_ADC_Type * p_instance) {
}
void hal_adc_stop(HAL_ADC_Type * p_instance) {
}
uint8_t hal_adc_value(HAL_ADC_Type * p_instance) {
uint16_t hal_adc_channel_value(hal_adc_config_t const * p_adc_conf) {
return 0;
}
uint8_t hal_adc_battery_level(HAL_ADC_Type * p_instance) {
uint16_t hal_adc_battery_level(void) {
return 0;
}