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) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -40,6 +40,37 @@ typedef struct _machine_adc_obj_t {
ADC_HandleTypeDef *adc; ADC_HandleTypeDef *adc;
} machine_adc_obj_t; } 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__() /// \method __str__()
/// Return a string describing the ADC object. /// 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) { 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 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[] = { 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 // parse args
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_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); 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); int adc_id = adc_find(args[ARG_NEW_PIN].u_obj);
s->base.type = type; const machine_adc_obj_t *self = &machine_adc_obj[adc_id];
mp_int_t channel_num; return MP_OBJ_FROM_PTR(self);
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);
}
/// \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() /// \method value()
/// Read adc level. /// Read adc level.
mp_obj_t machine_adc_value(mp_obj_t self_in) { 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); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_machine_adc_value_obj, machine_adc_value);
/// \method battery_level() /// \method battery_level()
/// Get battery level in percentage. /// Get battery level in percentage.
mp_obj_t machine_adc_battery_level(void) { 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 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[] = { STATIC const mp_map_elem_t machine_adc_locals_dict_table[] = {
// instance methods // 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 }, { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&mp_machine_adc_value_obj },
// class methods // class methods

View File

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

View File

@ -59,25 +59,17 @@ typedef enum {
*/ */
typedef struct { typedef struct {
hal_adc_channel_t channel; hal_adc_channel_t channel;
} hal_adc_init_t; } hal_adc_config_t;
/** /**
* @brief ADC handle Structure definition * @brief ADC handle Structure definition
*/ */
typedef struct __ADC_HandleTypeDef typedef struct __ADC_HandleTypeDef {
{ hal_adc_config_t config; /* ADC config parameters */
void *instance; /* ADC register base address */
hal_adc_init_t init; /* ADC initialization parameters */
} ADC_HandleTypeDef; } 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); uint16_t hal_adc_battery_level(void);
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);
#endif // HAL_ADC_H__ #endif // HAL_ADC_H__

View File

@ -29,20 +29,11 @@
#ifdef HAL_ADCE_MODULE_ENABLED #ifdef HAL_ADCE_MODULE_ENABLED
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) {
return 0; return 0;
} }
uint8_t hal_adc_battery_level(HAL_ADC_Type * p_instance) { uint16_t hal_adc_battery_level(void) {
return 0; return 0;
} }