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:
parent
24abb69eec
commit
6c54ed9a09
75
nrf5/adc.c
75
nrf5/adc.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue