Skyward boardcore
Loading...
Searching...
No Matches
DMA.cpp
Go to the documentation of this file.
1/* Copyright (c) 2025 Skyward Experimental Rocketry
2 * Author: Alberto Nidasio, Fabrizio Monti
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#include "DMA.h"
24
25#include <kernel/logging.h>
26#include <utils/ClockUtils.h>
27#include <utils/Debug.h>
28
29#include <map>
30
31using namespace miosix;
32
43void __attribute__((naked)) DMA1_Stream0_IRQHandler()
44{
45 saveContext();
46 asm volatile("bl _Z20DMA1_Stream0_IRQImplv");
47 restoreContext();
48}
49
55
56#ifndef STM32F407xx
57// This stream is used by miosix for STM32F407xx boards
58void __attribute__((naked)) DMA1_Stream1_IRQHandler()
59{
60 saveContext();
61 asm volatile("bl _Z20DMA1_Stream1_IRQImplv");
62 restoreContext();
63}
64
65void __attribute__((used)) DMA1_Stream1_IRQImpl()
66{
69}
70#endif // STM32F407xx
71
72void __attribute__((naked)) DMA1_Stream2_IRQHandler()
73{
74 saveContext();
75 asm volatile("bl _Z20DMA1_Stream2_IRQImplv");
76 restoreContext();
77}
78
79void __attribute__((used)) DMA1_Stream2_IRQImpl()
80{
83}
84
85#ifndef STM32F407xx
86// This stream is used by miosix for STM32F407xx boards
87void __attribute__((naked)) DMA1_Stream3_IRQHandler()
88{
89 saveContext();
90 asm volatile("bl _Z20DMA1_Stream3_IRQImplv");
91 restoreContext();
92}
93
94void __attribute__((used)) DMA1_Stream3_IRQImpl()
95{
98}
99#endif // STM32F407xx
100
101void __attribute__((naked)) DMA1_Stream4_IRQHandler()
102{
103 saveContext();
104 asm volatile("bl _Z20DMA1_Stream4_IRQImplv");
105 restoreContext();
106}
107
108void __attribute__((used)) DMA1_Stream4_IRQImpl()
109{
112}
113
114void __attribute__((naked)) DMA1_Stream5_IRQHandler()
115{
116 saveContext();
117 asm volatile("bl _Z20DMA1_Stream5_IRQImplv");
118 restoreContext();
119}
120
121void __attribute__((used)) DMA1_Stream5_IRQImpl()
122{
125}
126
127void __attribute__((naked)) DMA1_Stream6_IRQHandler()
128{
129 saveContext();
130 asm volatile("bl _Z20DMA1_Stream6_IRQImplv");
131 restoreContext();
132}
133
134void __attribute__((used)) DMA1_Stream6_IRQImpl()
135{
138}
139
140void __attribute__((naked)) DMA1_Stream7_IRQHandler()
141{
142 saveContext();
143 asm volatile("bl _Z20DMA1_Stream7_IRQImplv");
144 restoreContext();
145}
146
147void __attribute__((used)) DMA1_Stream7_IRQImpl()
148{
151}
152
153void __attribute__((naked)) DMA2_Stream0_IRQHandler()
154{
155 saveContext();
156 asm volatile("bl _Z20DMA2_Stream0_IRQImplv");
157 restoreContext();
158}
159
160void __attribute__((used)) DMA2_Stream0_IRQImpl()
161{
164}
165
166void __attribute__((naked)) DMA2_Stream1_IRQHandler()
167{
168 saveContext();
169 asm volatile("bl _Z20DMA2_Stream1_IRQImplv");
170 restoreContext();
171}
172
173void __attribute__((used)) DMA2_Stream1_IRQImpl()
174{
177}
178
179void __attribute__((naked)) DMA2_Stream2_IRQHandler()
180{
181 saveContext();
182 asm volatile("bl _Z20DMA2_Stream2_IRQImplv");
183 restoreContext();
184}
185
186void __attribute__((used)) DMA2_Stream2_IRQImpl()
187{
190}
191
192// This stream is used by miosix for all currently supported
193// boards, so it is simply commented out
194// void __attribute__((naked)) DMA2_Stream3_IRQHandler()
195// {
196// saveContext();
197// asm volatile("bl _Z20DMA2_Stream3_IRQImplv");
198// restoreContext();
199// }
200
201// void __attribute__((used)) DMA2_Stream3_IRQImpl()
202// {
203// Boardcore::DMADriver::instance().IRQhandleInterrupt(
204// Boardcore::DMADefs::DMAStreamId::DMA2_Str3);
205// }
206
207void __attribute__((naked)) DMA2_Stream4_IRQHandler()
208{
209 saveContext();
210 asm volatile("bl _Z20DMA2_Stream4_IRQImplv");
211 restoreContext();
212}
213
214void __attribute__((used)) DMA2_Stream4_IRQImpl()
215{
218}
219
220#if !defined(STM32F767xx) && !defined(STM32F429xx)
221// This stream is used by miosix for STM32F767xx
222// and STM32F429xx boards
223void __attribute__((naked)) DMA2_Stream5_IRQHandler()
224{
225 saveContext();
226 asm volatile("bl _Z20DMA2_Stream5_IRQImplv");
227 restoreContext();
228}
229
230void __attribute__((used)) DMA2_Stream5_IRQImpl()
231{
234}
235#endif // STM32F767xx & STM32F429xx
236
237void __attribute__((naked)) DMA2_Stream6_IRQHandler()
238{
239 saveContext();
240 asm volatile("bl _Z20DMA2_Stream6_IRQImplv");
241 restoreContext();
242}
243
244void __attribute__((used)) DMA2_Stream6_IRQImpl()
245{
248}
249
250#if !defined(STM32F767xx) && !defined(STM32F429xx)
251// This stream is used by miosix for STM32F767xx
252// and STM32F429xx boards
253void __attribute__((naked)) DMA2_Stream7_IRQHandler()
254{
255 saveContext();
256 asm volatile("bl _Z20DMA2_Stream7_IRQImplv");
257 restoreContext();
258}
259
260void __attribute__((used)) DMA2_Stream7_IRQImpl()
261{
264}
265#endif // STM32F767xx & STM32F429xx
266
267namespace Boardcore
268{
269
271{
272 DMAStream& stream = streams.at(id);
273
274 stream.readFlags();
275 stream.clearAllFlags();
276
277 // Run the callbacks if necessary
278 if (stream.halfTransferCallback && stream.halfTransferFlag)
279 stream.halfTransferCallback();
280
281 if (stream.transferCompleteCallback && stream.transferCompleteFlag)
282 stream.transferCompleteCallback();
283
284 if (stream.errorCallback &&
285 (stream.transferErrorFlag || stream.fifoErrorFlag ||
286 stream.directModeErrorFlag))
287 {
288 stream.errorCallback();
289 }
290
291 // Wakeup the thread if the user is waiting
292 if (stream.waitingThread)
293 IRQwakeupThread(stream);
294}
295
296void DMADriver::IRQwakeupThread(DMAStream& stream)
297{
298 // Wakeup the waiting thread
299 stream.waitingThread->wakeup();
300
301 // If the waiting thread has a higher priority than the current
302 // thread then reschedule
303 if (stream.waitingThread->IRQgetPriority() >
304 miosix::Thread::IRQgetCurrentThread()->IRQgetPriority())
305 {
306 miosix::Scheduler::IRQfindNextThread();
307 }
308
309 // Clear the thread pointer, this way the thread will be sure it is
310 // not a spurious wakeup
311 stream.waitingThread = nullptr;
312}
313
315{
316 static DMADriver instance;
317 return instance;
318}
319
321{
322 Lock<FastMutex> l(mutex);
323
324 // Return true, meaning that the channel is free, only if it is not yet
325 // allocated
326 return streams.count(id) == 0;
327}
328
330 DMADefs::Channel channel,
331 std::chrono::nanoseconds timeout)
332{
333 Lock<FastMutex> l(mutex);
334
335 // Wait until the stream is free or the timeout expires
336 while (streams.count(id) != 0)
337 {
338 if (timeout == std::chrono::nanoseconds::zero())
339 {
340 cv.wait(l);
341 }
342 else
343 {
344 auto res = cv.timedWait(l, timeout.count());
345
346 if (res == TimedWaitResult::Timeout)
347 {
348 // The timeout expired
349 return DMAStreamGuard(nullptr);
350 }
351 }
352 }
353
354 streams.insert(
355 std::pair<DMADefs::DMAStreamId, DMAStream>(id, DMAStream(id, channel)));
356 return DMAStreamGuard(&(streams.at(id)));
357}
358
360 DMADefs::Peripherals peripheral, std::chrono::nanoseconds timeout)
361{
362 const auto availableStreams =
363 DMADefs::mapPeripherals.equal_range(peripheral);
364
365 Lock<FastMutex> l(mutex);
366 while (true)
367 {
368 // Iterate through the streams for that peripheral,
369 // return the first available
370 for (auto it = availableStreams.first; it != availableStreams.second;
371 ++it)
372 {
373 DMADefs::DMAStreamId id = it->second.first;
374 DMADefs::Channel channel = it->second.second;
375
376 if (streams.count(id) == 0)
377 {
378 // Stream is free
379 streams.insert(std::pair<DMADefs::DMAStreamId, DMAStream>(
380 id, DMAStream(id, channel)));
381 return DMAStreamGuard(&(streams.at(id)));
382 }
383 }
384
385 if (timeout == std::chrono::nanoseconds::zero())
386 {
387 cv.wait(l);
388 }
389 else
390 {
391 auto res = cv.timedWait(l, timeout.count());
392
393 if (res == TimedWaitResult::Timeout)
394 {
395 // The timeout expired
396 return DMAStreamGuard(nullptr);
397 }
398 }
399 }
400}
401
403{
404 Lock<FastMutex> l(mutex);
405
406 if (streams.count(id) != 0)
407 {
408 streams.erase(id);
409 cv.broadcast();
410 }
411}
412
413DMADriver::DMADriver()
414{
415 // For now the clocks are always enabled
418
419 // Reset interrupts flags by setting the clear bits to 1
420 constexpr int resetValue = 0x0f7d0f7d;
421 DMA1->HIFCR = resetValue;
422 DMA1->LIFCR = resetValue;
423 DMA2->HIFCR = resetValue;
424 DMA2->LIFCR = resetValue;
425}
426
428{
429 currentSetup = transaction;
430
431 // Reset the configuration
432 registers->CR = 0;
433
434 // Wait for the stream to actually be disabled
435 while (registers->CR & DMA_SxCR_EN)
436 ;
437
438 setChannel(currentChannel);
439 registers->CR |= static_cast<uint32_t>(transaction.direction);
440 registers->CR |= static_cast<uint32_t>(transaction.priority);
441 if (transaction.circularMode)
442 registers->CR |= DMA_SxCR_CIRC;
443
445
447 {
448 // In memory to peripheral mode, the source address is the memory
449 // address
450
451 registers->CR |= static_cast<uint32_t>(transaction.srcSize)
452 << DMA_SxCR_MSIZE_Pos;
453 registers->CR |= static_cast<uint32_t>(transaction.dstSize)
454 << DMA_SxCR_PSIZE_Pos;
455
456 if (transaction.srcIncrement)
457 registers->CR |= DMA_SxCR_MINC;
458 if (transaction.dstIncrement)
459 registers->CR |= DMA_SxCR_PINC;
460
461 registers->M0AR = reinterpret_cast<uint32_t>(transaction.srcAddress);
462 registers->PAR = reinterpret_cast<uint32_t>(transaction.dstAddress);
463 }
464 else
465 {
466 // In peripheral to memory or memory to memory mode, the source address
467 // goes into the peripheral address register
468
469 registers->CR |= static_cast<uint32_t>(transaction.srcSize)
470 << DMA_SxCR_PSIZE_Pos;
471 registers->CR |= static_cast<uint32_t>(transaction.dstSize)
472 << DMA_SxCR_MSIZE_Pos;
473
474 if (transaction.srcIncrement)
475 registers->CR |= DMA_SxCR_PINC;
476 if (transaction.dstIncrement)
477 registers->CR |= DMA_SxCR_MINC;
478
479 registers->PAR = reinterpret_cast<uint32_t>(transaction.srcAddress);
480 registers->M0AR = reinterpret_cast<uint32_t>(transaction.dstAddress);
481 }
482
483 if (transaction.doubleBufferMode)
484 {
485 registers->CR |= DMA_SxCR_DBM;
486 registers->M1AR =
487 reinterpret_cast<uint32_t>(transaction.secondMemoryAddress);
488 }
489
490 bool enableInterrupt = false;
491 if (transaction.enableHalfTransferInterrupt)
492 {
494 registers->CR |= DMA_SxCR_HTIE;
495 enableInterrupt = true;
496 }
497 if (transaction.enableTransferCompleteInterrupt)
498 {
500 registers->CR |= DMA_SxCR_TCIE;
501 enableInterrupt = true;
502 }
503 if (transaction.enableTransferErrorInterrupt)
504 {
506 registers->CR |= DMA_SxCR_TEIE;
507 enableInterrupt = true;
508 }
509 if (transaction.enableFifoErrorInterrupt)
510 {
512 registers->FCR |= DMA_SxFCR_FEIE;
513 enableInterrupt = true;
514 }
515 if (transaction.enableDirectModeErrorInterrupt)
516 {
518 registers->CR |= DMA_SxCR_DMEIE;
519 enableInterrupt = true;
520 }
521
522 // Select the interrupt number
523 IRQn_Type irqNumber = DMADefs::irqNumberMapping[static_cast<uint8_t>(id)];
524 if (enableInterrupt)
525 {
526 NVIC_SetPriority(irqNumber, 8);
527 NVIC_ClearPendingIRQ(irqNumber);
528 NVIC_EnableIRQ(irqNumber);
529 }
530 else
531 {
532 NVIC_DisableIRQ(irqNumber);
533 }
534}
535
537{
538 // Reset all saved flags
539 halfTransferFlag = false;
540 transferCompleteFlag = false;
541 transferErrorFlag = false;
542 fifoErrorFlag = false;
543 directModeErrorFlag = false;
544
545 // Before setting EN bit to '1' to start a new transfer, the event
546 // flags corresponding to the stream in DMA_LISR or DMA_HISR
547 // register must be cleared.
549
550 // Enable the peripheral
551 registers->CR |= DMA_SxCR_EN;
552}
553
554void DMAStream::disable() { registers->CR &= ~DMA_SxCR_EN; }
555
557{
558 waitForInterruptEventImpl(
559 currentSetup.enableHalfTransferInterrupt,
560 std::bind(&DMAStream::getHalfTransferFlagStatus, this),
561 std::bind(&DMAStream::clearHalfTransferFlag, this), halfTransferFlag,
562 -1);
563}
564
566{
567 waitForInterruptEventImpl(
570 std::bind(&DMAStream::clearTransferCompleteFlag, this),
571 transferCompleteFlag, -1);
572
573#ifdef STM32F767xx
574 invalidateCache();
575#endif // STM32F767xx
576}
577
578bool DMAStream::timedWaitForHalfTransfer(std::chrono::nanoseconds timeout_ns)
579{
580 return waitForInterruptEventImpl(
581 currentSetup.enableHalfTransferInterrupt,
582 std::bind(&DMAStream::getHalfTransferFlagStatus, this),
583 std::bind(&DMAStream::clearHalfTransferFlag, this), halfTransferFlag,
584 timeout_ns.count());
585}
586
588 std::chrono::nanoseconds timeout_ns)
589{
590 bool ret = waitForInterruptEventImpl(
593 std::bind(&DMAStream::clearTransferCompleteFlag, this),
594 transferCompleteFlag, timeout_ns.count());
595
596#ifdef STM32F767xx
597 invalidateCache();
598#endif // STM32F767xx
599
600 return ret;
601}
602
603#ifdef STM32F767xx
604void DMAStream::invalidateCache()
605{
622 // If the data was copied from memory to a peripheral there's
623 // no need to worry about cache
625 return;
626
627 constexpr uint8_t CACHE_LINE_SIZE = 32;
628
629 // Aligned ptr: round down to the nearest address that is
630 // 32 bytes aligned
631 uintptr_t alignedPtr =
632 (uintptr_t)currentSetup.dstAddress & ~(CACHE_LINE_SIZE - 1);
633
634 // Evaluate how many bytes were added, due to the round down
635 uintptr_t diff = (uintptr_t)currentSetup.dstAddress - alignedPtr;
636
637 // Aligned size: compute the amount of bytes being invalidated
638 int32_t alignedSize = currentSetup.numberOfDataItems;
639 if (currentSetup.dstSize == DMATransaction::DataSize::BITS_16)
640 alignedSize *= 2;
641 else if (currentSetup.dstSize == DMATransaction::DataSize::BITS_32)
642 alignedSize *= 4;
643 alignedSize += diff;
644
645 SCB_InvalidateDCache_by_Addr((uint32_t*)alignedPtr, alignedSize);
646}
647#endif // STM32F767xx
648
649void DMAStream::setHalfTransferCallback(std::function<void()> callback)
650{
651 halfTransferCallback = callback;
652}
653
654void DMAStream::resetHalfTransferCallback() { halfTransferCallback = nullptr; }
655
656void DMAStream::setTransferCompleteCallback(std::function<void()> callback)
657{
658 transferCompleteCallback = callback;
659}
660
662{
663 transferCompleteCallback = nullptr;
664}
665
666void DMAStream::setErrorCallback(std::function<void()> callback)
667{
668 errorCallback = callback;
669}
670
671void DMAStream::resetErrorCallback() { errorCallback = nullptr; }
672
674{
675 uint8_t flags = *ISR >> IFindex;
676
677 halfTransferFlag = flags & DMA_LISR_HTIF0;
678 transferCompleteFlag = flags & DMA_LISR_TCIF0;
679 transferErrorFlag = flags & DMA_LISR_TEIF0;
680 fifoErrorFlag = flags & DMA_LISR_DMEIF0;
681 directModeErrorFlag = flags & DMA_LISR_DMEIF0;
682}
683
684bool DMAStream::setNumberOfDataItems(const uint16_t nBytes)
685{
686 // Verify that the stream is disabled while doing it
687 if ((registers->CR & DMA_SxCR_EN) != 0)
688 {
689 // Cannot proceed
690 return false;
691 }
692
693 currentSetup.numberOfDataItems = nBytes;
694 registers->NDTR = nBytes;
695 return true;
696}
697
699{
700 registers->CR |= static_cast<uint32_t>(channel);
701}
702
704{
705 return (registers->CR & DMA_SxCR_CT) != 0 ? 2 : 1;
706}
707
708DMAStream::DMAStream(DMADefs::DMAStreamId id, DMADefs::Channel channel)
709 : id(id), currentChannel(channel)
710{
711 // Get the channel registers base address and the interrupt flags clear
712 // register address
714 {
715 registers = reinterpret_cast<DMA_Stream_TypeDef*>(
716 DMA1_BASE + 0x10 + 0x18 * static_cast<uint8_t>(id));
717
719 {
720 // Streams from 0 to 3 use low registers (LIFCR and LISR)
721 IFCR = &DMA1->LIFCR;
722 ISR = &DMA1->LISR;
723 }
724 else
725 {
726 // Streams from 4 to 7 use high registers (HIFCR and HISR)
727 IFCR = &DMA1->HIFCR;
728 ISR = &DMA1->HISR;
729 }
730 }
731 else
732 {
733 registers = reinterpret_cast<DMA_Stream_TypeDef*>(
734 DMA2_BASE + 0x10 + 0x18 * (static_cast<uint8_t>(id) - 8));
735
737 {
738 // Streams from 0 to 3 use low registers (LIFCR and LISR)
739 IFCR = &DMA2->LIFCR;
740 ISR = &DMA2->LISR;
741 }
742 else
743 {
744 // Streams from 4 to 7 use high registers (HIFCR and HISR)
745 IFCR = &DMA2->HIFCR;
746 ISR = &DMA2->HISR;
747 }
748 }
749
750 // Compute the index for the interrupt flags clear register
751 // Refer to reference manual for the register bits structure
752 int offset = static_cast<uint8_t>(id) % 4;
753 IFindex = (offset % 2) * 6 + (offset / 2) * 16;
754}
755
757{
758 D(assert((pStream != nullptr) && "DMAStreamGuard: pointer is null"));
759
760 return pStream;
761}
762
763} // namespace Boardcore
void __attribute__((naked)) DMA1_Stream0_IRQHandler()
Definition DMA.cpp:43
#define D(x)
Definition Debug.h:57
This class is responsible for streams acquisition, streams release and interrupt handling.
Definition DMA.h:168
DMAStreamGuard acquireStreamForPeripheral(DMADefs::Peripherals peripheral, std::chrono::nanoseconds timeout=std::chrono::nanoseconds::zero())
Try to acquire a stream that is connected to the specified peripheral.
Definition DMA.cpp:359
static DMADriver & instance()
Definition DMA.cpp:314
DMAStreamGuard acquireStream(DMADefs::DMAStreamId id, DMADefs::Channel channel, std::chrono::nanoseconds timeout=std::chrono::nanoseconds::zero())
Try to acquire the specified stream and initialize it with the correct channel.
Definition DMA.cpp:329
void IRQhandleInterrupt(DMADefs::DMAStreamId id)
Definition DMA.cpp:270
void releaseStream(DMADefs::DMAStreamId id)
Definition DMA.cpp:402
bool tryStream(DMADefs::DMAStreamId id)
Definition DMA.cpp:320
Simple RAII class to handle DMA streams.
Definition DMA.h:557
DMAStream * operator->()
Definition DMA.cpp:756
This class represents the actual DMA stream. It can be used to setup, start and stop DMA transactions...
Definition DMA.h:232
bool getHalfTransferFlagStatus()
Returns the last read status of the half transfer flag.
Definition DMA.h:339
bool timedWaitForTransferComplete(std::chrono::nanoseconds timeout_ns)
Wait for the transfer complete signal. The caller waits for the corresponding interrupt,...
Definition DMA.cpp:587
void clearDirectModeErrorFlag()
Definition DMA.h:390
void resetTransferCompleteCallback()
Definition DMA.cpp:661
void disable()
Stop the DMA transaction (if running). This is equivalent to killing the transaction: DO NOT expect t...
Definition DMA.cpp:554
void clearFifoErrorFlag()
Definition DMA.h:388
void clearTransferErrorFlag()
Definition DMA.h:383
void clearAllFlags()
Clear all the flags for the selected stream in the DMA ISR register (LISR or HISR depending on the se...
Definition DMA.h:399
int getCurrentBufferNumber()
Returns the number of the buffer currently in use when in double buffer mode.
Definition DMA.cpp:703
bool getTransferCompleteFlagStatus()
Returns the last read status of the transfer complete flag.
Definition DMA.h:344
void setup(DMATransaction &transaction)
Setup the stream with the given configuration.
Definition DMA.cpp:427
void resetErrorCallback()
Definition DMA.cpp:671
bool timedWaitForHalfTransfer(std::chrono::nanoseconds timeout_ns)
Wait for the half transfer complete signal. The caller waits for the corresponding interrupt,...
Definition DMA.cpp:578
void clearTransferCompleteFlag()
Definition DMA.h:378
void setErrorCallback(std::function< void()> callback)
Definition DMA.cpp:666
void resetHalfTransferCallback()
Definition DMA.cpp:654
void setTransferCompleteCallback(std::function< void()> callback)
Definition DMA.cpp:656
bool setNumberOfDataItems(const uint16_t nBytes)
Set the number of bytes to be exchanged during a dma transaction. Useful in case you don't want to ch...
Definition DMA.cpp:684
void enable()
Activate the stream. As soon as the stream is enabled, it serves any DMA request from/to the peripher...
Definition DMA.cpp:536
void waitForTransferComplete()
Wait for the transfer complete signal. The caller waits for the corresponding interrupt,...
Definition DMA.cpp:565
void readFlags()
Reads the current flags status.
Definition DMA.cpp:673
void setHalfTransferCallback(std::function< void()> callback)
Definition DMA.cpp:649
void waitForHalfTransfer()
Wait for the half transfer complete signal. The caller waits for the corresponding interrupt,...
Definition DMA.cpp:556
void clearHalfTransferFlag()
Definition DMA.h:373
void setChannel(const DMADefs::Channel channel)
Select the channel to be used by the stream during the transactions.
Definition DMA.cpp:698
bool enablePeripheralClock(void *peripheral)
Enables a peripheral clock source from the APB1 and APB2 peripheral buses.
Definition ClockUtils.h:155
const IRQn_Type irqNumberMapping[]
Mapping between DMAStreamId and the corresponding irq number. This is needed because irq number value...
Definition DMADefs.cpp:60
Peripherals
All the peripherals connected to dma.
Definition DMADefs.h:130
Channel
Channels selectable for each dma stream.
Definition DMADefs.h:106
const std::multimap< Peripherals, std::pair< DMAStreamId, Channel > > mapPeripherals
Maps the peripherals to the dma streams (and the corresponding channel) that are connected with.
Driver for the VN100S IMU.
This is the configuration struct for a DMA transaction.
Definition DMA.h:55
bool enableFifoErrorInterrupt
Definition DMA.h:143
bool enableHalfTransferInterrupt
Definition DMA.h:119
uint16_t numberOfDataItems
Definition DMA.h:95
bool enableTransferErrorInterrupt
Definition DMA.h:129
volatile void * secondMemoryAddress
Definition DMA.h:94
volatile void * dstAddress
Definition DMA.h:93
volatile void * srcAddress
Definition DMA.h:92
bool doubleBufferMode
Enables double buffer mode.
Definition DMA.h:110
bool enableDirectModeErrorInterrupt
Definition DMA.h:156
Direction direction
Definition DMA.h:88
bool enableTransferCompleteInterrupt
Definition DMA.h:111
bool circularMode
Enables circular buffer mode.
Definition DMA.h:103