Skip to content

Commit

Permalink
[stm32] Add ADC DMA mode and ext. trigger for F1/2/37/4/7 and L1
Browse files Browse the repository at this point in the history
  • Loading branch information
victorandrehc authored and chris-durand committed Apr 1, 2023
1 parent 589aea7 commit fe722c7
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 6 deletions.
97 changes: 94 additions & 3 deletions src/modm/platform/adc/stm32/adc.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,44 @@ public:
%% endif
};

%% if target["family"] not in ["f1", "f3"]
enum class ExternalTriggerPolarity
{
NoTriggerDetection = 0x0u,
RisingEdge = 0x1u,
FallingEdge = 0x2u,
RisingAndFallingEdge = 0x3u,
};
%%endif

/**
* Enum mapping all events on a external trigger converter.
* The source mapped to each event varies on controller family,
* refer to the ADC external trigger section on reference manual
* of your controller for more information
*/
enum class RegularConversionExternalTrigger
{
Event0 = 0x0u,
Event1 = 0x1u,
Event2 = 0x2u,
Event3 = 0x3u,
Event4 = 0x4u,
Event5 = 0x5u,
Event6 = 0x6u,
Event7 = 0x7u,
%% if target["family"] not in ["f1", "f3"]
Event8 = 0x8u,
Event9 = 0x9u,
Event10 = 0xAu,
Event11 = 0xBu,
Event12 = 0xCu,
Event13 = 0xDu,
Event14 = 0xEu,
Event15 = 0xFu,
%% endif
};

/**
* Possible interrupts.
*
Expand Down Expand Up @@ -201,6 +239,9 @@ public:
static void
initialize();

static inline void
enable();

static inline void
disable();

Expand All @@ -225,7 +266,6 @@ public:
static inline uint16_t
getValue();


static inline uint16_t
readChannel(Channel channel);

Expand Down Expand Up @@ -271,14 +311,12 @@ public:
static inline Channel
getChannel();


static inline void
enableFreeRunningMode();

static inline void
disableFreeRunningMode();


static inline void
setLeftAdjustResult();

Expand Down Expand Up @@ -370,6 +408,59 @@ public:
static inline void
acknowledgeInterruptFlags(const InterruptFlag_t flags);

static inline uintptr_t
getDataRegisterAddress();

%% if target["family"] in ["f1","f3"]
static inline void
enableRegularConversionExternalTrigger(
RegularConversionExternalTrigger regularConversionExternalTrigger);

%%endif
%%if target["family"] not in ["f1","f3"]
static inline void
enableRegularConversionExternalTrigger(
ExternalTriggerPolarity externalTriggerPolarity,
RegularConversionExternalTrigger regularConversionExternalTrigger);

%%endif

/**
* Enable Dma mode for the ADC
*/
static inline void
enableDmaMode();

/**
* Disable Dma mode for the ADC
*/
static inline void
disableDmaMode();

/**
* get if adc is enabled
* @return true if ADC_CR2_ADON bit is set, false otherwise
*/
static inline bool
getAdcEnabled();

%% if target["family"] not in ["f1","f3"]
/**
* enable DMA selection for the ADC. If this is enabled DMA
* requests are issued as long as data are converted and
* the adc has dma enabled
*/
static inline void
enableDmaRequests();

/**
* disable dma selection for the ADC. If this is disabled
* no new DMA requests are issued after last transfer
*/
static inline void
disableDmaRequests();

%%endif
/**
* Enables scan mode
*/
Expand Down
75 changes: 72 additions & 3 deletions src/modm/platform/adc/stm32/adc_impl.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ modm::platform::Adc{{ id }}::initialize()
assertBaudrateInTolerance<result.frequency, frequency, tolerance >();

Rcc::enable<Peripheral::Adc{{id}}>();
ADC{{ per }}->CR2 |= ADC_CR2_ADON; // switch on ADC
enable(); // switch on ADC

setPrescaler(Prescaler{result.index});
}
Expand Down Expand Up @@ -165,6 +165,12 @@ modm::platform::Adc{{ id }}::disable()
RCC->APB2ENR &= ~RCC_APB2ENR_ADC{{ per }}EN; // stop ADC Clock
}

void
modm::platform::Adc{{ id }}::enable()
{
ADC{{ per }}->CR2 |= ADC_CR2_ADON; // switch on ADC
}

void
modm::platform::Adc{{ id }}::startConversion()
{
Expand Down Expand Up @@ -253,14 +259,77 @@ modm::platform::Adc{{ id }}::acknowledgeInterruptFlags(const InterruptFlag_t fla
ADC{{ per }}->SR = ~flags.value;
}

uintptr_t
modm::platform::Adc{{ id }}::getDataRegisterAddress()
{
return (uintptr_t) &(ADC{{ per }}->DR);
}
%% if target["family"] in ["f1","f3"]
void
modm::platform::Adc{{ id }}::enableRegularConversionExternalTrigger(
RegularConversionExternalTrigger regularConversionExternalTrigger)
{
const auto externalTrigger =
(static_cast<uint32_t>(regularConversionExternalTrigger) << ADC_CR2_EXTSEL_Pos);
const auto mask = ADC_CR2_EXTSEL_Msk;
ADC{{ per }}->CR2 = (ADC{{ per }}->CR2 & ~mask) | externalTrigger;
}
%%else
void
modm::platform::Adc{{ id }}::enableRegularConversionExternalTrigger(
ExternalTriggerPolarity externalTriggerPolarity,
RegularConversionExternalTrigger regularConversionExternalTrigger)
{
const auto polarity =
(static_cast<uint32_t>(externalTriggerPolarity) << ADC_CR2_EXTEN_Pos);
const auto externalTrigger =
(static_cast<uint32_t>(regularConversionExternalTrigger) << ADC_CR2_EXTSEL_Pos);
const auto mask = ADC_CR2_EXTEN_Msk | ADC_CR2_EXTSEL_Msk;
ADC{{ per }}->CR2 = (ADC{{ per }}->CR2 & ~mask) | polarity | externalTrigger;
}
%%endif

void
modm::platform::Adc{{ id }}::enableDmaMode()
{
ADC{{ per }}->CR2 |= ADC_CR2_DMA;
}

void
modm::platform::Adc{{ id }}::disableDmaMode()
{
ADC{{ per }}->CR2 &= ~ADC_CR2_DMA;
}

bool
modm::platform::Adc{{ id }}::getAdcEnabled()
{
return (ADC{{ per }}->CR2 & ADC_CR2_ADON) == ADC_CR2_ADON;
}

%% if target["family"] not in ["f1","f3"]
void
modm::platform::Adc{{ id }}::enableDmaRequests()
{
ADC{{ per }}->CR2 |= ADC_CR2_DDS;
}

void
modm::platform::Adc{{ id }}::disableDmaRequests()
{
ADC{{ per }}->CR2 &= ~ADC_CR2_DDS;
}

%%endif

void
modm::platform::Adc{{ id }}::enableScanMode()
{
ADC{{ per }}->CR1 |= (1 << ADC_CR1_SCAN);
ADC{{ per }}->CR1 |= ADC_CR1_SCAN;
}

void
modm::platform::Adc{{ id }}::disableScanMode()
{
ADC{{ per }}->CR1 &= ~(1 << ADC_CR1_SCAN);
ADC{{ per }}->CR1 &= ~ADC_CR1_SCAN;
}

0 comments on commit fe722c7

Please sign in to comment.