Skip to content

Commit 5e094fe

Browse files
authored
Merge pull request #14245 from jeromecoutant/PR_WL
STM32WL: I2C and ADC full support
2 parents 98659cf + 4550f92 commit 5e094fe

File tree

5 files changed

+186
-131
lines changed

5 files changed

+186
-131
lines changed

targets/TARGET_STM/TARGET_STM32WL/TARGET_STM32WL55xC/TARGET_NUCLEO_WL55JC/PeripheralPins.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ MBED_WEAK const PinMap PinMap_ADC[] = {
5555
{NC, NC, 0}
5656
};
5757

58-
// !!! SECTION TO BE CHECKED WITH DEVICE REFERENCE MANUAL
5958
MBED_WEAK const PinMap PinMap_ADC_Internal[] = {
60-
// {ADC_TEMP, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 16, 0)},
61-
// {ADC_VREF, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 17, 0)},
62-
// {ADC_VBAT, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 18, 0)},
59+
{ADC_TEMP, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 12, 0)},
60+
{ADC_VREF, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 13, 0)},
61+
{ADC_VBAT, ADC_1, STM_PIN_DATA_EXT(STM_MODE_ANALOG, GPIO_NOPULL, 0, 14, 0)},
6362
{NC, NC, 0}
6463
};
6564

targets/TARGET_STM/TARGET_STM32WL/analogin_device.c

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,35 @@
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+
91120
uint16_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+
190200
const PinMap *analogin_pinmap()
191201
{
192202
return PinMap_ADC;

targets/TARGET_STM/TARGET_STM32WL/analogout_device.c

Lines changed: 75 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,43 +23,88 @@
2323
#include "mbed_error.h"
2424
#include "PeripheralPins.h"
2525

26-
DAC_HandleTypeDef hdac;
26+
#if STATIC_PINMAP_READY
27+
#define ANALOGOUT_INIT_DIRECT analogout_init_direct
28+
void analogout_init_direct(dac_t *obj, const PinMap *pinmap)
29+
#else
30+
#define ANALOGOUT_INIT_DIRECT _analogout_init_direct
31+
static void _analogout_init_direct(dac_t *obj, const PinMap *pinmap)
32+
#endif
33+
{
34+
DAC_ChannelConfTypeDef sConfig = {0};
35+
36+
// Get the peripheral name from the pin and assign it to the object
37+
obj->dac = (DACName)pinmap->peripheral;
38+
MBED_ASSERT(obj->dac != (DACName)NC);
39+
40+
// Get the pin function and assign the used channel to the object
41+
uint32_t function = (uint32_t)pinmap->function;
42+
MBED_ASSERT(function != (uint32_t)NC);
43+
44+
switch (STM_PIN_CHANNEL(function)) {
45+
case 1:
46+
obj->channel = DAC_CHANNEL_1;
47+
break;
48+
default:
49+
error("Unknown DAC channel");
50+
break;
51+
}
52+
53+
// Configure GPIO
54+
pin_function(pinmap->pin, pinmap->function);
55+
pin_mode(pinmap->pin, PullNone);
56+
57+
// Save the pin for future use
58+
obj->pin = pinmap->pin;
59+
60+
// Enable DAC clock
61+
__HAL_RCC_DAC_CLK_ENABLE();
62+
63+
// Configure DAC
64+
obj->handle.Instance = DAC;
65+
obj->handle.State = HAL_DAC_STATE_RESET;
66+
67+
if (HAL_DAC_Init(&obj->handle) != HAL_OK) {
68+
error("HAL_DAC_Init failed");
69+
}
70+
71+
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
72+
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
73+
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
74+
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
75+
76+
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
77+
78+
if (HAL_DAC_ConfigChannel(&obj->handle, &sConfig, obj->channel) != HAL_OK) {
79+
error("Cannot configure DAC channel\n");
80+
}
81+
82+
analogout_write_u16(obj, 0);
83+
}
2784

2885
void analogout_init(dac_t *obj, PinName pin)
2986
{
87+
int peripheral = (int)pinmap_peripheral(pin, PinMap_DAC);
88+
int function = (int)pinmap_find_function(pin, PinMap_DAC);
89+
90+
const PinMap static_pinmap = {pin, peripheral, function};
3091

31-
DAC_ChannelConfTypeDef sConfig = {0};
32-
33-
/* obj Initialization */
34-
obj->dac = (DACName)NC;
35-
36-
obj->pin = pin;
37-
38-
obj->channel = DAC_CHANNEL_1;
39-
40-
/* DAC Initialization */
41-
hdac.Instance = DAC;
42-
if (HAL_DAC_Init(&hdac) != HAL_OK)
43-
{
44-
//Error_Handler();
45-
}
46-
/** DAC channel OUT1 config
47-
*/
48-
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
49-
sConfig.DAC_Trigger = DAC_TRIGGER_T1_TRGO;
50-
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
51-
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
52-
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
53-
54-
if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
55-
{
56-
//Error_Handler();
57-
}
58-
92+
ANALOGOUT_INIT_DIRECT(obj, &static_pinmap);
93+
}
94+
95+
void analogout_free(dac_t *obj)
96+
{
97+
__HAL_RCC_DAC_FORCE_RESET();
98+
__HAL_RCC_DAC_RELEASE_RESET();
99+
__HAL_RCC_DAC_CLK_DISABLE();
100+
101+
// Configure GPIO
102+
pin_function(obj->pin, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0));
59103
}
60104

61105
const PinMap *analogout_pinmap()
62106
{
63107
return PinMap_DAC;
64108
}
65-
#endif
109+
110+
#endif // DEVICE_ANALOGOUT

0 commit comments

Comments
 (0)