summaryrefslogtreecommitdiffstatshomepage
path: root/ports/stm32/machine_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/machine_adc.c')
-rw-r--r--ports/stm32/machine_adc.c68
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);
}