1919#include "mbed_assert.h"
2020#include "mbed_error.h"
2121#include "mbed_debug.h"
22- #include "mbed_wait_api.h"
2322#include "cmsis.h"
2423#include "pinmap.h"
2524#include "PeripheralPins.h"
2625
27- void analogin_init (analogin_t * obj , PinName pin )
26+
27+ #if STATIC_PINMAP_READY
28+ #define ANALOGIN_INIT_DIRECT analogin_init_direct
29+ void analogin_init_direct (analogin_t * obj , const PinMap * pinmap )
30+ #else
31+ #define ANALOGIN_INIT_DIRECT _analogin_init_direct
32+ static void _analogin_init_direct (analogin_t * obj , const PinMap * pinmap )
33+ #endif
2834{
29- uint32_t function = (uint32_t )NC ;
35+ uint32_t function = (uint32_t )pinmap -> function ;
36+
37+ // Get the peripheral name from the pin and assign it to the object
38+ obj -> handle .Instance = (ADC_TypeDef * )pinmap -> peripheral ;
3039
3140 // ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...)
3241 // are described in PinNames.h and PeripheralPins.c
3342 // Pin value must be between 0xF0 and 0xFF
34- if ((pin < 0xF0 ) || (pin >= 0x100 )) {
43+ if ((pinmap -> pin < 0xF0 ) || (pinmap -> pin >= 0x100 )) {
3544 // Normal channels
36- // Get the peripheral name from the pin and assign it to the object
37- obj -> handle .Instance = (ADC_TypeDef * )pinmap_peripheral (pin , PinMap_ADC );
38- // Get the functions (adc channel) from the pin and assign it to the object
39- function = pinmap_function (pin , PinMap_ADC );
45+
4046 // Configure GPIO
41- pinmap_pinout (pin , PinMap_ADC );
47+ pin_function (pinmap -> pin , pinmap -> function );
48+ pin_mode (pinmap -> pin , PullNone );
4249 } else {
4350 // Internal channels
44- obj -> handle .Instance = (ADC_TypeDef * )pinmap_peripheral (pin , PinMap_ADC_Internal );
45- function = pinmap_function (pin , PinMap_ADC_Internal );
4651 // No GPIO configuration for internal channels
4752 }
4853 MBED_ASSERT (obj -> handle .Instance != (ADC_TypeDef * )NC );
@@ -51,58 +56,77 @@ void analogin_init(analogin_t *obj, PinName pin)
5156 obj -> channel = STM_PIN_CHANNEL (function );
5257
5358 // Save pin number for the read function
54- obj -> pin = pin ;
59+ obj -> pin = pinmap -> pin ;
5560
5661 // Configure ADC object structures
5762 obj -> handle .State = HAL_ADC_STATE_RESET ;
58- obj -> handle .Init .ClockPrescaler = ADC_CLOCK_ASYNC_DIV2 ; // Asynchronous clock mode, input ADC clock
63+ obj -> handle .Init .ClockPrescaler = ADC_CLOCK_ASYNC_DIV2 ;
5964 obj -> handle .Init .Resolution = ADC_RESOLUTION_12B ;
6065 obj -> handle .Init .DataAlign = ADC_DATAALIGN_RIGHT ;
61- obj -> handle .Init .ScanConvMode = ADC_SCAN_DISABLE ; // Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1)
62- obj -> handle .Init .EOCSelection = ADC_EOC_SINGLE_CONV ; // On STM32L1xx ADC, overrun detection is enabled only if EOC selection is set to each conversion (or transfer by DMA enabled, this is not the case in this example).
66+ obj -> handle .Init .ScanConvMode = ADC_SCAN_DISABLE ;
67+ obj -> handle .Init .EOCSelection = ADC_EOC_SINGLE_CONV ;
6368 obj -> handle .Init .LowPowerAutoWait = DISABLE ;
64- obj -> handle .Init .ContinuousConvMode = DISABLE ; // Continuous mode disabled to have only 1 conversion at each conversion trig
65- obj -> handle .Init .NbrOfConversion = 1 ; // Parameter discarded because sequencer is disabled
66- obj -> handle .Init .DiscontinuousConvMode = DISABLE ; // Parameter discarded because sequencer is disabled
67- //obj->handle.Init.NbrOfDiscConversion = 1; // Parameter discarded because sequencer is disabled
68- obj -> handle .Init .ExternalTrigConv = ADC_SOFTWARE_START ; // Software start to trig the 1st conversion manually, without external event
69+ obj -> handle .Init .ContinuousConvMode = DISABLE ;
70+ obj -> handle .Init .NbrOfConversion = 1 ;
71+ obj -> handle .Init .DiscontinuousConvMode = DISABLE ;
72+ obj -> handle .Init .ExternalTrigConv = ADC_SOFTWARE_START ;
6973 obj -> handle .Init .ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE ;
7074 obj -> handle .Init .DMAContinuousRequests = DISABLE ;
71- obj -> handle .Init .Overrun = ADC_OVR_DATA_OVERWRITTEN ; // DR register is overwritten with the last conversion result in case of overrun
72- obj -> handle .Init .OversamplingMode = DISABLE ; // No oversampling
73-
74- // Enable ADC core clock
75- __HAL_RCC_ADC_CLK_ENABLE ();
76-
77- // Enable ADC conversion clock.
78- // Only necessary with asynchronous clock source
75+ obj -> handle .Init .Overrun = ADC_OVR_DATA_OVERWRITTEN ;
76+ obj -> handle .Init .LowPowerAutoPowerOff = DISABLE ;
77+ obj -> handle .Init .SamplingTimeCommon1 = ADC_SAMPLETIME_19CYCLES_5 ;
78+ obj -> handle .Init .SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5 ;
79+ obj -> handle .Init .OversamplingMode = DISABLE ;
80+ obj -> handle .Init .Oversampling .Ratio = 0 ; // workaround
81+ obj -> handle .Init .Oversampling .RightBitShift = 0 ; // workaround
82+ obj -> handle .Init .Oversampling .TriggeredMode = 0 ; // workaround
83+ obj -> handle .Init .TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH ;
84+
85+ // Enable ADC clock
7986 __HAL_RCC_ADC_CONFIG (RCC_ADCCLKSOURCE_SYSCLK );
87+ __HAL_RCC_ADC_CLK_ENABLE ();
8088
8189 if (HAL_ADC_Init (& obj -> handle ) != HAL_OK ) {
82- error ("ADC initialization failed\r\n " );
90+ error ("Cannot initialize ADC " );
8391 }
8492
8593 // ADC calibration is done only once
86- //if (!HAL_ADCEx_Calibration_GetValue(&obj->handle, ADC_SINGLE_ENDED)) {
87- // HAL_ADCEx_Calibration_Start(&obj->handle, ADC_SINGLE_ENDED);
88- //}
94+ if (!HAL_ADCEx_Calibration_GetValue (& obj -> handle )) {
95+ if (HAL_ADCEx_Calibration_Start (& obj -> handle ) != HAL_OK ) {
96+ error ("HAL_ADCEx_Calibration_Start error" );
97+ }
98+ }
99+ }
100+
101+ void analogin_init (analogin_t * obj , PinName pin )
102+ {
103+ int peripheral ;
104+ int function ;
105+
106+ if ((pin < 0xF0 ) || (pin >= 0x100 )) {
107+ peripheral = (int )pinmap_peripheral (pin , PinMap_ADC );
108+ function = (int )pinmap_find_function (pin , PinMap_ADC );
109+ } else {
110+ peripheral = (int )pinmap_peripheral (pin , PinMap_ADC_Internal );
111+ function = (int )pinmap_find_function (pin , PinMap_ADC_Internal );
112+ }
113+
114+ const PinMap static_pinmap = {pin , peripheral , function };
115+
116+ ANALOGIN_INIT_DIRECT (obj , & static_pinmap );
89117}
90118
119+
91120uint16_t adc_read (analogin_t * obj )
92121{
93122 ADC_ChannelConfTypeDef sConfig = {0 };
94123
95- // Configure ADC channel
96124 sConfig .Rank = ADC_REGULAR_RANK_1 ;
97- //sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5;
98- //sConfig.SingleDiff = ADC_SINGLE_ENDED;
99- //sConfig.OffsetNumber = ADC_OFFSET_NONE;
100- //sConfig.Offset = 0;
125+ sConfig .SamplingTime = ADC_SAMPLINGTIME_COMMON_1 ;
101126
102127 switch (obj -> channel ) {
103128 case 0 :
104- sConfig .Channel = ADC_CHANNEL_VREFINT ;
105- //sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; // Minimum ADC sampling time when reading the internal reference voltage is 4us
129+ sConfig .Channel = ADC_CHANNEL_0 ;
106130 break ;
107131 case 1 :
108132 sConfig .Channel = ADC_CHANNEL_1 ;
@@ -138,55 +162,41 @@ uint16_t adc_read(analogin_t *obj)
138162 sConfig .Channel = ADC_CHANNEL_11 ;
139163 break ;
140164 case 12 :
141- sConfig .Channel = ADC_CHANNEL_12 ;
165+ sConfig .Channel = ADC_CHANNEL_TEMPSENSOR ;
166+ sConfig .SamplingTime = ADC_SAMPLINGTIME_COMMON_2 ;
142167 break ;
143168 case 13 :
144- sConfig .Channel = ADC_CHANNEL_13 ;
169+ sConfig .Channel = ADC_CHANNEL_VREFINT ;
170+ sConfig .SamplingTime = ADC_SAMPLINGTIME_COMMON_2 ;
145171 break ;
146172 case 14 :
147- sConfig .Channel = ADC_CHANNEL_14 ;
148- break ;
149- case 15 :
150- sConfig .Channel = ADC_CHANNEL_15 ;
151- break ;
152- case 16 :
153- sConfig .Channel = ADC_CHANNEL_16 ;
154- break ;
155- case 17 :
156- sConfig .Channel = ADC_CHANNEL_TEMPSENSOR ;
157- //sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5; // Minimum ADC sampling time when reading the temperature is 5us
158- break ;
159- case 18 :
160173 sConfig .Channel = ADC_CHANNEL_VBAT ;
161- // sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5; // Minimum ADC sampling time when reading the VBAT is 12us
174+ sConfig .SamplingTime = ADC_SAMPLINGTIME_COMMON_2 ;
162175 break ;
163176 default :
164177 return 0 ;
165178 }
166179
167180 if (HAL_ADC_ConfigChannel (& obj -> handle , & sConfig ) != HAL_OK ) {
168- debug ("ADC channel configuration failed\r \n" );
181+ debug ("HAL_ADC_ConfigChannel error \n" );
169182 }
170183
171- // Start conversion
172184 if (HAL_ADC_Start (& obj -> handle ) != HAL_OK ) {
173- debug ("ADC start of conversion failed\r \n" );
185+ debug ("HAL_ADC_Start error \n" );
174186 }
175187
176188 // Wait end of conversion and get value
177189 uint16_t adcValue = 0 ;
178- if (HAL_ADC_PollForConversion (& obj -> handle , 10 ) == HAL_OK ) {
190+ if (HAL_ADC_PollForConversion (& obj -> handle , 100 ) == HAL_OK ) {
179191 adcValue = (uint16_t )HAL_ADC_GetValue (& obj -> handle );
180192 }
181193
182- if (HAL_ADC_Stop (& obj -> handle ) != HAL_OK ) {
183- debug ("HAL_ADC_Stop failed\r\n" );
184- }
185-
186194 LL_ADC_SetCommonPathInternalCh (__LL_ADC_COMMON_INSTANCE ((& obj -> handle )-> Instance ), LL_ADC_PATH_INTERNAL_NONE );
195+
187196 return adcValue ;
188197}
189198
199+
190200const PinMap * analogin_pinmap ()
191201{
192202 return PinMap_ADC ;
0 commit comments