From 7498b8ac9773cf842a165e96c13a49a080e748f8 Mon Sep 17 00:00:00 2001
From: Fabrizio Monti <fabrizio.monti@skywarder.eu>
Date: Thu, 20 Feb 2025 21:13:53 +0100
Subject: [PATCH] [DMA] DMAStreams are now allocated inside the std::map,
 without requiring new and delete operators and reducing the use of pointers.

---
 src/shared/drivers/dma/DMA.cpp            | 51 +++++++++++------------
 src/shared/drivers/dma/DMA.h              | 11 +++--
 src/tests/drivers/test-dma-mem-to-mem.cpp |  6 +--
 3 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/src/shared/drivers/dma/DMA.cpp b/src/shared/drivers/dma/DMA.cpp
index aa2eea4e2..d654466d8 100644
--- a/src/shared/drivers/dma/DMA.cpp
+++ b/src/shared/drivers/dma/DMA.cpp
@@ -247,42 +247,38 @@ namespace Boardcore
 
 void DMADriver::IRQhandleInterrupt(DMADefs::DMAStreamId id)
 {
-    auto stream = streams[id];
+    DMAStream& stream = streams.at(id);
 
-    stream->readFlags();
-    stream->clearAllFlags();
+    stream.readFlags();
+    stream.clearAllFlags();
 
-    // Run the callbacks if neccessary
-    if (stream->halfTransferCallback && stream->halfTransferFlag)
-    {
-        stream->halfTransferCallback();
-    }
-    if (stream->transferCompleteCallback && stream->transferCompleteFlag)
-    {
-        stream->transferCompleteCallback();
-    }
-    if (stream->errorCallback &&
-        (stream->transferErrorFlag || stream->fifoErrorFlag ||
-         stream->directModeErrorFlag))
+    // Run the callbacks if necessary
+    if (stream.halfTransferCallback && stream.halfTransferFlag)
+        stream.halfTransferCallback();
+
+    if (stream.transferCompleteCallback && stream.transferCompleteFlag)
+        stream.transferCompleteCallback();
+
+    if (stream.errorCallback &&
+        (stream.transferErrorFlag || stream.fifoErrorFlag ||
+         stream.directModeErrorFlag))
     {
-        stream->errorCallback();
+        stream.errorCallback();
     }
 
     // Wakeup the thread if the user is waiting
-    if (stream->waitingThread)
-    {
+    if (stream.waitingThread)
         IRQwakeupThread(stream);
-    }
 }
 
-void DMADriver::IRQwakeupThread(DMAStream* stream)
+void DMADriver::IRQwakeupThread(DMAStream& stream)
 {
     // Wakeup the waiting thread
-    stream->waitingThread->wakeup();
+    stream.waitingThread->wakeup();
 
     // If the waiting thread has a higher priority than the current
     // thread then reschedule
-    if (stream->waitingThread->IRQgetPriority() >
+    if (stream.waitingThread->IRQgetPriority() >
         miosix::Thread::IRQgetCurrentThread()->IRQgetPriority())
     {
         miosix::Scheduler::IRQfindNextThread();
@@ -290,7 +286,7 @@ void DMADriver::IRQwakeupThread(DMAStream* stream)
 
     // Clear the thread pointer, this way the thread will be sure it is
     // not a spurious wakeup
-    stream->waitingThread = nullptr;
+    stream.waitingThread = nullptr;
 }
 
 DMADriver& DMADriver::instance()
@@ -338,7 +334,9 @@ DMAStreamGuard DMADriver::acquireStreamBlocking(
     // if (streams.size() == 0)
     //     RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
 
-    return DMAStreamGuard((streams[id] = new DMAStream(id, channel)));
+    streams.insert(
+        std::pair<DMADefs::DMAStreamId, DMAStream>(id, DMAStream(id, channel)));
+    return DMAStreamGuard(&(streams.at(id)));
 }
 
 DMAStreamGuard DMADriver::automaticAcquireStreamBlocking(
@@ -361,7 +359,9 @@ DMAStreamGuard DMADriver::automaticAcquireStreamBlocking(
             if (streams.count(id) == 0)
             {
                 // Stream is free
-                return DMAStreamGuard(streams[id] = new DMAStream(id, channel));
+                streams.insert(std::pair<DMADefs::DMAStreamId, DMAStream>(
+                    id, DMAStream(id, channel)));
+                return DMAStreamGuard(&(streams.at(id)));
             }
         }
 
@@ -388,7 +388,6 @@ void DMADriver::releaseStream(DMADefs::DMAStreamId id)
 
     if (streams.count(id) != 0)
     {
-        delete streams[id];
         streams.erase(id);
         cv.broadcast();
     }
diff --git a/src/shared/drivers/dma/DMA.h b/src/shared/drivers/dma/DMA.h
index 10398a705..c62fa1c6a 100644
--- a/src/shared/drivers/dma/DMA.h
+++ b/src/shared/drivers/dma/DMA.h
@@ -134,11 +134,11 @@ public:
 private:
     DMADriver();
 
-    void IRQwakeupThread(DMAStream* stream);
+    void IRQwakeupThread(DMAStream& stream);
 
     miosix::FastMutex mutex;
     miosix::ConditionVariable cv;
-    std::map<DMADefs::DMAStreamId, DMAStream*> streams;
+    std::map<DMADefs::DMAStreamId, DMAStream> streams;
 
 public:
     DMADriver(const DMADriver&)            = delete;
@@ -396,9 +396,7 @@ private:
             else
             {
                 while (!getEventStatus())
-                {
                     readFlags();
-                }
                 result = true;
             }
 
@@ -415,6 +413,9 @@ private:
 public:
     DMAStream(const DMAStream&)            = delete;
     DMAStream& operator=(const DMAStream&) = delete;
+
+    DMAStream(DMAStream&&) noexcept            = default;
+    DMAStream& operator=(DMAStream&&) noexcept = default;
 };
 
 /**
@@ -428,9 +429,7 @@ public:
     ~DMAStreamGuard()
     {
         if (pStream != nullptr)
-        {
             DMADriver::instance().releaseStream(pStream->getStreamId());
-        }
     }
 
     DMAStreamGuard(const DMAStreamGuard&)            = delete;
diff --git a/src/tests/drivers/test-dma-mem-to-mem.cpp b/src/tests/drivers/test-dma-mem-to-mem.cpp
index 75153aef7..7109a1e3d 100644
--- a/src/tests/drivers/test-dma-mem-to-mem.cpp
+++ b/src/tests/drivers/test-dma-mem-to-mem.cpp
@@ -29,7 +29,7 @@
 using namespace miosix;
 using namespace Boardcore;
 
-void printBuffer(uint8_t *buffer, size_t size);
+void printBuffer(uint8_t* buffer, size_t size);
 
 int main()
 {
@@ -88,12 +88,10 @@ int main()
     return 0;
 }
 
-void printBuffer(uint8_t *buffer, size_t size)
+void printBuffer(uint8_t* buffer, size_t size)
 {
     for (size_t i = 0; i < size - 1; i++)
-    {
         printf("%x,", buffer[i]);
-    }
 
     printf("%x\n", buffer[size - 1]);
 }
-- 
GitLab