You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi !!!
I would like to discuss the topic of adding functionality to the Mbed os and how best to do it.
I see two ways:
1 - Change the source files of the Mbed
2 - Override files in the cmake script for a custom target.
I usually use method 2 to keep the Mbed clean. After testing the changes in the API, I would like to share the code with the community.
Below I will give an example using the oversampling module.
A lot of novel MCUs have oversampling module on the die, so we can use this feature. in case the device has no oversampling module we can use software realization.
My proposal:
(I use STM32l4 series mcu for example)
in targets/TARGET_STM/TARGET_STM32L4/analogin_device.c
#if STATIC_PINMAP_READY
#define ANALOGIN_INIT_DIRECT analogin_init_direct
void analogin_init_direct(analogin_t *obj, const PinMap *pinmap)
#else
#define ANALOGIN_INIT_DIRECT _analogin_init_direct
void static _analogin_init_direct(analogin_t *obj, const PinMap *pinmap)
#endif
{
uint32_t function = (uint32_t)pinmap->function;
// Get the peripheral name from the pin and assign it to the object
obj->handle.Instance = (ADC_TypeDef *)pinmap->peripheral;
// ADC Internal Channels "pins" (Temperature, Vref, Vbat, ...)
// are described in PinNames.h and PeripheralPins.c
// Pin value must be between 0xF0 and 0xFF
if ((pinmap->pin < 0xF0) || (pinmap->pin >= 0x100)) {
// Configure GPIO
pin_function(pinmap->pin, pinmap->function);
pin_mode(pinmap->pin, PullNone);
} else {
// Internal channels
// No GPIO configuration for internal channels
}
MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC);
MBED_ASSERT(function != (uint32_t)NC);
obj->channel = STM_PIN_CHANNEL(function);
// Save pin number for the read function
obj->pin = pinmap->pin;
// Configure ADC object structures
obj->handle.State = HAL_ADC_STATE_RESET;
obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; // Asynchronous clock mode, input ADC clock
obj->handle.Init.Resolution = ADC_RESOLUTION_12B;
obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
obj->handle.Init.ScanConvMode = DISABLE; // Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1)
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).
obj->handle.Init.LowPowerAutoWait = DISABLE; // Auto-wait (reduce power)
obj->handle.Init.ContinuousConvMode = DISABLE; // Continuous mode disabled to have only 1 conversion at each conversion trig
obj->handle.Init.NbrOfConversion = 1; // Parameter discarded because sequencer is disabled
obj->handle.Init.DiscontinuousConvMode = DISABLE; // Parameter discarded because sequencer is disabled
obj->handle.Init.NbrOfDiscConversion = 1; // Parameter discarded because sequencer is disabled
obj->handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; // Software start to trig the 1st conversion manually, without external event
obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
obj->handle.Init.DMAContinuousRequests = DISABLE;
obj->handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; // DR register is overwritten with the last conversion result in case of overrun
#if defined(ADC_OVERSAMPLING)
obj->handle.Init.OversamplingMode = ENABLE; // Enable oversampling
obj->handle.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER; // Single trigger
#if defined(ADC_OVERSAMPLING_14BIT)
obj->handle.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_4; // 4x oversampling
obj->handle.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_2; // Adjust to 14-bit
#elif defined(ADC_OVERSAMPLING_15BIT)
obj->handle.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_32; // 32x oversampling
obj->handle.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_3; // Adjust to 15-bit resolution
#elif defined(ADC_OVERSAMPLING_16BIT)
obj->handle.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_256; // 256x oversampling
obj->handle.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4; // Adjust to 16-bit resolution
#endif
#else
obj->handle.Init.OversamplingMode = DISABLE; // No oversamplingS
#endif
#if defined(ADC_CFGR_DFSDMCFG) &&defined(DFSDM1_Channel0)
obj->handle.Init.DFSDMConfig = 0;
#endif
// Enable ADC clock
__HAL_RCC_ADC_CLK_ENABLE();
#if defined(RCC_CCIPR_ADCSEL)
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);
#endif
if (HAL_ADC_Init(&obj->handle) != HAL_OK) {
error("Cannot initialize ADC\n");
}
// ADC calibration is done only once
if (!HAL_ADCEx_Calibration_GetValue(&obj->handle, ADC_SINGLE_ENDED)) {
HAL_ADCEx_Calibration_Start(&obj->handle, ADC_SINGLE_ENDED);
}
}
we can redefine these files in custom target cmake, like this:
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Hi !!!
I would like to discuss the topic of adding functionality to the Mbed os and how best to do it.
I see two ways:
1 - Change the source files of the Mbed
2 - Override files in the cmake script for a custom target.
I usually use method 2 to keep the Mbed clean. After testing the changes in the API, I would like to share the code with the community.
Below I will give an example using the oversampling module.
A lot of novel MCUs have oversampling module on the die, so we can use this feature. in case the device has no oversampling module we can use software realization.
My proposal:
(I use STM32l4 series mcu for example)
Changes in targets/TARGET_STM/analogin_api.c
in targets/TARGET_STM/TARGET_STM32L4/analogin_device.c
we can redefine these files in custom target cmake, like this:
So now we can use it in our code. let's config mbed_app.json5
Beta Was this translation helpful? Give feedback.
All reactions