-
Notifications
You must be signed in to change notification settings - Fork 143
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[example] Add SAMV71 DMA linked list transfer example
- Loading branch information
1 parent
1d774c5
commit 2195a72
Showing
2 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
118 changes: 118 additions & 0 deletions
118
examples/samv71_xplained_ultra/dma/linked_list_transfer/main.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* Copyright (c) 2023, 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 <cmath> | ||
#include <numbers> | ||
|
||
using namespace Board; | ||
|
||
/* | ||
* DMA linked list transfer example | ||
* | ||
* Output two alternating signals on DAC output 0 | ||
*/ | ||
|
||
constexpr auto computeSinTable(float frequency = 1.f) | ||
{ | ||
std::array<uint16_t, 50> 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 std::array<uint16_t, 50> signal0 = computeSinTable(1.0f); | ||
constexpr std::array<uint16_t, 50> signal1 = computeSinTable(2.0f); | ||
|
||
using Out0 = GpioB13; | ||
|
||
void initializeDac() | ||
{ | ||
Dac::connect<Out0::Ch0>(); | ||
Dac::initialize<SystemClock, modm::MHz(12)>(); | ||
|
||
// Max speed mode: DAC runs at DAC clock / 12 and triggers DMA | ||
Dac::setChannelMode(Dac::Channel::Channel0, Dac::Mode::MaxSpeed); | ||
|
||
Dac::enableChannel(Dac::Channel::Channel0); | ||
} | ||
|
||
using ListTransfer = LinkedListTransfer<Dma::View2, Dma::View0Src>; | ||
|
||
ListTransfer prepareTransfer() | ||
{ | ||
ListTransfer transfer; | ||
|
||
// Transfer configuration, set by first descriptor. | ||
// It is not overwritten by the second View0 descriptor. | ||
Dma::ChannelConfig_t config; | ||
Dma::TransferType_t::set(config, Dma::TransferType::Peripheral); | ||
Dma::PeripheralDirection_t::set(config, Dma::PeripheralDirection::MemoryToPeripheral); | ||
// 16 bit data size | ||
Dma::DataWidth_t::set(config, Dma::DataWidth::HalfWord); | ||
// const data in flash, flash is connected to DMA AHB interface 1 | ||
Dma::SourceBusInterface_t::set(config, Dma::BusInterface::Bus1); | ||
// peripherals are connected to DMA AHB interface 1 | ||
Dma::DestinationBusInterface_t::set(config, Dma::BusInterface::Bus1); | ||
// Auto-increment source address after each sample | ||
Dma::SourceAddressingMode_t::set(config, Dma::AddressingMode::Incrementing); | ||
// Transfer is triggered by DAC channel 0 request | ||
Dma::DmaRequest_t::set(config, DmaRequests::Dacc::Ch0Tx); | ||
|
||
auto [d0, d1] = transfer.descriptors(); | ||
|
||
// Configure first descriptor (type 2) | ||
// Set: configuration, source, destination, size | ||
d0.setConfiguration(config); | ||
d0.setSourceAddress(signal0.data()); | ||
d0.setDestinationAddress(Dac::channel0DataRegister()); | ||
d0.setDataLength(signal0.size()); | ||
|
||
// Configure first descriptor (type 0) | ||
// Update source and size, other parameters remain unchanged | ||
d1.setSourceAddress(signal1.data()); | ||
d1.setDataLength(signal1.size()); | ||
|
||
// Circular mode | ||
// After the second transfer has finished, the sequence automatically starts | ||
// again with the first descriptor. | ||
transfer.setCircularMode(true); | ||
|
||
return transfer; | ||
} | ||
|
||
DmaChannel channel = Dma::channel(0); | ||
// Transfer object must remain valid while transfer is active | ||
auto transfer = prepareTransfer(); | ||
|
||
int main() | ||
{ | ||
Board::initialize(); | ||
initializeDac(); | ||
|
||
Dma::initialize(); | ||
|
||
channel.startTransfer(transfer); | ||
|
||
while (true) | ||
{ | ||
Led0::toggle(); | ||
Led1::toggle(); | ||
modm::delay(500ms); | ||
|
||
MODM_LOG_INFO << "ping" << modm::endl; | ||
} | ||
|
||
return 0; | ||
} |
11 changes: 11 additions & 0 deletions
11
examples/samv71_xplained_ultra/dma/linked_list_transfer/project.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<library> | ||
<extends>modm:samv71-xplained-ultra</extends> | ||
<options> | ||
<option name="modm:build:build.path">../../../../build/samv71_xplained_ultra/dma_linked_list_transfer</option> | ||
</options> | ||
<modules> | ||
<module>modm:build:scons</module> | ||
<module>modm:platform:dac</module> | ||
<module>modm:platform:dma</module> | ||
</modules> | ||
</library> |