diff options
Diffstat (limited to 'ports/stm32/machine_adc.c')
-rw-r--r-- | ports/stm32/machine_adc.c | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c index c3211ea4f4..63cd4e089d 100644 --- a/ports/stm32/machine_adc.c +++ b/ports/stm32/machine_adc.c @@ -30,7 +30,7 @@ #include "py/mphal.h" #include "adc.h" -#if defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL) +#if defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) || defined(STM32WL) #define ADC_V2 (1) #else #define ADC_V2 (0) @@ -80,11 +80,14 @@ #define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_12CYCLES_5 #define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_160CYCLES_5 #elif defined(STM32L1) -#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_384CYCLES +#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_16CYCLES #define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_384CYCLES #elif defined(STM32L4) || defined(STM32WB) #define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_12CYCLES_5 #define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_247CYCLES_5 +#elif defined(STM32N6) +#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_11CYCLES_5 +#define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_246CYCLES_5 #endif // Timeout for waiting for end-of-conversion @@ -127,6 +130,8 @@ static uint32_t adc_ll_channel(uint32_t channel_id) { case MACHINE_ADC_INT_CH_TEMPSENSOR: #if defined(STM32G4) adc_ll_ch = ADC_CHANNEL_TEMPSENSOR_ADC1; + #elif defined(STM32N6) + adc_ll_ch = ADC_CHANNEL_0; // TODO #else adc_ll_ch = ADC_CHANNEL_TEMPSENSOR; #endif @@ -183,7 +188,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) { if (adc == ADC1) { #if defined(STM32H5) __HAL_RCC_ADC_CLK_ENABLE(); - #elif defined(STM32G4) || defined(STM32H7) + #elif defined(STM32G4) || defined(STM32H7) || defined(STM32N6) __HAL_RCC_ADC12_CLK_ENABLE(); #else __HAL_RCC_ADC1_CLK_ENABLE(); @@ -193,7 +198,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) { if (adc == ADC2) { #if defined(STM32H5) __HAL_RCC_ADC_CLK_ENABLE(); - #elif defined(STM32G4) || defined(STM32H7) + #elif defined(STM32G4) || defined(STM32H7) || defined(STM32N6) __HAL_RCC_ADC12_CLK_ENABLE(); #else __HAL_RCC_ADC2_CLK_ENABLE(); @@ -225,13 +230,15 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) { ADC3_COMMON->CCR = 3 << ADC_CCR_CKMODE_Pos; #elif defined(STM32L0) ADC1_COMMON->CCR = 0; // ADCPR=PCLK/2 + #elif defined(STM32L1) + ADC1_COMMON->CCR = 1 << ADC_CCR_ADCPRE_Pos; // ADCPRE=2 #elif defined(STM32WB) ADC1_COMMON->CCR = 0 << ADC_CCR_PRESC_Pos | 0 << ADC_CCR_CKMODE_Pos; // PRESC=1, MODE=ASYNC #elif defined(STM32WL) ADC_COMMON->CCR = 0 << ADC_CCR_PRESC_Pos; // PRESC=1 #endif - #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) + #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) if (adc->CR & ADC_CR_DEEPPWD) { adc->CR = 0; // disable deep powerdown } @@ -255,6 +262,11 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) { LL_ADC_StartCalibration(adc); #elif defined(STM32G4) || defined(STM32H5) || defined(STM32L4) || defined(STM32WB) LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED); + #elif defined(STM32N6) + ADC_HandleTypeDef hadc; + hadc.Instance = adc; + hadc.State = 0; + HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED); #else LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET_LINEARITY, LL_ADC_SINGLE_ENDED); #endif @@ -310,11 +322,17 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) { uint32_t cfgr = res << ADC_CFGR_RES_Pos; adc->CFGR = (adc->CFGR & ~cfgr_clr) | cfgr; + #elif defined(STM32N6) + + uint32_t cfgr1_clr = ADC_CFGR1_CONT | ADC_CFGR1_EXTEN; + uint32_t cfgr1 = res << ADC_CFGR1_RES_Pos; + adc->CFGR1 = (adc->CFGR1 & ~cfgr1_clr) | cfgr1; + #endif } static int adc_get_bits(ADC_TypeDef *adc) { - #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32WL) + #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32N6) || defined(STM32WL) uint32_t res = (adc->CFGR1 & ADC_CFGR1_RES) >> ADC_CFGR1_RES_Pos; #elif defined(STM32F4) || defined(STM32F7) || defined(STM32L1) uint32_t res = (adc->CR1 & ADC_CR1_RES) >> ADC_CR1_RES_Pos; @@ -385,8 +403,34 @@ static void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp } *smpr = (*smpr & ~(7 << (channel * 3))) | sample_time << (channel * 3); // select sample time - #elif defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) - #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) + #elif defined(STM32L1) + + ADC_Common_TypeDef *adc_common = ADC1_COMMON; + if (channel == ADC_CHANNEL_VREFINT || channel == ADC_CHANNEL_TEMPSENSOR) { + adc_common->CCR |= ADC_CCR_TSVREFE; + if (channel == ADC_CHANNEL_TEMPSENSOR) { + adc_stabilisation_delay_us(ADC_TEMPSENSOR_DELAY_US); + } + } + + adc->SQR1 = (1 - 1) << ADC_SQR1_L_Pos; + adc->SQR5 = (channel & 0x1f) << ADC_SQR5_SQ1_Pos; + + __IO uint32_t *smpr; + if (channel >= 20) { + smpr = &adc->SMPR1; + channel -= 20; + } else if (channel >= 10) { + smpr = &adc->SMPR2; + channel -= 10; + } else { + smpr = &adc->SMPR3; + } + *smpr = (*smpr & ~(7 << (channel * 3))) | sample_time << (channel * 3); // select sample time + + #elif defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined(STM32WB) + + #if defined(STM32G4) || defined(STM32H5) || defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ) || defined(STM32N6) ADC_Common_TypeDef *adc_common = ADC12_COMMON; #elif defined(STM32H7) #if defined(ADC_VER_V5_V90) @@ -404,6 +448,7 @@ static void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp #endif if (channel == ADC_CHANNEL_VREFINT) { adc_common->CCR |= ADC_CCR_VREFEN; + #if !defined(STM32N6) #if defined(STM32G4) } else if (channel == ADC_CHANNEL_TEMPSENSOR_ADC1) { adc_common->CCR |= ADC_CCR_VSENSESEL; @@ -412,19 +457,20 @@ static void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp adc_common->CCR |= ADC_CCR_TSEN; #endif adc_stabilisation_delay_us(ADC_TEMPSENSOR_DELAY_US); + #endif } else if (channel == ADC_CHANNEL_VBAT) { #if defined(STM32G4) adc_common->CCR |= ADC_CCR_VBATSEL; #else adc_common->CCR |= ADC_CCR_VBATEN; #endif - #if defined(STM32H5) + #if defined(STM32H5) || defined(STM32N6) } else if (channel == ADC_CHANNEL_VDDCORE) { adc->OR |= ADC_OR_OP0; // Enable Vddcore channel on ADC2 #endif } - #if defined(STM32G4) || defined(STM32H5) - // G4 and H5 use encoded literals for internal channels -> extract ADC channel for following code + #if defined(STM32G4) || defined(STM32H5) || defined(STM32N6) || defined(STM32WB) + // MCU uses encoded literals for internal channels -> extract ADC channel for following code if (__LL_ADC_IS_CHANNEL_INTERNAL(channel)) { channel = __LL_ADC_CHANNEL_TO_DECIMAL_NB(channel); } |