From de947f1b28576a6704e856f76952921d04f0bcc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Frakn=C3=B3i=20Tam=C3=A1s?= <fraknoitamas@gmail.com>
Date: Sat, 12 Jun 2021 21:02:40 +0200
Subject: [PATCH] spisender periodic async

---
 test_anim/spisender.cpp | 52 +++++++++++++++++++++++++++++++++++++++++
 test_anim/spisender.h   | 17 +++++++++++---
 2 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/test_anim/spisender.cpp b/test_anim/spisender.cpp
index eb15b4e..b17ff82 100644
--- a/test_anim/spisender.cpp
+++ b/test_anim/spisender.cpp
@@ -1,9 +1,12 @@
 #include "spisender.h"
+#include "ola_receiver.h"
 #include "wiringPi.h"
 #include "wiringPiSPI.h"
 #include <unistd.h>
 #include <stdint.h>
 
+pthread_mutex_t SpiSender::mutex_frame = PTHREAD_MUTEX_INITIALIZER;
+
 SpiSender::SpiSender()
 {
     wiringPiSetup();
@@ -17,11 +20,20 @@ SpiSender::SpiSender()
     fd = wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED);
     uint8_t dummy = 0;
     wiringPiSPIDataRW(SPI_CHANNEL, &dummy, 1);
+
+    exit_flag = false;
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+    pthread_create(&sender_thread, &attr, SpiSender::sender_caller, (void*)this);
+    pthread_attr_destroy(&attr);
 }
 
 SpiSender::~SpiSender()
 {
     close(fd);
+    exit_flag = true;
+    pthread_join(sender_thread, NULL);
 }
 
 bool SpiSender::sendFrame(const SpiFrame &frame) const
@@ -37,4 +49,44 @@ bool SpiSender::canSend() const
 {
     return digitalRead(readyPin);
 }
+void* SpiSender::sender_caller(void* arg)
+{
+    SpiSender* sender = (SpiSender*)arg;
+    printf("Spi thread started.\n");
+    sender->sender_loop();
+    pthread_exit(NULL);
+}
+
+void SpiSender::sender_loop()
+{
+    while (!exit_flag)
+    {
+        if (canSend())
+        {
+            pthread_mutex_lock(&mutex_frame);
+            sendFrame(SpiFrame(frame));
+            pthread_mutex_unlock(&mutex_frame);
+        }
+        //printf("Frame sent.\n");
+        usleep(6000);
+    }
+    printf("SpiSender thread exit");
+}
+
+void SpiSender::exit()
+{
+    exit_flag = true;
+}
 
+void SpiSender::updateFrame(const MxFrame& newFrame, int startY, int endY)
+{
+    pthread_mutex_lock(&mutex_frame);
+    for (size_t y = startY; y <= endY; y++)
+    {
+        for (size_t x = 0; x < 32; x++)
+        {
+            frame.pixels[y][x] = newFrame.pixels[y][x];
+        }
+    }
+    pthread_mutex_unlock(&mutex_frame);
+}
diff --git a/test_anim/spisender.h b/test_anim/spisender.h
index d156344..7d64cf5 100644
--- a/test_anim/spisender.h
+++ b/test_anim/spisender.h
@@ -2,22 +2,33 @@
 #define SPISENDER_H
 
 #include "spiframe.h"
+#include <pthread.h>
+#include <atomic>
 
 class SpiSender
 {
 private:
     const int readyPin = 6; // WiringPi PIN. (22 on header)
     const int resetPin = 5; // WiringPi PIN. (18 on header)
-    const int SPI_SPEED = 1800000;
+    const int SPI_SPEED = 18000000;
     const int SPI_CHANNEL = 0;
     int fd = 0;
     bool firstFrame = true;
+    bool sendFrame(const SpiFrame& frame) const;
+    bool canSend() const;
+    MxFrame frame;
+    pthread_t sender_thread;
+    static pthread_mutex_t mutex_frame;
+    std::atomic<bool> exit_flag;
+
+    static void* sender_caller(void* arg);
+    void sender_loop();
 
 public:
     SpiSender();
     ~SpiSender();
-    bool sendFrame(const SpiFrame& frame) const;
-    bool canSend() const;
+    void exit();
+    void updateFrame(const MxFrame& newFrame, int startY = 0, int endY = 25);
 };
 
 #endif // SPISENDER_H
-- 
GitLab