summaryrefslogtreecommitdiffstatshomepage
path: root/stm/adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'stm/adc.c')
-rw-r--r--stm/adc.c446
1 files changed, 0 insertions, 446 deletions
diff --git a/stm/adc.c b/stm/adc.c
deleted file mode 100644
index ad11f8fdd4..0000000000
--- a/stm/adc.c
+++ /dev/null
@@ -1,446 +0,0 @@
-#include <stdio.h>
-#include <stm32f4xx.h>
-
-#include "mpconfig.h"
-#include "misc.h"
-#include "nlr.h"
-#include "qstr.h"
-#include "obj.h"
-#include "adc.h"
-
-/* ADC defintions */
-#define ADCx (ADC1)
-#define ADCx_CLK (RCC_APB2Periph_ADC1)
-#define ADC_NUM_CHANNELS (16)
-
-/* Internally connected ADC channels Temp/VBAT/VREF*/
-#if defined (STM32F40XX) || defined(STM32F41XX) || defined(STM32F40_41xxx)
-#define ADC_TEMP_CHANNEL (16)
-#define ADC_VBAT_CHANNEL (18)
-#define ADC_VREF_CHANNEL (17)
-#elif defined (STM32F42XX) || defined(STM32F43XX)
-#define ADC_TEMP_CHANNEL (18)
-#define ADC_VBAT_CHANNEL (18) /* same channel as TEMP */
-#define ADC_VREF_CHANNEL (17)
-#endif
-
-/* Core temperature sensor definitions */
-#define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resoultion) */
-#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */
-
-/* VBAT divider */
-#if defined (STM32F40XX) || defined(STM32F41XX) || defined(STM32F40_41xxx)
-#define VBAT_DIV (2)
-#elif defined (STM32F42XX) || defined(STM32F43XX)
-#define VBAT_DIV (4)
-#endif
-
-/* GPIO struct */
-typedef struct {
- GPIO_TypeDef* port;
- uint32_t pin;
-} gpio_t;
-
-/* ADC GPIOs */
-static const gpio_t adc_gpio[] = {
- {GPIOA, GPIO_Pin_0}, /* ADC123_IN0 */
- {GPIOA, GPIO_Pin_1}, /* ADC123_IN1 */
- {GPIOA, GPIO_Pin_2}, /* ADC123_IN2 */
- {GPIOA, GPIO_Pin_3}, /* ADC123_IN3 */
- {GPIOA, GPIO_Pin_4}, /* ADC12_IN4 */
- {GPIOA, GPIO_Pin_5}, /* ADC12_IN5 */
- {GPIOA, GPIO_Pin_6}, /* ADC12_IN6 */
- {GPIOA, GPIO_Pin_7}, /* ADC12_IN7 */
- {GPIOB, GPIO_Pin_0}, /* ADC12_IN8 */
- {GPIOB, GPIO_Pin_1}, /* ADC12_IN9 */
- {GPIOC, GPIO_Pin_0}, /* ADC123_IN10 */
- {GPIOC, GPIO_Pin_1}, /* ADC123_IN11 */
- {GPIOC, GPIO_Pin_2}, /* ADC123_IN12 */
- {GPIOC, GPIO_Pin_3}, /* ADC123_IN13 */
- {GPIOC, GPIO_Pin_4}, /* ADC12_IN14 */
- {GPIOC, GPIO_Pin_5}, /* ADC12_IN15 */
-
-};
-
-void adc_init_all(uint32_t resolution) {
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- ADC_CommonInitTypeDef ADC_CommonInitStructure;
-
- /* Enable ADCx, DMA and GPIO clocks */
-#if 0
- /* GPIO clocks enabled in main */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
- RCC_AHB1Periph_GPIOB |
- RCC_AHB1Periph_GPIOC, ENABLE);
-#endif
- RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
-
- /* ADC Common Init */
- ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
- ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
- ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
- ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
- ADC_CommonInit(&ADC_CommonInitStructure);
-
- /* Configure ADC GPIOs */
- for (int i=0; i<ADC_NUM_CHANNELS; i++) {
- GPIO_InitStructure.GPIO_Pin = adc_gpio[i].pin;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(adc_gpio[i].port, &GPIO_InitStructure);
- }
-
- /* ADCx Init */
-// ADC_DeInit();
- ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfConversion = 1;
- ADC_Init(ADCx, &ADC_InitStructure);
-
- /* Enable ADCx */
- ADC_Cmd(ADCx, ENABLE);
-
- /* Enable VBAT/VREF monitor */
- ADC_VBATCmd(ENABLE);
-
- /* Enable temperature sensor */
- ADC_TempSensorVrefintCmd(ENABLE);
-}
-
-void adc_init_single(uint32_t channel) {
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- ADC_CommonInitTypeDef ADC_CommonInitStructure;
-
- /* Enable ADCx, DMA and GPIO clocks */
-#if 0
- /* GPIO clocks enabled in main */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
- RCC_AHB1Periph_GPIOB |
- RCC_AHB1Periph_GPIOC, ENABLE);
-#endif
- RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
-
- /* ADC Common Init */
- ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
- ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
- ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
- ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
- ADC_CommonInit(&ADC_CommonInitStructure);
-
- /* Configure ADC GPIO for the single channel */
- GPIO_InitStructure.GPIO_Pin = adc_gpio[channel].pin;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(adc_gpio[channel].port, &GPIO_InitStructure);
-
- /* ADCx Init */
-// ADC_DeInit();
- ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE;
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
- ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfConversion = 1;
- ADC_Init(ADCx, &ADC_InitStructure);
-
- /* Enable ADCx */
- ADC_Cmd(ADCx, ENABLE);
-
- /* Enable VBAT/VREF monitor */
- ADC_VBATCmd(ENABLE);
-
- /* Enable temperature sensor */
- ADC_TempSensorVrefintCmd(ENABLE);
-}
-
-uint32_t adc_read_channel(int channel)
-{
- int timeout = 10000;
-
- if (channel > (ADC_NUM_CHANNELS-1)) {
- return 0;
- }
-
- /* ADC regular channel config ADC/Channel/SEQ Rank/Sample time */
- ADC_RegularChannelConfig(ADCx, channel, 1, ADC_SampleTime_15Cycles);
-
- /* Start ADC single conversion */
- ADC_SoftwareStartConv(ADCx);
-
- /* Wait for conversion to be complete*/
- while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
- }
-
- /* ADC conversion timed out */
- if (timeout == 0) {
- return 0;
- }
-
- /* Return converted data */
- return ADC_GetConversionValue(ADCx);
-}
-
-int adc_read_core_temp()
-{
- int timeout = 10000;
-
- /* ADC temperature sensor channel config ADC/Channel/SEQ Rank/Sample time */
- /* Note: sample time must be higher than minimum sample time */
- ADC_RegularChannelConfig(ADCx, ADC_TEMP_CHANNEL, 1, ADC_SampleTime_480Cycles);
-
- /* Start ADC single conversion */
- ADC_SoftwareStartConv(ADCx);
-
- /* Wait for conversion to be complete*/
- while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
- }
-
- /* ADC conversion timed out */
- if (timeout == 0) {
- return 0;
- }
-
- /* Convert ADC reading to temperature */
- /* Temperature formula from datasheet P.411 */
- return ((ADC_GetConversionValue(ADCx) - CORE_TEMP_V25) / CORE_TEMP_AVG_SLOPE) + 25;
-}
-
-float adc_read_core_vbat()
-{
- int timeout = 10000;
-
- /* ADC VBAT channel config ADC/Channel/SEQ Rank/Sample time */
- /* Note: sample time must be higher than minimum sample time */
- ADC_RegularChannelConfig(ADCx, ADC_VBAT_CHANNEL, 1, ADC_SampleTime_144Cycles);
-
- /* Start ADC single conversion */
- ADC_SoftwareStartConv(ADCx);
-
- /* Wait for conversion to be complete */
- while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
- }
-
- /* ADC conversion timed out */
- if (timeout == 0) {
- return 0;
- }
-
- /* Convert ADC reading to voltage, VBAT pin is
- internally connected to a bridge divider by VBAT_DIV */
- return ADC_GetConversionValue(ADCx)*VBAT_DIV/4096.0f*3.3f;
-}
-
-float adc_read_core_vref()
-{
- int timeout = 10000;
-
- /* ADC VBAT channel config ADC/Channel/SEQ Rank/Sample time */
- /* Note: sample time must be higher than minimum sample time */
- ADC_RegularChannelConfig(ADCx, ADC_VREF_CHANNEL, 1, ADC_SampleTime_112Cycles);
-
- /* Start ADC single conversion */
- ADC_SoftwareStartConv(ADCx);
-
- /* Wait for conversion to be complete*/
- while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
- }
-
- /* ADC conversion timed out */
- if (timeout == 0) {
- return 0;
- }
-
- /* Convert ADC reading to voltage */
- return ADC_GetConversionValue(ADCx)/4096.0f*3.3f;
-}
-
-/******************************************************************************/
-/* Micro Python bindings : adc_all object */
-
-typedef struct _pyb_obj_adc_all_t {
- mp_obj_base_t base;
- bool is_enabled;
-} pyb_obj_adc_all_t;
-
-static void adc_all_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
- print(env, "<ADC all>");
-}
-
-static mp_obj_t adc_all_read_channel(mp_obj_t self_in, mp_obj_t channel) {
- pyb_obj_adc_all_t *self = self_in;
-
- if (self->is_enabled) {
- uint32_t chan = mp_obj_get_int(channel);
- uint32_t data = adc_read_channel(chan);
- return mp_obj_new_int(data);
- } else {
- return mp_const_none;
- }
-}
-
-static mp_obj_t adc_all_read_core_temp(mp_obj_t self_in) {
- pyb_obj_adc_all_t *self = self_in;
-
- if (self->is_enabled) {
- int data = adc_read_core_temp();
- return mp_obj_new_int(data);
- } else {
- return mp_const_none;
- }
-}
-
-static mp_obj_t adc_all_read_core_vbat(mp_obj_t self_in) {
- pyb_obj_adc_all_t *self = self_in;
-
- if (self->is_enabled) {
- float data = adc_read_core_vbat();
- return mp_obj_new_float(data);
- } else {
- return mp_const_none;
- }
-}
-
-static mp_obj_t adc_all_read_core_vref(mp_obj_t self_in) {
- pyb_obj_adc_all_t *self = self_in;
-
- if (self->is_enabled) {
- float data = adc_read_core_vref();
- return mp_obj_new_float(data);
- } else {
- return mp_const_none;
- }
-}
-
-static MP_DEFINE_CONST_FUN_OBJ_2(adc_all_read_channel_obj, adc_all_read_channel);
-static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_temp_obj, adc_all_read_core_temp);
-static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vbat_obj, adc_all_read_core_vbat);
-static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vref_obj, adc_all_read_core_vref);
-
-STATIC const mp_map_elem_t adc_all_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_channel), (mp_obj_t) &adc_all_read_channel_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_temp), (mp_obj_t)&adc_all_read_core_temp_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vbat), (mp_obj_t)&adc_all_read_core_vbat_obj},
- { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vref), (mp_obj_t)&adc_all_read_core_vref_obj},
-};
-
-STATIC MP_DEFINE_CONST_DICT(adc_all_locals_dict, adc_all_locals_dict_table);
-
-static const mp_obj_type_t adc_all_type = {
- { &mp_type_type },
- .name = MP_QSTR_ADC,
- .print = adc_all_print,
- .locals_dict = (mp_obj_t)&adc_all_locals_dict,
-};
-
-mp_obj_t pyb_ADC_all(mp_obj_t resolution) {
- /* init ADC */
- adc_init_all(mp_obj_get_int(resolution));
-
- pyb_obj_adc_all_t *o = m_new_obj(pyb_obj_adc_all_t);
- o->base.type = &adc_all_type;
- o->is_enabled = true;
- return o;
-}
-
-MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_all_obj, pyb_ADC_all);
-
-/******************************************************************************/
-/* Micro Python bindings : adc object (single channel) */
-
-typedef struct _pyb_obj_adc_t {
- mp_obj_base_t base;
- mp_obj_t pin_name;
- int channel;
- bool is_enabled;
-} pyb_obj_adc_t;
-
-static void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
- pyb_obj_adc_t *self = self_in;
- print(env, "<ADC on ");
- mp_obj_print_helper(print, env, self->pin_name, PRINT_STR);
- print(env, " channel=%lu>", self->channel);
-}
-
-static mp_obj_t adc_read(mp_obj_t self_in) {
- pyb_obj_adc_t *self = self_in;
-
- if (self->is_enabled) {
- uint32_t data = adc_read_channel(self->channel);
- return mp_obj_new_int(data);
- } else {
- return mp_const_none;
- }
-}
-
-static MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
-
-STATIC const mp_map_elem_t adc_locals_dict_table[] = {
- { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj},
-};
-
-STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
-
-static const mp_obj_type_t adc_type = {
- { &mp_type_type },
- .name = MP_QSTR_ADC,
- .print = adc_print,
- .locals_dict = (mp_obj_t)&adc_locals_dict,
-};
-
-mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) {
-
- pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t);
- o->base.type = &adc_type;
- o->pin_name = pin_name_obj;
-
- // work out the channel from the pin name
- const char *pin_name = mp_obj_str_get_str(pin_name_obj);
- GPIO_TypeDef *port;
- switch (pin_name[0]) {
- case 'A': case 'a': port = GPIOA; break;
- case 'B': case 'b': port = GPIOB; break;
- case 'C': case 'c': port = GPIOC; break;
- default: goto pin_error;
- }
- uint pin_num = 0;
- for (const char *s = pin_name + 1; *s; s++) {
- if (!('0' <= *s && *s <= '9')) {
- goto pin_error;
- }
- pin_num = 10 * pin_num + *s - '0';
- }
- if (!(0 <= pin_num && pin_num <= 15)) {
- goto pin_error;
- }
-
- int i;
- for (i = 0; i < ADC_NUM_CHANNELS; i++) {
- if (adc_gpio[i].port == port && adc_gpio[i].pin == (1 << pin_num)) {
- o->channel = i;
- break;
- }
- }
-
- if (i == ADC_NUM_CHANNELS) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not have ADC capabilities", pin_name));
- }
-
- // init ADC just for this channel
- adc_init_single(o->channel);
-
- o->is_enabled = true;
-
- return o;
-
-pin_error:
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not exist", pin_name));
-}
-
-MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_obj, pyb_ADC);