5151/// val = adc.read_core_vref() # read MCU VREF
5252
5353/* ADC definitions */
54- #if defined(STM32H5 )
54+ #if defined(STM32H5 ) || defined( STM32N6 )
5555// STM32H5 features two ADC instances, ADCx and pin_adc_table are set dynamically
5656#define PIN_ADC_MASK (PIN_ADC1 | PIN_ADC2)
5757#else
107107#define ADC_CAL2 ((uint16_t *)(ADC_CAL_ADDRESS + 4))
108108#define ADC_CAL_BITS (12)
109109
110- #elif defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32L1 ) || defined(STM32L4 ) || defined(STM32WB )
110+ #elif defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32L1 ) || defined(STM32L4 ) || defined(STM32N6 ) || defined( STM32WB )
111111
112112#define ADC_SCALE_V (((float)VREFINT_CAL_VREF) / 1000.0f)
113113#define ADC_CAL_ADDRESS (VREFINT_CAL_ADDR)
166166#define VBAT_DIV (3)
167167#elif defined(STM32L152xE )
168168// STM32L152xE does not have vbat.
169+ #elif defined(STM32N6 )
170+ // ADC2 VINP 16
171+ #define VBAT_DIV (4)
169172#else
170173#error Unsupported processor
171174#endif
@@ -247,7 +250,7 @@ static bool is_adcx_channel(int channel) {
247250 handle .Instance = ADCx ;
248251 return __HAL_ADC_IS_CHANNEL_INTERNAL (channel )
249252 || IS_ADC_CHANNEL (& handle , __HAL_ADC_DECIMAL_NB_TO_CHANNEL (channel ));
250- #elif defined(STM32H5 )
253+ #elif defined(STM32H5 ) || defined( STM32N6 )
251254 // The first argument to the IS_ADC_CHANNEL macro is unused.
252255 return __HAL_ADC_IS_CHANNEL_INTERNAL (channel )
253256 || IS_ADC_CHANNEL (NULL , __HAL_ADC_DECIMAL_NB_TO_CHANNEL (channel ));
@@ -260,7 +263,7 @@ static void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t ti
260263 uint32_t tickstart = HAL_GetTick ();
261264 #if defined(STM32F4 ) || defined(STM32F7 ) || defined(STM32L1 )
262265 while ((adcHandle -> Instance -> SR & ADC_FLAG_EOC ) != ADC_FLAG_EOC ) {
263- #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
266+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32H7) || defined(STM32L4) || defined(STM32N6) || defined( STM32WB)
264267 while (READ_BIT (adcHandle -> Instance -> ISR , ADC_FLAG_EOC ) != ADC_FLAG_EOC ) {
265268 #else
266269 #error Unsupported processor
@@ -279,7 +282,7 @@ static void adcx_clock_enable(ADC_HandleTypeDef *adch) {
279282 __HAL_RCC_ADC_CONFIG (RCC_ADCCLKSOURCE_CLKP );
280283 #elif defined(STM32G0 )
281284 __HAL_RCC_ADC_CLK_ENABLE ();
282- #elif defined(STM32G4 )
285+ #elif defined(STM32G4 ) || defined( STM32N6 )
283286 __HAL_RCC_ADC12_CLK_ENABLE ();
284287 #elif defined(STM32H5 )
285288 __HAL_RCC_ADC_CLK_ENABLE ();
@@ -352,6 +355,15 @@ static void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
352355 adch -> Init .OversamplingMode = DISABLE ;
353356 adch -> Init .DataAlign = ADC_DATAALIGN_RIGHT ;
354357 adch -> Init .DMAContinuousRequests = DISABLE ;
358+ #elif defined(STM32N6 )
359+ adch -> Init .GainCompensation = 0 ;
360+ adch -> Init .ScanConvMode = ADC_SCAN_DISABLE ;
361+ adch -> Init .LowPowerAutoWait = DISABLE ;
362+ adch -> Init .SamplingMode = ADC_SAMPLING_MODE_NORMAL ;
363+ adch -> Init .ConversionDataManagement = ADC_CONVERSIONDATA_DR ;
364+ adch -> Init .Overrun = ADC_OVR_DATA_OVERWRITTEN ;
365+ adch -> Init .LeftBitShift = ADC_LEFTBITSHIFT_NONE ;
366+ adch -> Init .OversamplingMode = DISABLE ;
355367 #else
356368 #error Unsupported processor
357369 #endif
@@ -384,7 +396,7 @@ static void adc_init_single(pyb_obj_adc_t *adc_obj, ADC_TypeDef *adc) {
384396static void adc_config_channel (ADC_HandleTypeDef * adc_handle , uint32_t channel ) {
385397 ADC_ChannelConfTypeDef sConfig ;
386398
387- #if defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32H7 ) || defined(STM32L4 ) || defined(STM32WB )
399+ #if defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32H7 ) || defined(STM32L4 ) || defined(STM32N6 ) || defined( STM32WB )
388400 sConfig .Rank = ADC_REGULAR_RANK_1 ;
389401 if (__HAL_ADC_IS_CHANNEL_INTERNAL (channel ) == 0 ) {
390402 channel = __HAL_ADC_DECIMAL_NB_TO_CHANNEL (channel );
@@ -433,6 +445,18 @@ static void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
433445 sConfig .SingleDiff = ADC_SINGLE_ENDED ;
434446 sConfig .OffsetNumber = ADC_OFFSET_NONE ;
435447 sConfig .Offset = 0 ;
448+ #elif defined(STM32N6 )
449+ if (__HAL_ADC_IS_CHANNEL_INTERNAL (channel )) {
450+ sConfig .SamplingTime = ADC_SAMPLETIME_246CYCLES_5 ;
451+ } else {
452+ sConfig .SamplingTime = ADC_SAMPLETIME_11CYCLES_5 ;
453+ }
454+ sConfig .SingleDiff = ADC_SINGLE_ENDED ;
455+ sConfig .OffsetNumber = ADC_OFFSET_NONE ;
456+ sConfig .Offset = 0 ;
457+ sConfig .OffsetSignedSaturation = DISABLE ;
458+ sConfig .OffsetSaturation = DISABLE ;
459+ sConfig .OffsetSign = ADC_OFFSET_SIGN_POSITIVE ;
436460 #else
437461 #error Unsupported processor
438462 #endif
@@ -510,7 +534,7 @@ static mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
510534 // 1st argument is the pin name
511535 mp_obj_t pin_obj = args [0 ];
512536
513- #if defined(STM32H5 )
537+ #if defined(STM32H5 ) || defined( STM32N6 )
514538 // STM32H5 has two ADC instances where some pins are only available on ADC1 or ADC2 (but not both).
515539 // Assume we're using a channel of ADC1. Can be overridden for ADC2 later in this function.
516540 ADC_TypeDef * adc = ADC1 ;
@@ -527,7 +551,7 @@ static mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
527551 // No ADC function on the given pin.
528552 mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("Pin(%q) doesn't have ADC capabilities" ), pin -> name );
529553 }
530- #if defined(STM32H5 )
554+ #if defined(STM32H5 ) || defined( STM32N6 )
531555 if ((pin -> adc_num & PIN_ADC2 ) == PIN_ADC2 ) {
532556 adc = ADC2 ;
533557 pin_adc_table = pin_adc2 ;
@@ -542,7 +566,7 @@ static mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
542566 }
543567
544568 // If this channel corresponds to a pin then configure the pin in ADC mode.
545- #if defined(STM32H5 )
569+ #if defined(STM32H5 ) || defined( STM32N6 )
546570 if (channel < num_adc_pins ) {
547571 const machine_pin_obj_t * pin = pin_adc_table [channel ];
548572 if (pin != NULL ) {
@@ -563,7 +587,7 @@ static mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
563587 o -> base .type = & pyb_adc_type ;
564588 o -> pin_name = pin_obj ;
565589 o -> channel = channel ;
566- #if defined(STM32H5 )
590+ #if defined(STM32H5 ) || defined( STM32N6 )
567591 adc_init_single (o , adc );
568592 #else
569593 adc_init_single (o , ADCx );
@@ -654,7 +678,7 @@ static mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
654678 // for subsequent samples we can just set the "start sample" bit
655679 #if defined(STM32F4 ) || defined(STM32F7 ) || defined(STM32L1 )
656680 self -> handle .Instance -> CR2 |= (uint32_t )ADC_CR2_SWSTART ;
657- #elif defined(STM32F0 ) || defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32H7 ) || defined(STM32L4 ) || defined(STM32WB )
681+ #elif defined(STM32F0 ) || defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32H7 ) || defined(STM32L4 ) || defined(STM32N6 ) || defined( STM32WB )
658682 SET_BIT (self -> handle .Instance -> CR , ADC_CR_ADSTART );
659683 #else
660684 #error Unsupported processor
@@ -764,7 +788,7 @@ static mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i
764788 // ADC is started: set the "start sample" bit
765789 #if defined(STM32F4 ) || defined(STM32F7 ) || defined(STM32L1 )
766790 adc -> handle .Instance -> CR2 |= (uint32_t )ADC_CR2_SWSTART ;
767- #elif defined(STM32F0 ) || defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32H7 ) || defined(STM32L4 ) || defined(STM32WB )
791+ #elif defined(STM32F0 ) || defined(STM32G0 ) || defined(STM32G4 ) || defined(STM32H5 ) || defined(STM32H7 ) || defined(STM32L4 ) || defined(STM32N6 ) || defined( STM32WB )
768792 SET_BIT (adc -> handle .Instance -> CR , ADC_CR_ADSTART );
769793 #else
770794 #error Unsupported processor
@@ -898,6 +922,8 @@ int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
898922 } else {
899923 return 0 ;
900924 }
925+ #elif defined(STM32N6 )
926+ int32_t raw_value = 0 ; // TODO
901927 #else
902928 int32_t raw_value = adc_config_and_read_ref (adcHandle , ADC_CHANNEL_TEMPSENSOR );
903929 #endif
@@ -909,6 +935,10 @@ int adc_read_core_temp(ADC_HandleTypeDef *adcHandle) {
909935static volatile float adc_refcor = 1.0f ;
910936
911937float adc_read_core_temp_float (ADC_HandleTypeDef * adcHandle ) {
938+ #if defined(STM32N6 )
939+ return 0.0f ; // TODO
940+ #else
941+
912942 #if defined(STM32G4 ) || defined(STM32L1 ) || defined(STM32L4 )
913943 // Update the reference correction factor before reading tempsensor
914944 // because TS_CAL1 and TS_CAL2 of STM32G4,L1/L4 are at VDDA=3.0V
@@ -931,6 +961,8 @@ float adc_read_core_temp_float(ADC_HandleTypeDef *adcHandle) {
931961 float core_temp_avg_slope = (* ADC_CAL2 - * ADC_CAL1 ) / 80.0f ;
932962 #endif
933963 return (((float )raw_value * adc_refcor - * ADC_CAL1 ) / core_temp_avg_slope ) + 30.0f ;
964+
965+ #endif
934966}
935967
936968float adc_read_core_vbat (ADC_HandleTypeDef * adcHandle ) {
0 commit comments