You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.5 KiB

/**
* @file main.cpp
* @brief Source file for the main application.
* @author Adam Prochazka <xproch0f>
*
* This file contains the implementation of the main application, which integrates the Receiver
* and Displayer classes, manages their threads, and handles the overall execution flow.
*/
#include "main.hpp"
#include "Receiver.hpp"
#ifndef DISPLAYER_HPP
#include "Displayer.hpp"
#endif
int cdcFile;
bool quit = false;
/**
* @brief Reads and processes data from the serial communication in a loop. - for debug purposes
* @param receiverPtr Pointer to a pointer to the Receiver class instance.
* @param port Serial port to be opened.
*/
void readLoop(Receiver ** receiverPtr, char * port){
(*receiverPtr)->openStream(port);
(*receiverPtr)->initSerial();
while (!quit) {
unsigned char character[CDC_FRAME_SIZE];
(*receiverPtr)->readCdcData(&character);
if((*receiverPtr)->findStart(&character) != -1)
{std::cout << "start" << std::endl;}
else if((*receiverPtr)->findEnd(&character) != -1)
{std::cout << "stop" << std::endl;}
else{
std::cout << "-";
}
std::this_thread::sleep_for(std::chrono::milliseconds(3));
}
close(cdcFile);
}
/**
* @brief Flips through the textures in a separate thread.
* @param displayerPtr Pointer to the Displayer class instance.
*/
void windowFlipThread(Displayer * displayerPtr){
displayerPtr->flipThroughTextures();
}
/**
* @brief Wrapper function to call bufferToDisplay() method of the Receiver instance.
* @param receiverPtr Pointer to a pointer to the Receiver instance.
*/
void WrapperBufferToDisplay(Receiver ** receiverPtr){
(*receiverPtr)->bufferToDisplay();
}
/**
* @brief Main loop for the Receiver instance.
* @param receiverPtr Pointer to a pointer to the Receiver instance.
*/
void receiverLoop(Receiver ** receiverPtr, bool *q, bool printRaw, bool saveToFile){
std::vector<std::thread> displayThreads;
while(!(*q)){
(*receiverPtr)->fillBuffer(saveToFile);
(*receiverPtr)->bufferToDisplay(printRaw);
//running in a thread also works, but for simplicity is not used.
//std::thread t2(WrapperBufferToDisplay, receiverPtr);
//t2.detach();
}
}
int main(int argc, char * argv[])
{
char * port = nullptr;
bool printRaw = false;
bool saveToFile = false;
int opt;
while ((opt = getopt(argc, argv, "p:r:s")) != -1) {
switch (opt) {
case 'p':
port = optarg;
break;
case 'r':
printRaw = true;
break;
case 's':
saveToFile = true;
break;
default:
std::cerr << "Usage: sudo ./main -p <serial_port> [-r to print raw data] [-s to save images]" << std::endl;
std::cerr << "Example: sudo ./main -p /dev/ttyACM0 -r -s" << std::endl;
return 1;
}
}
if (!port) {
std::cerr << "Serial port not specified" << std::endl;
return 1;
}
std::cout << "Serial port: " << port << std::endl;
std::cout << "Print raw data: " << (printRaw ? "true" : "false") << std::endl;
std::cout << "Save images: " << (saveToFile ? "true" : "false") << std::endl;
Displayer dis;
Receiver *rec = new Receiver(&dis);
dis.createWindow();
dis.renderWindow();
rec->openStream(port);
rec->initSerial();
rec->initTextures();
rec->fillBuffer();
rec->bufferToDisplay();
std::thread t1(receiverLoop, &rec, &quit, std::ref(printRaw), std::ref(saveToFile));
t1.detach();
dis.windowLoop(&quit);
rec->closeStream();
return 0;
}