-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathLeptonThread.cpp
More file actions
148 lines (122 loc) · 3.78 KB
/
LeptonThread.cpp
File metadata and controls
148 lines (122 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Engineer: Thomas Reaney
// College: National University of Ireland Galway
// Date: 20/02/2017
#include "LeptonThread.h"
#include <QString>
#include <QTextStream>
LeptonThread::LeptonThread()
: QThread()
, result(RowPacketBytes*FrameHeight)
, rawData(FrameWords) {}
LeptonThread::~LeptonThread() {}
// Define the parameters for the LeptonThread
const char *LeptonThread::device = "/dev/spidev0.0";
unsigned char LeptonThread::mode = 0, LeptonThread::bits = 8;
unsigned int LeptonThread::speed = 16000000;
unsigned short LeptonThread::delay = 0;
QVector<unsigned char> LeptonThread::tx(LeptonThread::RowPacketBytes, 0);
// Method: Used to initialize the LeptonThread
bool LeptonThread::initLepton()
{
fd = open(device, O_RDWR);
if (fd < 0)
qDebug() << "Can't open device";
else if (-1 == ioctl(fd, SPI_IOC_WR_MODE, &mode))
qDebug() << "Can't set SPI mode";
else if (-1 == ioctl(fd, SPI_IOC_RD_MODE, &mode))
qDebug() << "Can't get SPI mode";
else if (-1 == ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits))
qDebug() << "Can't set bits per word";
else if (-1 == ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits))
qDebug() << "Can't get bits per word";
else if (-1 == ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed))
qDebug() << "Can't set max speed";
else if (-1 == ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed))
qDebug() << "Can't get max speed";
else
return true;
return false;
}
// Method: Used to get a packet of data over SPI
int LeptonThread::getPacket(int iRow, unsigned char *packetData)
{
_tr.rx_buf = (unsigned long) packetData;
return ioctl(fd, SPI_IOC_MESSAGE(1), &_tr);
}
// Method: Used to run LeptonThread
void LeptonThread::run()
{
if (!initLepton()) return;
usleep(250000);
_tr.tx_buf = (unsigned long) &tx[0];
_tr.len = RowPacketBytes;
_tr.delay_usecs = delay;
_tr.speed_hz = speed;
_tr.bits_per_word = bits;
// Initialize the number of error packets received and the number of resets
int resets = 0;
int errors = 0;
while (true)
{
int iRow;
for (iRow=0; iRow<FrameHeight;)
{
unsigned char *packet = &result[iRow*RowPacketBytes];
if (getPacket(iRow, packet) < 1)
{
qDebug() << "Error transferring SPI packet";
return;
}
int packetNumber;
if ((packet[0] & 0xf) == 0xf) {
packetNumber = -1;
} else {
packetNumber = packet[1];
}
if (packetNumber == -1)
{
usleep(1000);
if (++errors > 300) break;
continue;
}
if (packetNumber != iRow)
{
usleep(1000);
break;
}
++iRow;
}
if (iRow < FrameHeight)
{
if (++resets >= 750)
{
qDebug() << "Packet reset counter hit 750";
resets = 0;
usleep(750000);
}
continue;
}
resets = 0;
errors = 0;
uint16_t minValue = 65535;
uint16_t maxValue = 0;
unsigned char *in = &result[0];
unsigned short *out = &rawData[0];
// Convert unsigned char[] to unsigned short[]
for (int iRow=0; iRow<FrameHeight; ++iRow)
{
in += 4;
for (int iCol=0; iCol<FrameWidth; ++iCol)
{
unsigned short value = in[0];
value <<= 8;
value |= in[1];
in += 2;
if (value > maxValue) maxValue = value;
if (value < minValue) minValue = value;
*(out++) = value;
}
}
emit updateImage(&rawData[0], minValue, maxValue);
}
}