//#DOC Main, program entry and main loop
#include "main.h"
#include <otSerial.h>
#include <otMalloc.h>
#include <otPrintf.h>
#include <otLepton3.h>
#include <otSpi.h>
#include <otFPGA.h>
#include <otTimer.h>
#include <otImage.h>
#include <otString.h>
#include <otGraphics.h>
#include <otTFMini.h>
#include "palette.h"
#define X_OFFSET 0
#define Y_OFFSET 0
otLepton3 ir;
otImage display; // Image for display
otImage image; // Image store and processing library
otGraphics tft; // Display library
otTFMini lidar;
U16 * irBuffer;
const U16 * pal[5];
void DisplayLeptonModel()
{
LEP_CHAR8 oemPartString[32];
// Get the OEM FLIR Systems Part Number (IDD section 4.6.4)
if(ir.getOemFlirPartNumber((LEP_OEM_PART_NUMBER_T_PTR) oemPartString) == LEP_OK)
{
printf("Part number: %s ==> ", oemPartString);
// Part numbers from FLIR Lepton Engineering Datasheet, section 1.5 Key Specifications
if(_strstr(oemPartString, "500-0659-01") != NULL)
{
printf("Lepton 2 Shuttered\n");
}
else
if(_strstr(oemPartString, "500-0763-01") != NULL)
{
printf("Lepton 2.5 Shuttered (Radiometric)\n");
}
else
if(_strstr(oemPartString, "500-0726-01") != NULL)
{
printf("Lepton 3 Shuttered\n");
}
else
if(_strstr(oemPartString, "500-0771-01") != NULL)
{
printf("Lepton 3.5 Shuttered (Radiometric)\n");
}
else
printf("Unknown\n");
}
}
// Show the hottest point of the image
void Cursor(U16 x, U16 y, U16 color)
{
U16 xs, ys, xd, yd;
x *= 2;
y *= 2;
if(x >= 5) xs = x - 5; else xs = 0;
if(y >= 5) ys = y - 5; else ys = 0;
if(x <= 314) xd = x + 5; else xd = 319;
if(y <= 234) yd = y + 5; else yd = 239;
tft.drawLine(xs, y, xd, y, color);
tft.drawLine(x, ys, x, yd, color);
}
// Image display
FAST_CODE_1 void Display()
{
// LEP_SYS_FPA_TEMPERATURE_KELVIN_T fpaKx100;
U16 _min = 65535, _max = 0;
U16 xloc[2], yloc[2];
U16 * ptr = (U16 *) image.data();
U32 i;
char buf[80];
// Find min/max in the image
for(i = 0; i < 19200; i++)
{
if(ptr[i] > _max) { _max = ptr[i]; yloc[1] = i / 160; xloc[1] = i % 160; }
if(ptr[i] < _min) { _min = ptr[i]; yloc[0] = i / 160; xloc[0] = i % 160; }
}
// Get FPA temperature as Kelvin
// ir.getSysFpaTemperatureKelvin(&fpaKx100);
// F32 t = (fpaKx100 - 27315) / 100.0;
// Get AUX temperature as Kelvin
// F32 a = (F32) ir.temperature(false);
// Convert min/max as temperature
F32 MN = (_min - 27315) / 100.0;
F32 MX = (_max - 27315) / 100.0;
U16 d = lidar.getDistance();
// Convert grab image to 8 bit for display
image.shrink(display, (U32) _min + 1, (F32) (_max - _min) / 256.0f);
// Enable SPI channel for display
SpiSet(SA_LCD);
// Show the image with a zoom of 2x
tft.showImagePalZx2(0, 0, 320, 240, (const U8 *) display.data(), pal[1]);
// Show the hot point with a cursor
Cursor(xloc[1], yloc[1], RGB565_BLACK);
Cursor(xloc[0], yloc[0], RGB565_WHITE);
// Display min/max on display
sprintf(buf, "%3.1fC %3.1fC %ucm", MN, MX, d);
tft.setCursor(0, 220); tft.writeString(buf);
// Change SPI channel to Lepton
SpiSet(SA_Y6);
/*
// Print on console some statistics
printf("Image statistics : Min = %05d @ %2d:%2d -> %.1f C\n", _min, xloc[0], yloc[0], MN);
printf("Image statistics : Max = %05d @ %2d:%2d -> %.1f C\n", _max, xloc[1], yloc[1], MX);
printf("LWIR AUX Temperature: %.2f K : %.1f C.\n", a, a - 273.15f);
printf("LWIR FPA Temperature: %.2f K : %.1f C.\n", t, t - 273.15f);
*/
}
void setup()
{
UartEnableSignals(UART0);
UartSetBaud(UART0, 115200);
_initMalloc();
setStdout(4096, UART0); // printf output is now directed on UART0
FpgaInit();
FpgaHiddenPort(HP_EXT_I2C, true);
// Init the timer for time measure
TimerSetAsCounter(TIMER0);
TimerEnable(TIMER0, true);
// Create an image buffer
image.create(160, 120, 1, otImage::IMG_U16);
display.create(160, 120, 1, otImage::IMG_U8);
// Load some palettes
pal[0] = gray;
pal[1] = coldFire;
pal[2] = coldFireLog;
pal[3] = volcanoLin;
pal[4] = volcanoLog;
// Init display
tft.init();
tft.setRotation(otGraphics::IR_90);
tft.setTextColor(RGB565_YELLOW, RGB565_BLACK);
tft.setTextSize(2);
tft.fillRect(0, 0, 320, 240, RGB565_BLACK);
lidar.init(UART1);
DelayMs(1000);
if(ir.openPort(SA_Y6, 100, 12, TIMER0) != LEP_OK)
{
printf("Lepton 3 open failed\n");
IDLE;
}
else
{
if(ir.setRadTLinearAutoResolution(LEP_RAD_ENABLE) == LEP_OK)
{
if(ir.setOemVideoOutputFormat(LEP_VIDEO_OUTPUT_FORMAT_RAW14) == LEP_OK)
{
// Enable VSYNC on the GPIO3 output (you should be able to see this using an oscilloscope)
// (IDD section 4.6.15 OEM GPIO Mode Select)
if(ir.setOemGpioMode(LEP_OEM_GPIO_MODE_VSYNC) == LEP_OK)
{
DisplayLeptonModel();
}
else printf("Set GPIO failed\n");
}
else printf("Get Video Format failed\n");
}
else printf("Set RAD Linear AutoResolution Enable failed\n");
}
ir.startGrab((U16 *) image.data());
}
void loop()
{
U32 loopCounter = 0;
F64 mnT, mxT, ctT;
LEP_SYS_FPA_TEMPERATURE_KELVIN_T fpaKx100;
while(1)
{
if(ir.isGrabDone())
{
//ir.temperatureRange(mnT, mxT, ctT);
//printf("[%4u] Min = %5.1lfC :: Max = %5.1lfC :: Center = %5.1lfC :: ET = %u us\n", loopCounter++, mnT, mxT, ctT, ir.elapsedTime());
Display();
ir.startGrab((U16 *) image.data());
}
/* else
if(ir.getSysFpaTemperatureKelvin(&fpaKx100) == LEP_OK)
{
F32 fpaC = (fpaKx100 - 27315) / 100.0; // Convert to Celsius
printf("[%4u] FPA = %5.1fC\n", loopCounter++, fpaC);
DelayMs(100);
}*/
}
}