Skip to content

Commit cedf648

Browse files
committed
Add voltage ADC, standardize mphalport
1 parent 4ba050d commit cedf648

File tree

3 files changed

+75
-72
lines changed

3 files changed

+75
-72
lines changed

ports/stm32f4/common-hal/microcontroller/Processor.c

Lines changed: 42 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,42 @@
3737
#define ADC_CAL_ADDRESS (0x1fff7a2a)
3838
#define ADC_CAL1 ((uint16_t*)(ADC_CAL_ADDRESS + 2))
3939
#define ADC_CAL2 ((uint16_t*)(ADC_CAL_ADDRESS + 4))
40+
#define VREFIN_CAL ((uint16_t *)ADC_CAL_ADDRESS)
4041

4142
// correction factor for reference value
4243
STATIC volatile float adc_refcor = 1.0f;
4344

44-
#define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resoultion) */
45-
#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */
45+
STATIC void set_adc_params(ADC_HandleTypeDef *AdcHandle) {
46+
AdcHandle->Instance = ADC1;
47+
AdcHandle->Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
48+
AdcHandle->Init.Resolution = ADC_RESOLUTION_12B;
49+
AdcHandle->Init.ScanConvMode = DISABLE;
50+
AdcHandle->Init.ContinuousConvMode = DISABLE;
51+
AdcHandle->Init.DiscontinuousConvMode = DISABLE;
52+
AdcHandle->Init.NbrOfDiscConversion = 0;
53+
AdcHandle->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
54+
AdcHandle->Init.ExternalTrigConv = ADC_SOFTWARE_START;
55+
AdcHandle->Init.DataAlign = ADC_DATAALIGN_RIGHT;
56+
AdcHandle->Init.NbrOfConversion = 1;
57+
AdcHandle->Init.DMAContinuousRequests = DISABLE;
58+
AdcHandle->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
59+
}
4660

