summaryrefslogtreecommitdiff
path: root/ports/stm32/adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/adc.c')
-rw-r--r--ports/stm32/adc.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c
index 27f6c5c23..326fc97b2 100644
--- a/ports/stm32/adc.c
+++ b/ports/stm32/adc.c
@@ -107,7 +107,7 @@
#define ADC_CAL2 ((uint16_t *)(ADC_CAL_ADDRESS + 4))
#define ADC_CAL_BITS (12)
-#elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB)
+#elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L1) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)
#define ADC_SCALE_V (((float)VREFINT_CAL_VREF) / 1000.0f)
#define ADC_CAL_ADDRESS (VREFINT_CAL_ADDR)
@@ -116,6 +116,8 @@
#if defined(STM32H7)
#define ADC_CAL_BITS (16)
+#elif defined(STM32U5)
+#define ADC_CAL_BITS (14)
#else
#define ADC_CAL_BITS (12) // UM2319/UM2570, __HAL_ADC_CALC_TEMPERATURE: 'corresponds to a resolution of 12 bits'
#endif
@@ -166,6 +168,8 @@
#elif defined(STM32N6)
// ADC2 VINP 16
#define VBAT_DIV (4)
+#elif defined(STM32U5)
+#define VBAT_DIV (4)
#else
#error Unsupported processor
#endif
@@ -233,6 +237,14 @@ static inline uint32_t adc_get_internal_channel(uint32_t channel) {
} else if (channel == 18) {
channel = ADC_CHANNEL_VBAT;
}
+ #elif defined(STM32U5)
+ if (channel == 0) {
+ channel = ADC_CHANNEL_VREFINT;
+ } else if (channel == 18) {
+ channel = ADC_CHANNEL_VBAT;
+ } else if (channel == 19) {
+ channel = ADC_CHANNEL_TEMPSENSOR;
+ }
#endif
return channel;
}
@@ -247,7 +259,7 @@ static bool is_adcx_channel(int channel) {
// The HAL of STM32L1 defines some channels those may not be available on package
return __HAL_ADC_IS_CHANNEL_INTERNAL(channel)
|| (channel < MP_ARRAY_SIZE(pin_adcall_table) && pin_adcall_table[channel]);
- #elif defined(STM32G0) || defined(STM32H7)
+ #elif defined(STM32G0) || defined(STM32H7) || defined(STM32U5)
return __HAL_ADC_IS_CHANNEL_INTERNAL(channel)
|| IS_ADC_CHANNEL(__HAL_ADC_DECIMAL_NB_TO_CHANNEL(channel));
#elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
@@ -268,7 +280,7 @@ static void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t ti
uint32_t tickstart = HAL_GetTick();
#if defined(STM32F4) || defined(STM32F7) || defined(STM32L1)
while ((adcHandle->Instance->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
- #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)
while (READ_BIT(adcHandle->Instance->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {
#else
#error Unsupported processor
@@ -303,6 +315,8 @@ static void adcx_clock_enable(ADC_HandleTypeDef *adch) {
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);
}
__HAL_RCC_ADC_CLK_ENABLE();
+ #elif defined(STM32U5)
+ __HAL_RCC_ADC12_CLK_ENABLE();
#else
#error Unsupported processor
#endif
@@ -353,12 +367,12 @@ static void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
adch->Init.LowPowerAutoWait = DISABLE;
adch->Init.DataAlign = ADC_DATAALIGN_RIGHT;
adch->Init.DMAContinuousRequests = DISABLE;
- #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32U5) || defined(STM32WB)
#if defined(STM32G0)
adch->Init.SamplingTimeCommon1 = ADC_SAMPLETIME_12CYCLES_5;
adch->Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
#endif
- #if defined(STM32G4) || defined(STM32H5)
+ #if defined(STM32G4) || defined(STM32H5) || defined(STM32U5)
adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV16;
#else
adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
@@ -369,6 +383,12 @@ static void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
adch->Init.OversamplingMode = DISABLE;
adch->Init.DataAlign = ADC_DATAALIGN_RIGHT;
adch->Init.DMAContinuousRequests = DISABLE;
+ #if defined(STM32U5)
+ adch->Init.GainCompensation = 0;
+ adch->Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
+ adch->Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
+ adch->Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
+ #endif
#elif defined(STM32N6)
adch->Init.GainCompensation = 0;
adch->Init.ScanConvMode = ADC_SCAN_DISABLE;
@@ -384,7 +404,7 @@ static void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
HAL_ADC_Init(adch);
- #if defined(STM32H7)
+ #if defined(STM32H7) || defined(STM32U5)
HAL_ADCEx_Calibration_Start(adch, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
#endif
#if defined(STM32G0)
@@ -415,6 +435,8 @@ static void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel) == 0) {
channel = __HAL_ADC_DECIMAL_NB_TO_CHANNEL(channel);
}
+ #elif defined(STM32U5)
+ sConfig.Rank = ADC_REGULAR_RANK_1;
#else
sConfig.Rank = 1;
#endif
@@ -471,6 +493,15 @@ static void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
sConfig.OffsetSignedSaturation = DISABLE;
sConfig.OffsetSaturation = DISABLE;
sConfig.OffsetSign = ADC_OFFSET_SIGN_POSITIVE;
+ #elif defined(STM32U5)
+ if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) {
+ sConfig.SamplingTime = ADC_SAMPLETIME_391CYCLES_5;
+ } else {
+ sConfig.SamplingTime = ADC4_SAMPLETIME_3CYCLES_5;
+ }
+ sConfig.SingleDiff = ADC_SINGLE_ENDED;
+ sConfig.OffsetNumber = ADC_OFFSET_NONE;
+ sConfig.Offset = 0;
#else
#error Unsupported processor
#endif
@@ -692,7 +723,7 @@ static mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
// for subsequent samples we can just set the "start sample" bit
#if defined(STM32F4) || defined(STM32F7) || defined(STM32L1)
self->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
- #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)
SET_BIT(self->handle.Instance->CR, ADC_CR_ADSTART);
#else
#error Unsupported processor
@@ -802,7 +833,7 @@ static mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i
// ADC is started: set the "start sample" bit
#if defined(STM32F4) || defined(STM32F7) || defined(STM32L1)
adc->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
- #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32U5) || defined(STM32WB)
SET_BIT(adc->handle.Instance->CR, ADC_CR_ADSTART);
#else
#error Unsupported processor
@@ -953,7 +984,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
return 0.0f; // TODO
#else
- #if defined(STM32G0) || defined(STM32G4) || defined(STM32L1) || defined(STM32L4)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32L1) || defined(STM32L4) || defined(STM32U5)
// Update the reference correction factor before reading tempsensor
// because TS_CAL1 and TS_CAL2 of STM32G0,G4,L1,L4 are at VDDA=3.0V
adc_read_core_vref(adcHandle);
@@ -967,7 +998,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
return 0;
}
float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 100.0f;
- #elif defined(STM32H5) || defined(STM32WB)
+ #elif defined(STM32H5) || defined(STM32U5) || defined(STM32WB)
int32_t raw_value = adc_config_and_read_ref(adcHandle, ADC_CHANNEL_TEMPSENSOR);
float core_temp_avg_slope = (*ADC_CAL2 - *ADC_CAL1) / 100.0f;
#else
@@ -980,7 +1011,7 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
}
float adc_read_core_vbat(ADC_HandleTypeDef *adcHandle) {
- #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32U5)
// Update the reference correction factor before reading tempsensor
// because VREFINT of STM32G0,G4,L4 is at VDDA=3.0V
adc_read_core_vref(adcHandle);