Skip to content

Commit

Permalink
feat: add ADC and timer for mcu stm32wbaxx (#328)
Browse files Browse the repository at this point in the history
extend adc feature
  • Loading branch information
cassio-lazaro authored Jun 18, 2024
1 parent 6577c8e commit d413549
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 62 deletions.
45 changes: 23 additions & 22 deletions hal_st/stm32fxxx/AdcDmaStm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,42 @@ namespace hal
TransferDone();
})
, analogPin(pin)
#if defined(STM32G0)
, timer(3, timing, { TimerBaseStm::CounterMode::up, infra::MakeOptional<TimerBaseStm::Trigger>({ TimerBaseStm::Trigger::TriggerOutput::update, false }) })
#else
#ifdef TIM2
, timer(2, timing, { TimerBaseStm::CounterMode::up, infra::MakeOptional<TimerBaseStm::Trigger>({ TimerBaseStm::Trigger::TriggerOutput::update, false }) })
#else
, timer(3, timing, { TimerBaseStm::CounterMode::up, infra::MakeOptional<TimerBaseStm::Trigger>({ TimerBaseStm::Trigger::TriggerOutput::update, false }) })
#endif
{
ADC_ChannelConfTypeDef channelConfig;
ADC_ChannelConfTypeDef channelConfig{};
channelConfig.Channel = adc.Channel(analogPin);
#if !defined(STM32WB)
#ifdef ADC_REGULAR_RANK_1
channelConfig.Rank = ADC_REGULAR_RANK_1;
#else
channelConfig.Rank = 1;
#endif

#ifdef ADC_SMPR_SMP1
channelConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
#else
channelConfig.Rank = ADC_REGULAR_RANK_1;
channelConfig.SamplingTime = hal::detail::AdcStmChannelConfig().samplingTime;
#endif
#if defined(STM32F0) || defined(STM32F3)
channelConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
#elif defined(STM32WB)
channelConfig.SingleDiff = ADC_SINGLE_ENDED;
channelConfig.SamplingTime = ADC_SAMPLETIME_92CYCLES_5;
channelConfig.Offset = 0;
#ifdef ADC_OFFSET_NONE
channelConfig.OffsetNumber = ADC_OFFSET_NONE;
#elif defined(STM32G0)
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES_5;
#elif defined(STM32G4)
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES_5;
channelConfig.Offset = 0;
#else
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
#endif
#ifdef ADC_SINGLE_ENDED
channelConfig.SingleDiff = ADC_SINGLE_ENDED;
#endif
#ifdef ADC_OFFSET_1
channelConfig.Offset = 0;
#endif
ReconfigureTrigger();

auto result = HAL_ADC_ConfigChannel(&adc.Handle(), &channelConfig);
assert(result == HAL_OK);

#ifdef ADC_SINGLE_ENDED
result = HAL_ADCEx_Calibration_Start(&adc.Handle(), ADC_SINGLE_ENDED);
#endif
assert(result == HAL_OK);
}

Expand All @@ -63,14 +64,14 @@ namespace hal
{
HAL_ADC_Stop(&adc.Handle());

#if defined(STM32F4) || defined(STM32F7)
#if defined(ADC_EXTERNALTRIGCONV_T2_TRGO)
LL_ADC_REG_SetTriggerSource(adc.Handle().Instance, ADC_EXTERNALTRIGCONV_T2_TRGO);
#elif defined(STM32G0)
#elif defined(ADC_EXTERNALTRIG_T3_TRGO)
LL_ADC_REG_SetTriggerSource(adc.Handle().Instance, ADC_EXTERNALTRIG_T3_TRGO);
#else
LL_ADC_REG_SetTriggerSource(adc.Handle().Instance, ADC_EXTERNALTRIG_T2_TRGO);
#endif
LL_ADC_REG_SetTriggerEdge(adc.Handle().Instance, LL_ADC_REG_TRIG_EXT_RISING);
LL_ADC_REG_SetTriggerEdge(adc.Handle().Instance, ADC_EXTERNALTRIGCONVEDGE_RISING);
}

void AdcTriggeredByTimerWithDma::Configure()
Expand Down
65 changes: 35 additions & 30 deletions hal_st/stm32fxxx/AnalogToDigitalPinStm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,34 +38,37 @@ namespace

