Skip to content

Commit dad32cd

Browse files
committed
[example] Add SAMV71 DMA block transfer example
1 parent 23852c6 commit dad32cd

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright (c) 2023, Christopher Durand
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#include <modm/board.hpp>
13+
#include <cmath>
14+
#include <numbers>
15+
16+
using namespace Board;
17+
18+
/*
19+
* DMA block transfer example
20+
*
21+
* Output sine signal on DAC output 0
22+
*/
23+
24+
constexpr auto computeSinTable(float frequency = 1.f)
25+
{
26+
std::array<uint16_t, 50> data{};
27+
constexpr auto HalfOutput = Dac::MaxOutput / 2.f;
28+
for (size_t i = 0; i < data.size(); ++i) {
29+
constexpr auto pi = std::numbers::pi_v<float>;
30+
data[i] = HalfOutput * (1 + sin(i * (2 * pi * frequency / data.size())));
31+
}
32+
return data;
33+
}
34+
35+
constexpr std::array<uint16_t, 50> sinTable = computeSinTable(1.0f);
36+
37+
using Out0 = GpioB13;
38+
39+
void initializeDac()
40+
{
41+
Dac::connect<Out0::Ch0>();
42+
Dac::initialize<SystemClock, 12_MHz>();
43+
44+
// Max speed mode: DAC runs at DAC clock / 12 and triggers DMA
45+
Dac::setChannelMode(Dac::Channel::Channel0, Dac::Mode::MaxSpeed);
46+
47+
Dac::enableChannel(Dac::Channel::Channel0);
48+
}
49+
50+
BlockTransfer prepareTransfer()
51+
{
52+
BlockTransfer transfer;
53+
transfer.setSourceAddress(sinTable.data());
54+
transfer.setDestinationAddress(Dac::channel0DataRegister());
55+
transfer.setDataLength(sinTable.size());
56+
57+
Dma::ChannelConfig_t config;
58+
Dma::TransferType_t::set(config, Dma::TransferType::Peripheral);
59+
Dma::PeripheralDirection_t::set(config, Dma::PeripheralDirection::MemoryToPeripheral);
60+
// 16 bit data size
61+
Dma::DataWidth_t::set(config, Dma::DataWidth::HalfWord);
62+
// const data in flash, flash is connected to DMA AHB interface 1
63+
Dma::SourceBusInterface_t::set(config, Dma::BusInterface::Bus1);
64+
// peripherals are connected to DMA AHB interface 1
65+
Dma::DestinationBusInterface_t::set(config, Dma::BusInterface::Bus1);
66+
// Auto-increment source address after each sample
67+
Dma::SourceAddressingMode_t::set(config, Dma::AddressingMode::Incrementing);
68+
// Transfer is triggered by DAC channel 0 request
69+
Dma::DmaRequest_t::set(config, DmaRequests::Dacc::Ch0Tx);
70+
transfer.setConfiguration(config);
71+
72+
return transfer;
73+
}
74+
75+
DmaChannel channel = Dma::channel(0);
76+
const auto transfer = prepareTransfer();
77+
78+
int main()
79+
{
80+
Board::initialize();
81+
initializeDac();
82+
83+
Dma::initialize();
84+
const int priority = 5;
85+
Dma::enableInterruptVector(priority);
86+
87+
channel.enableInterrupts();
88+
channel.enableInterruptFlag(DmaChannel::Interrupt::EndOfBlock);
89+
90+
channel.setInterruptHandler([](auto flags) {
91+
if (flags & DmaChannel::Interrupt::EndOfBlock) {
92+
// transfer completed, restart
93+
channel.startTransfer(transfer);
94+
}
95+
});
96+
97+
channel.startTransfer(transfer);
98+
99+
while (true)
100+
{
101+
Led0::toggle();
102+
Led1::toggle();
103+
modm::delay(500ms);
104+
105+
MODM_LOG_INFO << "ping" << modm::endl;
106+
}
107+
108+
return 0;
109+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<library>
2+
<extends>modm:samv71-xplained-ultra</extends>
3+
<options>
4+
<option name="modm:build:build.path">../../../../build/samv71_xplained_ultra/dma_block_transfer</option>
5+
</options>
6+
<modules>
7+
<module>modm:build:scons</module>
8+
<module>modm:platform:dac</module>
9+
<module>modm:platform:dma</module>
10+
</modules>
11+
</library>

0 commit comments

Comments
 (0)