//#DOC Main, program entry and main loop
#include "main.h"
// Test executed @ 525MHz and 131MHz peripheral clock
// Grab time 22.5 ms @ full resolution
// Data correction 136 ms
U8 imageType = otImage::IMG_U16; // Default image type
U32 timeBase = 1000000; // Sampling time base
bool dataAlign = false; // Specify where to do data alignment
otCamera camera; // Library for the camera control
otImageSensor sensor; // Library for image sensor settings
otImage image; // Image store and processing library
otVMC showData; // Utiliy to show memory contents
otImageFile imgFile; // Library to save different image file format
otFILE file; // File I/O library
otCommandParser parser; // Console command parser
otSerialThread io; // Serial interrupt handler
otUSB usb; // Declare USB library
// USB slave comnnad to check system ready
FAST_CODE_1 void usb_Nop(otUSB * usbHandler)
{
usbHandler->putWord(USB_ACK);
}
// Console related
FAST_CODE_2 U8 _getChar()
{
printf("\nPress . or ESC to stop display or any other key to continue\n");
return io.waitChar();
}
void commandLineInterpreter()
{
U8 commandLine[256];
if(io.getString(commandLine, 256))
switch(parser.parse((char *) commandLine))
{
case 1: printf("\nBatch exists but is empty: [%s]\n", commandLine);
break;
case 2: printf("\nBatch don't exists: [%s]\n", commandLine);
break;
case 3: printf("\nUnknown command: [%s]\n", commandLine);
break;
case 4: printf("\n???\n");
break;
case 5: // Syntax error
break;
}
otLegacyDisplayPrompt();
}
// Enable/disable sensor low noise mode
S32 __sensLowNoise(int Argc, char * Argv)
{
int mod = _atoi((char *) ARGV(1));
if(mod)
sensor.lowNoise(true);
else
sensor.lowNoise(false);
return 1;
}
// Free desktop image server
S32 __imageFree(int Argc, char * Argv)
{
usb.putByte(ER_IMAGE_FREE);
return 1;
}
// Set PYTHON1300 shutter setup
S32 __sensShutter(int Argc, char * Argv)
{
U16 exp = 1, res = 1, pre = 1;
if(Argc > 1)
exp = _atoi((char *) ARGV(1));
if(Argc > 2)
res = _atoi((char *) ARGV(2));
if(Argc > 3)
pre = _atoi((char *) ARGV(3));
sensor.pythonShutter(exp, res, pre);
}
// Create a local image buffer and remote image server
S32 __imageInit(int Argc, char * Argv)
{
U16 x = _atoi((char *) ARGV(1));
U16 y = _atoi((char *) ARGV(2));
U16 n = _atoi((char *) ARGV(3));
U8 t = _atoi((char *) ARGV(4));
U8 it = otImage::IMG_U16;
usb.putByte(ER_IMAGE_FREE);
if(image.data())
image.close();
switch(t)
{
case 0: imageType = otImage::IMG_U8;
it = otImage::IMG_U8;
break;
case 1: imageType = otImage::IMG_U16;
break;
case 2: imageType = otImage::IMG_U8 | 0x80;
break;
}
sensor.setROI(0, 0, x, y);
image.create(sensor.horPixel(), sensor.verPixel(), n, (otImage::ImageType) it);
usb.putByte(ER_IMAGE_CREATE);
usb.putWord(sensor.horPixel());
usb.putWord(sensor.verPixel());
usb.putWord(n);
usb.putByte(imageType & 0x7F);
return 1;
}
// Command to grab an image(s) and trasfer the contents to desktop via DAQ
FAST_CODE_2 S32 __imageGrab(int Argc, char * Argv)
{
U32 n = image.pixels(), et;
if(Argc > 1)
{
F32 expo;
expo = _atof((char *) ARGV(1));
sensor.setExposure(expo);
}
ElapsedTimeStart(TIMER0);
camera.grab(image, TIMER0, dataAlign);
et = ElapsedTimeEndUs(TIMER0);
if(dataAlign)
usb.putByte(ER_IMAGE_TRANSFER);
else
usb.putByte(ER_IMAGE_TRANSFER_S);
switch(imageType)
{
case otImage::IMG_U8:
{
U8 * ptr;
for(U32 f = 0; f < image.frames(); f++)
{
ptr = (U8 *) image.data(f);
for(U32 i = 0; i < n; i++)
usb.putByte(ptr[i]);
}
}
break;
case otImage::IMG_U16:
{
U16 * ptr;
for(U32 f = 0; f < image.frames(); f++)
{
ptr = (U16 *) image.data(f);
for(U32 i = 0; i < n; i++)
{
usb.putWord(ptr[i]);
}
}
}
break;
case (otImage::IMG_U8 | 0x80):
{
U16 * ptr;
for(U32 f = 0; f < image.frames(); f++)
{
ptr = (U16 *) image.data(f);
for(U32 i = 0; i < n; i++)
{
usb.putByte(ptr[i] >> 2);
}
}
}
break;
}
// Set image delta time
usb.putByte(ER_IMAGE_DTIME);
usb.putLong(timeBase);
usb.putLong(et);
return 1;
}
void setup()
{
// Init stout used by printf
setStdout(4096, UART0); // printf output is now directed on UART0
// Init UART0 handler
io.init(UART0, 115200);
// Init the timer for time measure
TimerSetAsCounter(TIMER0);
TimerEnable(TIMER0, true);
RtcOn();
// This test has been written in this date
RtcSetDate(2021, 8, 18);
RtcSetTime(12, 0, 0);
// Init the camera based on PYTHON1300
camera.init(otCamera::CM_TIZIANO);
// Init image sensor
sensor.init(otImageSensor::IS_PYTHON1300);
// Show sensor resolution
printf("Sensor resolution: %dx%d\n", sensor.horPixel(), sensor.verPixel());
// Init display utility
showData.open();
if(file.init())
{
file.setStdin(_getChar);
file.setStdout(printf);
// If SD is present and ready
parser.init(PARSER_MAX_AVAILABLE_COMMANDS, &file);
otLegacyCommandsInit(&parser, &io, &file);
}
else
{
printf("Can't init SD card!\n");
// Set command line without SD
parser.init(PARSER_MAX_AVAILABLE_COMMANDS);
otLegacyCommandsInit(&parser, &io);
}
// Set default procedure for library message
file.setStdout(printf);
// Set I/O access
imgFile.init(&file);
// Init USB channel, the command list can accept 64 different commands
usb.init(64);
// Command used by DAQ to check if DSP is ready
usb.addCallback(usb_Nop, USB_NOP);
// Add more user command here ....
// x sensor sample clock check
FpgaPortPxSet(PD_FUNC_1, PD_OUTPUT, PD_OUTPUT, PD_OUTPUT, PD_OUTPUT, PD_OUTPUT, PD_OUTPUT, PD_OUTPUT);
// User commands
parser.add("IMAGE.NEW" , "NI", __imageInit, false, 4, 4, "128,1280;128,1024;1,10000;0,2", "horSize verSize frames type; Create a new image server");
parser.add("IMAGE.GRAB", "GRAB", __imageGrab, false, 0, 1, "", "[exposure]; Grab and display an image, default exposure 1ms");
parser.add("IMAGE.FREE", "FI", __imageFree, false, 0, 0, "", "; Free desktop image server");
parser.add("SENSOR.SHUT", "SS", __sensShutter, false, 0, 3, "", "[expose] [reset] [prescaler]; Python shutter");
parser.add("SENSOR.LNOISE", "SN", __sensLowNoise, false, 1, 1, "", "0 | 1; Python low noise mode enable/disable");
// Add more user command here ....
// Default sensor setup
sensor.setROI(0, 0, 1280, 1024);
image.create(sensor.horPixel(), sensor.verPixel(), 1, otImage::IMG_U16);
sensor.lowNoise(true);
}
void loop()
{
// Handle for command line requests
if(io.ready()) commandLineInterpreter();
// Handle for USB commands
usb.process();
}