namespace hal
{
AnalogToDigitalPinImplStm::AnalogToDigitalPinImplStm(hal::GpioPinStm& pin, AdcStm& adc)
AnalogToDigitalPinImplStm::AnalogToDigitalPinImplStm(hal::GpioPinStm& pin, AdcStm& adc, const Config& config)
: analogPin(pin)
, adc(adc)
, config(config)
{
HAL_ADC_Stop(&adc.Handle());
LL_ADC_REG_SetTriggerSource(adc.Handle().Instance, ADC_SOFTWARE_START);
}

void AnalogToDigitalPinImplStm::Measure(std::size_t numberOfSamples, const infra::Function<void(infra::MemoryRange<uint16_t>)>& onDone)
{
ADC_ChannelConfTypeDef channelConfig;
ADC_ChannelConfTypeDef channelConfig{};
channelConfig.Channel = adc.Channel(analogPin);
#if defined(STM32WB) || defined(STM32G0) || defined(STM32G4)

#ifdef ADC_REGULAR_RANK_1
channelConfig.Rank = ADC_REGULAR_RANK_1;
#else
channelConfig.Rank = 1;
#endif
#if defined(STM32F0) || defined(STM32F3)
channelConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;
#elif defined(STM32WB) || defined(STM32G4)
channelConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
channelConfig.Offset = 0;
#ifdef ADC_SMPR_SMP1
channelConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
#else
channelConfig.SamplingTime = config.samplingTime;
#endif
#ifdef ADC_OFFSET_NONE
channelConfig.OffsetNumber = ADC_OFFSET_NONE;
#endif
#ifdef ADC_SINGLE_ENDED
channelConfig.SingleDiff = ADC_SINGLE_ENDED;
#elif defined(STM32G0) || defined(STM32WBA)
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES_5;
#else
channelConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
#endif
#ifdef ADC_OFFSET_1
channelConfig.Offset = 0;
#endif
HAL_StatusTypeDef result = HAL_ADC_ConfigChannel(&adc.Handle(), &channelConfig);
Expand All @@ -84,25 +87,27 @@ namespace hal

void AnalogToDigitalInternalTemperatureStm::Measure(std::size_t numberOfSamples, const infra::Function<void(infra::MemoryRange<uint16_t>)>& onDone)
{
ADC_ChannelConfTypeDef channelConfig;
#if defined(ADC_CHANNEL_TEMPSENSOR)
ADC_ChannelConfTypeDef channelConfig{};
#ifdef ADC_CHANNEL_TEMPSENSOR
channelConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
#else
if (adc.index == 1)
channelConfig.Channel = ADC_CHANNEL_TEMPSENSOR_ADC1;
else
channelConfig.Channel = ADC_CHANNEL_TEMPSENSOR_ADC5;
#endif
#if defined(STM32WB) || defined(STM32G0) || defined(STM32G4)
#ifdef ADC_REGULAR_RANK_1
channelConfig.Rank = ADC_REGULAR_RANK_1;
#else
channelConfig.Rank = 1;
#endif
#if defined(STM32WB) || defined(STM32G4)
#ifdef ADC_OFFSET_NONE
channelConfig.OffsetNumber = ADC_OFFSET_NONE;
#endif
#ifdef ADC_SINGLE_ENDED
channelConfig.SingleDiff = ADC_SINGLE_ENDED;
#endif
#if !defined(STM32F0) && !defined(STM32F3) && !defined(STM32G0) && !defined(STM32WBA)
#ifdef ADC_OFFSET_1
channelConfig.Offset = 0;
#endif
channelConfig.SamplingTime = config.samplingTime;
Expand Down Expand Up @@ -131,37 +136,37 @@ namespace hal
EnableClockAdc(index);

handle.Instance = peripheralAdc[index];
#if !defined(STM32F3) && !defined(STM32WBA)
handle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
handle.Init.Resolution = ADC_RESOLUTION_12B;
#elif defined(STM32WBA)
#ifdef ADC_CLOCK_ASYNC_DIV4
handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
handle.Init.Resolution = ADC_RESOLUTION_12B;
#else
handle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
#endif
handle.Init.Resolution = ADC_RESOLUTION_12B;
handle.Init.ScanConvMode = DISABLE;
handle.Init.ContinuousConvMode = DISABLE;
handle.Init.DiscontinuousConvMode = DISABLE;
#if !defined(STM32G0) && !defined(STM32WBA)
#if defined(ADC_CFGR_DISCNUM) || defined(ADC_CR1_DISCNUM)
handle.Init.NbrOfDiscConversion = 0;
#endif
#if !defined(STM32F3)
handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
handle.Init.DMAContinuousRequests = DISABLE;
#endif
handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
handle.Init.NbrOfConversion = 1;
#if defined(STM32WB) || defined(STM32G0) || defined(STM32G4)
handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
#ifdef ADC_OVR_DATA_OVERWRITTEN
handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
#endif
#ifdef IS_ADC_OVERSAMPLING_RATIO
handle.Init.OversamplingMode = DISABLE;
#elif !defined(STM32F3)
handle.Init.EOCSelection = DISABLE;
#endif
#ifdef ADC_SMPR_SMP1
handle.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_79CYCLES_5;
#endif
HAL_StatusTypeDef result = HAL_ADC_Init(&handle);
assert(result == HAL_OK);

#if defined(STM32WB)
#ifdef IS_ADC_SINGLE_DIFFERENTIAL
result = HAL_ADCEx_Calibration_Start(&handle, ADC_SINGLE_ENDED);
assert(result == HAL_OK);
#endif
Expand Down Expand Up @@ -193,7 +198,7 @@ namespace hal
void AdcStm::MeasurementDone()
{
assert(onDone != nullptr);
#if defined(STM32WB) || defined(STM32G4) || defined(STM32G0) || defined(STM32WBA)
#ifdef ADC_ISR_EOC
handle.Instance->ISR |= ADC_ISR_EOC | ADC_ISR_EOS;
#else
handle.Instance->SR &= ~ADC_SR_EOC;
Expand Down
13 changes: 7 additions & 6 deletions hal_st/stm32fxxx/AnalogToDigitalPinStm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ namespace hal
{
struct AdcStmChannelConfig
{
#if defined(STM32F0) || defined(STM32F3)
uint32_t samplingTime{ ADC_SAMPLETIME_7CYCLES_5 };
#elif defined(STM32WB) || defined(STM32G4)
#if defined(ADC_SAMPLETIME_2CYCLES_5)
uint32_t samplingTime{ ADC_SAMPLETIME_2CYCLES_5 };
#elif defined(STM32G0) || defined(STM32WBA)
#elif defined(ADC_SAMPLETIME_3CYCLES_5)
uint32_t samplingTime{ ADC_SAMPLETIME_3CYCLES_5 };
#else
uint32_t samplingTime{ ADC_SAMPLETIME_3CYCLES };
Expand All @@ -31,13 +29,16 @@ namespace hal
: public AnalogToDigitalPinImplBase<uint16_t>
{
public:
explicit AnalogToDigitalPinImplStm(hal::GpioPinStm& pin, AdcStm& adc);
using Config = detail::AdcStmChannelConfig;

AnalogToDigitalPinImplStm(hal::GpioPinStm& pin, AdcStm& adc, const Config& config = Config());

void Measure(std::size_t numberOfSamples, const infra::Function<void(infra::MemoryRange<uint16_t>)>& onDone) override;

private:
AnalogPinStm analogPin;
AdcStm& adc;
Config config;
};

class AnalogToDigitalInternalTemperatureStm
Expand All @@ -46,7 +47,7 @@ namespace hal
public:
using Config = detail::AdcStmChannelConfig;

AnalogToDigitalInternalTemperatureStm(AdcStm& adc, const Config& config = Config());
explicit AnalogToDigitalInternalTemperatureStm(AdcStm& adc, const Config& config = Config());

void Measure(std::size_t numberOfSamples, const infra::Function<void(infra::MemoryRange<uint16_t>)>& onDone) override;

Expand Down
16 changes: 12 additions & 4 deletions hal_st/stm32fxxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ target_link_libraries(hal_st.stm32fxxx PUBLIC
)

target_sources(hal_st.stm32fxxx PRIVATE
$<$<STREQUAL:${TARGET_MCU},stm32wb55>:AdcDmaStm.cpp>
$<$<STREQUAL:${TARGET_MCU},stm32wb55>:AdcDmaStm.hpp>
$<$<OR:$<STREQUAL:${TARGET_MCU},stm32wb55>,$<STREQUAL:${TARGET_MCU_FAMILY},stm32wbaxx>>:AdcDmaStm.cpp>
$<$<OR:$<STREQUAL:${TARGET_MCU},stm32wb55>,$<STREQUAL:${TARGET_MCU_FAMILY},stm32wbaxx>>:AdcDmaStm.hpp>
AnalogToDigitalPinStm.cpp
AnalogToDigitalPinStm.hpp
BackupRamStm.cpp
Expand Down Expand Up @@ -123,7 +123,7 @@ if (TARGET_MCU_VENDOR STREQUAL st)
elseif (TARGET_MCU_VARIANT STREQUAL stm32wb55rg)
set(gpio_xml "${CMAKE_CURRENT_SOURCE_DIR}/ip/GPIO-STM32WB55x_gpio_v1_0_Modes.xml")
set(mcu_xml "${CMAKE_CURRENT_SOURCE_DIR}/mcu/STM32WB55RGVx.xml")
elseif (TARGET_MCU_VARIANT STREQUAL stm32wba52cg)
elseif (TARGET_MCU STREQUAL stm32wba52)
set(gpio_xml "${CMAKE_CURRENT_SOURCE_DIR}/ip/GPIO-STM32WBA52x_gpio_v1_0_Modes.xml")
set(mcu_xml "${CMAKE_CURRENT_SOURCE_DIR}/mcu/STM32WBA52CGUx.xml")
else()
Expand All @@ -135,8 +135,16 @@ if (TARGET_MCU_VENDOR STREQUAL st)
generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PinoutTableDefault.cpp GeneratePinoutTableCpp.xsl "${CMAKE_CURRENT_BINARY_DIR}/generated/stm32fxxx/PinoutTableDefaultStructure.xml")
generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PinoutTableDefault.hpp GeneratePinoutTableHpp.xsl "${CMAKE_CURRENT_BINARY_DIR}/generated/stm32fxxx/PinoutTableDefaultStructure.xml")

generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PeripheralTableStructure.xml GeneratePeripheralTableStructure.xsl $<IF:$<OR:$<STREQUAL:${TARGET_MCU_FAMILY},stm32wbaxx>,$<STREQUAL:${TARGET_MCU_FAMILY},stm32wbxx>>,PeripheralTableWbxx.xml,PeripheralTableFxxx.xml>
if (TARGET_MCU_FAMILY STREQUAL stm32wbxx)
generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PeripheralTableStructure.xml GeneratePeripheralTableStructure.xsl PeripheralTableWbxx.xml
--stringparam mcu-document ${mcu_xml})
elseif (TARGET_MCU_FAMILY STREQUAL stm32wbaxx)
generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PeripheralTableStructure.xml GeneratePeripheralTableStructure.xsl PeripheralTableWbaxx.xml
--stringparam mcu-document ${mcu_xml})
else()
generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PeripheralTableStructure.xml GeneratePeripheralTableStructure.xsl PeripheralTableFxxx.xml
--stringparam mcu-document ${mcu_xml})
endif()

generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PeripheralTable.cpp GeneratePeripheralTableCpp.xsl "${CMAKE_CURRENT_BINARY_DIR}/generated/stm32fxxx/PeripheralTableStructure.xml")
generate_xslt(hal_st.stm32fxxx generated/stm32fxxx/PeripheralTable.hpp GeneratePeripheralTableHpp.xsl "${CMAKE_CURRENT_BINARY_DIR}/generated/stm32fxxx/PeripheralTableStructure.xml")
Expand Down
29 changes: 29 additions & 0 deletions hal_st/stm32fxxx/PeripheralTableWbaxx.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<peripherals xmlns:xi="http://www.w3.org/2001/XInclude">
<peripheral name="Uart" type="USART_TypeDef*">
<item name="USART"/>
<interrupt/>
</peripheral>
<peripheral name="Lpuart" type="USART_TypeDef*">
<item name="LPUART"/>
<interrupt/>
</peripheral>
<peripheral name="Spi" type="SPI_TypeDef*"><item name="SPI"/><interrupt/></peripheral>
<peripheral name="I2c" type="I2C_TypeDef*"><item name="I2C"/>
<interrupt name="Ev" postfix="_EV"/>
<interrupt name="Er" postfix="_ER"/>
</peripheral>
<peripheral name="Sai" type="SAI_TypeDef*"><item name="SAI"/>
<interrupt/>
</peripheral>
<peripheral name="Adc" type="ADC_TypeDef*"><item name="ADC"/></peripheral>
<peripheral name="QuadSpi" type="QUADSPI_TypeDef*" base="QUADSPI_R_BASE">
<item name="QUADSPI"/>
<interrupt/>
</peripheral>
<peripheral name="Rng" type="RNG_TypeDef*"><item name="RNG"/></peripheral>
<peripheral name="Rtc" type="RTC_TypeDef*"><item name="RTC"/></peripheral>
<peripheral name="Timer" type="TIM_TypeDef*" prefix="TIM">
<item name="TIM1_8WBA5"/>
</peripheral>
</peripherals>

0 comments on commit d413549

Please sign in to comment.