Skip to content

Commit 182948d

Browse files
committed
[example] Add SAMV71 DMA linked list transfer example
1 parent dad32cd commit 182948d

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
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 linked list transfer example
20+
*
21+
* Output two alternating signals 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> signal0 = computeSinTable(1.0f);
36+
constexpr std::array<uint16_t, 50> signal1 = computeSinTable(2.0f);
37+
38+
using Out0 = GpioB13;
39+
40+
void initializeDac()
41+
{
42+
Dac::connect<Out0::Ch0>();
43+
Dac::initialize<SystemClock, 12_MHz>();
44+
45+
// Max speed mode: DAC runs at DAC clock / 12 and triggers DMA
46+
Dac::setChannelMode(Dac::Channel::Channel0, Dac::Mode::MaxSpeed);
47+
48+
Dac::enableChannel(Dac::Channel::Channel0);
49+
}
50+
51+
using ListTransfer = LinkedListTransfer<Dma::View2, Dma::View0Src>;
52+
53+
ListTransfer prepareTransfer()
54+
{
55+
ListTransfer transfer;
56+
57+
// Transfer configuration, set by first descriptor.
58+
// It is not overwritten by the second View0 descriptor.
59+
Dma::ChannelConfig_t config;
60+
Dma::TransferType_t::set(config, Dma::TransferType::Peripheral);
61+
Dma::PeripheralDirection_t::set(config, Dma::PeripheralDirection::MemoryToPeripheral);
62+
// 16 bit data size
63+
Dma::DataWidth_t::set(config, Dma::DataWidth::HalfWord);
64+
// const data in flash, flash is connected to DMA AHB interface 1
65+
Dma::SourceBusInterface_t::set(config, Dma::BusInterface::Bus1);
66+
// peripherals are connected to DMA AHB interface 1
67+
Dma::DestinationBusInterface_t::set(config, Dma::BusInterface::Bus1);
68+
// Auto-increment source address after each sample
69+
Dma::SourceAddressingMode_t::set(config, Dma::AddressingMode::Incrementing);
70+
// Transfer is triggered by DAC channel 0 request
71+
Dma::DmaRequest_t::set(config, DmaRequests::Dacc::Ch0Tx);
72+
73+
auto [d0, d1] = transfer.descriptors();
74+
75+
// Configure first descriptor (type 2)
76+
// Set: configuration, source, destination, size
77+
d0.setConfiguration(config);
78+
d0.setSourceAddress(signal0.data());
79+
d0.setDestinationAddress(Dac::channel0DataRegister());
80+
d0.setDataLength(signal0.size());
81+
82+
// Configure first descriptor (type 0)
83+
// Update source and size, other parameters remain unchanged
84+
d1.setSourceAddress(signal1.data());
85+
d1.setDataLength(signal1.size());
86+
87+
// Circular mode
88+
// After the second transfer has finished, the sequence automatically starts
89+
// again with the first descriptor.
90+
transfer.setCircularMode(true);
91+
92+
return transfer;
93+
}
94+
95+
DmaChannel channel = Dma::channel(0);
96+
// Transfer object must remain valid while transfer is active
97+
auto transfer = prepareTransfer();
98+
99+
int main()
100+
{
101+
Board::initialize();
102+
initializeDac();
103+
104+
Dma::initialize();
105+
106+
channel.startTransfer(transfer);
107+
108+
while (true)
109+
{
110+
Led0::toggle();
111+
Led1::toggle();
112+
modm::delay(500ms);
113+
114+
MODM_LOG_INFO << "ping" << modm::endl;
115+
}
116+
117+
return 0;
118+
}
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_linked_list_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)