Skip to content

Commit fbe0409

Browse files
authored
Merge pull request #13601 from AGlass0fMilk/fix-g474-adc
Fix AnalogIn implementation on STM32G4 series
2 parents 2165297 + 76d488d commit fbe0409

File tree

3 files changed

+152
-47
lines changed

3 files changed

+152
-47
lines changed

targets/TARGET_STM/TARGET_STM32G4/TARGET_STM32G474xx/TARGET_NUCLEO_G474RE/PeripheralPins.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ MBED_WEAK const PinMap PinMap_ADC[] = {
9696
{NC, NC, 0}
9797
};
9898

99-
// !!! SECTION TO BE CHECKED WITH DEVICE REFERENCE MANUAL
10099
MBED_WEAK const PinMap PinMap_ADC_Internal[] = {
101-
{ADC_TEMP, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 16, 0)},
102-
{ADC_VREF, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 17, 0)},
103-
{ADC_VBAT, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 18, 0)},
100+
{ADC_TEMP, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 16, 0)}, // ADC1_IN16
101+
{ADC_VREF, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 18, 0)}, // ADC1_IN18
102+
{ADC_VBAT, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 17, 0)}, // ADC1_IN17
104103
{NC, NC, 0}
105104
};
106105

targets/TARGET_STM/TARGET_STM32G4/analogin_device.c

Lines changed: 149 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,43 @@
3636
#include "mbed_error.h"
3737
#include "mbed_debug.h"
3838
#include "PeripheralPins.h"
39+
#include "stm32g4xx_ll_bus.h"
40+
#include "string.h"
41+
42+
#if defined(ADC1)
43+
static uint8_t adc1_en_counter = 0;
44+
#define ADC1_EN_CTR adc1_en_counter
45+
#else
46+
#define ADC1_EN_CTR 0
47+
#endif
48+
49+
#if defined(ADC2)
50+
static uint8_t adc2_en_counter = 0;
51+
#define ADC2_EN_CTR adc2_en_counter
52+
#else
53+
#define ADC2_EN_CTR 0
54+
#endif
55+
56+
#if defined(ADC3)
57+
static uint8_t adc3_en_counter = 0;
58+
#define ADC3_EN_CTR adc3_en_counter
59+
#else
60+
#define ADC3_EN_CTR 0
61+
#endif
62+
63+
#if defined(ADC4)
64+
static uint8_t adc4_en_counter = 0;
65+
#define ADC4_EN_CTR adc4_en_counter
66+
#else
67+
#define ADC4_EN_CTR 0
68+
#endif
69+
70+
#if defined(ADC5)
71+
static uint8_t adc5_en_counter = 0;
72+
#define ADC5_EN_CTR adc5_en_counter
73+
#else
74+
#define ADC5_EN_CTR 0
75+
#endif
3976

4077
#if STATIC_PINMAP_READY
4178
#define ANALOGIN_INIT_DIRECT analogin_init_direct
@@ -72,6 +109,7 @@ static void _analogin_init_direct(analogin_t *obj, const PinMap *pinmap)
72109

73110
// Configure ADC object structures
74111
obj->handle.State = HAL_ADC_STATE_RESET;
112+
memset(&obj->handle.Init, 0, sizeof(obj->handle.Init));
75113
obj->handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
76114
obj->handle.Init.Resolution = ADC_RESOLUTION_12B;
77115
obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
@@ -82,40 +120,48 @@ static void _analogin_init_direct(analogin_t *obj, const PinMap *pinmap)
82120
obj->handle.Init.NbrOfConversion = 1;
83121
obj->handle.Init.DiscontinuousConvMode = DISABLE;
84122
obj->handle.Init.NbrOfDiscConversion = 0;
85-
obj->handle.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1;
123+
obj->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
86124
obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
87125
obj->handle.Init.DMAContinuousRequests = DISABLE;
88126
obj->handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
127+
obj->handle.Init.GainCompensation = 0;
128+
obj->handle.Init.OversamplingMode = DISABLE;
129+
obj->handle.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
89130

