From def7baea57627743697d16efca59adc8ce82b71b Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Mon, 23 Dec 2019 17:58:06 +0900 Subject: [PATCH 01/11] Changed to reduce Qt dependencies --- software/raspberrypi_video/Lepton.cpp | 286 ++++++++++++++++++ software/raspberrypi_video/Lepton.h | 60 ++++ software/raspberrypi_video/LeptonAction.cpp | 20 ++ software/raspberrypi_video/LeptonAction.h | 18 ++ software/raspberrypi_video/LeptonActionQt.cpp | 21 ++ software/raspberrypi_video/LeptonActionQt.h | 21 ++ software/raspberrypi_video/LeptonThread.cpp | 268 +--------------- software/raspberrypi_video/LeptonThread.h | 30 +- software/raspberrypi_video/main.cpp | 16 +- 9 files changed, 455 insertions(+), 285 deletions(-) create mode 100644 software/raspberrypi_video/Lepton.cpp create mode 100644 software/raspberrypi_video/Lepton.h create mode 100644 software/raspberrypi_video/LeptonAction.cpp create mode 100644 software/raspberrypi_video/LeptonAction.h create mode 100644 software/raspberrypi_video/LeptonActionQt.cpp create mode 100644 software/raspberrypi_video/LeptonActionQt.h diff --git a/software/raspberrypi_video/Lepton.cpp b/software/raspberrypi_video/Lepton.cpp new file mode 100644 index 0000000..be8c3eb --- /dev/null +++ b/software/raspberrypi_video/Lepton.cpp @@ -0,0 +1,286 @@ +#include +#include + +#include "Lepton.h" +#include "LeptonAction.h" + +#include "Palettes.h" +#include "SPI.h" +#include "Lepton_I2C.h" + +Lepton::Lepton() +{ + // + loglevel = 0; + + // + typeColormap = 3; // 1:colormap_rainbow / 2:colormap_grayscale / 3:colormap_ironblack(default) + selectedColormap = colormap_ironblack; + selectedColormapSize = get_size_colormap_ironblack(); + + // + typeLepton = 2; // 2:Lepton 2.x / 3:Lepton 3.x + myImageWidth = 80; + myImageHeight = 60; + + // + spiSpeed = 20 * 1000 * 1000; // SPI bus speed 20MHz + + // min/max value for scaling + autoRangeMin = true; + autoRangeMax = true; + rangeMin = 30000; + rangeMax = 32000; +} + +Lepton::~Lepton() { +} + +void Lepton::setLogLevel(uint16_t newLoglevel) +{ + loglevel = newLoglevel; +} + +void Lepton::useColormap(int newTypeColormap) +{ + switch (newTypeColormap) { + case 1: + typeColormap = 1; + selectedColormap = colormap_rainbow; + selectedColormapSize = get_size_colormap_rainbow(); + break; + case 2: + typeColormap = 2; + selectedColormap = colormap_grayscale; + selectedColormapSize = get_size_colormap_grayscale(); + break; + default: + typeColormap = 3; + selectedColormap = colormap_ironblack; + selectedColormapSize = get_size_colormap_ironblack(); + break; + } +} + +void Lepton::useLepton(int newTypeLepton) +{ + switch (newTypeLepton) { + case 3: + typeLepton = 3; + myImageWidth = 160; + myImageHeight = 120; + break; + default: + typeLepton = 2; + myImageWidth = 80; + myImageHeight = 60; + } +} + +void Lepton::useSpiSpeedMhz(unsigned int newSpiSpeed) +{ + spiSpeed = newSpiSpeed * 1000 * 1000; +} + +void Lepton::setAutomaticScalingRange() +{ + autoRangeMin = true; + autoRangeMax = true; +} + +void Lepton::useRangeMinValue(uint16_t newMinValue) +{ + autoRangeMin = false; + rangeMin = newMinValue; +} + +void Lepton::useRangeMaxValue(uint16_t newMaxValue) +{ + autoRangeMax = false; + rangeMax = newMaxValue; +} + +void Lepton::open() +{ + //open spi port + SpiOpenPort(0, spiSpeed); +} + +void Lepton::close() +{ + //close spi port + SpiClosePort(0); +} + +int Lepton::readFrameData(LeptonAction *leptonAction) +{ + const int *colormap = selectedColormap; + const int colormapSize = selectedColormapSize; + uint16_t minValue = rangeMin; + uint16_t maxValue = rangeMax; + float diff = maxValue - minValue; + float scale = 255/diff; + + //read data packets from lepton over SPI + int resets = 0; + int segmentNumber = -1; + for(int j=0;jclose(); + lepton_reboot(); + n_wrong_segment = 0; + n_zero_value_drop_frame = 0; + usleep(750000); + this->open(); + } + continue; + } + if ((typeLepton == 3) && (packetNumber == 20)) { + segmentNumber = (result[j*PACKET_SIZE] >> 4) & 0x0f; + if ((segmentNumber < 1) || (4 < segmentNumber)) { + log_message(10, "[ERROR] Wrong segment number " + std::to_string(segmentNumber)); + break; + } + } + } + if(resets >= 30) { + log_message(3, "done reading, resets: " + std::to_string(resets)); + } + + // + int iSegmentStart = 1; + int iSegmentStop; + if (typeLepton == 3) { + if ((segmentNumber < 1) || (4 < segmentNumber)) { + n_wrong_segment++; + if ((n_wrong_segment % 12) == 0) { + log_message(5, "[WARNING] Got wrong segment number continuously " + std::to_string(n_wrong_segment) + " times"); + } + return 0; + } + if (n_wrong_segment != 0) { + log_message(8, "[WARNING] Got wrong segment number continuously " + std::to_string(n_wrong_segment) + " times [RECOVERED] : " + std::to_string(segmentNumber)); + n_wrong_segment = 0; + } + + // + memcpy(shelf[segmentNumber - 1], result, sizeof(uint8_t) * PACKET_SIZE*PACKETS_PER_FRAME); + if (segmentNumber != 4) { + return segmentNumber; + } + iSegmentStop = 4; + } + else { + memcpy(shelf[0], result, sizeof(uint8_t) * PACKET_SIZE*PACKETS_PER_FRAME); + iSegmentStop = 1; + } + + if ((autoRangeMin == true) || (autoRangeMax == true)) { + if (autoRangeMin == true) { + maxValue = 65535; + } + if (autoRangeMax == true) { + maxValue = 0; + } + for(int iSegment = iSegmentStart; iSegment <= iSegmentStop; iSegment++) { + for(int i=0;i maxValue)) { + maxValue = value; + } + if ((autoRangeMin == true) && (value < minValue)) { + minValue = value; + } + } + } + diff = maxValue - minValue; + scale = 255/diff; + } + + int row, column; + uint16_t value; + uint16_t valueFrameBuffer; + for(int iSegment = iSegmentStart; iSegment <= iSegmentStop; iSegment++) { + int ofsRow = 30 * (iSegment - 1); + for(int i=0;isetRawValue(column, row, valueFrameBuffer); + leptonAction->setPixel(column, row, colormap[ofs_r], colormap[ofs_g], colormap[ofs_b]); + } + } + + if (n_zero_value_drop_frame != 0) { + log_message(8, "[WARNING] Found zero-value. Drop the frame continuously " + std::to_string(n_zero_value_drop_frame) + " times [RECOVERED]"); + n_zero_value_drop_frame = 0; + } + + if (typeLepton != 3) { + segmentNumber = 1; + } + return segmentNumber; +} + +int Lepton::getWidth() +{ + return myImageWidth; +} + +int Lepton::getHeight() +{ + return myImageHeight; +} + +void Lepton::log_message(uint16_t level, std::string msg) +{ + if (level <= loglevel) { + std::cerr << msg << std::endl; + } +} + diff --git a/software/raspberrypi_video/Lepton.h b/software/raspberrypi_video/Lepton.h new file mode 100644 index 0000000..8f29aca --- /dev/null +++ b/software/raspberrypi_video/Lepton.h @@ -0,0 +1,60 @@ +#ifndef TEXTLEPTON +#define TEXTLEPTON + +#include +#include + +#include "LeptonAction.h" + +#define PACKET_SIZE 164 +#define PACKET_SIZE_UINT16 (PACKET_SIZE/2) +#define PACKETS_PER_FRAME 60 +#define FRAME_SIZE_UINT16 (PACKET_SIZE_UINT16*PACKETS_PER_FRAME) + +class Lepton +{ + +public: + Lepton(); + ~Lepton(); + + void setLogLevel(uint16_t); + void useColormap(int); + void useLepton(int); + void useSpiSpeedMhz(unsigned int); + void setAutomaticScalingRange(); + void useRangeMinValue(uint16_t); + void useRangeMaxValue(uint16_t); + void open(); + int readFrameData(LeptonAction *); + void close(); + int getWidth(); + int getHeight(); + +private: + + void log_message(uint16_t, std::string); + + uint16_t loglevel; + int typeColormap; + const int *selectedColormap; + int selectedColormapSize; + int typeLepton; + unsigned int spiSpeed; + bool autoRangeMin; + bool autoRangeMax; + uint16_t rangeMin; + uint16_t rangeMax; + int myImageWidth; + int myImageHeight; + + uint8_t result[PACKET_SIZE*PACKETS_PER_FRAME]; + uint8_t shelf[4][PACKET_SIZE*PACKETS_PER_FRAME]; + uint16_t *frameBuffer; + + uint16_t n_wrong_segment = 0; + uint16_t n_zero_value_drop_frame = 0; + +}; + +#endif diff --git a/software/raspberrypi_video/LeptonAction.cpp b/software/raspberrypi_video/LeptonAction.cpp new file mode 100644 index 0000000..542f50a --- /dev/null +++ b/software/raspberrypi_video/LeptonAction.cpp @@ -0,0 +1,20 @@ +#include +#include "LeptonAction.h" + +LeptonAction::LeptonAction() +{ +} + +LeptonAction::~LeptonAction() { +} + +void LeptonAction::setRawValue(int col, int row, uint16_t val) +{ + // override this method +} + +void LeptonAction::setPixel(int col, int row, int colorR, int colorG, int colorB) +{ + // override this method +} + diff --git a/software/raspberrypi_video/LeptonAction.h b/software/raspberrypi_video/LeptonAction.h new file mode 100644 index 0000000..7988c48 --- /dev/null +++ b/software/raspberrypi_video/LeptonAction.h @@ -0,0 +1,18 @@ +#ifndef TEXTLEPTONACTION +#define TEXTLEPTONACTION + +class LeptonAction +{ + +public: + LeptonAction(); + ~LeptonAction(); + + virtual void setRawValue(int, int, uint16_t); + virtual void setPixel(int, int, int, int, int); + +private: + +}; + +#endif diff --git a/software/raspberrypi_video/LeptonActionQt.cpp b/software/raspberrypi_video/LeptonActionQt.cpp new file mode 100644 index 0000000..64a5087 --- /dev/null +++ b/software/raspberrypi_video/LeptonActionQt.cpp @@ -0,0 +1,21 @@ +#include + +#include "LeptonActionQt.h" + +LeptonActionQt::LeptonActionQt() +{ +} + +LeptonActionQt::~LeptonActionQt() { +} + +void LeptonActionQt::setQImage(QImage *newMyImage) +{ + myImage = newMyImage; +} + +void LeptonActionQt::setPixel(int col, int row, int colorR, int colorG, int colorB) +{ + QRgb color = qRgb(colorR, colorG, colorB); + myImage->setPixel(col, row, color); +} diff --git a/software/raspberrypi_video/LeptonActionQt.h b/software/raspberrypi_video/LeptonActionQt.h new file mode 100644 index 0000000..328f687 --- /dev/null +++ b/software/raspberrypi_video/LeptonActionQt.h @@ -0,0 +1,21 @@ +#ifndef TEXTLEPTONACTIONQT +#define TEXTLEPTONACTIONQT + +#include "LeptonAction.h" + +class LeptonActionQt : public LeptonAction +{ + +public: + LeptonActionQt(); + ~LeptonActionQt(); + + void setQImage(QImage *); + virtual void setPixel(int, int, int, int, int); + +private: + QImage *myImage; + +}; + +#endif diff --git a/software/raspberrypi_video/LeptonThread.cpp b/software/raspberrypi_video/LeptonThread.cpp index 712c3e4..bb65f92 100644 --- a/software/raspberrypi_video/LeptonThread.cpp +++ b/software/raspberrypi_video/LeptonThread.cpp @@ -1,276 +1,47 @@ #include -#include "LeptonThread.h" +#include +#include -#include "Palettes.h" -#include "SPI.h" +#include "LeptonThread.h" +#include "Lepton.h" +#include "LeptonAction.h" +#include "LeptonActionQt.h" #include "Lepton_I2C.h" -#define PACKET_SIZE 164 -#define PACKET_SIZE_UINT16 (PACKET_SIZE/2) -#define PACKETS_PER_FRAME 60 -#define FRAME_SIZE_UINT16 (PACKET_SIZE_UINT16*PACKETS_PER_FRAME) -#define FPS 27; - LeptonThread::LeptonThread() : QThread() { - // - loglevel = 0; - - // - typeColormap = 3; // 1:colormap_rainbow / 2:colormap_grayscale / 3:colormap_ironblack(default) - selectedColormap = colormap_ironblack; - selectedColormapSize = get_size_colormap_ironblack(); - - // - typeLepton = 2; // 2:Lepton 2.x / 3:Lepton 3.x - myImageWidth = 80; - myImageHeight = 60; - - // - spiSpeed = 20 * 1000 * 1000; // SPI bus speed 20MHz - - // min/max value for scaling - autoRangeMin = true; - autoRangeMax = true; - rangeMin = 30000; - rangeMax = 32000; } LeptonThread::~LeptonThread() { } -void LeptonThread::setLogLevel(uint16_t newLoglevel) -{ - loglevel = newLoglevel; -} - -void LeptonThread::useColormap(int newTypeColormap) -{ - switch (newTypeColormap) { - case 1: - typeColormap = 1; - selectedColormap = colormap_rainbow; - selectedColormapSize = get_size_colormap_rainbow(); - break; - case 2: - typeColormap = 2; - selectedColormap = colormap_grayscale; - selectedColormapSize = get_size_colormap_grayscale(); - break; - default: - typeColormap = 3; - selectedColormap = colormap_ironblack; - selectedColormapSize = get_size_colormap_ironblack(); - break; - } -} - -void LeptonThread::useLepton(int newTypeLepton) -{ - switch (newTypeLepton) { - case 3: - typeLepton = 3; - myImageWidth = 160; - myImageHeight = 120; - break; - default: - typeLepton = 2; - myImageWidth = 80; - myImageHeight = 60; - } -} - -void LeptonThread::useSpiSpeedMhz(unsigned int newSpiSpeed) -{ - spiSpeed = newSpiSpeed * 1000 * 1000; -} - -void LeptonThread::setAutomaticScalingRange() +void LeptonThread::setLepton(Lepton *newLepton) { - autoRangeMin = true; - autoRangeMax = true; -} - -void LeptonThread::useRangeMinValue(uint16_t newMinValue) -{ - autoRangeMin = false; - rangeMin = newMinValue; -} - -void LeptonThread::useRangeMaxValue(uint16_t newMaxValue) -{ - autoRangeMax = false; - rangeMax = newMaxValue; + myLepton = newLepton; } void LeptonThread::run() { //create the initial image - myImage = QImage(myImageWidth, myImageHeight, QImage::Format_RGB888); - - const int *colormap = selectedColormap; - const int colormapSize = selectedColormapSize; - uint16_t minValue = rangeMin; - uint16_t maxValue = rangeMax; - float diff = maxValue - minValue; - float scale = 255/diff; - uint16_t n_wrong_segment = 0; - uint16_t n_zero_value_drop_frame = 0; + myImage = QImage(myLepton->getWidth(), myLepton->getHeight(), QImage::Format_RGB888); + LeptonActionQt *leptonAction = new LeptonActionQt(); + leptonAction->setQImage(&myImage); - //open spi port - SpiOpenPort(0, spiSpeed); + //open Lepton port + myLepton->open(); while(true) { //read data packets from lepton over SPI - int resets = 0; - int segmentNumber = -1; - for(int j=0;j> 4) & 0x0f; - if ((segmentNumber < 1) || (4 < segmentNumber)) { - log_message(10, "[ERROR] Wrong segment number " + std::to_string(segmentNumber)); - break; - } - } - } - if(resets >= 30) { - log_message(3, "done reading, resets: " + std::to_string(resets)); - } - - - // - int iSegmentStart = 1; - int iSegmentStop; - if (typeLepton == 3) { - if ((segmentNumber < 1) || (4 < segmentNumber)) { - n_wrong_segment++; - if ((n_wrong_segment % 12) == 0) { - log_message(5, "[WARNING] Got wrong segment number continuously " + std::to_string(n_wrong_segment) + " times"); - } - continue; - } - if (n_wrong_segment != 0) { - log_message(8, "[WARNING] Got wrong segment number continuously " + std::to_string(n_wrong_segment) + " times [RECOVERED] : " + std::to_string(segmentNumber)); - n_wrong_segment = 0; - } - - // - memcpy(shelf[segmentNumber - 1], result, sizeof(uint8_t) * PACKET_SIZE*PACKETS_PER_FRAME); - if (segmentNumber != 4) { - continue; - } - iSegmentStop = 4; - } - else { - memcpy(shelf[0], result, sizeof(uint8_t) * PACKET_SIZE*PACKETS_PER_FRAME); - iSegmentStop = 1; - } - - if ((autoRangeMin == true) || (autoRangeMax == true)) { - if (autoRangeMin == true) { - maxValue = 65535; - } - if (autoRangeMax == true) { - maxValue = 0; - } - for(int iSegment = iSegmentStart; iSegment <= iSegmentStop; iSegment++) { - for(int i=0;i maxValue)) { - maxValue = value; - } - if ((autoRangeMin == true) && (value < minValue)) { - minValue = value; - } - } - } - diff = maxValue - minValue; - scale = 255/diff; - } - - int row, column; - uint16_t value; - uint16_t valueFrameBuffer; - QRgb color; - for(int iSegment = iSegmentStart; iSegment <= iSegmentStop; iSegment++) { - int ofsRow = 30 * (iSegment - 1); - for(int i=0;ireadFrameData(leptonAction); //lets emit the signal for update emit updateImage(myImage); } - //finally, close SPI port just bcuz - SpiClosePort(0); + //finally, close Lepton just bcuz + myLepton->close(); } void LeptonThread::performFFC() { @@ -278,10 +49,3 @@ void LeptonThread::performFFC() { lepton_perform_ffc(); } -void LeptonThread::log_message(uint16_t level, std::string msg) -{ - if (level <= loglevel) { - std::cerr << msg << std::endl; - } -} - diff --git a/software/raspberrypi_video/LeptonThread.h b/software/raspberrypi_video/LeptonThread.h index 36326c6..e955a4b 100644 --- a/software/raspberrypi_video/LeptonThread.h +++ b/software/raspberrypi_video/LeptonThread.h @@ -9,10 +9,7 @@ #include #include -#define PACKET_SIZE 164 -#define PACKET_SIZE_UINT16 (PACKET_SIZE/2) -#define PACKETS_PER_FRAME 60 -#define FRAME_SIZE_UINT16 (PACKET_SIZE_UINT16*PACKETS_PER_FRAME) +#include "Lepton.h" class LeptonThread : public QThread { @@ -22,13 +19,7 @@ class LeptonThread : public QThread LeptonThread(); ~LeptonThread(); - void setLogLevel(uint16_t); - void useColormap(int); - void useLepton(int); - void useSpiSpeedMhz(unsigned int); - void setAutomaticScalingRange(); - void useRangeMinValue(uint16_t); - void useRangeMaxValue(uint16_t); + void setLepton(Lepton *); void run(); public slots: @@ -40,25 +31,12 @@ public slots: private: - void log_message(uint16_t, std::string); - uint16_t loglevel; - int typeColormap; - const int *selectedColormap; - int selectedColormapSize; - int typeLepton; - unsigned int spiSpeed; - bool autoRangeMin; - bool autoRangeMax; - uint16_t rangeMin; - uint16_t rangeMax; + Lepton *myLepton; + int myImageWidth; int myImageHeight; QImage myImage; - uint8_t result[PACKET_SIZE*PACKETS_PER_FRAME]; - uint8_t shelf[4][PACKET_SIZE*PACKETS_PER_FRAME]; - uint16_t *frameBuffer; - }; #endif diff --git a/software/raspberrypi_video/main.cpp b/software/raspberrypi_video/main.cpp index 3dab6b6..656cba4 100644 --- a/software/raspberrypi_video/main.cpp +++ b/software/raspberrypi_video/main.cpp @@ -126,14 +126,16 @@ int main( int argc, char **argv ) //create a thread to gather SPI data //when the thread emits updateImage, the label should update its image accordingly + Lepton *myLepton = new Lepton(); + myLepton->setLogLevel(loglevel); + myLepton->useColormap(typeColormap); + myLepton->useLepton(typeLepton); + myLepton->useSpiSpeedMhz(spiSpeed); + myLepton->setAutomaticScalingRange(); + if (0 <= rangeMin) myLepton->useRangeMinValue(rangeMin); + if (0 <= rangeMax) myLepton->useRangeMaxValue(rangeMax); LeptonThread *thread = new LeptonThread(); - thread->setLogLevel(loglevel); - thread->useColormap(typeColormap); - thread->useLepton(typeLepton); - thread->useSpiSpeedMhz(spiSpeed); - thread->setAutomaticScalingRange(); - if (0 <= rangeMin) thread->useRangeMinValue(rangeMin); - if (0 <= rangeMax) thread->useRangeMaxValue(rangeMax); + thread->setLepton(myLepton); QObject::connect(thread, SIGNAL(updateImage(QImage)), &myLabel, SLOT(setImage(QImage))); //connect ffc button to the thread's ffc action From deb29caa40a0bd37265dd878038927c557af49f6 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Tue, 24 Dec 2019 18:00:59 +0900 Subject: [PATCH 02/11] Lepton access modules are moved to 'raspberrypi_libs/leptonSPI' --- .../leptonSPI}/Lepton.cpp | 0 .../leptonSPI}/Lepton.h | 0 .../leptonSPI}/LeptonAction.cpp | 0 .../leptonSPI}/LeptonAction.h | 0 .../leptonSPI}/Lepton_I2C.cpp | 0 .../leptonSPI}/Lepton_I2C.h | 0 software/raspberrypi_libs/leptonSPI/Makefile | 26 +++++++++++++++++++ .../leptonSPI}/Palettes.cpp | 0 .../leptonSPI}/Palettes.h | 0 .../leptonSPI}/SPI.cpp | 0 .../leptonSPI}/SPI.h | 0 .../raspberrypi_video/raspberrypi_video.pro | 11 +++++--- 12 files changed, 33 insertions(+), 4 deletions(-) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/Lepton.cpp (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/Lepton.h (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/LeptonAction.cpp (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/LeptonAction.h (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/Lepton_I2C.cpp (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/Lepton_I2C.h (100%) create mode 100644 software/raspberrypi_libs/leptonSPI/Makefile rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/Palettes.cpp (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/Palettes.h (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/SPI.cpp (100%) rename software/{raspberrypi_video => raspberrypi_libs/leptonSPI}/SPI.h (100%) diff --git a/software/raspberrypi_video/Lepton.cpp b/software/raspberrypi_libs/leptonSPI/Lepton.cpp similarity index 100% rename from software/raspberrypi_video/Lepton.cpp rename to software/raspberrypi_libs/leptonSPI/Lepton.cpp diff --git a/software/raspberrypi_video/Lepton.h b/software/raspberrypi_libs/leptonSPI/Lepton.h similarity index 100% rename from software/raspberrypi_video/Lepton.h rename to software/raspberrypi_libs/leptonSPI/Lepton.h diff --git a/software/raspberrypi_video/LeptonAction.cpp b/software/raspberrypi_libs/leptonSPI/LeptonAction.cpp similarity index 100% rename from software/raspberrypi_video/LeptonAction.cpp rename to software/raspberrypi_libs/leptonSPI/LeptonAction.cpp diff --git a/software/raspberrypi_video/LeptonAction.h b/software/raspberrypi_libs/leptonSPI/LeptonAction.h similarity index 100% rename from software/raspberrypi_video/LeptonAction.h rename to software/raspberrypi_libs/leptonSPI/LeptonAction.h diff --git a/software/raspberrypi_video/Lepton_I2C.cpp b/software/raspberrypi_libs/leptonSPI/Lepton_I2C.cpp similarity index 100% rename from software/raspberrypi_video/Lepton_I2C.cpp rename to software/raspberrypi_libs/leptonSPI/Lepton_I2C.cpp diff --git a/software/raspberrypi_video/Lepton_I2C.h b/software/raspberrypi_libs/leptonSPI/Lepton_I2C.h similarity index 100% rename from software/raspberrypi_video/Lepton_I2C.h rename to software/raspberrypi_libs/leptonSPI/Lepton_I2C.h diff --git a/software/raspberrypi_libs/leptonSPI/Makefile b/software/raspberrypi_libs/leptonSPI/Makefile new file mode 100644 index 0000000..2199fdc --- /dev/null +++ b/software/raspberrypi_libs/leptonSPI/Makefile @@ -0,0 +1,26 @@ +# +CC = gcc +CXX = g++ +LINK = ar + +# +CFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES) -I. -I.. +CXXFLAGS = -pipe -O2 -Wall -W -D_REENTRANT $(DEFINES) -I. -I.. + +# +TARGET = libleptonSPI.a +OBJECTS = LeptonAction.o Lepton.o Lepton_I2C.o Palettes.o SPI.o + +%: %.cpp + $(CXX) -c $(CXXFLAGS) -o $@ $< + +$(TARGET): $(OBJECTS) + $(LINK) rcs $(TARGET) $(OBJECTS) + +all: $(TARGET) + +$(TARTGET): %.o + +clean: + rm *.o *.a + diff --git a/software/raspberrypi_video/Palettes.cpp b/software/raspberrypi_libs/leptonSPI/Palettes.cpp similarity index 100% rename from software/raspberrypi_video/Palettes.cpp rename to software/raspberrypi_libs/leptonSPI/Palettes.cpp diff --git a/software/raspberrypi_video/Palettes.h b/software/raspberrypi_libs/leptonSPI/Palettes.h similarity index 100% rename from software/raspberrypi_video/Palettes.h rename to software/raspberrypi_libs/leptonSPI/Palettes.h diff --git a/software/raspberrypi_video/SPI.cpp b/software/raspberrypi_libs/leptonSPI/SPI.cpp similarity index 100% rename from software/raspberrypi_video/SPI.cpp rename to software/raspberrypi_libs/leptonSPI/SPI.cpp diff --git a/software/raspberrypi_video/SPI.h b/software/raspberrypi_libs/leptonSPI/SPI.h similarity index 100% rename from software/raspberrypi_video/SPI.h rename to software/raspberrypi_libs/leptonSPI/SPI.h diff --git a/software/raspberrypi_video/raspberrypi_video.pro b/software/raspberrypi_video/raspberrypi_video.pro index b41b6d1..f55aac3 100644 --- a/software/raspberrypi_video/raspberrypi_video.pro +++ b/software/raspberrypi_video/raspberrypi_video.pro @@ -7,14 +7,17 @@ TARGET = raspberrypi_video RPI_LIBS = ../raspberrypi_libs LEPTONSDK = leptonSDKEmb32PUB +LEPTONSPI = leptonSPI -PRE_TARGETDEPS += sdk -QMAKE_EXTRA_TARGETS += sdk sdkclean +PRE_TARGETDEPS += sdk spi +QMAKE_EXTRA_TARGETS += sdk sdkclean spi spiclean sdk.commands = make -C $${RPI_LIBS}/$${LEPTONSDK} sdkclean.commands = make -C $${RPI_LIBS}/$${LEPTONSDK} clean +spi.commands = make -C $${RPI_LIBS}/$${LEPTONSPI} +spiclean.commands = make -C $${RPI_LIBS}/$${LEPTONSPI} clean DEPENDPATH += . -INCLUDEPATH += . $${RPI_LIBS} +INCLUDEPATH += . $${RPI_LIBS} $${RPI_LIBS}/$${LEPTONSPI} DESTDIR=. OBJECTS_DIR=gen_objs @@ -24,7 +27,7 @@ HEADERS += *.h SOURCES += *.cpp -unix:LIBS += -L$${RPI_LIBS}/$${LEPTONSDK}/Debug -lLEPTON_SDK +unix:LIBS += -L$${RPI_LIBS}/$${LEPTONSDK}/Debug -L$${RPI_LIBS}/$${LEPTONSPI} -l$${LEPTONSPI} -lLEPTON_SDK unix:QMAKE_CLEAN += -r $(OBJECTS_DIR) $${MOC_DIR} From fd074b610bc9f4283c96e51d1b103a34896ea9e3 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Thu, 6 Feb 2020 16:35:19 +0900 Subject: [PATCH 03/11] Update raspberrypi_capture to use raspberrypi_libs/leptonSPI --- .../raspberrypi_capture/LeptonActionFile.cpp | 76 ++++++ .../raspberrypi_capture/LeptonActionFile.h | 28 +++ .../LeptonActionFileCsv.cpp | 94 ++++++++ .../raspberrypi_capture/LeptonActionFileCsv.h | 31 +++ .../LeptonActionFilePgm.cpp | 95 ++++++++ .../raspberrypi_capture/LeptonActionFilePgm.h | 31 +++ .../LeptonActionFilePng.cpp | 62 +++++ .../raspberrypi_capture/LeptonActionFilePng.h | 30 +++ .../raspberrypi_capture/raspberrypi_capture.c | 206 ----------------- .../raspberrypi_capture.cpp | 217 ++++++++++++++++++ .../raspberrypi_capture.pro | 30 +++ 11 files changed, 694 insertions(+), 206 deletions(-) create mode 100644 software/raspberrypi_capture/LeptonActionFile.cpp create mode 100644 software/raspberrypi_capture/LeptonActionFile.h create mode 100644 software/raspberrypi_capture/LeptonActionFileCsv.cpp create mode 100644 software/raspberrypi_capture/LeptonActionFileCsv.h create mode 100644 software/raspberrypi_capture/LeptonActionFilePgm.cpp create mode 100644 software/raspberrypi_capture/LeptonActionFilePgm.h create mode 100644 software/raspberrypi_capture/LeptonActionFilePng.cpp create mode 100644 software/raspberrypi_capture/LeptonActionFilePng.h delete mode 100644 software/raspberrypi_capture/raspberrypi_capture.c create mode 100644 software/raspberrypi_capture/raspberrypi_capture.cpp create mode 100644 software/raspberrypi_capture/raspberrypi_capture.pro diff --git a/software/raspberrypi_capture/LeptonActionFile.cpp b/software/raspberrypi_capture/LeptonActionFile.cpp new file mode 100644 index 0000000..a5248d7 --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFile.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include + +#include "LeptonActionFile.h" + +LeptonActionFile::LeptonActionFile() +{ +} + +LeptonActionFile::LeptonActionFile(int w, int h) +{ + create(w, h); +} + +LeptonActionFile::~LeptonActionFile() { +} + +void LeptonActionFile::create(int w, int h) +{ +} + +char * LeptonActionFile::getDefaultFilename(char *filename) +{ + // + const char *dir = getenv("LEPTON_DATA_DIR"); + if (dir == NULL) { + dir = "."; + } + + // + struct timeval tv; + gettimeofday(&tv, NULL); + struct tm *now = localtime(&tv.tv_sec); + sprintf(filename, "%s/lepton-%04d%02d%02d-%02d%02d%02d.%03d", dir, now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, (int)(tv.tv_usec/1000)); + + return filename; +} + +char * LeptonActionFile::getFileExt(char *extname) +{ + sprintf(extname, ".ext"); + return extname; +} + +void LeptonActionFile::saveBasename(char *filebase) +{ + char filename[PATH_MAX]; + char extname[PATH_MAX]; + + if (filebase == NULL) { + save(); + return; + } + sprintf(filename, "%s%s", filebase, getFileExt(extname)); + save(filename); +} + +void LeptonActionFile::save() +{ + char filename[PATH_MAX]; + char extname[PATH_MAX]; + + sprintf(filename, "%s%s", getDefaultFilename(filename), getFileExt(extname)); + save(filename); +} + +void LeptonActionFile::save(char *filename) +{ +} + +void LeptonActionFile::setPixel(int col, int row, int colorR, int colorG, int colorB) +{ +} diff --git a/software/raspberrypi_capture/LeptonActionFile.h b/software/raspberrypi_capture/LeptonActionFile.h new file mode 100644 index 0000000..db3e9de --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFile.h @@ -0,0 +1,28 @@ +#ifndef DEF_LeptonActionFile_h +#define DEF_LeptonActionFile_h + +#include + +#include "LeptonAction.h" + +class LeptonActionFile : public LeptonAction +{ + +public: + LeptonActionFile(); + LeptonActionFile(int, int); + ~LeptonActionFile(); + + virtual void create(int, int); + virtual char * getDefaultFilename(char *); + virtual char * getFileExt(char *); + virtual void saveBasename(char *); + virtual void save(); + virtual void save(char *); + virtual void setPixel(int, int, int, int, int); + +private: + +}; + +#endif diff --git a/software/raspberrypi_capture/LeptonActionFileCsv.cpp b/software/raspberrypi_capture/LeptonActionFileCsv.cpp new file mode 100644 index 0000000..f15e623 --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFileCsv.cpp @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include + +#include "LeptonActionFileCsv.h" + +LeptonActionFileCsv::LeptonActionFileCsv() +{ +} + +LeptonActionFileCsv::LeptonActionFileCsv(int w, int h) +{ + create(w, h); +} + +LeptonActionFileCsv::~LeptonActionFileCsv() { + if (image_csv != NULL) { + free(image_csv); + } +} + +void LeptonActionFileCsv::create(int w, int h) +{ + if (image_csv != NULL) { + free(image_csv); + } + image_csv = (uint16_t *)malloc(sizeof(uint16_t) * w * h); + image_width = w; + image_height = h; +} + +char * LeptonActionFileCsv::getDefaultFilename(char *filename) +{ + return LeptonActionFile::getDefaultFilename(filename); +} + +char* LeptonActionFileCsv::getFileExt(char *extname) +{ + sprintf(extname, ".csv"); + return extname; +} + +void LeptonActionFileCsv::saveBasename(char *filebase) +{ + LeptonActionFile::saveBasename(filebase); +} + +void LeptonActionFileCsv::save() +{ + LeptonActionFile::save(); +} + +void LeptonActionFileCsv::save(char *filename) +{ + if (filename == NULL) { + save(); + return; + } + + uint16_t valMin = UINT16_MAX; + uint16_t valMax = 0; + for (int row = 0; row < image_height; row++) { + for (int col = 0; col < image_width; col++) { + uint16_t val = *(image_csv + row * image_width + col); + if (val < valMin) { + valMin = val; + } + if (valMax < val) { + valMax = val; + } + } + } + + // + FILE *fh = fopen(filename, "w"); + for (int row = 0; row < image_height; row++) { + for (int col = 0; col < image_width; col++) { + uint16_t val = *(image_csv + row * image_width + col); + fprintf(fh, "%d ", val); + if (col != image_width - 1) { + fprintf(fh, ","); + } + } + fprintf(fh, "\n"); + } + fclose(fh); +} + +void LeptonActionFileCsv::setRawValue(int col, int row, uint16_t val) +{ + *(image_csv + row * image_width + col) = val; +} diff --git a/software/raspberrypi_capture/LeptonActionFileCsv.h b/software/raspberrypi_capture/LeptonActionFileCsv.h new file mode 100644 index 0000000..0aedb4d --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFileCsv.h @@ -0,0 +1,31 @@ +#ifndef DEF_LeptonActionFileCsv_h +#define DEF_LeptonActionFileCsv_h + +#include + +#include "LeptonActionFile.h" + +class LeptonActionFileCsv : public LeptonActionFile +{ + +public: + LeptonActionFileCsv(); + LeptonActionFileCsv(int, int); + ~LeptonActionFileCsv(); + + virtual void create(int, int); + virtual char * getDefaultFilename(char *); + virtual char * getFileExt(char *); + virtual void saveBasename(char *); + virtual void save(); + virtual void save(char *); + virtual void setRawValue(int, int, uint16_t); + +private: + uint16_t *image_csv = NULL; + int image_width; + int image_height; + +}; + +#endif diff --git a/software/raspberrypi_capture/LeptonActionFilePgm.cpp b/software/raspberrypi_capture/LeptonActionFilePgm.cpp new file mode 100644 index 0000000..683bceb --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFilePgm.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include + +#include "LeptonActionFilePgm.h" + +LeptonActionFilePgm::LeptonActionFilePgm() +{ +} + +LeptonActionFilePgm::LeptonActionFilePgm(int w, int h) +{ + create(w, h); +} + +LeptonActionFilePgm::~LeptonActionFilePgm() { + if (image_pgm != NULL) { + free(image_pgm); + } +} + +void LeptonActionFilePgm::create(int w, int h) +{ + if (image_pgm != NULL) { + free(image_pgm); + } + image_pgm = (uint16_t *)malloc(sizeof(uint16_t) * w * h); + image_width = w; + image_height = h; +} + +char * LeptonActionFilePgm::getDefaultFilename(char *filename) +{ + return LeptonActionFile::getDefaultFilename(filename); +} + +char* LeptonActionFilePgm::getFileExt(char *extname) +{ + sprintf(extname, ".pgm"); + return extname; +} + +void LeptonActionFilePgm::saveBasename(char *filebase) +{ + LeptonActionFile::saveBasename(filebase); +} + +void LeptonActionFilePgm::save() +{ + LeptonActionFile::save(); +} + +void LeptonActionFilePgm::save(char *filename) +{ + if (filename == NULL) { + save(); + return; + } + + char *magicNumber = "P2"; // PGM + uint16_t valMin = UINT16_MAX; + uint16_t valMax = 0; + for (int row = 0; row < image_height; row++) { + for (int col = 0; col < image_width; col++) { + uint16_t val = *(image_pgm + row * image_width + col); + if (val < valMin) { + valMin = val; + } + if (valMax < val) { + valMax = val; + } + } + } + + // + FILE *fh = fopen(filename, "w"); + fprintf(fh, "%s\n", magicNumber); + fprintf(fh, "%d %d\n", image_width, image_height); + fprintf(fh, "%d\n", valMax - valMin); + for (int row = 0; row < image_height; row++) { + for (int col = 0; col < image_width; col++) { + uint16_t val = *(image_pgm + row * image_width + col) - valMin; + fprintf(fh, "%d ", val); + } + fprintf(fh, "\n"); + } + fclose(fh); +} + +void LeptonActionFilePgm::setRawValue(int col, int row, uint16_t val) +{ + *(image_pgm + row * image_width + col) = val; +} diff --git a/software/raspberrypi_capture/LeptonActionFilePgm.h b/software/raspberrypi_capture/LeptonActionFilePgm.h new file mode 100644 index 0000000..485d094 --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFilePgm.h @@ -0,0 +1,31 @@ +#ifndef DEF_LeptonActionFilePgm_h +#define DEF_LeptonActionFilePgm_h + +#include + +#include "LeptonActionFile.h" + +class LeptonActionFilePgm : public LeptonActionFile +{ + +public: + LeptonActionFilePgm(); + LeptonActionFilePgm(int, int); + ~LeptonActionFilePgm(); + + virtual void create(int, int); + virtual char * getDefaultFilename(char *); + virtual char * getFileExt(char *); + virtual void saveBasename(char *); + virtual void save(); + virtual void save(char *); + virtual void setRawValue(int, int, uint16_t); + +private: + uint16_t *image_pgm = NULL; + int image_width; + int image_height; + +}; + +#endif diff --git a/software/raspberrypi_capture/LeptonActionFilePng.cpp b/software/raspberrypi_capture/LeptonActionFilePng.cpp new file mode 100644 index 0000000..a752641 --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFilePng.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "LeptonActionFilePng.h" + +LeptonActionFilePng::LeptonActionFilePng() +{ +} + +LeptonActionFilePng::LeptonActionFilePng(int w, int h) +{ + create(w, h); +} + +LeptonActionFilePng::~LeptonActionFilePng() { +} + +void LeptonActionFilePng::create(int w, int h) +{ + image_png.resize(w, h); +} + +char * LeptonActionFilePng::getDefaultFilename(char *filename) +{ + return LeptonActionFile::getDefaultFilename(filename); +} + +char* LeptonActionFilePng::getFileExt(char *extname) +{ + sprintf(extname, ".png"); + return extname; +} + +void LeptonActionFilePng::saveBasename(char *filebase) +{ + LeptonActionFile::saveBasename(filebase); +} + +void LeptonActionFilePng::save() +{ + LeptonActionFile::save(); +} + +void LeptonActionFilePng::save(char *filename) +{ + if (filename == NULL) { + save(); + return; + } + + image_png.write(filename); +} + +void LeptonActionFilePng::setPixel(int col, int row, int colorR, int colorG, int colorB) +{ + image_png[row][col] = png::rgb_pixel(colorR, colorG, colorB); +} diff --git a/software/raspberrypi_capture/LeptonActionFilePng.h b/software/raspberrypi_capture/LeptonActionFilePng.h new file mode 100644 index 0000000..41e05b6 --- /dev/null +++ b/software/raspberrypi_capture/LeptonActionFilePng.h @@ -0,0 +1,30 @@ +#ifndef DEF_LeptonActionFilePng_h +#define DEF_LeptonActionFilePng_h + +#include +#include + +#include "LeptonActionFile.h" + +class LeptonActionFilePng : public LeptonActionFile +{ + +public: + LeptonActionFilePng(); + LeptonActionFilePng(int, int); + ~LeptonActionFilePng(); + + virtual void create(int, int); + virtual char * getDefaultFilename(char *); + virtual char * getFileExt(char *); + virtual void saveBasename(char *); + virtual void save(); + virtual void save(char *); + virtual void setPixel(int, int, int, int, int); + +private: + png::image < png::rgb_pixel > image_png; + +}; + +#endif diff --git a/software/raspberrypi_capture/raspberrypi_capture.c b/software/raspberrypi_capture/raspberrypi_capture.c deleted file mode 100644 index 52f348f..0000000 --- a/software/raspberrypi_capture/raspberrypi_capture.c +++ /dev/null @@ -1,206 +0,0 @@ -/* -Copyright (c) 2014, Pure Engineering LLC -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -static void pabort(const char *s) -{ - perror(s); - abort(); -} - -static const char *device = "/dev/spidev0.1"; -static uint8_t mode; -static uint8_t bits = 8; -static uint32_t speed = 16000000; -static uint16_t delay; - -#define VOSPI_FRAME_SIZE (164) -uint8_t lepton_frame_packet[VOSPI_FRAME_SIZE]; -static unsigned int lepton_image[80][80]; - -static void save_pgm_file(void) -{ - int i; - int j; - unsigned int maxval = 0; - unsigned int minval = UINT_MAX; - char image_name[32]; - int image_index = 0; - - do { - sprintf(image_name, "IMG_%.4d.pgm", image_index); - image_index += 1; - if (image_index > 9999) - { - image_index = 0; - break; - } - - } while (access(image_name, F_OK) == 0); - - FILE *f = fopen(image_name, "w"); - if (f == NULL) - { - printf("Error opening file!\n"); - exit(1); - } - - printf("Calculating min/max values for proper scaling...\n"); - for(i=0;i<60;i++) - { - for(j=0;j<80;j++) - { - if (lepton_image[i][j] > maxval) { - maxval = lepton_image[i][j]; - } - if (lepton_image[i][j] < minval) { - minval = lepton_image[i][j]; - } - } - } - printf("maxval = %u\n",maxval); - printf("minval = %u\n",minval); - - fprintf(f,"P2\n80 60\n%u\n",maxval-minval); - for(i=0;i<60;i++) - { - for(j=0;j<80;j++) - { - fprintf(f,"%d ", lepton_image[i][j] - minval); - } - fprintf(f,"\n"); - } - fprintf(f,"\n\n"); - - fclose(f); -} - -int transfer(int fd) -{ - int ret; - int i; - int frame_number; - uint8_t tx[VOSPI_FRAME_SIZE] = {0, }; - struct spi_ioc_transfer tr = { - .tx_buf = (unsigned long)tx, - .rx_buf = (unsigned long)lepton_frame_packet, - .len = VOSPI_FRAME_SIZE, - .delay_usecs = delay, - .speed_hz = speed, - .bits_per_word = bits, - }; - - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - if (ret < 1) - pabort("can't send spi message"); - - if(((lepton_frame_packet[0]&0xf) != 0x0f)) - { - frame_number = lepton_frame_packet[1]; - - if(frame_number < 60 ) - { - for(i=0;i<80;i++) - { - lepton_image[frame_number][i] = (lepton_frame_packet[2*i+4] << 8 | lepton_frame_packet[2*i+5]); - } - } - } - return frame_number; -} - -int main(int argc, char *argv[]) -{ - int ret = 0; - int fd; - - - fd = open(device, O_RDWR); - if (fd < 0) - { - pabort("can't open device"); - } - - ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); - if (ret == -1) - { - pabort("can't set spi mode"); - } - - ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); - if (ret == -1) - { - pabort("can't get spi mode"); - } - - ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); - if (ret == -1) - { - pabort("can't set bits per word"); - } - - ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); - if (ret == -1) - { - pabort("can't get bits per word"); - } - - ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); - if (ret == -1) - { - pabort("can't set max speed hz"); - } - - ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); - if (ret == -1) - { - pabort("can't get max speed hz"); - } - - printf("spi mode: %d\n", mode); - printf("bits per word: %d\n", bits); - printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); - - while(transfer(fd)!=59){} - - close(fd); - - save_pgm_file(); - - return ret; -} diff --git a/software/raspberrypi_capture/raspberrypi_capture.cpp b/software/raspberrypi_capture/raspberrypi_capture.cpp new file mode 100644 index 0000000..707466f --- /dev/null +++ b/software/raspberrypi_capture/raspberrypi_capture.cpp @@ -0,0 +1,217 @@ +#include +#include + +#include "Lepton.h" +#include "LeptonAction.h" +#include "LeptonActionFile.h" +#include "LeptonActionFileCsv.h" +#include "LeptonActionFilePng.h" +#include "LeptonActionFilePgm.h" + +void printUsage(char *cmd) { + char *cmdname = basename(cmd); + printf("Usage: %s [OPTION]...\n" + " -h display this help and exit\n" + " -cm x select colormap\n" + " 1 : rainbow\n" + " 2 : grayscale\n" + " 3 : ironblack [default]\n" + " -tl x select type of Lepton\n" + " 2 : Lepton 2.x [default]\n" + " 3 : Lepton 3.x\n" + " [for your reference] Please use nice command\n" + " e.g. sudo nice -n 0 ./%s -tl 3\n" + " -ss x SPI bus speed [MHz] (10 - 30)\n" + " 20 : 20MHz [default]\n" + " -min x override minimum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -min 30000\n" + " -max x override maximum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -max 32000\n" + " -d x log level (0-255)\n" + " -dms x delay time [milliseconds] (0 - 65535)\n" + " [default] 0\n" + " -ims x interval [milliseconds] (1 - 65535)\n" + " -c x count (0 - 65535)\n" + " 0 : endless\n" + " [default] take one shot\n" + " -tff x select type of file format\n" + " 0 : CSV\n" + " 1 : PNG [default]\n" + " 2 : PGM\n" + " -o x use 'x' as basename for file\n" + " [default] lepton-YYYYMMDD-hhmmss.sss\n" + " extension depends on file format\n" + " CSV : .cvs\n" + " PNG : .png\n" + " PGM : .pmg\n" + "Environment variable(s)\n" + " LEPTON_DATA_DIR\n" + " make png file(s) in this directory\n" + "", cmdname, cmdname); + return; +} + +int main( int argc, char **argv ) +{ + int typeColormap = 3; // colormap_ironblack + int typeLepton = 2; // Lepton 2.x + int spiSpeed = 20; // SPI bus speed 20MHz + int rangeMin = -1; // + int rangeMax = -1; // + int delayMs = 0; // + int intervalMs = 0; // + int limitTakePic = 1; // + int count_take_pic = 0; + int typeFileFormat = 1; // 1:PNG 2:PGM + int segment_number0 = 0; + int loglevel = 0; + char *filename = NULL; + for(int i=1; i < argc; i++) { + if (strcmp(argv[i], "-h") == 0) { + printUsage(argv[0]); + exit(0); + } + else if (strcmp(argv[i], "-d") == 0) { + int val = 3; + if ((i + 1 != argc) && (strncmp(argv[i + 1], "-", 1) != 0)) { + val = std::atoi(argv[i + 1]); + i++; + } + if (0 <= val) { + loglevel = val & 0xFF; + } + } + else if ((strcmp(argv[i], "-cm") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((val == 1) || (val == 2)) { + typeColormap = val; + i++; + } + } + else if ((strcmp(argv[i], "-tl") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if (val == 3) { + typeLepton = val; + i++; + } + } + else if ((strcmp(argv[i], "-ss") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((10 <= val) && (val <= 30)) { + spiSpeed = val; + i++; + } + } + else if ((strcmp(argv[i], "-min") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((0 <= val) && (val <= 65535)) { + rangeMin = val; + i++; + } + } + else if ((strcmp(argv[i], "-max") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((0 <= val) && (val <= 65535)) { + rangeMax = val; + i++; + } + } + else if ((strcmp(argv[i], "-dms") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((0 <= val) && (val <= 65535)) { + delayMs = val; + i++; + } + } + else if ((strcmp(argv[i], "-ims") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((1 <= val) && (val <= 65535)) { + intervalMs = val; + i++; + } + } + else if ((strcmp(argv[i], "-c") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((0 <= val) && (val <= 65535)) { + limitTakePic = val; + i++; + } + } + else if ((strcmp(argv[i], "-tff") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((0 <= val) || (val <= 2)) { + typeFileFormat = val; + i++; + } + } + else if ((strcmp(argv[i], "-o") == 0) && (i + 1 != argc)) { + char *val = argv[i + 1]; + if (strcmp(val, "") != 0) { + filename = val; + i++; + } + } + } + + //create a thread to gather SPI data + //when the thread emits updateImage, the label should update its image accordingly + Lepton *myLepton = new Lepton(); + myLepton->setLogLevel(loglevel); + myLepton->useColormap(typeColormap); + myLepton->useLepton(typeLepton); + myLepton->useSpiSpeedMhz(spiSpeed); + myLepton->setAutomaticScalingRange(); + if (0 <= rangeMin) myLepton->useRangeMinValue(rangeMin); + if (0 <= rangeMax) myLepton->useRangeMaxValue(rangeMax); + + // + LeptonActionFile *leptonActionFile; + switch (typeFileFormat) { + case 0: + leptonActionFile = new LeptonActionFileCsv(myLepton->getWidth(), myLepton->getHeight()); + break; + case 2: + leptonActionFile = new LeptonActionFilePgm(myLepton->getWidth(), myLepton->getHeight()); + break; + default: + leptonActionFile = new LeptonActionFilePng(myLepton->getWidth(), myLepton->getHeight()); + break; + } + LeptonAction *leptonAction = leptonActionFile; + + //open Lepton port + myLepton->open(); + + // + usleep(delayMs * 1000); + while(true) { + //read data packets from lepton over SPI + int segment_number = myLepton->readFrameData(leptonAction); + + if (segment_number0 + 1 == segment_number) { + if ((typeLepton == 2) || (segment_number == 4)) { + leptonActionFile->saveBasename(filename); + count_take_pic++; + if ((limitTakePic != 0) && (limitTakePic <= count_take_pic)) { + break; + } + usleep(intervalMs * 1000); + segment_number0 = 0; + } + else { + segment_number0 = segment_number; + } + } + else { + segment_number0 = 0; + } + } + + //finally, close Lepton just bcuz + myLepton->close(); + + return 0; +} + diff --git a/software/raspberrypi_capture/raspberrypi_capture.pro b/software/raspberrypi_capture/raspberrypi_capture.pro new file mode 100644 index 0000000..1b5b92c --- /dev/null +++ b/software/raspberrypi_capture/raspberrypi_capture.pro @@ -0,0 +1,30 @@ + +TEMPLATE = app +#QT += core gui +#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = raspberrypi_capture + +RPI_LIBS = ../raspberrypi_libs +LEPTONSDK = leptonSDKEmb32PUB + +PRE_TARGETDEPS += sdk +QMAKE_EXTRA_TARGETS += sdk sdkclean +sdk.commands = make -C $${RPI_LIBS}/$${LEPTONSDK} +sdkclean.commands = make -C $${RPI_LIBS}/$${LEPTONSDK} clean + +DEPENDPATH += . +INCLUDEPATH += . $${RPI_LIBS} $${RPI_LIBS}/leptonSPI + +DESTDIR=. +OBJECTS_DIR=gen_objs +MOC_DIR=gen_mocs + +HEADERS += *.h + +SOURCES += *.cpp + +unix:LIBS += -L$${RPI_LIBS}/$${LEPTONSDK}/Debug -L$${RPI_LIBS}/leptonSPI -lleptonSPI -lLEPTON_SDK -lpng + +unix:QMAKE_CLEAN += -r $(OBJECTS_DIR) $${MOC_DIR} + From 9d9c230f74206ca75713ac6a2dc2f271f0ef1684 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Sat, 21 Mar 2020 05:19:50 +0000 Subject: [PATCH 04/11] modified raspberrypi_libs/leptonSPI selectable spi-device --- .../raspberrypi_libs/leptonSPI/Lepton.cpp | 14 +++- software/raspberrypi_libs/leptonSPI/Lepton.h | 2 + software/raspberrypi_libs/leptonSPI/SPI.cpp | 84 +++++++++++-------- software/raspberrypi_libs/leptonSPI/SPI.h | 17 ++-- 4 files changed, 67 insertions(+), 50 deletions(-) diff --git a/software/raspberrypi_libs/leptonSPI/Lepton.cpp b/software/raspberrypi_libs/leptonSPI/Lepton.cpp index be8c3eb..6b5103a 100644 --- a/software/raspberrypi_libs/leptonSPI/Lepton.cpp +++ b/software/raspberrypi_libs/leptonSPI/Lepton.cpp @@ -24,6 +24,7 @@ Lepton::Lepton() myImageHeight = 60; // + spiDevice = DEFAULT_SPI_DEVICE; spiSpeed = 20 * 1000 * 1000; // SPI bus speed 20MHz // min/max value for scaling @@ -77,6 +78,11 @@ void Lepton::useLepton(int newTypeLepton) } } +void Lepton::useSpiDevice(char *newSpiDevice) +{ + spiDevice = newSpiDevice; +} + void Lepton::useSpiSpeedMhz(unsigned int newSpiSpeed) { spiSpeed = newSpiSpeed * 1000 * 1000; @@ -103,13 +109,15 @@ void Lepton::useRangeMaxValue(uint16_t newMaxValue) void Lepton::open() { //open spi port - SpiOpenPort(0, spiSpeed); + SpiSetDevice(spiDevice); + SpiSetSpeed(spiSpeed); + SpiOpenPort(); } void Lepton::close() { //close spi port - SpiClosePort(0); + SpiClosePort(); } int Lepton::readFrameData(LeptonAction *leptonAction) @@ -126,7 +134,7 @@ int Lepton::readFrameData(LeptonAction *leptonAction) int segmentNumber = -1; for(int j=0;j #include #include @@ -25,13 +22,11 @@ #include #include -extern int spi_cs0_fd; -extern int spi_cs1_fd; -extern unsigned char spi_mode; -extern unsigned char spi_bitsPerWord; -extern unsigned int spi_speed; +#define DEFAULT_SPI_DEVICE "/dev/spidev0.0" -int SpiOpenPort(int spi_device, unsigned int spi_speed); -int SpiClosePort(int spi_device); +void SpiSetDevice (char *); +void SpiSetSpeed (unsigned int); +int SpiOpenPort(); +size_t SpiRead(void *, size_t); +int SpiClosePort(); -#endif From b8f7170d4f5f2d16dc821f9bd7885ce2845115bf Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Thu, 2 Apr 2020 15:03:11 +0900 Subject: [PATCH 05/11] modified raspberrypi_video selectable spi-device --- software/raspberrypi_video/main.cpp | 51 +++++++++++++++++------------ 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/software/raspberrypi_video/main.cpp b/software/raspberrypi_video/main.cpp index 656cba4..3e14250 100644 --- a/software/raspberrypi_video/main.cpp +++ b/software/raspberrypi_video/main.cpp @@ -9,32 +9,35 @@ #include #include +#include "SPI.h" #include "LeptonThread.h" #include "MyLabel.h" void printUsage(char *cmd) { - char *cmdname = basename(cmd); + char *cmdname = basename(cmd); printf("Usage: %s [OPTION]...\n" - " -h display this help and exit\n" - " -cm x select colormap\n" - " 1 : rainbow\n" - " 2 : grayscale\n" - " 3 : ironblack [default]\n" - " -tl x select type of Lepton\n" - " 2 : Lepton 2.x [default]\n" - " 3 : Lepton 3.x\n" - " [for your reference] Please use nice command\n" - " e.g. sudo nice -n 0 ./%s -tl 3\n" - " -ss x SPI bus speed [MHz] (10 - 30)\n" - " 20 : 20MHz [default]\n" - " -min x override minimum value for scaling (0 - 65535)\n" - " [default] automatic scaling range adjustment\n" - " e.g. -min 30000\n" - " -max x override maximum value for scaling (0 - 65535)\n" - " [default] automatic scaling range adjustment\n" - " e.g. -max 32000\n" - " -d x log level (0-255)\n" - "", cmdname, cmdname); + " -h display this help and exit\n" + " -cm x select colormap\n" + " 1 : rainbow\n" + " 2 : grayscale\n" + " 3 : ironblack [default]\n" + " -tl x select type of Lepton\n" + " 2 : Lepton 2.x [default]\n" + " 3 : Lepton 3.x\n" + " [for your reference] Please use nice command\n" + " e.g. sudo nice -n 0 ./%s -tl 3\n" + " -sd x select SPI device\n" + " %s [default]\n" + " -ss x SPI bus speed [MHz] (10 - 30)\n" + " 20 : 20MHz [default]\n" + " -min x override minimum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -min 30000\n" + " -max x override maximum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -max 32000\n" + " -d x log level (0-255)\n" + "", cmdname, cmdname, DEFAULT_SPI_DEVICE); return; } @@ -42,6 +45,7 @@ int main( int argc, char **argv ) { int typeColormap = 3; // colormap_ironblack int typeLepton = 2; // Lepton 2.x + char *spiDevice = DEFAULT_SPI_DEVICE; // SPI Device int spiSpeed = 20; // SPI bus speed 20MHz int rangeMin = -1; // int rangeMax = -1; // @@ -75,6 +79,10 @@ int main( int argc, char **argv ) i++; } } + else if ((strcmp(argv[i], "-sd") == 0) && (i + 1 != argc)) { + spiDevice = argv[i + 1]; + i++; + } else if ((strcmp(argv[i], "-ss") == 0) && (i + 1 != argc)) { int val = std::atoi(argv[i + 1]); if ((10 <= val) && (val <= 30)) { @@ -130,6 +138,7 @@ int main( int argc, char **argv ) myLepton->setLogLevel(loglevel); myLepton->useColormap(typeColormap); myLepton->useLepton(typeLepton); + myLepton->useSpiDevice(spiDevice); myLepton->useSpiSpeedMhz(spiSpeed); myLepton->setAutomaticScalingRange(); if (0 <= rangeMin) myLepton->useRangeMinValue(rangeMin); From 8bb2d8e22701a65173e6c56fc8521c1ab33bd030 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Wed, 8 Apr 2020 09:38:23 +0900 Subject: [PATCH 06/11] modified raspberrypi_capture selectable spi-device --- software/raspberrypi_capture/Makefile | 26 ------ .../raspberrypi_capture.cpp | 87 ++++++++++--------- 2 files changed, 48 insertions(+), 65 deletions(-) delete mode 100644 software/raspberrypi_capture/Makefile diff --git a/software/raspberrypi_capture/Makefile b/software/raspberrypi_capture/Makefile deleted file mode 100644 index d31dc62..0000000 --- a/software/raspberrypi_capture/Makefile +++ /dev/null @@ -1,26 +0,0 @@ - -TARGET = raspberrypi_capture -LIBS = -lm -CC = gcc -CFLAGS = -g -Wall - -.PHONY: default all clean - -default: $(TARGET) -all: default - -OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c)) -HEADERS = $(wildcard *.h) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c $< -o $@ - -.PRECIOUS: $(TARGET) $(OBJECTS) - -$(TARGET): $(OBJECTS) - $(CC) $(OBJECTS) -Wall $(LIBS) -o $@ - -clean: - -rm -f *.o - -rm -f $(TARGET) - diff --git a/software/raspberrypi_capture/raspberrypi_capture.cpp b/software/raspberrypi_capture/raspberrypi_capture.cpp index 707466f..0aa47f8 100644 --- a/software/raspberrypi_capture/raspberrypi_capture.cpp +++ b/software/raspberrypi_capture/raspberrypi_capture.cpp @@ -7,49 +7,52 @@ #include "LeptonActionFileCsv.h" #include "LeptonActionFilePng.h" #include "LeptonActionFilePgm.h" +#include "SPI.h" void printUsage(char *cmd) { char *cmdname = basename(cmd); printf("Usage: %s [OPTION]...\n" - " -h display this help and exit\n" - " -cm x select colormap\n" - " 1 : rainbow\n" - " 2 : grayscale\n" - " 3 : ironblack [default]\n" - " -tl x select type of Lepton\n" - " 2 : Lepton 2.x [default]\n" - " 3 : Lepton 3.x\n" - " [for your reference] Please use nice command\n" - " e.g. sudo nice -n 0 ./%s -tl 3\n" - " -ss x SPI bus speed [MHz] (10 - 30)\n" - " 20 : 20MHz [default]\n" - " -min x override minimum value for scaling (0 - 65535)\n" - " [default] automatic scaling range adjustment\n" - " e.g. -min 30000\n" - " -max x override maximum value for scaling (0 - 65535)\n" - " [default] automatic scaling range adjustment\n" - " e.g. -max 32000\n" - " -d x log level (0-255)\n" - " -dms x delay time [milliseconds] (0 - 65535)\n" - " [default] 0\n" - " -ims x interval [milliseconds] (1 - 65535)\n" - " -c x count (0 - 65535)\n" - " 0 : endless\n" - " [default] take one shot\n" - " -tff x select type of file format\n" - " 0 : CSV\n" - " 1 : PNG [default]\n" - " 2 : PGM\n" - " -o x use 'x' as basename for file\n" - " [default] lepton-YYYYMMDD-hhmmss.sss\n" - " extension depends on file format\n" - " CSV : .cvs\n" - " PNG : .png\n" - " PGM : .pmg\n" - "Environment variable(s)\n" - " LEPTON_DATA_DIR\n" - " make png file(s) in this directory\n" - "", cmdname, cmdname); + " -h display this help and exit\n" + " -cm x select colormap\n" + " 1 : rainbow\n" + " 2 : grayscale\n" + " 3 : ironblack [default]\n" + " -tl x select type of Lepton\n" + " 2 : Lepton 2.x [default]\n" + " 3 : Lepton 3.x\n" + " [for your reference] Please use nice command\n" + " e.g. sudo nice -n 0 ./%s -tl 3\n" + " -sd x select SPI device\n" + " %s [default]\n" + " -ss x SPI bus speed [MHz] (10 - 30)\n" + " 20 : 20MHz [default]\n" + " -min x override minimum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -min 30000\n" + " -max x override maximum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -max 32000\n" + " -d x log level (0-255)\n" + " -dms x delay time [milliseconds] (0 - 65535)\n" + " [default] 0\n" + " -ims x interval [milliseconds] (1 - 65535)\n" + " -c x count (0 - 65535)\n" + " 0 : endless\n" + " [default] take one shot\n" + " -tff x select type of file format\n" + " 0 : CSV\n" + " 1 : PNG [default]\n" + " 2 : PGM\n" + " -o x use 'x' as basename for file\n" + " [default] lepton-YYYYMMDD-hhmmss.sss\n" + " extension depends on file format\n" + " CSV : .cvs\n" + " PNG : .png\n" + " PGM : .pmg\n" + "Environment variable(s)\n" + " LEPTON_DATA_DIR\n" + " make png file(s) in this directory\n" + "", cmdname, cmdname, DEFAULT_SPI_DEVICE); return; } @@ -57,6 +60,7 @@ int main( int argc, char **argv ) { int typeColormap = 3; // colormap_ironblack int typeLepton = 2; // Lepton 2.x + char *spiDevice = DEFAULT_SPI_DEVICE; // SPI Device int spiSpeed = 20; // SPI bus speed 20MHz int rangeMin = -1; // int rangeMax = -1; // @@ -97,6 +101,10 @@ int main( int argc, char **argv ) i++; } } + else if ((strcmp(argv[i], "-sd") == 0) && (i + 1 != argc)) { + spiDevice = argv[i + 1]; + i++; + } else if ((strcmp(argv[i], "-ss") == 0) && (i + 1 != argc)) { int val = std::atoi(argv[i + 1]); if ((10 <= val) && (val <= 30)) { @@ -161,6 +169,7 @@ int main( int argc, char **argv ) myLepton->setLogLevel(loglevel); myLepton->useColormap(typeColormap); myLepton->useLepton(typeLepton); + myLepton->useSpiDevice(spiDevice); myLepton->useSpiSpeedMhz(spiSpeed); myLepton->setAutomaticScalingRange(); if (0 <= rangeMin) myLepton->useRangeMinValue(rangeMin); From 2a1fee7057191c6b08acbda79a1bc3939bb751b9 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Wed, 8 Apr 2020 10:08:56 +0900 Subject: [PATCH 07/11] modified v4l2lepton use leptonSPI selectable spi-device --- software/v4l2lepton/LeptonActionV4l2.cpp | 81 ++++++ software/v4l2lepton/LeptonActionV4l2.h | 31 ++ software/v4l2lepton/Lepton_I2C.cpp | 24 -- software/v4l2lepton/Lepton_I2C.h | 6 - software/v4l2lepton/Makefile | 31 -- software/v4l2lepton/Palettes.cpp | 7 - software/v4l2lepton/Palettes.h | 8 - software/v4l2lepton/SPI.cpp | 92 ------ software/v4l2lepton/SPI.h | 36 --- software/v4l2lepton/leptsci.c | 98 ------- software/v4l2lepton/leptsci.h | 3 - software/v4l2lepton/v4l2lepton.cpp | 354 ++++++++--------------- software/v4l2lepton/v4l2lepton.pro | 30 ++ 13 files changed, 269 insertions(+), 532 deletions(-) create mode 100644 software/v4l2lepton/LeptonActionV4l2.cpp create mode 100644 software/v4l2lepton/LeptonActionV4l2.h delete mode 100644 software/v4l2lepton/Lepton_I2C.cpp delete mode 100644 software/v4l2lepton/Lepton_I2C.h delete mode 100644 software/v4l2lepton/Makefile delete mode 100644 software/v4l2lepton/Palettes.cpp delete mode 100644 software/v4l2lepton/Palettes.h delete mode 100644 software/v4l2lepton/SPI.cpp delete mode 100644 software/v4l2lepton/SPI.h delete mode 100644 software/v4l2lepton/leptsci.c delete mode 100644 software/v4l2lepton/leptsci.h create mode 100644 software/v4l2lepton/v4l2lepton.pro diff --git a/software/v4l2lepton/LeptonActionV4l2.cpp b/software/v4l2lepton/LeptonActionV4l2.cpp new file mode 100644 index 0000000..fa3ff17 --- /dev/null +++ b/software/v4l2lepton/LeptonActionV4l2.cpp @@ -0,0 +1,81 @@ +#include +#include +#include +#include /* low-level i/o */ +#include +#include +#include +#include + +#include + +#include "LeptonActionV4l2.h" + +LeptonActionV4l2::LeptonActionV4l2() +{ +} + +LeptonActionV4l2::~LeptonActionV4l2() { + if (video_buf != NULL) { + free(video_buf); + } +} + +void LeptonActionV4l2::init(char *dev_video, int w, int h) +{ + v4l2dev = dev_video; + width = w; + height = h; + size_video_buf = width * height * 3; + + if (0 < v4l2sink) { + close(v4l2sink); + } + v4l2sink = open(v4l2dev, O_WRONLY); + if (v4l2sink < 0) { + fprintf(stderr, "Failed to open v4l2sink device. (%s)\n", strerror(errno)); + exit(-2); + } + + // setup video for proper format + struct v4l2_format v; + int stat; + v.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + stat = ioctl(v4l2sink, VIDIOC_G_FMT, &v); + if (stat < 0) { + fprintf(stderr, "[ERROR] Failed to ioctl v4l2sink VIDIOC_G_FMT. (%s)\n", strerror(errno)); + exit(stat); + } + v.fmt.pix.width = width; + v.fmt.pix.height = height; + v.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; + + // + v.fmt.pix.sizeimage = size_video_buf; + stat = ioctl(v4l2sink, VIDIOC_S_FMT, &v); + if (stat < 0) { + fprintf(stderr, "[ERROR] Failed to ioctl v4l2sink VIDIOC_S_FMT. (%s)\n", strerror(errno)); + exit(stat); + } + + if (video_buf != NULL) { + free(video_buf); + } + video_buf = (char*)malloc(size_video_buf); +} + +void LeptonActionV4l2::send_video() +{ + int wsize = write(v4l2sink, video_buf, size_video_buf); + if (wsize != size_video_buf) { + fprintf(stderr, "[WARNING] Sent data size mismatch. (write %d/%d bytes)\n", wsize, size_video_buf); + } +} + +void LeptonActionV4l2::setPixel(int col, int row, int colorR, int colorG, int colorB) +{ + int ofs = row * width * 3 + col * 3; + video_buf[ofs + 0] = colorR; + video_buf[ofs + 1] = colorG; + video_buf[ofs + 2] = colorB; +} diff --git a/software/v4l2lepton/LeptonActionV4l2.h b/software/v4l2lepton/LeptonActionV4l2.h new file mode 100644 index 0000000..5cf6b5c --- /dev/null +++ b/software/v4l2lepton/LeptonActionV4l2.h @@ -0,0 +1,31 @@ +#ifndef TEXTLEPTONACTIONV4L2 +#define TEXTLEPTONACTIONV4L2 + +#include "LeptonAction.h" + +#define DEV_VIDEO "/dev/video1" + +class LeptonActionV4l2 : public LeptonAction +{ + +public: + LeptonActionV4l2(); + ~LeptonActionV4l2(); + + virtual void setPixel(int, int, int, int, int); + + void init(char *dev_video, int w, int h); + void send_video(); + +private: + char *v4l2dev = DEV_VIDEO; + int v4l2sink = -1; + + int width; + int height; + int size_video_buf; + char *video_buf = NULL; + +}; + +#endif diff --git a/software/v4l2lepton/Lepton_I2C.cpp b/software/v4l2lepton/Lepton_I2C.cpp deleted file mode 100644 index 40c7572..0000000 --- a/software/v4l2lepton/Lepton_I2C.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "Lepton_I2C.h" - -#include "leptonSDKEmb32PUB/LEPTON_SDK.h" -#include "leptonSDKEmb32PUB/LEPTON_SYS.h" -#include "leptonSDKEmb32PUB/LEPTON_Types.h" - -bool _connected; - -LEP_CAMERA_PORT_DESC_T _port; - -int lepton_connect() { - LEP_OpenPort(1, LEP_CCI_TWI, 400, &_port); - _connected = true; - return 0; -} - -void lepton_perform_ffc() { - if(!_connected) { - lepton_connect(); - } - LEP_RunSysFFCNormalization(&_port); -} - -//presumably more commands could go here if desired diff --git a/software/v4l2lepton/Lepton_I2C.h b/software/v4l2lepton/Lepton_I2C.h deleted file mode 100644 index a43409e..0000000 --- a/software/v4l2lepton/Lepton_I2C.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef LEPTON_I2C -#define LEPTON_I2C - -void lepton_perform_ffc(); - -#endif diff --git a/software/v4l2lepton/Makefile b/software/v4l2lepton/Makefile deleted file mode 100644 index e774710..0000000 --- a/software/v4l2lepton/Makefile +++ /dev/null @@ -1,31 +0,0 @@ - -CC = gcc -CXX = g++ -CFLAGS = -pipe -O2 -Wall -W -D_REENTRANT -lpthread -lLEPTON_SDK -L/usr/lib/arm-linux-gnueabihf -L../raspberrypi_libs/leptonSDKEmb32PUB/Debug -CXXFLAGS = -pipe -O2 -Wall -W -D_REENTRANT -lpthread -lLEPTON_SDK -L/usr/lib/arm-linux-gnueabihf -L../raspberrypi_libs/leptonSDKEmb32PUB/Debug -INCPATH = -I. -I../raspberrypi_libs - -all: sdk leptsci.o SPI.o Lepton_I2C.o Palettes.o v4l2lepton - -sdk: - make -C ../raspberrypi_libs/leptonSDKEmb32PUB - -sdkclean: - make -C ../raspberrypi_libs/leptonSDKEmb32PUB clean - -Palettes.o: Palettes.cpp Palettes.h - ${CXX} -c ${CXXFLAGS} ${INCPATH} -o Palettes.o Palettes.cpp - -SPI.o: SPI.cpp SPI.h - ${CXX} -c ${CXXFLAGS} ${INCPATH} -o SPI.o SPI.cpp - -Lepton_I2C.o: - ${CXX} -c ${CXXFLAGS} ${INCPATH} -o Lepton_I2C.o Lepton_I2C.cpp - -v4l2lepton: v4l2lepton.o leptsci.o Palettes.o SPI.o - ${CXX} -o v4l2lepton leptsci.o Palettes.o SPI.o v4l2lepton.cpp ${CXXFLAGS} - -leptsci.o: leptsci.c - -clean: - rm -f SPI.o Lepton_I2C.o Palettes.o leptsci.o v4l2lepton.o v4l2lepton diff --git a/software/v4l2lepton/Palettes.cpp b/software/v4l2lepton/Palettes.cpp deleted file mode 100644 index 5dd67fc..0000000 --- a/software/v4l2lepton/Palettes.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -const int colormap_rainbow[] = {1, 3, 74, 0, 3, 74, 0, 3, 75, 0, 3, 75, 0, 3, 76, 0, 3, 76, 0, 3, 77, 0, 3, 79, 0, 3, 82, 0, 5, 85, 0, 7, 88, 0, 10, 91, 0, 14, 94, 0, 19, 98, 0, 22, 100, 0, 25, 103, 0, 28, 106, 0, 32, 109, 0, 35, 112, 0, 38, 116, 0, 40, 119, 0, 42, 123, 0, 45, 128, 0, 49, 133, 0, 50, 134, 0, 51, 136, 0, 52, 137, 0, 53, 139, 0, 54, 142, 0, 55, 144, 0, 56, 145, 0, 58, 149, 0, 61, 154, 0, 63, 156, 0, 65, 159, 0, 66, 161, 0, 68, 164, 0, 69, 167, 0, 71, 170, 0, 73, 174, 0, 75, 179, 0, 76, 181, 0, 78, 184, 0, 79, 187, 0, 80, 188, 0, 81, 190, 0, 84, 194, 0, 87, 198, 0, 88, 200, 0, 90, 203, 0, 92, 205, 0, 94, 207, 0, 94, 208, 0, 95, 209, 0, 96, 210, 0, 97, 211, 0, 99, 214, 0, 102, 217, 0, 103, 218, 0, 104, 219, 0, 105, 220, 0, 107, 221, 0, 109, 223, 0, 111, 223, 0, 113, 223, 0, 115, 222, 0, 117, 221, 0, 118, 220, 1, 120, 219, 1, 122, 217, 2, 124, 216, 2, 126, 214, 3, 129, 212, 3, 131, 207, 4, 132, 205, 4, 133, 202, 4, 134, 197, 5, 136, 192, 6, 138, 185, 7, 141, 178, 8, 142, 172, 10, 144, 166, 10, 144, 162, 11, 145, 158, 12, 146, 153, 13, 147, 149, 15, 149, 140, 17, 151, 132, 22, 153, 120, 25, 154, 115, 28, 156, 109, 34, 158, 101, 40, 160, 94, 45, 162, 86, 51, 164, 79, 59, 167, 69, 67, 171, 60, 72, 173, 54, 78, 175, 48, 83, 177, 43, 89, 179, 39, 93, 181, 35, 98, 183, 31, 105, 185, 26, 109, 187, 23, 113, 188, 21, 118, 189, 19, 123, 191, 17, 128, 193, 14, 134, 195, 12, 138, 196, 10, 142, 197, 8, 146, 198, 6, 151, 200, 5, 155, 201, 4, 160, 203, 3, 164, 204, 2, 169, 205, 2, 173, 206, 1, 175, 207, 1, 178, 207, 1, 184, 208, 0, 190, 210, 0, 193, 211, 0, 196, 212, 0, 199, 212, 0, 202, 213, 1, 207, 214, 2, 212, 215, 3, 215, 214, 3, 218, 214, 3, 220, 213, 3, 222, 213, 4, 224, 212, 4, 225, 212, 5, 226, 212, 5, 229, 211, 5, 232, 211, 6, 232, 211, 6, 233, 211, 6, 234, 210, 6, 235, 210, 7, 236, 209, 7, 237, 208, 8, 239, 206, 8, 241, 204, 9, 242, 203, 9, 244, 202, 10, 244, 201, 10, 245, 200, 10, 245, 199, 11, 246, 198, 11, 247, 197, 12, 248, 194, 13, 249, 191, 14, 250, 189, 14, 251, 187, 15, 251, 185, 16, 252, 183, 17, 252, 178, 18, 253, 174, 19, 253, 171, 19, 254, 168, 20, 254, 165, 21, 254, 164, 21, 255, 163, 22, 255, 161, 22, 255, 159, 23, 255, 157, 23, 255, 155, 24, 255, 149, 25, 255, 143, 27, 255, 139, 28, 255, 135, 30, 255, 131, 31, 255, 127, 32, 255, 118, 34, 255, 110, 36, 255, 104, 37, 255, 101, 38, 255, 99, 39, 255, 93, 40, 255, 88, 42, 254, 82, 43, 254, 77, 45, 254, 69, 47, 254, 62, 49, 253, 57, 50, 253, 53, 52, 252, 49, 53, 252, 45, 55, 251, 39, 57, 251, 33, 59, 251, 32, 60, 251, 31, 60, 251, 30, 61, 251, 29, 61, 251, 28, 62, 250, 27, 63, 250, 27, 65, 249, 26, 66, 249, 26, 68, 248, 25, 70, 248, 24, 73, 247, 24, 75, 247, 25, 77, 247, 25, 79, 247, 26, 81, 247, 32, 83, 247, 35, 85, 247, 38, 86, 247, 42, 88, 247, 46, 90, 247, 50, 92, 248, 55, 94, 248, 59, 96, 248, 64, 98, 248, 72, 101, 249, 81, 104, 249, 87, 106, 250, 93, 108, 250, 95, 109, 250, 98, 110, 250, 100, 111, 251, 101, 112, 251, 102, 113, 251, 109, 117, 252, 116, 121, 252, 121, 123, 253, 126, 126, 253, 130, 128, 254, 135, 131, 254, 139, 133, 254, 144, 136, 254, 151, 140, 255, 158, 144, 255, 163, 146, 255, 168, 149, 255, 173, 152, 255, 176, 153, 255, 178, 155, 255, 184, 160, 255, 191, 165, 255, 195, 168, 255, 199, 172, 255, 203, 175, 255, 207, 179, 255, 211, 182, 255, 216, 185, 255, 218, 190, 255, 220, 196, 255, 222, 200, 255, 225, 202, 255, 227, 204, 255, 230, 206, 255, 233, 208}; - -const int colormap_grayscale[] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, 111, 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 116, 116, 116, 117, 117, 117, 118, 118, 118, 119, 119, 119, 120, 120, 120, 121, 121, 121, 122, 122, 122, 123, 123, 123, 124, 124, 124, 125, 125, 125, 126, 126, 126, 127, 127, 127, 128, 128, 128, 129, 129, 129, 130, 130, 130, 131, 131, 131, 132, 132, 132, 133, 133, 133, 134, 134, 134, 135, 135, 135, 136, 136, 136, 137, 137, 137, 138, 138, 138, 139, 139, 139, 140, 140, 140, 141, 141, 141, 142, 142, 142, 143, 143, 143, 144, 144, 144, 145, 145, 145, 146, 146, 146, 147, 147, 147, 148, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 151, 152, 152, 152, 153, 153, 153, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 163, 163, 163, 164, 164, 164, 165, 165, 165, 166, 166, 166, 167, 167, 167, 168, 168, 168, 169, 169, 169, 170, 170, 170, 171, 171, 171, 172, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, 188, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197, 197, 198, 198, 198, 199, 199, 199, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 204, 204, 204, 205, 205, 205, 206, 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 213, 213, 213, 214, 214, 214, 215, 215, 215, 216, 216, 216, 217, 217, 217, 218, 218, 218, 219, 219, 219, 220, 220, 220, 221, 221, 221, 222, 222, 222, 223, 223, 223, 224, 224, 224, 225, 225, 225, 226, 226, 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, 230, 230, 230, 231, 231, 231, 232, 232, 232, 233, 233, 233, 234, 234, 234, 235, 235, 235, 236, 236, 236, 237, 237, 237, 238, 238, 238, 239, 239, 239, 240, 240, 240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245, 246, 246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255, 255, 255}; - -const int colormap_ironblack[] = {255, 255, 255, 253, 253, 253, 251, 251, 251, 249, 249, 249, 247, 247, 247, 245, 245, 245, 243, 243, 243, 241, 241, 241, 239, 239, 239, 237, 237, 237, 235, 235, 235, 233, 233, 233, 231, 231, 231, 229, 229, 229, 227, 227, 227, 225, 225, 225, 223, 223, 223, 221, 221, 221, 219, 219, 219, 217, 217, 217, 215, 215, 215, 213, 213, 213, 211, 211, 211, 209, 209, 209, 207, 207, 207, 205, 205, 205, 203, 203, 203, 201, 201, 201, 199, 199, 199, 197, 197, 197, 195, 195, 195, 193, 193, 193, 191, 191, 191, 189, 189, 189, 187, 187, 187, 185, 185, 185, 183, 183, 183, 181, 181, 181, 179, 179, 179, 177, 177, 177, 175, 175, 175, 173, 173, 173, 171, 171, 171, 169, 169, 169, 167, 167, 167, 165, 165, 165, 163, 163, 163, 161, 161, 161, 159, 159, 159, 157, 157, 157, 155, 155, 155, 153, 153, 153, 151, 151, 151, 149, 149, 149, 147, 147, 147, 145, 145, 145, 143, 143, 143, 141, 141, 141, 139, 139, 139, 137, 137, 137, 135, 135, 135, 133, 133, 133, 131, 131, 131, 129, 129, 129, 126, 126, 126, 124, 124, 124, 122, 122, 122, 120, 120, 120, 118, 118, 118, 116, 116, 116, 114, 114, 114, 112, 112, 112, 110, 110, 110, 108, 108, 108, 106, 106, 106, 104, 104, 104, 102, 102, 102, 100, 100, 100, 98, 98, 98, 96, 96, 96, 94, 94, 94, 92, 92, 92, 90, 90, 90, 88, 88, 88, 86, 86, 86, 84, 84, 84, 82, 82, 82, 80, 80, 80, 78, 78, 78, 76, 76, 76, 74, 74, 74, 72, 72, 72, 70, 70, 70, 68, 68, 68, 66, 66, 66, 64, 64, 64, 62, 62, 62, 60, 60, 60, 58, 58, 58, 56, 56, 56, 54, 54, 54, 52, 52, 52, 50, 50, 50, 48, 48, 48, 46, 46, 46, 44, 44, 44, 42, 42, 42, 40, 40, 40, 38, 38, 38, 36, 36, 36, 34, 34, 34, 32, 32, 32, 30, 30, 30, 28, 28, 28, 26, 26, 26, 24, 24, 24, 22, 22, 22, 20, 20, 20, 18, 18, 18, 16, 16, 16, 14, 14, 14, 12, 12, 12, 10, 10, 10, 8, 8, 8, 6, 6, 6, 4, 4, 4, 2, 2, 2, 0, 0, 0, 0, 0, 9, 2, 0, 16, 4, 0, 24, 6, 0, 31, 8, 0, 38, 10, 0, 45, 12, 0, 53, 14, 0, 60, 17, 0, 67, 19, 0, 74, 21, 0, 82, 23, 0, 89, 25, 0, 96, 27, 0, 103, 29, 0, 111, 31, 0, 118, 36, 0, 120, 41, 0, 121, 46, 0, 122, 51, 0, 123, 56, 0, 124, 61, 0, 125, 66, 0, 126, 71, 0, 127, 76, 1, 128, 81, 1, 129, 86, 1, 130, 91, 1, 131, 96, 1, 132, 101, 1, 133, 106, 1, 134, 111, 1, 135, 116, 1, 136, 121, 1, 136, 125, 2, 137, 130, 2, 137, 135, 3, 137, 139, 3, 138, 144, 3, 138, 149, 4, 138, 153, 4, 139, 158, 5, 139, 163, 5, 139, 167, 5, 140, 172, 6, 140, 177, 6, 140, 181, 7, 141, 186, 7, 141, 189, 10, 137, 191, 13, 132, 194, 16, 127, 196, 19, 121, 198, 22, 116, 200, 25, 111, 203, 28, 106, 205, 31, 101, 207, 34, 95, 209, 37, 90, 212, 40, 85, 214, 43, 80, 216, 46, 75, 218, 49, 69, 221, 52, 64, 223, 55, 59, 224, 57, 49, 225, 60, 47, 226, 64, 44, 227, 67, 42, 228, 71, 39, 229, 74, 37, 230, 78, 34, 231, 81, 32, 231, 85, 29, 232, 88, 27, 233, 92, 24, 234, 95, 22, 235, 99, 19, 236, 102, 17, 237, 106, 14, 238, 109, 12, 239, 112, 12, 240, 116, 12, 240, 119, 12, 241, 123, 12, 241, 127, 12, 242, 130, 12, 242, 134, 12, 243, 138, 12, 243, 141, 13, 244, 145, 13, 244, 149, 13, 245, 152, 13, 245, 156, 13, 246, 160, 13, 246, 163, 13, 247, 167, 13, 247, 171, 13, 248, 175, 14, 248, 178, 15, 249, 182, 16, 249, 185, 18, 250, 189, 19, 250, 192, 20, 251, 196, 21, 251, 199, 22, 252, 203, 23, 252, 206, 24, 253, 210, 25, 253, 213, 27, 254, 217, 28, 254, 220, 29, 255, 224, 30, 255, 227, 39, 255, 229, 53, 255, 231, 67, 255, 233, 81, 255, 234, 95, 255, 236, 109, 255, 238, 123, 255, 240, 137, 255, 242, 151, 255, 244, 165, 255, 246, 179, 255, 248, 193, 255, 249, 207, 255, 251, 221, 255, 253, 235, 255, 255, 24}; diff --git a/software/v4l2lepton/Palettes.h b/software/v4l2lepton/Palettes.h deleted file mode 100644 index ec91834..0000000 --- a/software/v4l2lepton/Palettes.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PALETTES_H -#define PALETTES_H - -extern const int colormap_rainbow[]; -extern const int colormap_grayscale[]; -extern const int colormap_ironblack[]; - -#endif diff --git a/software/v4l2lepton/SPI.cpp b/software/v4l2lepton/SPI.cpp deleted file mode 100644 index df57b19..0000000 --- a/software/v4l2lepton/SPI.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "SPI.h" - -int spi_cs_fd = -1; - -unsigned char spi_mode = SPI_MODE_3; -unsigned char spi_bitsPerWord = 8; -unsigned int spi_speed = 10000000; - -int SpiOpenPort (char* spi_device) -{ - int status_value = -1; - - //----- SET SPI MODE ----- - //SPI_MODE_0 (0,0) CPOL=0 (Clock Idle low level), CPHA=0 (SDO transmit/change edge active to idle) - //SPI_MODE_1 (0,1) CPOL=0 (Clock Idle low level), CPHA=1 (SDO transmit/change edge idle to active) - //SPI_MODE_2 (1,0) CPOL=1 (Clock Idle high level), CPHA=0 (SDO transmit/change edge active to idle) - //SPI_MODE_3 (1,1) CPOL=1 (Clock Idle high level), CPHA=1 (SDO transmit/change edge idle to active) - spi_mode = SPI_MODE_3; - - //----- SET BITS PER WORD ----- - spi_bitsPerWord = 8; - - //----- SET SPI BUS SPEED ----- - spi_speed = 10000000; //1000000 = 1MHz (1uS per bit) - - if (spi_device) - spi_cs_fd = open(std::string(spi_device).c_str(), O_RDWR); - else - spi_cs_fd = open(std::string("/dev/spidev0.1").c_str(), O_RDWR); - - if (spi_cs_fd < 0) - { - perror("Error - Could not open SPI device"); - exit(1); - } - - status_value = ioctl(spi_cs_fd, SPI_IOC_WR_MODE, &spi_mode); - if(status_value < 0) - { - perror("Could not set SPIMode (WR)...ioctl fail"); - exit(1); - } - - status_value = ioctl(spi_cs_fd, SPI_IOC_RD_MODE, &spi_mode); - if(status_value < 0) - { - perror("Could not set SPIMode (RD)...ioctl fail"); - exit(1); - } - - status_value = ioctl(spi_cs_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bitsPerWord); - if(status_value < 0) - { - perror("Could not set SPI bitsPerWord (WR)...ioctl fail"); - exit(1); - } - - status_value = ioctl(spi_cs_fd, SPI_IOC_RD_BITS_PER_WORD, &spi_bitsPerWord); - if(status_value < 0) - { - perror("Could not set SPI bitsPerWord(RD)...ioctl fail"); - exit(1); - } - - status_value = ioctl(spi_cs_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed); - if(status_value < 0) - { - perror("Could not set SPI speed (WR)...ioctl fail"); - exit(1); - } - - status_value = ioctl(spi_cs_fd, SPI_IOC_RD_MAX_SPEED_HZ, &spi_speed); - if(status_value < 0) - { - perror("Could not set SPI speed (RD)...ioctl fail"); - exit(1); - } - return(status_value); -} - -int SpiClosePort(void) -{ - int status_value = -1; - - status_value = close(spi_cs_fd); - if(status_value < 0) - { - perror("Error - Could not close SPI device"); - exit(1); - } - return(status_value); -} diff --git a/software/v4l2lepton/SPI.h b/software/v4l2lepton/SPI.h deleted file mode 100644 index fce1919..0000000 --- a/software/v4l2lepton/SPI.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SPI testing utility (using spidev driver) - * - * Copyright (c) 2007 MontaVista Software, Inc. - * Copyright (c) 2007 Anton Vorontsov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * Cross-compile with cross-gcc -I/path/to/cross-kernel/include - */ - -#ifndef SPI_H -#define SPI_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int spi_cs_fd; -extern unsigned char spi_mode; -extern unsigned char spi_bitsPerWord; -extern unsigned int spi_speed; - -int SpiOpenPort(char *device); -int SpiClosePort(void); - -#endif diff --git a/software/v4l2lepton/leptsci.c b/software/v4l2lepton/leptsci.c deleted file mode 100644 index 552de44..0000000 --- a/software/v4l2lepton/leptsci.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static uint8_t bits = 8; -static uint32_t speed = 16000000; //16 -static uint16_t delay = 0; -static int leptfd; - -int leptopen() -{ - uint8_t mode = 0; - const char device[] = "/dev/spidev0.0"; - leptfd = open(device, O_RDWR); - if (leptfd < 0) - return -1; - if (-1 == ioctl(leptfd, SPI_IOC_WR_MODE, &mode)) - return -2; - if (-1 == ioctl(leptfd, SPI_IOC_RD_MODE, &mode)) - return -3; - if (-1 == ioctl(leptfd, SPI_IOC_WR_BITS_PER_WORD, &bits)) - return -4; - if (-1 == ioctl(leptfd, SPI_IOC_RD_BITS_PER_WORD, &bits)) - return -5; - if (-1 == ioctl(leptfd, SPI_IOC_WR_MAX_SPEED_HZ, &speed)) - return -6; - if (-1 == ioctl(leptfd, SPI_IOC_RD_MAX_SPEED_HZ, &speed)) - return -7; - return 0; -} - -void leptclose() -{ - close(leptfd); -} - -int leptget(unsigned short *img) -{ -#define VOSPI_FRAME_SIZE (164) - int row = -1; - int hiccup = 0; - int notready = 0; - do { - - uint8_t lepacket[VOSPI_FRAME_SIZE]; - uint8_t tx[VOSPI_FRAME_SIZE] = { 0, }; - struct spi_ioc_transfer tr = { - .tx_buf = (unsigned long) tx, - .rx_buf = (unsigned long) lepacket, - .len = VOSPI_FRAME_SIZE, - .delay_usecs = delay, - .speed_hz = speed, - .bits_per_word = bits, - }; - - int i; - i = ioctl(leptfd, SPI_IOC_MESSAGE(1), &tr); - if (i < 1) { - fprintf(stderr, "1"); - continue; - } - //return -1; - if (((lepacket[0] & 0xf) == 0x0f)) { - //fprintf( stderr, "." ); - if (!notready) - usleep(25000); // wait for next frame - else - usleep(1000); - notready++; - continue; - } - //if( notready ) fprintf( stderr, "<%d>", notready ); - notready = 0; - //return -2; - row = lepacket[1]; - hiccup++; - if (row >= 60) { - if (hiccup > 8) { - //leptclose(); - usleep(125000); - //leptopen(); - fprintf(stderr, "!\n"); - } - fprintf(stderr, "[%d]", row); - continue; - } - hiccup = 0; - for (i = 0; i < 80; i++) - img[row * 80 + i] - = (lepacket[2 * i + 4] << 8) | lepacket[2 * i + 5]; - //printf ("%d ",img[row*81]); - } while (row != 59); - return 0; -} diff --git a/software/v4l2lepton/leptsci.h b/software/v4l2lepton/leptsci.h deleted file mode 100644 index 21820f9..0000000 --- a/software/v4l2lepton/leptsci.h +++ /dev/null @@ -1,3 +0,0 @@ -int leptopen(void); -int leptget(unsigned short *); -int leptclose(void); diff --git a/software/v4l2lepton/v4l2lepton.cpp b/software/v4l2lepton/v4l2lepton.cpp index a98fd0d..4dc601d 100644 --- a/software/v4l2lepton/v4l2lepton.cpp +++ b/software/v4l2lepton/v4l2lepton.cpp @@ -11,242 +11,142 @@ #include #include #include -#include -#include #include #include #include #include -#include "Palettes.h" #include "SPI.h" -#include "Lepton_I2C.h" - -#define PACKET_SIZE 164 -#define PACKET_SIZE_UINT16 (PACKET_SIZE/2) -#define PACKETS_PER_FRAME 60 -#define FRAME_SIZE_UINT16 (PACKET_SIZE_UINT16*PACKETS_PER_FRAME) -#define FPS 27; - -static char const *v4l2dev = "/dev/video1"; -static char *spidev = NULL; -static int v4l2sink = -1; -static int width = 80; //640; // Default for Flash -static int height = 60; //480; // Default for Flash -static char *vidsendbuf = NULL; -static int vidsendsiz = 0; - -static int resets = 0; -static uint8_t result[PACKET_SIZE*PACKETS_PER_FRAME]; -static uint16_t *frameBuffer; - -static void init_device() { - SpiOpenPort(spidev); -} - -static void grab_frame() { - - resets = 0; - for (int j = 0; j < PACKETS_PER_FRAME; j++) { - read(spi_cs_fd, result + sizeof(uint8_t) * PACKET_SIZE * j, sizeof(uint8_t) * PACKET_SIZE); - int packetNumber = result[j * PACKET_SIZE + 1]; - if (packetNumber != j) { - j = -1; - resets += 1; - usleep(1000); - if (resets == 750) { - SpiClosePort(); - usleep(750000); - SpiOpenPort(spidev); - } - } - } - if (resets >= 30) { - fprintf( stderr, "done reading, resets: \n" ); - } - - frameBuffer = (uint16_t *)result; - int row, column; - uint16_t value; - uint16_t minValue = 65535; - uint16_t maxValue = 0; - - for (int i = 0; i < FRAME_SIZE_UINT16; i++) { - if (i % PACKET_SIZE_UINT16 < 2) { - continue; - } - - int temp = result[i * 2]; - result[i * 2] = result[i * 2 + 1]; - result[i * 2 + 1] = temp; - - value = frameBuffer[i]; - if (value > maxValue) { - maxValue = value; - } - if (value < minValue) { - minValue = value; - } - column = i % PACKET_SIZE_UINT16 - 2; - row = i / PACKET_SIZE_UINT16; - } - - float diff = maxValue - minValue; - float scale = 255 / diff; - for (int i = 0; i < FRAME_SIZE_UINT16; i++) { - if (i % PACKET_SIZE_UINT16 < 2) { - continue; - } - value = (frameBuffer[i] - minValue) * scale; - const int *colormap = colormap_ironblack; - column = (i % PACKET_SIZE_UINT16) - 2; - row = i / PACKET_SIZE_UINT16; - - // Set video buffer pixel to scaled colormap value - int idx = row * width * 3 + column * 3; - vidsendbuf[idx + 0] = colormap[3 * value]; - vidsendbuf[idx + 1] = colormap[3 * value + 1]; - vidsendbuf[idx + 2] = colormap[3 * value + 2]; - } - - /* - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - memset( vidsendbuf, 0, 3); - memcpy( vidsendbuf+3, vidsendbuf, vidsendsiz-3 ); - */ -} - -static void stop_device() { - SpiClosePort(); -} - -static void open_vpipe() -{ - v4l2sink = open(v4l2dev, O_WRONLY); - if (v4l2sink < 0) { - fprintf(stderr, "Failed to open v4l2sink device. (%s)\n", strerror(errno)); - exit(-2); - } - // setup video for proper format - struct v4l2_format v; - int t; - v.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - t = ioctl(v4l2sink, VIDIOC_G_FMT, &v); - if( t < 0 ) - exit(t); - v.fmt.pix.width = width; - v.fmt.pix.height = height; - v.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; - vidsendsiz = width * height * 3; - v.fmt.pix.sizeimage = vidsendsiz; - t = ioctl(v4l2sink, VIDIOC_S_FMT, &v); - if( t < 0 ) - exit(t); - vidsendbuf = (char*)malloc( vidsendsiz ); +#include "Lepton.h" +#include "LeptonAction.h" +#include "LeptonActionV4l2.h" + +#define DEFAULT_VIDEO_DEVICE "/dev/video1" + +void printUsage(char *cmd) { + char *cmdname = basename(cmd); + printf("Usage: %s [OPTION]...\n" + " -h display this help and exit\n" + " -cm x select colormap\n" + " 1 : rainbow\n" + " 2 : grayscale\n" + " 3 : ironblack [default]\n" + " -tl x select type of Lepton\n" + " 2 : Lepton 2.x [default]\n" + " 3 : Lepton 3.x\n" + " [for your reference] Please use nice command\n" + " e.g. sudo nice -n 0 ./%s -tl 3\n" + " -sd x select SPI device\n" + " %s [default]\n" + " -ss x SPI bus speed [MHz] (10 - 30)\n" + " 20 : 20MHz [default]\n" + " -vd x v4l2 loopback device " + " %s [default]\n" + " -min x override minimum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -min 30000\n" + " -max x override maximum value for scaling (0 - 65535)\n" + " [default] automatic scaling range adjustment\n" + " e.g. -max 32000\n" + "", cmd, cmd, DEFAULT_SPI_DEVICE, DEFAULT_VIDEO_DEVICE); } -static pthread_t sender; -static sem_t lock1,lock2; -static void *sendvid(void *v) -{ - (void)v; - for (;;) { - sem_wait(&lock1); - if (vidsendsiz != write(v4l2sink, vidsendbuf, vidsendsiz)) - exit(-1); - sem_post(&lock2); - } -} - -void usage(char *exec) -{ - printf("Usage: %s [options]\n" - "Options:\n" - " -d | --device name Use name as spidev device " - "(/dev/spidev0.1 by default)\n" - " -h | --help Print this message\n" - " -v | --video name Use name as v4l2loopback device " - "(%s by default)\n" - "", exec, v4l2dev); -} - -static const char short_options [] = "d:hv:"; - -static const struct option long_options [] = { - { "device", required_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - { "video", required_argument, NULL, 'v' }, - { 0, 0, 0, 0 } -}; - int main(int argc, char **argv) { - struct timespec ts; - - // processing command line parameters - for (;;) { - int index; - int c; - - c = getopt_long(argc, argv, - short_options, long_options, - &index); - - if (-1 == c) - break; - - switch (c) { - case 0: - break; - - case 'd': - spidev = optarg; - break; - - case 'h': - usage(argv[0]); - exit(EXIT_SUCCESS); - - case 'v': - v4l2dev = optarg; - break; - - default: - usage(argv[0]); - exit(EXIT_FAILURE); - } - } - - open_vpipe(); - - // open and lock response - if (sem_init(&lock2, 0, 1) == -1) - exit(-1); - sem_wait(&lock2); - - if (sem_init(&lock1, 0, 1) == -1) - exit(-1); - pthread_create(&sender, NULL, sendvid, NULL); - for (;;) { - // wait until a frame can be written - fprintf( stderr, "Waiting for sink\n" ); - sem_wait(&lock2); - // setup source - init_device(); // open and setup SPI - for (;;) { - grab_frame(); - // push it out - sem_post(&lock1); - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += 2; - // wait for it to get written (or is blocking) - if (sem_timedwait(&lock2, &ts)) - break; - } - stop_device(); // close SPI - } - close(v4l2sink); - return 0; + int typeColormap = 3; // colormap_ironblack + int typeLepton = 2; // Lepton 2.x + char *spiDevice = DEFAULT_SPI_DEVICE; // SPI Device + int spiSpeed = 20; // SPI bus speed 20MHz + char *v4l2Device = DEFAULT_VIDEO_DEVICE; + int rangeMin = -1; // + int rangeMax = -1; // + + for(int i=1; i < argc; i++) { + if (strcmp(argv[i], "-h") == 0) { + printUsage(argv[0]); + exit(0); + } + else if ((strcmp(argv[i], "-cm") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((val == 1) || (val == 2)) { + typeColormap = val; + i++; + } + } + else if ((strcmp(argv[i], "-tl") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if (val == 3) { + typeLepton = val; + i++; + } + } + else if ((strcmp(argv[i], "-sd") == 0) && (i + 1 != argc)) { + spiDevice = argv[i + 1]; + i++; + } + else if ((strcmp(argv[i], "-ss") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((10 <= val) && (val <= 30)) { + spiSpeed = val; + i++; + } + } + else if ((strcmp(argv[i], "-vd") == 0) && (i + 1 != argc)) { + v4l2Device = argv[i + 1]; + i++; + } + else if ((strcmp(argv[i], "-min") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((0 <= val) && (val <= 65535)) { + rangeMin = val; + i++; + } + } + else if ((strcmp(argv[i], "-max") == 0) && (i + 1 != argc)) { + int val = std::atoi(argv[i + 1]); + if ((0 <= val) && (val <= 65535)) { + rangeMax = val; + i++; + } + } + } + + // + Lepton *myLepton = new Lepton(); + myLepton->useColormap(typeColormap); + myLepton->useLepton(typeLepton); + myLepton->useSpiDevice(spiDevice); + myLepton->useSpiSpeedMhz(spiSpeed); + myLepton->setAutomaticScalingRange(); + if (0 <= rangeMin) myLepton->useRangeMinValue(rangeMin); + if (0 <= rangeMax) myLepton->useRangeMaxValue(rangeMax); + + // + LeptonActionV4l2 *leptonActionV4l2 = new LeptonActionV4l2(); + leptonActionV4l2->init(v4l2Device, myLepton->getWidth(), myLepton->getHeight()); + + // + int segment_number0 = 0; + for (;;) { + myLepton->open(); + for (;;) { + int segment_number = myLepton->readFrameData((LeptonAction*)leptonActionV4l2); + if (segment_number0 + 1 == segment_number) { + if ((typeLepton == 2) || (segment_number == 4)) { + leptonActionV4l2->send_video(); + segment_number0 = 0; + } + else { + segment_number0 = segment_number; + } + } + else { + segment_number0 = 0; + } + } + myLepton->close(); + } + + return 0; } diff --git a/software/v4l2lepton/v4l2lepton.pro b/software/v4l2lepton/v4l2lepton.pro new file mode 100644 index 0000000..739ea65 --- /dev/null +++ b/software/v4l2lepton/v4l2lepton.pro @@ -0,0 +1,30 @@ + +TEMPLATE = app +#QT += core gui +#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = v4l2lepton + +RPI_LIBS = ../raspberrypi_libs +LEPTONSDK = leptonSDKEmb32PUB + +PRE_TARGETDEPS += sdk +QMAKE_EXTRA_TARGETS += sdk sdkclean +sdk.commands = make -C $${RPI_LIBS}/$${LEPTONSDK} +sdkclean.commands = make -C $${RPI_LIBS}/$${LEPTONSDK} clean + +DEPENDPATH += . +INCLUDEPATH += . $${RPI_LIBS} $${RPI_LIBS}/leptonSPI + +DESTDIR=. +OBJECTS_DIR=gen_objs +MOC_DIR=gen_mocs + +HEADERS += *.h + +SOURCES += *.cpp + +unix:LIBS += -L$${RPI_LIBS}/$${LEPTONSDK}/Debug -L$${RPI_LIBS}/leptonSPI -lleptonSPI -lLEPTON_SDK + +unix:QMAKE_CLEAN += -r $(OBJECTS_DIR) $${MOC_DIR} + From 0e53165c4eeb99f3f92463acdaff1fc06ed84566 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Wed, 8 Apr 2020 10:25:29 +0900 Subject: [PATCH 08/11] add raspberrypi_libs/leptonSPI/.gitignore --- software/raspberrypi_libs/leptonSPI/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 software/raspberrypi_libs/leptonSPI/.gitignore diff --git a/software/raspberrypi_libs/leptonSPI/.gitignore b/software/raspberrypi_libs/leptonSPI/.gitignore new file mode 100644 index 0000000..e0292b1 --- /dev/null +++ b/software/raspberrypi_libs/leptonSPI/.gitignore @@ -0,0 +1,2 @@ +*.o +*.a From 4c19a6b41d58d159cd34b82bb54cce2a2dc00241 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Wed, 8 Apr 2020 10:29:11 +0900 Subject: [PATCH 09/11] modified raspberrypi_video/.gitignore --- software/raspberrypi_video/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/software/raspberrypi_video/.gitignore b/software/raspberrypi_video/.gitignore index b5e01e7..a0cb92a 100644 --- a/software/raspberrypi_video/.gitignore +++ b/software/raspberrypi_video/.gitignore @@ -4,4 +4,4 @@ gen_objs gen_mocs *.o raspberrypi_video - +.qmake* From ced9dd204bdc28b3323015e3994b319eeacde96f Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Wed, 8 Apr 2020 10:32:14 +0900 Subject: [PATCH 10/11] add raspberrypi_capture/.gitignore --- software/raspberrypi_capture/.gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 software/raspberrypi_capture/.gitignore diff --git a/software/raspberrypi_capture/.gitignore b/software/raspberrypi_capture/.gitignore new file mode 100644 index 0000000..6a2c028 --- /dev/null +++ b/software/raspberrypi_capture/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Makefile +gen_objs +gen_mocs +*.o +raspberrypi_capture +.qmake* From 8daf9f492e1f5735198caedae9ac8e4cd973cbb6 Mon Sep 17 00:00:00 2001 From: Toshio HIGUCHI Date: Wed, 8 Apr 2020 10:33:37 +0900 Subject: [PATCH 11/11] add v4l2lepton/.gitignore --- software/v4l2lepton/.gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 software/v4l2lepton/.gitignore diff --git a/software/v4l2lepton/.gitignore b/software/v4l2lepton/.gitignore new file mode 100644 index 0000000..e4fbff6 --- /dev/null +++ b/software/v4l2lepton/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Makefile +gen_objs +gen_mocs +*.o +v4l2lepton +.qmake*