diff --git a/Firmware_V3/.vscode/settings.json b/Firmware_V3/.vscode/settings.json index f1fce88..e10f25c 100644 --- a/Firmware_V3/.vscode/settings.json +++ b/Firmware_V3/.vscode/settings.json @@ -1,6 +1,7 @@ { "files.associations": { "*.tcc": "cpp", - "functional": "cpp" + "functional": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/Firmware_V3/include/globalvariables.h b/Firmware_V3/include/globalvariables.h index e04a725..29514ed 100644 --- a/Firmware_V3/include/globalvariables.h +++ b/Firmware_V3/include/globalvariables.h @@ -85,6 +85,6 @@ extern volatile bool longTouch; extern volatile bool serialMode; extern volatile byte loadTouch; extern volatile bool leptonBufferValid; -extern volatile bool displayUpdated; +extern volatile bool disableSPIIRQ; #endif /* GLOBALVARIABLES_H */ diff --git a/Firmware_V3/include/loadmenu.h b/Firmware_V3/include/loadmenu.h index a1877eb..bbb4d4c 100644 --- a/Firmware_V3/include/loadmenu.h +++ b/Firmware_V3/include/loadmenu.h @@ -23,11 +23,11 @@ bool convertPrompt(); void convertVideo(char* dirname); void deleteImage(char* filename); void deleteVideo(char* dirname); -void displayGUI(int imgCount, char* infoText); -void displayVideoFrame(int i); -uint16_t getVideoFrameNumber(); +void displayGUI(uint32_t imgCount, char* infoText); +void displayVideoFrame(uint32_t imgCount); +uint32_t getVideoFrameNumber(); int loadMenu(char* title, int* array, int length); -void openImage(char* filename, int imgCount); -void playVideo(char* dirname, int imgCount); +void openImage(char* filename, uint32_t imgCount); +void playVideo(char* dirname, uint32_t imgCount); #endif /* LOADMENU_H */ diff --git a/Firmware_V3/include/save.h b/Firmware_V3/include/save.h index 0651b25..edf56af 100644 --- a/Firmware_V3/include/save.h +++ b/Firmware_V3/include/save.h @@ -18,14 +18,13 @@ /*########################## PUBLIC PROCEDURES ################################*/ -void createBMPFile(char* filename); void createSDName(char* filename, boolean folder = false); -void frameFilename(char* filename, uint16_t count); +void frameFilename(char* filename, uint32_t count); void imgSaveEnd(); void imgSaveStart(); -void processVideoFrames(int framesCaptured, char* dirname); +void processVideoFrames(uint32_t framesCaptured, char* dirname); void saveBuffer(char* filename); -void saveRawData(bool isImage, char* name, uint16_t framesCaptured = 0); +void saveRawData(bool isImage, char* name, uint32_t framesCaptured = 0); void saveVideoFrame(char* filename); #endif /* SAVE_H */ diff --git a/Firmware_V3/include/videomenu.h b/Firmware_V3/include/videomenu.h index 803b9d7..6831b61 100644 --- a/Firmware_V3/include/videomenu.h +++ b/Firmware_V3/include/videomenu.h @@ -18,8 +18,8 @@ /*########################## PUBLIC PROCEDURES ################################*/ -void videoCaptureInterval(int16_t* remainingTime, int* framesCaptured); -void videoCaptureNormal(int* framesCaptured); +void videoCaptureInterval(int16_t* remainingTime, uint32_t* framesCaptured, uint16_t* folderFrames, char* buffer, char* dirName); +void videoCaptureNormal(uint32_t* framesCaptured, uint16_t* folderFrames, char* buffer, char* dirName); void videoCapture(); bool videoIntervalChooser(); bool videoIntervalHandler(byte* pos); diff --git a/Firmware_V3/lib/SdFat/src/SdFatConfig.h b/Firmware_V3/lib/SdFat/src/SdFatConfig.h index a883897..9c14d07 100644 --- a/Firmware_V3/lib/SdFat/src/SdFatConfig.h +++ b/Firmware_V3/lib/SdFat/src/SdFatConfig.h @@ -202,7 +202,7 @@ typedef uint8_t SdCsPin_t; * Set USE_SD_CRC to 2 to used a larger table driven CRC-CCITT function. This * function is faster for AVR but may be slower for ARM and other processors. */ -#define USE_SD_CRC 0 +#define USE_SD_CRC 1 //------------------------------------------------------------------------------ /** If the symbol USE_FCNTL_H is nonzero, open flags for access modes O_RDONLY, * O_WRONLY, O_RDWR and the open modifiers O_APPEND, O_CREAT, O_EXCL, O_SYNC diff --git a/Firmware_V3/other/platformio_teensy4.zip b/Firmware_V3/other/platformio_teensy4.zip index 898b8f5..1238370 100644 Binary files a/Firmware_V3/other/platformio_teensy4.zip and b/Firmware_V3/other/platformio_teensy4.zip differ diff --git a/Firmware_V3/src/general/globalvariables.cpp b/Firmware_V3/src/general/globalvariables.cpp index 2dc1e7c..fd7eaf9 100644 --- a/Firmware_V3/src/general/globalvariables.cpp +++ b/Firmware_V3/src/general/globalvariables.cpp @@ -26,7 +26,7 @@ /*############################# PUBLIC VARIABLES ##############################*/ //Current firmware version -char versionString[] = "Firmware 3.02 from 21.06.2021"; +char versionString[] = "Firmware 3.02 from 05.07.2021"; uint16_t fwVersion = 302; //320x240 buffer @@ -150,4 +150,4 @@ volatile byte loadTouch; //Current buffer valid volatile bool leptonBufferValid; //Display is currently updated, do not use SPI in IRQ -volatile bool displayUpdated; +volatile bool disableSPIIRQ; diff --git a/Firmware_V3/src/gui/loadmenu.cpp b/Firmware_V3/src/gui/loadmenu.cpp index 90e8fd4..f05cda1 100644 --- a/Firmware_V3/src/gui/loadmenu.cpp +++ b/Firmware_V3/src/gui/loadmenu.cpp @@ -31,7 +31,7 @@ /*######################## PUBLIC FUNCTION BODIES #############################*/ /* Display the GUI elements for the load menu */ -void displayGUI(int imgCount, char* infoText) { +void displayGUI(uint32_t imgCount, char* infoText) { //Set text color changeTextColor(); //set Background transparent @@ -89,9 +89,9 @@ void deleteVideo(char* dirname) { sd.chdir(dirname); //Delete all files - uint16_t videoCounter = 0; + uint32_t videoCounter = 0; bool exists; - char filename[] = "00000.DAT"; + char filename[] = "000000.DAT"; //Go through the frames while (1) { @@ -106,15 +106,15 @@ void deleteVideo(char* dirname) { else sd.remove(filename); //Remove Bitmap if there - strcpy(&filename[5], ".BMP"); + strcpy(&filename[6], ".BMP"); if (sd.exists(filename)) sd.remove(filename); //Remove Jpeg if there - strcpy(&filename[5], ".JPG"); + strcpy(&filename[6], ".JPG"); if (sd.exists(filename)) sd.remove(filename); //Reset ending - strcpy(&filename[5], ".DAT"); + strcpy(&filename[6], ".DAT"); //Raise counter videoCounter++; } @@ -265,8 +265,8 @@ void convertVideo(char* dirname) { sd.chdir("/"); sd.chdir(dirname); - uint16_t frames = getVideoFrameNumber(); - char filename[] = "00000.BMP"; + uint32_t frames = getVideoFrameNumber(); + char filename[] = "000000.BMP"; //Delete the ending for a video dirname[14] = '\0'; @@ -298,7 +298,7 @@ void convertVideo(char* dirname) { } /* Loads an image from the SDCard and prints it on screen */ -void openImage(char* filename, int imgCount) { +void openImage(char* filename, uint32_t imgCount) { //Show message on screen showFullMessage((char*) "Please wait, image is loading.."); @@ -352,10 +352,10 @@ void openImage(char* filename, int imgCount) { } /* Get the number of frames in the video */ -uint16_t getVideoFrameNumber() { - uint16_t videoCounter = 0; +uint32_t getVideoFrameNumber() { + uint32_t videoCounter = 0; bool exists; - char filename[] = "00000.DAT"; + char filename[] = "000000.DAT"; //Look how many frames we have while (true) { @@ -375,12 +375,12 @@ uint16_t getVideoFrameNumber() { } /* Display the selected video frame */ -void displayVideoFrame(int i) +void displayVideoFrame(uint32_t imgCount) { - char filename[] = "00000.DAT"; + char filename[] = "000000.DAT"; //Get the frame name - frameFilename(filename, i); + frameFilename(filename, imgCount); //Load Raw data loadRawData(filename); @@ -390,24 +390,24 @@ void displayVideoFrame(int i) } /* Play a video from the internal storage */ -void playVideo(char* dirname, int imgCount) { +void playVideo(char* dirname, uint32_t imgCount) { char buffer[14]; //Save the current frame number - int frameNumber = 0; + uint32_t frameNumber = 0; //Switch to video folder sd.chdir("/"); sd.chdir(dirname); //Get the total number of frames in the dir - uint16_t numberOfFrames = getVideoFrameNumber(); + uint32_t numberOfFrames = getVideoFrameNumber(); //Jump here when pausing a video showFrame: //Display frame displayVideoFrame(frameNumber); //Create string - sprintf(buffer, "%5d / %-5d", frameNumber + 1, numberOfFrames); + sprintf(buffer, "%6lu / %-6lu", frameNumber + 1, numberOfFrames); //Display GUI displayGUI(imgCount, buffer); //Display play message @@ -464,7 +464,7 @@ void playVideo(char* dirname, int imgCount) { //Display frame displayVideoFrame(frameNumber); //Create string - sprintf(buffer, "%5d / %-5d", frameNumber + 1, numberOfFrames); + sprintf(buffer, "%6lu / %-6lu", frameNumber + 1, numberOfFrames); //Display GUI displayGUI(imgCount, buffer); } diff --git a/Firmware_V3/src/gui/mainmenu.cpp b/Firmware_V3/src/gui/mainmenu.cpp index f2ca3fd..a6cfdcc 100644 --- a/Firmware_V3/src/gui/mainmenu.cpp +++ b/Firmware_V3/src/gui/mainmenu.cpp @@ -1428,6 +1428,9 @@ void mainMenuHandler(byte *pos) //Main loop while (true) { + //Enter mass storage on USB connect + checkMassStorage(); + //Check for screen sleep if (screenOffCheck()) drawMainMenu(*pos); diff --git a/Firmware_V3/src/gui/videomenu.cpp b/Firmware_V3/src/gui/videomenu.cpp index bde6a1e..10ea2b8 100644 --- a/Firmware_V3/src/gui/videomenu.cpp +++ b/Firmware_V3/src/gui/videomenu.cpp @@ -173,15 +173,14 @@ bool videoIntervalChooser() { } /* Captures video frames in an interval */ -void videoCaptureInterval(int16_t* remainingTime, int* framesCaptured) { - char buffer[30]; - +void videoCaptureInterval(int16_t* remainingTime, uint32_t* framesCaptured, uint16_t* folderFrames, char* buffer, char* dirName) { //Measure time long measure = millis(); //If there is no more time or the first frame - if ((*remainingTime <= 0) || (*framesCaptured == 0)) { - saveRawData(false, NULL, *framesCaptured); + if ((*remainingTime <= 0) || (*folderFrames == 0)) { + saveRawData(false, dirName, *folderFrames); + *folderFrames = *folderFrames + 1; } //Convert lepton data to RGB565 colors @@ -230,11 +229,10 @@ void videoCaptureInterval(int16_t* remainingTime, int* framesCaptured) { } /* Normal video capture */ -void videoCaptureNormal(int* framesCaptured) { - char buffer[30]; - +void videoCaptureNormal(uint32_t* framesCaptured, uint16_t* folderFrames, char* buffer, char* dirName) { //Save video raw frame - saveRawData(false, NULL, *framesCaptured); + saveRawData(false, dirName, *folderFrames); + *folderFrames = *folderFrames + 1; //Convert the colors convertColors(); @@ -252,7 +250,7 @@ void videoCaptureNormal(int* framesCaptured) { *framesCaptured = *framesCaptured + 1; //Display current frames captured - sprintf(buffer, "Frames captured: %5d", *framesCaptured); + sprintf(buffer, "Frames captured: %6lu", *framesCaptured); display_print(buffer, 70, 200); //Disable image buffer @@ -262,31 +260,52 @@ void videoCaptureNormal(int* framesCaptured) { displayBuffer(); } +void videoCreateFolder(char *dirName) { + createSDName(dirName, true); + if(!sd.chdir("/")) + { + beginSD(); + if(!sd.chdir("/")) + { + showFullMessage((char*) "Error creating folder!"); + delay(1000); + return; + } + } + sd.mkdir(dirName); + sd.chdir(dirName); +} + /* This screen is shown during the video capture */ void videoCapture() { //Help variables - char dirname[20]; + char dirName[20]; + char buffer[30]; int16_t delayTime = videoInterval; - int framesCaptured = 0; + uint32_t framesCaptured = 0; + uint16_t folderFrames = 0; //Show message - showFullMessage((char*)"Touch screen to turn it off"); - display_print((char*) "STARTING VIDEO MODE", CENTER, 50); - display_print((char*) "Press the button to abort", CENTER, 170); + showFullMessage((char*)"Touch screen to turn it on/off"); + display_print((char*) "CAPTURING FRAMES..", CENTER, 50); + display_print((char*) "Press push button to stop", CENTER, 170); delay(1000); //Create folder - createSDName(dirname, true); - sd.chdir("/"); - sd.mkdir(dirname); - sd.chdir(dirname); + videoCreateFolder(dirName); //Switch to recording mode videoSave = videoSave_recording; + lepton_startFrame(); //Main loop - lepton_startFrame(); while (videoSave == videoSave_recording) { + //Do not store too many files in one folder, otherwise MTP will make issues + if(folderFrames >= 1000) + { + videoCreateFolder(dirName); + folderFrames = 0; + } //Touch - turn display on or off if (!digitalRead(pin_touch_irq)) { @@ -299,11 +318,11 @@ void videoCapture() { //Video capture if (videoInterval == 0) { - videoCaptureNormal(&framesCaptured); + videoCaptureNormal(&framesCaptured, &folderFrames, buffer, dirName); } //Interval capture else { - videoCaptureInterval(&delayTime, &framesCaptured); + videoCaptureInterval(&delayTime, &framesCaptured, &folderFrames, buffer, dirName); } lepton_startFrame(); @@ -313,9 +332,9 @@ void videoCapture() { if (!checkScreenLight()) enableScreenLight(); - //Post processing for interval videos if enabled and wished - if ((framesCaptured > 0) && (convertPrompt())) - processVideoFrames(framesCaptured, dirname); + //Post processing for interval videos if enabled + if ((framesCaptured > 0) && convertEnabled) + processVideoFrames(framesCaptured, dirName); //Show finished message else { @@ -323,9 +342,6 @@ void videoCapture() { delay(1000); } - //Go back to root directory - sd.chdir("/"); - //Refresh free space refreshFreeSpace(); diff --git a/Firmware_V3/src/hardware/display/display.cpp b/Firmware_V3/src/hardware/display/display.cpp index 112c3f8..09ca21a 100644 --- a/Firmware_V3/src/hardware/display/display.cpp +++ b/Firmware_V3/src/hardware/display/display.cpp @@ -1455,7 +1455,7 @@ void display_exitSleepMode() /* Write 320x240 RGB565 data to the screen */ void display_writeScreen(unsigned short *pcolors) { - displayUpdated = true; + disableSPIIRQ = true; display_begin_spi_transaction(); display_setAddr(0, 0, 319, 239); display_writecommand_cont(ILI9341_RAMWR); @@ -1468,5 +1468,5 @@ void display_writeScreen(unsigned short *pcolors) } display_writedata16_last(*pftbft); display_end_spi_transaction(); - displayUpdated = false; + disableSPIIRQ = false; } \ No newline at end of file diff --git a/Firmware_V3/src/hardware/lepton.cpp b/Firmware_V3/src/hardware/lepton.cpp index 945409a..9bb328d 100644 --- a/Firmware_V3/src/hardware/lepton.cpp +++ b/Firmware_V3/src/hardware/lepton.cpp @@ -71,15 +71,8 @@ void lepton_endFrame() /* Start Lepton SPI Transmission */ void lepton_begin() { - if(videoSave == videoSave_recording) - { - SPI1.beginTransaction(SPISettings(60000000, MSBFIRST, SPI_MODE1)); - } - else - { SPI1.beginTransaction(SPISettings(25000000, MSBFIRST, SPI_MODE1)); - } - digitalWriteFast(pin_lepton_cs, LOW); + digitalWriteFast(pin_lepton_cs, LOW); } /* Reset the SPI bus to re-initiate Lepton communication */ @@ -93,8 +86,8 @@ void lepton_reset() /* End Lepton SPI Transmission */ void lepton_end() { - digitalWriteFast(pin_lepton_cs, HIGH); - SPI1.endTransaction(); + digitalWriteFast(pin_lepton_cs, HIGH); + SPI1.endTransaction(); } /* Store one package of 80 columns into RAM */ @@ -250,7 +243,7 @@ bool lepton_getPacketAsync(uint8_t *line, uint8_t *seg) /* Get one frame of raw values from the Lepton asynchronously */ void lepton_getFrameAsync() { - if(displayUpdated) + if (disableSPIIRQ) return; uint32_t startUsec; diff --git a/Firmware_V3/src/thermal/save.cpp b/Firmware_V3/src/thermal/save.cpp index efd150f..9e59b30 100644 --- a/Firmware_V3/src/thermal/save.cpp +++ b/Firmware_V3/src/thermal/save.cpp @@ -16,9 +16,9 @@ /*################################# INCLUDES ##################################*/ #include +#include #include #include -#include #include #include #include @@ -122,16 +122,6 @@ void createSDName(char *filename, boolean folder) } } -/* Creates a bmp file for the thermal image */ -void createBMPFile(char *filename) -{ - //File extension and open - strcpy(&filename[14], ".BMP"); - sdFile.open(filename, O_RDWR | O_CREAT | O_AT_END); - //Write the BMP header - sdFile.write((uint8_t *)bmp_header_large, 66); -} - /* Start the image save procedure */ void imgSaveStart() { @@ -167,22 +157,30 @@ void imgSaveStart() } /* Creates the filename for the video frames */ -void frameFilename(char *filename, uint16_t count) +void frameFilename(char *filename, uint32_t count) { - filename[0] = '0' + count / 10000 % 10; - filename[1] = '0' + count / 1000 % 10; - filename[2] = '0' + count / 100 % 10; - filename[3] = '0' + count / 10 % 10; - filename[4] = '0' + count % 10; + filename[0] = '0' + count / 100000 % 10; + filename[1] = '0' + count / 10000 % 10; + filename[2] = '0' + count / 1000 % 10; + filename[3] = '0' + count / 100 % 10; + filename[4] = '0' + count / 10 % 10; + filename[5] = '0' + count % 10; } /* Save video frame to image file */ void saveVideoFrame(char *filename) { - - // Open the file for writing - sdFile.open(filename, O_RDWR | O_CREAT | O_AT_END); + if (!sdFile.open(filename, O_RDWR | O_CREAT | O_AT_END)) + { + beginSD(); + if (!sdFile.open(filename, O_RDWR | O_CREAT | O_AT_END)) + { + showFullMessage((char *)"Error saving BMP!"); + delay(1000); + return; + } + } //Write 160x120 BMP header sdFile.write((uint8_t *)bmp_header_small, 66); @@ -198,11 +196,11 @@ void saveVideoFrame(char *filename) } /* Proccess video frames */ -void processVideoFrames(int framesCaptured, char *dirname) +void processVideoFrames(uint32_t framesCaptured, char *dirname) { char buffer[30]; - char filename[] = "00000.DAT"; - int framesConverted = 0; + char filename[] = "000000.DAT"; + uint32_t framesConverted = 0; //Display title display_fillScr(200, 200, 200); @@ -218,7 +216,7 @@ void processVideoFrames(int framesCaptured, char *dirname) display_print((char *)"Press button to abort the process", CENTER, 120); //Display content - sprintf(buffer, "Frames converted: %5d / %5d", framesConverted, framesCaptured); + sprintf(buffer, "Frames converted: %6lu / %6lu", framesConverted, framesCaptured); display_print(buffer, CENTER, 160); sprintf(buffer, "Folder name: %s", dirname); display_print(buffer, CENTER, 200); @@ -235,7 +233,7 @@ void processVideoFrames(int framesCaptured, char *dirname) //Get filename frameFilename(filename, framesConverted); - strcpy(&filename[5], ".DAT"); + strcpy(&filename[6], ".DAT"); //Load Raw data loadRawData(filename); @@ -257,7 +255,7 @@ void processVideoFrames(int framesCaptured, char *dirname) displayInfos(); //Save frame to image file - strcpy(&filename[5], ".BMP"); + strcpy(&filename[6], ".BMP"); saveVideoFrame(filename); //Font color @@ -266,7 +264,7 @@ void processVideoFrames(int framesCaptured, char *dirname) display_setColor(VGA_BLACK); //Update screen content - sprintf(buffer, "Frames converted: %5d / %5d", framesConverted + 1, framesCaptured); + sprintf(buffer, "Frames converted: %6lu / %6lu", framesConverted + 1, framesCaptured); display_print(buffer, CENTER, 160); } @@ -276,7 +274,7 @@ void processVideoFrames(int framesCaptured, char *dirname) } /* Saves raw data for an image or an video frame */ -void saveRawData(bool isImage, char *name, uint16_t framesCaptured) +void saveRawData(bool isImage, char *name, uint32_t framesCaptured) { uint16_t result; @@ -284,15 +282,34 @@ void saveRawData(bool isImage, char *name, uint16_t framesCaptured) if (isImage) { strcpy(&name[14], ".DAT"); - sdFile.open(name, O_RDWR | O_CREAT | O_AT_END); + if (!sdFile.open(name, O_RDWR | O_CREAT | O_AT_END)) + { + beginSD(); + if (!sdFile.open(name, O_RDWR | O_CREAT | O_AT_END)) + { + showFullMessage((char *)"Error saving image!"); + delay(1000); + return; + } + } } //Create filename for video frame else { - char filename[] = "00000.DAT"; - frameFilename(filename, framesCaptured); - sdFile.open(filename, O_RDWR | O_CREAT | O_AT_END); + char fileName[] = "000000.DAT"; + frameFilename(fileName, framesCaptured); + if (!sdFile.open(fileName, O_RDWR | O_CREAT | O_AT_END)) + { + beginSD(); + sd.chdir("/" + String(name)); + if (!sdFile.open(fileName, O_RDWR | O_CREAT | O_AT_END)) + { + showFullMessage((char *)"Error saving frame!"); + delay(1000); + return; + } + } } //For the Lepton2.5 sensor, write 4800 raw values @@ -386,7 +403,20 @@ void saveBuffer(char *filename) unsigned short pixel; //Create file - createBMPFile(filename); + strcpy(&filename[14], ".BMP"); + if (!sdFile.open(filename, O_RDWR | O_CREAT | O_AT_END)) + { + beginSD(); + if (!sdFile.open(filename, O_RDWR | O_CREAT | O_AT_END)) + { + showFullMessage((char *)"Error saving BMP!"); + delay(1000); + return; + } + } + + //Write the BMP header + sdFile.write((uint8_t *)bmp_header_large, 66); //Allocate space for sd buffer uint8_t *sdBuffer = (uint8_t *)calloc(1280, sizeof(uint8_t)); diff --git a/Firmware_V3/src/thermal/thermal.cpp b/Firmware_V3/src/thermal/thermal.cpp index 5cf903d..2dbbef8 100644 --- a/Firmware_V3/src/thermal/thermal.cpp +++ b/Firmware_V3/src/thermal/thermal.cpp @@ -116,11 +116,6 @@ void buttonIRQ() } } -/* Lepton interrupt handler */ -void leptonIRQ() -{ -} - /* Handler for a long touch press */ void longTouchHandler() { @@ -552,7 +547,7 @@ void liveModeInit() showMenu = showMenu_disabled; usbConnected = true; longTouch = false; - displayUpdated = false; + disableSPIIRQ = false; clearTempPoints(); lepton_startFrame();