Skip to content

Commit

Permalink
[example] Add Nucleo G474RE DAC DMA example
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-durand committed Jun 6, 2021
1 parent a0bdef3 commit 9cbea26
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
123 changes: 123 additions & 0 deletions examples/nucleo_g474re/dac_dma/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (c) 2021, Christopher Durand
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include <modm/board.hpp>

#include <numbers>
#include <cmath>
#include <array>

using namespace Board;

constexpr auto computeSinTable(float frequency = 1.f)
{
std::array<uint16_t, 100> data{};
constexpr auto HalfOutput = ((1 << 12) - 1) / 2; // 12 bit dac
for (size_t i = 0; i < data.size(); ++i) {
constexpr auto pi = std::numbers::pi_v<float>;
data[i] = HalfOutput * (1 + sin(i * (2 * pi * frequency / data.size())));
}
return data;
}

constexpr auto sinTable1 = computeSinTable(1.0f);
constexpr auto sinTable2 = computeSinTable(2.0f);

// DAC1 channel 1 on GpioA4: constantly output 20kHz sine signal in circular mode
// DAC4 channel 1 on GpioB12: switch between 20kHz and 40 kHz sine signal after DMA transfer complete

void setupDac1()
{
using Dac = Dac1Dma;
using DacChannel = Dac::Channel1<Dma1::Channel1>;

Dac::connect<GpioOutputA4::Out1>();
Dac::initialize<Board::SystemClock>();

DacChannel::configure(sinTable1.data(), sinTable1.size(), DmaBase::CircularMode::Enabled);

// trigger source 5: timer 4 for DAC4, see reference manual
DacChannel::setTriggerSource(5);

DacChannel::startDma();
DacChannel::enableDacChannel();
}

void setupDac4()
{
using Dac = Dac4Dma;
using DacChannel = Dac::Channel1<Dma1::Channel2>;

Dac::initialize<Board::SystemClock>();

// Internal output to opamp 4
DacChannel::setMode(DacChannel::Mode::Internal);

DacChannel::configure(sinTable1.data(), sinTable1.size(), DmaBase::CircularMode::Disabled);

// trigger source 5: timer 4 for DAC4, see reference manual
DacChannel::setTriggerSource(5);

// switch between signals when transfer completed
static bool toggleBit = false;
Dma1::Channel1::setTransferCompleteIrqHandler([]() {
DacChannel::stopDma();
toggleBit = !toggleBit;
if (toggleBit) {
DacChannel::setData(sinTable1.data(), sinTable1.size());
} else {
DacChannel::setData(sinTable2.data(), sinTable2.size());
}
DacChannel::startDma();
});

Dma1::Channel1::enableInterruptVector();
Dma1::Channel1::enableInterrupt(Dma1::Interrupt::TransferComplete | Dma1::Interrupt::Error);

// DAC4 channel 1 output via opamp 4 in follower mode connected to output B12
GpioOutputB12::setAnalogInput();
OPAMP4->CSR = OPAMP_CSR_OPAMPxEN | OPAMP_CSR_VPSEL | OPAMP_CSR_VMSEL;

DacChannel::startDma();
DacChannel::enableDacChannel();
}

int main()
{
Board::initialize();
LedD13::setOutput();

MODM_LOG_INFO << "DAC DMA Demo" << modm::endl;

Dma1::enable();

setupDac1();
setupDac4();

// configure timer 4 as trigger for DACs
// 170 MHz / 85 = 2 MHz => 2 Msps DAC output
Timer4::enable();
Timer4::setMode(Timer4::Mode::UpCounter);
Timer4::setPrescaler(1);
Timer4::setOverflow(85 - 1);
Timer4::applyAndReset();
Timer4::start();

// Enable trigger out for timer 4
TIM4->CR2 |= TIM_CR2_MMS_1;

while (true)
{
LedD13::toggle();
modm::delay_ms(500);
}

return 0;
}
14 changes: 14 additions & 0 deletions examples/nucleo_g474re/dac_dma/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<library>
<extends>modm:nucleo-g474re</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_g474re/dac_dma</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:dac:1</module>
<module>modm:platform:dac:4</module>
<module>modm:platform:dma</module>
<module>modm:platform:timer:4</module>
<module>modm:build:scons</module>
</modules>
</library>

0 comments on commit 9cbea26

Please sign in to comment.