90131
#if defined(ADC1)
91132
if ((ADCName)obj->handle.Instance == ADC_1) {
92-
__HAL_RCC_ADC12_CONFIG(RCC_ADC12CLKSOURCE_SYSCLK); // TODO - which clock?
93-
// SYSCLK or PLL?
133+
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12);
134+
__HAL_RCC_ADC12_CONFIG(RCC_ADC12CLKSOURCE_SYSCLK);
135+
adc1_en_counter++;
94136
}
95137
#endif
96138
#if defined(ADC2)
97139
if ((ADCName)obj->handle.Instance == ADC_2) {
98-
__HAL_RCC_ADC12_CONFIG(RCC_ADC12CLKSOURCE_SYSCLK); // TODO - which clock?
99-
// SYSCLK or PLL?
140+
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12);
141+
__HAL_RCC_ADC12_CONFIG(RCC_ADC12CLKSOURCE_SYSCLK);
142+
adc2_en_counter++;
100143
}
101144
#endif
102145
#if defined(ADC3)
103146
if ((ADCName)obj->handle.Instance == ADC_3) {
104-
__HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK); // TODO - which clock?
105-
// SYSCLK or PLL?
147+
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC345);
148+
__HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK);
149+
adc3_en_counter++;
106150
}
107151
#endif
108152
#if defined(ADC4)
109153
if ((ADCName)obj->handle.Instance == ADC_4) {
110-
__HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK); // TODO - which clock?
111-
// SYSCLK or PLL?
154+
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC345);
155+
__HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK);
156+
adc4_en_counter++;
112157
}
113158
#endif
114159

115160
#if defined(ADC5)
116-
if ((ADCName)obj->handle.Instance == ADC_4) {
117-
__HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK); // TODO - which clock?
118-
// SYSCLK or PLL?
161+
if ((ADCName)obj->handle.Instance == ADC_5) {
162+
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC345);
163+
__HAL_RCC_ADC345_CONFIG(RCC_ADC345CLKSOURCE_SYSCLK);
164+
adc5_en_counter++;
119165
}
120166

121167
#endif
@@ -153,7 +199,7 @@ uint16_t adc_read(analogin_t *obj)
153199

154200
// Configure ADC channel
155201
sConfig.Rank = ADC_REGULAR_RANK_1;
156-
sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5;
202+
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
157203
sConfig.SingleDiff = ADC_SINGLE_ENDED;
158204
sConfig.OffsetNumber = ADC_OFFSET_NONE;
159205
sConfig.Offset = 0;
@@ -202,45 +248,31 @@ uint16_t adc_read(analogin_t *obj)
202248
sConfig.Channel = ADC_CHANNEL_14;
203249
break;
204250
case 15:
205-
if ((ADCName)obj->handle.Instance == ADC_1) {
206-
sConfig.Channel = ADC_CHANNEL_VOPAMP1;
207-
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
208-
} else {
209-
sConfig.Channel = ADC_CHANNEL_15;
210-
}
251+
sConfig.Channel = ADC_CHANNEL_15;
211252
break;
212253
case 16:
254+
sConfig.Channel = ADC_CHANNEL_16;
255+
213256
if ((ADCName)obj->handle.Instance == ADC_1) {
214257
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR_ADC1;
215-
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
216-
} else {
217-
sConfig.Channel = ADC_CHANNEL_16;
258+
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
218259
}
219260
break;
220261
case 17:
221-
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
262+
sConfig.Channel = ADC_CHANNEL_17;
263+
222264
if ((ADCName)obj->handle.Instance == ADC_1) {
223265
sConfig.Channel = ADC_CHANNEL_VBAT;
266+
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
224267
}
225-
#if defined(ADC2)
226-
if ((ADCName)obj->handle.Instance == ADC_2) {
227-
sConfig.Channel = ADC_CHANNEL_VOPAMP2;
228-
}
229-
#endif
230-
#if defined(ADC3)
231-
if ((ADCName)obj->handle.Instance == ADC_3) {
232-
sConfig.Channel = ADC_CHANNEL_VOPAMP3_ADC3;
233-
}
234-
#endif
235-
#if defined(ADC4)
236-
if ((ADCName)obj->handle.Instance == ADC_4) {
237-
sConfig.Channel = ADC_CHANNEL_VOPAMP4;
238-
}
239-
#endif
240268
break;
241269
case 18:
242-
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
243-
sConfig.Channel = ADC_CHANNEL_VREFINT;
270+
sConfig.Channel = ADC_CHANNEL_18;
271+
272+
if ((ADCName)obj->handle.Instance == ADC_1) {
273+
sConfig.Channel = ADC_CHANNEL_VREFINT;
274+
sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
275+
}
244276
break;
245277
default:
246278
return 0;
@@ -261,7 +293,9 @@ uint16_t adc_read(analogin_t *obj)
261293
} else {
262294
debug("HAL_ADC_PollForConversion issue\n");
263295
}
296+
264297
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE((&obj->handle)->Instance), LL_ADC_PATH_INTERNAL_NONE);
298+
265299
if (HAL_ADC_Stop(&obj->handle) != HAL_OK) {
266300
debug("HAL_ADC_Stop issue\n");;
267301
}
@@ -274,4 +308,79 @@ const PinMap *analogin_pinmap()
274308
return PinMap_ADC;
275309
}
276310