4761
float common_hal_mcu_processor_get_temperature(void) {
4862
__HAL_RCC_ADC1_CLK_ENABLE();
4963

5064
//HAL Implementation
5165
ADC_HandleTypeDef AdcHandle;
5266
ADC_ChannelConfTypeDef sConfig;
53-
54-
AdcHandle.Instance = ADC1;
55-
AdcHandle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
56-
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
57-
AdcHandle.Init.ScanConvMode = DISABLE;
58-
AdcHandle.Init.ContinuousConvMode = DISABLE;
59-
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
60-
AdcHandle.Init.NbrOfDiscConversion = 0;
61-
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
62-
AdcHandle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
63-
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
64-
AdcHandle.Init.NbrOfConversion = 1;
65-
AdcHandle.Init.DMAContinuousRequests = DISABLE;
66-
AdcHandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
67+
set_adc_params(&AdcHandle);
6768
HAL_ADC_Init(&AdcHandle);
6869

6970
ADC->CCR |= ADC_CCR_TSVREFE;
7071
ADC->CCR &= ~ADC_CCR_VBATE; // If this somehow got turned on, it'll return bad values.
7172

7273
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; //either 16 or 18, depending on chip
7374
sConfig.Rank = 1;
74-
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; //Taken from micropython
75+
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; // Temp sensor likes 10us minimum
7576
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
7677

7778
HAL_ADC_Start(&AdcHandle);
@@ -84,50 +85,35 @@ float common_hal_mcu_processor_get_temperature(void) {
8485
//There's no F4 specific appnote for this but it works the same as the L1 in AN3964
8586
float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 80.0;
8687
return (((float)value * adc_refcor - *ADC_CAL1) / core_temp_avg_slope) + 30.0f;
87-
88-
// STATIC uint32_t adc_config_and_read_channel(ADC_HandleTypeDef *adcHandle, uint32_t channel) {
89-
// adc_config_channel(adcHandle, channel);
90-
// uint32_t raw_value = adc_read_channel(adcHandle);
91-
92-
// #if defined(STM32F4) || defined(STM32F7)
93-
// // ST docs say that (at least on STM32F42x and STM32F43x), VBATE must
94-
// // be disabled when TSVREFE is enabled for TEMPSENSOR and VREFINT
95-
// // conversions to work. VBATE is enabled by the above call to read
96-
// // the channel, and here we disable VBATE so a subsequent call for
97-
// // TEMPSENSOR or VREFINT works correctly.
98-
// if (channel == ADC_CHANNEL_VBAT) {
99-
// ADC->CCR &= ~ADC_CCR_VBATE;
100-
// }
101-
// #endif
102-
103-
// return raw_value;
104-
105-
// int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
106-
// int32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_TEMPSENSOR);
107-
// return ((raw_value - CORE_TEMP_V25) / CORE_TEMP_AVG_SLOPE) + 25;
108-
// }
109-
110-
// #if MICROPY_PY_BUILTINS_FLOAT
111-
// // correction factor for reference value
112-
// STATIC volatile float adc_refcor = 1.0f;
113-
114-
// float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
115-
// int32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_TEMPSENSOR);
116-
// float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 80.0;
117-
// return (((float)raw_value * adc_refcor - *ADC_CAL1) / core_temp_avg_slope) + 30.0f;
118-
// }
11988
}
12089

12190
float common_hal_mcu_processor_get_voltage(void) {
122-
// float adc_read_core_vref(ADC_HandleTypeDef *adcHandle) {
123-
// uint32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_VREFINT);
91+
__HAL_RCC_ADC1_CLK_ENABLE();
92+
93+
//HAL Implementation
94+
ADC_HandleTypeDef AdcHandle;
95+
ADC_ChannelConfTypeDef sConfig;
96+
set_adc_params(&AdcHandle);
97+
HAL_ADC_Init(&AdcHandle);
98+
99+
ADC->CCR |= ADC_CCR_TSVREFE;
100+
101+
sConfig.Channel = ADC_CHANNEL_VREFINT;
102+
sConfig.Rank = 1;
103+
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
104+
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
105+
106+
HAL_ADC_Start(&AdcHandle);
107+
if (HAL_ADC_PollForConversion(&AdcHandle,1) != HAL_OK) {
108+
mp_raise_RuntimeError(translate("Voltage read timed out"));
109+
}
110+
uint32_t value = (uint32_t)HAL_ADC_GetValue(&AdcHandle);
111+
HAL_ADC_Stop(&AdcHandle);
124112

125-
// // update the reference correction factor
126-
// adc_refcor = ((float)(*VREFIN_CAL)) / ((float)raw_value);
113+
//This value could be used to actively correct ADC values.
114+
adc_refcor = ((float)(*VREFIN_CAL)) / ((float)value);
127115

128-
// return (*VREFIN_CAL) * ADC_SCALE;
129-
// }
130-
return NAN;
116+
return adc_refcor * 3.3f;
131117
}
132118

133119
uint32_t common_hal_mcu_processor_get_frequency(void) {

ports/stm32f4/mphalport.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,15 @@
3131
#include "py/mpstate.h"
3232
#include "py/gc.h"
3333

34+
#include "shared-bindings/microcontroller/__init__.h"
3435
#include "supervisor/shared/tick.h"
36+
#include "stm32f4xx_hal.h"
3537

36-
/*------------------------------------------------------------------*/
37-
/* delay
38-
*------------------------------------------------------------------*/
3938
void mp_hal_delay_ms(mp_uint_t delay) {
4039
uint64_t start_tick = supervisor_ticks_ms64();
4140
uint64_t duration = 0;
4241
while (duration < delay) {
43-
#ifdef MICROPY_VM_HOOK_LOOP
44-
MICROPY_VM_HOOK_LOOP
45-
#endif
42+
RUN_BACKGROUND_TASKS;
4643
// Check to see if we've been CTRL-Ced by autoreload or the user.
4744
if(MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception)) ||
4845
MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
@@ -52,3 +49,15 @@ void mp_hal_delay_ms(mp_uint_t delay) {
5249
// TODO(tannewt): Go to sleep for a little while while we wait.
5350
}
5451
}
52+
53+
void mp_hal_delay_us(mp_uint_t delay) {
54+
common_hal_mcu_delay_us();
55+
}
56+
57+
void mp_hal_disable_all_interrupts(void) {
58+
common_hal_mcu_disable_interrupts();
59+
}
60+
61+
void mp_hal_enable_all_interrupts(void) {
62+
common_hal_mcu_enable_interrupts();
63+
}

ports/stm32f4/mphalport.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,28 @@
2424
* THE SOFTWARE.
2525
*/
2626

27-
#ifndef __STM32F4_HAL
28-
#define __STM32F4_HAL
27+
#ifndef MICROPY_INCLUDED_STM32F4_MPHALPORT_H
28+
#define MICROPY_INCLUDED_STM32F4_MPHALPORT_H
2929

30-
#include <stdbool.h>
31-
#include <stdint.h>
30+
#include "py/obj.h"
31+
32+
#include "lib/oofatfs/ff.h"
3233

33-
#include "lib/utils/interrupt_char.h"
34-
#include "py/mpconfig.h"
3534
#include "supervisor/shared/tick.h"
3635

36+
// Global millisecond tick count (driven by SysTick interrupt).
37+
static inline mp_uint_t mp_hal_ticks_ms(void) {
38+
return supervisor_ticks_ms32();
39+
}
40+
// Number of bytes in receive buffer
41+
volatile uint8_t usb_rx_count;
42+
volatile bool mp_cdc_enabled;
43+
44+
int receive_usb(void);
3745

38-
#define mp_hal_ticks_ms() ((mp_uint_t) supervisor_ticks_ms32())
39-
//#define mp_hal_delay_us(us) NRFX_DELAY_US((uint32_t) (us))
46+
void mp_hal_set_interrupt_char(int c);
4047

41-
bool mp_hal_stdin_any(void);
48+
void mp_hal_disable_all_interrupts(void);
49+
void mp_hal_enable_all_interrupts(void);
4250

43-
#endif
51+
#endif // MICROPY_INCLUDED_STM32F4_MPHALPORT_H

0 commit comments

Comments
 (0)