Skip to content

Commit

Permalink
[stm32] H7 DMA and fixes for DAC DMA
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Dec 31, 2021
2 parents 5a9ad25 + cc22238 commit e3c0321
Show file tree
Hide file tree
Showing 18 changed files with 454 additions and 58 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git

## Microcontrollers

modm can create a HAL for <!--allcount-->3195<!--/allcount--> devices of these vendors:
modm can create a HAL for <!--allcount-->3256<!--/allcount--> devices of these vendors:

- STMicroelectronics STM32: <!--stmcount-->2621<!--/stmcount--> devices.
- STMicroelectronics STM32: <!--stmcount-->2682<!--/stmcount--> devices.
- Microchip SAM: <!--samcount-->186<!--/samcount--> devices.
- Microchip AVR: <!--avrcount-->388<!--/avrcount--> devices.

Expand Down Expand Up @@ -206,13 +206,13 @@ Please [discover modm's peripheral drivers for your specific device][discover].
<td align="left">DMA</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">○</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">○</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td align="center">✅</td>
Expand Down
80 changes: 80 additions & 0 deletions examples/nucleo_f446ze/dac_dma/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* 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 sinTable = computeSinTable(1.0f);

// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode

void setupDac()
{
using Dac = DacDma;
using DacChannel = Dac::Channel1<Dma1::Channel5>;

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

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

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

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

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

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

Dma1::enable();
setupDac();

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

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

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

return 0;
}
13 changes: 13 additions & 0 deletions examples/nucleo_f446ze/dac_dma/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<extends>modm:nucleo-f446ze</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_f446ze/dac_dma</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:dac</module>
<module>modm:platform:dma</module>
<module>modm:platform:timer:4</module>
<module>modm:build:scons</module>
</modules>
</library>
80 changes: 80 additions & 0 deletions examples/nucleo_h723zg/dac_dma/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* 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 sinTable = computeSinTable(1.0f);

// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode

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

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

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

// trigger source 3: timer 4, see reference manual
DacChannel::setTriggerSource(3);

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

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

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

Dma1::enable();
setupDac();

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

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

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

return 0;
}
13 changes: 13 additions & 0 deletions examples/nucleo_h723zg/dac_dma/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<extends>modm:nucleo-h723zg</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_h723zg/dac_dma</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:dac:1</module>
<module>modm:platform:dma</module>
<module>modm:platform:timer:4</module>
<module>modm:build:scons</module>
</modules>
</library>
80 changes: 80 additions & 0 deletions examples/nucleo_l476rg/dac_dma/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* 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 sinTable = computeSinTable(1.0f);

// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode

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

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

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

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

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

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

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

Dma1::enable();
setupDac();

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

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

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

return 0;
}
13 changes: 13 additions & 0 deletions examples/nucleo_l476rg/dac_dma/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<library>
<extends>modm:nucleo-l476rg</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_l476rg/dac_dma</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:dac:1</module>
<module>modm:platform:dma</module>
<module>modm:platform:timer:4</module>
<module>modm:build:scons</module>
</modules>
</library>
83 changes: 83 additions & 0 deletions examples/stm32f769i_discovery/dac_dma/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* 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 sinTable = computeSinTable(1.0f);

// DAC1 channel 1 on GpioA4: constantly output sine signal in circular mode

void setupDac()
{
using Dac = DacDma;
using DacChannel = Dac::Channel1<Dma1::Channel5>;

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

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

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

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

int main()
{
Board::initialize();
LedJ5::setOutput();
LedJ13::setOutput(true);

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

Dma1::enable();
setupDac();

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

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

//GpioOutputA4::setOutput(true);
while (true)
{
LedJ5::toggle();
LedJ13::toggle();
modm::delay_ms(500);
}

return 0;
}
Loading

0 comments on commit e3c0321

Please sign in to comment.