311+
void analogin_free(analogin_t *obj)
312+
{
313+
#if defined(ADC1)
314+
if ((ADCName)obj->handle.Instance == ADC_1) {
315+
adc1_en_counter--;
316+
if(ADC1_EN_CTR == 0)
317+
{
318+
HAL_ADC_DeInit(&obj->handle);
319+
320+
// Disable clock if ADC2 is also unused
321+
if(ADC2_EN_CTR == 0) {
322+
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_ADC12);
323+
}
324+
}
325+
}
326+
#endif
327+
#if defined(ADC2)
328+
if ((ADCName)obj->handle.Instance == ADC_2) {
329+
adc2_en_counter--;
330+
if(ADC2_EN_CTR == 0)
331+
{
332+
HAL_ADC_DeInit(&obj->handle);
333+
334+
// Disable clock if ADC1 is also unused
335+
if(ADC1_EN_CTR == 0) {
336+
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_ADC12);
337+
}
338+
}
339+
}
340+
#endif
341+
#if defined(ADC3)
342+
if ((ADCName)obj->handle.Instance == ADC_3) {
343+
adc3_en_counter--;
344+
if(ADC3_EN_CTR == 0)
345+
{
346+
HAL_ADC_DeInit(&obj->handle);
347+
348+
// Disable clock if ADC4 and ADC5 are also unused
349+
if((ADC4_EN_CTR + ADC5_EN_CTR) == 0) {
350+
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_ADC345);
351+
}
352+
}
353+
}
354+
#endif
355+
#if defined(ADC4)
356+
if ((ADCName)obj->handle.Instance == ADC_4) {
357+
adc4_en_counter--;
358+
if(ADC4_EN_CTR == 0)
359+
{
360+
HAL_ADC_DeInit(&obj->handle);
361+
362+
// Disable clock if ADC3 and ADC5 are also unused
363+
if((ADC3_EN_CTR + ADC5_EN_CTR) == 0) {
364+
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_ADC345);
365+
}
366+
}
367+
}
368+
#endif
369+
370+
#if defined(ADC5)
371+
if ((ADCName)obj->handle.Instance == ADC_5) {
372+
adc5_en_counter--;
373+
if(ADC5_EN_CTR == 0)
374+
{
375+
HAL_ADC_DeInit(&obj->handle);
376+
377+
// Disable clock if ADC3 and ADC4 are also unused
378+
if((ADC3_EN_CTR + ADC4_EN_CTR) == 0) {
379+
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_ADC345);
380+
}
381+
}
382+
}
383+
#endif
384+
}
385+
277386
#endif

targets/targets.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,9 +2469,6 @@
24692469
"EXTRA_IDLE_STACK_REQUIRED",
24702470
"MBED_TICKLESS"
24712471
],
2472-
"device_has_remove": [
2473-
"ANALOGIN"
2474-
],
24752472
"overrides": {
24762473
"lpticker_delay_ticks": 0
24772474
},

0 commit comments

Comments
 (0)