summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXaviDCR92 <xavi.dcr@gmail.com>2017-07-20 23:54:08 +0200
committerXaviDCR92 <xavi.dcr@gmail.com>2017-07-20 23:54:08 +0200
commitf4b10b24bcf178e1d9072fb494922c875c0ecb0a (patch)
treed392dc48f77546abeb56d2e209845bc50a47c07e
+ Added first version of QPSXSerial. Still lot of job to do and room for improvement.
-rw-r--r--main.cpp11
-rw-r--r--qpsxserial.cpp458
-rw-r--r--qpsxserial.h54
-rw-r--r--release/QPSXSerial.exebin0 -> 49152 bytes
-rw-r--r--release/QPSXSerial_20072017_Win32.zipbin0 -> 17145085 bytes
5 files changed, 523 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..748160a
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,11 @@
+#include "qpsxserial.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ QPSXSerial w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/qpsxserial.cpp b/qpsxserial.cpp
new file mode 100644
index 0000000..6bc0a5a
--- /dev/null
+++ b/qpsxserial.cpp
@@ -0,0 +1,458 @@
+#include <QFileDialog>
+#include <QFile>
+#include <QSerialPortInfo>
+#include "qpsxserial.h"
+#include "ui_qpsxserial.h"
+
+QPSXSerial::QPSXSerial(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::QPSXSerial)
+{
+ ui->setupUi(this);
+ lost_packet_timer = new QTimer();
+
+ connect(lost_packet_timer, SIGNAL(timeout()), this, SLOT(onPacketLost()));
+
+ connect(ui->loadFile_Btn, SIGNAL(released()), this, SLOT(onLoadFileBtnReleased()));
+ connect(ui->updatePorts_Btn, SIGNAL(released()), this, SLOT(onUpdatePortsBtnReleased()));
+ connect(ui->send_Btn, SIGNAL(released()), this, SLOT(onSendBtnReleased()));
+ connect(ui->ports_ComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(onPortSelectedComboBox(QString)));
+ connect(&serial, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
+ connect(&serial, SIGNAL(readyRead()), this, SLOT(onReadyRead(void)));
+
+ ack = false;
+ init_timer = NULL;
+
+ ui->exeProgressBar->setVisible(false);
+
+ ui->send_Btn->setEnabled(false);
+
+ ui->inFileName->setVisible(false);
+
+ write_ready = false;
+ exe_sent = false;
+}
+
+QPSXSerial::~QPSXSerial()
+{
+ if(serial.isOpen() == true)
+ {
+ serial.close();
+ }
+
+ delete ui;
+}
+
+void QPSXSerial::onLoadFileBtnReleased(void)
+{
+ selectedFolder = QFileDialog::getExistingDirectory( this,
+ "Load folder with PSX data",
+ "C:/",
+ QFileDialog::ShowDirsOnly );
+
+ if(selectedFolder.isEmpty() == true)
+ {
+ return;
+ }
+
+ selectedFolder.append("/");
+
+ ui->loadedFile_LineEdit->setText(selectedFolder);
+
+ QFile system_f(selectedFolder + "\\SYSTEM.CNF");
+
+ if(system_f.open(QFile::ReadOnly) == false)
+ {
+ qDebug() << "Could not open " + selectedFolder + "\\SYSTEM.CNF";
+ return;
+ }
+
+ QTextStream system_txt(&system_f);
+
+ QString fileSelected;
+
+ do
+ {
+ if(system_txt.atEnd() == true)
+ {
+ return;
+ }
+
+ QString line = system_txt.readLine();
+
+ QStringList tokens = line.split("=");
+
+ if(tokens.isEmpty() == true)
+ {
+ continue;
+ }
+
+ if(tokens.at(0).contains("BOOT") == false)
+ {
+ continue;
+ }
+
+ fileSelected = tokens.at(1).split("\\").at(1);
+
+ fileSelected.chop(2); // Remove ";1" suffix.
+ break;
+
+ }while(1);
+
+
+ inputExe = selectedFolder + fileSelected;
+ qDebug() << "inputExe = " + inputExe;
+}
+
+void QPSXSerial::onUpdatePortsBtnReleased(void)
+{
+ ui->ports_ComboBox->clear();
+
+ foreach(QSerialPortInfo port, QSerialPortInfo::availablePorts())
+ {
+ ui->ports_ComboBox->addItem(port.portName());
+ }
+}
+
+void QPSXSerial::onSendBtnReleased(void)
+{
+ qDebug() << serial.isOpen();
+
+ if(serial.isOpen() == false)
+ {
+ if(selectedPort.isEmpty() == true)
+ {
+ qDebug() << "No selected port!";
+ return;
+ }
+
+ serial.setPortName(selectedPort);
+ serial.setBaudRate(QSerialPort::Baud115200);
+ serial.setParity(QSerialPort::NoParity);
+ serial.setDataBits(QSerialPort::Data8);
+ serial.setStopBits(QSerialPort::OneStop);
+
+ if(serial.open(QIODevice::ReadWrite) == false)
+ {
+ qDebug() << "Could not open port " + selectedPort;
+ return;
+ }
+
+ qDebug() << "Connected succesfully to " + selectedPort;
+
+ if(init_timer == NULL)
+ {
+ init_timer = new QTimer();
+
+ init_timer->setSingleShot(true);
+ init_timer->setInterval(1000);
+
+ connect(init_timer, SIGNAL(timeout(void)), this, SLOT(connectToPSXTimeout(void)));
+ }
+
+ ui->exeProgressBar->setVisible(true);
+
+ ui->exeProgressBar->setMinimum(0);
+ ui->exeProgressBar->setMaximum(0);
+
+ ui->inFileName->setText("Waiting for PSX response...");
+
+ ui->inFileName->setVisible(true);
+
+ init_timer->start(1000);
+
+ ui->send_Btn->setText("Disconnect from PSX");
+ }
+ else
+ {
+ serial.close();
+ ui->send_Btn->setText("Send to PSX!");
+ qDebug() << "Disconnected";
+ init_timer->stop();
+ }
+}
+
+void QPSXSerial::connectToPSXTimeout(void)
+{
+ QByteArray ba;
+
+ if(ack == false)
+ {
+ ba.append(99);
+
+ serial.write(ba);
+
+ //qDebug() << "Retry...";
+
+ init_timer->start(1000);
+ }
+}
+
+void QPSXSerial::onPortSelectedComboBox(QString port)
+{
+ selectedPort = port;
+ ui->send_Btn->setEnabled(true);
+ qDebug() << "Selected port: " + selectedPort;
+}
+
+void QPSXSerial::onBytesWritten(qint64)
+{
+ //qDebug() << "Bytes written: " + QString::number(bytes_written);
+
+ /*byte_sent_received = false;
+
+ while(byte_sent_received == false)
+ {
+ QApplication::processEvents();
+ }*/
+
+ write_ready = true;
+}
+
+void QPSXSerial::onReadyRead(void)
+{
+ static bool first_entered = false;
+ QByteArray data = serial.readAll();
+ static QTime time = QTime::currentTime();
+
+ //qDebug() << QString("Received ") + QString::number(data.count()) + QString(" bytes.");
+ //qDebug() << QString("Took ") + QString::number(time.msecsTo(QTime::currentTime()));
+
+ if(exe_sent == true)
+ {
+ //qDebug() << data;
+
+ QByteArray header = data.left(5);
+
+ if(header == "cdrom")
+ {
+ qDebug() << "INPUT FRAME: " + data;
+ QString filePath = QString(data);
+
+ filePath.remove("cdrom:\\");
+
+ qDebug() << "selectedFolder = " + selectedFolder;
+
+ filePath.prepend(selectedFolder);
+
+ filePath.replace("\\", "/");
+
+ filePath.chop(2); // Remove ending ";1"
+
+ qDebug() << "filePath = " + filePath;
+
+ QFile f(filePath);
+
+ if(f.open(QFile::ReadOnly) == false)
+ {
+ qDebug() << "Error while reading input file!";
+ return;
+ }
+
+ QByteArray file_data = f.readAll();
+ quint32 sz = file_data.count();
+
+ sendDataSize(sz);
+
+ while(ack == false)
+ {
+ QApplication::processEvents();
+ }
+
+ qDebug() << "sendData for file...";
+
+ sendData(file_data, filePath);
+ }
+ else
+ {
+ if(data.count() == 1)
+ {
+ if(data.at(0) == 'b')
+ {
+ ack = true;
+ }
+ }
+ else
+ {
+ qDebug() << data;
+ }
+ }
+ }
+
+ if(data.isEmpty() == false)
+ {
+ quint8 data_byte = (quint8)data.at(0);
+
+ if(data_byte == 'b')
+ {
+ //qDebug() << "Received ACK";
+ // Received handshaking byte. Start transmission!
+
+ ack = true;
+
+ init_timer->stop();
+
+ if(first_entered == false)
+ {
+ first_entered = true;
+
+ if(sendExe() == false)
+ {
+ qDebug() << "An error happened when sending EXE file!";
+ }
+
+ exe_sent = true;
+ }
+ }
+ }
+
+ time = QTime::currentTime();
+}
+
+bool QPSXSerial::sendExe(void)
+{
+ QFile f(inputExe);
+
+ if(f.open(QFile::ReadOnly) == false)
+ {
+ qDebug() << "Could not open input EXE file!";
+ return false;
+ }
+
+ f.seek(0);
+
+ ack = false;
+
+ QByteArray data = f.read(2048 /* PSX-EXE header */);
+ qDebug () << "Sending PSX-EXE header...";
+
+ for(int i = 0; i < 32; i++)
+ {
+ QByteArray send;
+ write_ready = false;
+
+ send.append(data[i]);
+
+ serial.write(send);
+
+ while(write_ready == false)
+ {
+ QApplication::processEvents();
+ }
+ }
+
+ while(ack == false)
+ {
+ QApplication::processEvents();
+ }
+
+ qDebug () << "Sending EXE size...";
+
+ qint64 sz = f.size() - 2048;
+
+ sendDataSize((quint32)sz);
+
+ while(ack == false)
+ {
+ QApplication::processEvents();
+ }
+
+ // Send file size without header
+
+ qDebug() << "Dump EXE data...";
+
+ f.seek(2048);
+
+ data = f.readAll();
+
+ qDebug() << data.count();
+
+ sendData(data, inputExe);
+
+ f.close();
+
+ return true;
+}
+
+void QPSXSerial::sendDataSize(quint32 size)
+{
+ QByteArray ar;
+
+ for(unsigned int i = 0; i < sizeof(quint32); i++)
+ {
+ char send = (char)( size >> (i << 3) );
+
+ QByteArray send_arr;
+
+ send_arr.append(send);
+
+ ar.append(send);
+
+ serial.write(send_arr);
+
+ while(write_ready == false)
+ {
+ QApplication::processEvents();
+ }
+ }
+
+ for(unsigned int i = 0; i < sizeof(quint32); i++)
+ {
+ qDebug() << "0x" + QString::number(ar.at(i), 16);
+ }
+
+ ack = false;
+}
+
+void QPSXSerial::onPacketLost(void)
+{
+ qDebug() << "Entering onPacketLost...";
+
+ if(ack == false)
+ {
+
+ serial.write(last_packet_sent);
+ lost_packet_timer->start(100);
+ }
+}
+
+void QPSXSerial::sendData(QByteArray data, QString fileName)
+{
+ ui->exeProgressBar->setVisible(true);
+ ui->exeProgressBar->setRange(0, data.count());
+ ui->inFileName->setText(fileName);
+ ui->inFileName->setVisible(true);
+
+ lost_packet_timer->setInterval(100);
+ lost_packet_timer->setSingleShot(true);
+
+ for(int i = 0; i < data.count(); i+= 8)
+ {
+ QByteArray send;
+ ack = false;
+
+ send.append(data.mid(i, 8));
+
+ //qDebug() << "Sent packet";
+
+ serial.write(send);
+
+ last_packet_sent = send;
+
+ lost_packet_timer->start(100);
+
+ while(ack == false)
+ {
+ QApplication::processEvents();
+ }
+
+ ui->exeProgressBar->setValue(i);
+ }
+
+ lost_packet_timer->stop();
+
+ ui->exeProgressBar->setValue(data.count());
+ ui->inFileName->setText("Transfer complete!");
+
+ ack = false;
+}
diff --git a/qpsxserial.h b/qpsxserial.h
new file mode 100644
index 0000000..2728ce3
--- /dev/null
+++ b/qpsxserial.h
@@ -0,0 +1,54 @@
+#ifndef QPSXSERIAL_H
+#define QPSXSERIAL_H
+
+#include <QMainWindow>
+#include <QtSerialPort/QSerialPort>
+#include <QString>
+#include <QDebug>
+#include <QTimer>
+#include <QThread>
+#include <QTime>
+#include <QWinTaskbarButton>
+
+namespace Ui {
+class QPSXSerial;
+}
+
+class QPSXSerial : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit QPSXSerial(QWidget *parent = 0);
+ ~QPSXSerial();
+
+private:
+ bool sendExe(void);
+ void sendData(QByteArray data, QString fileName);
+ void sendDataSize(quint32 size);
+
+ Ui::QPSXSerial *ui;
+ QString inputExe;
+ QString selectedPort;
+ QString selectedFolder;
+ QSerialPort serial;
+ bool ack;
+ bool exe_sent;
+ QTimer* init_timer;
+ bool write_ready;
+ bool byte_sent_received;
+ QByteArray last_packet_sent;
+ QTimer* lost_packet_timer;
+
+private slots:
+ void onLoadFileBtnReleased(void);
+ void onUpdatePortsBtnReleased(void);
+ void onSendBtnReleased(void);
+ void onPortSelectedComboBox(QString);
+ void onBytesWritten(qint64);
+ void onReadyRead(void);
+ void connectToPSXTimeout(void);
+ void onPacketLost(void);
+};
+
+#endif // QPSXSERIAL_H
diff --git a/release/QPSXSerial.exe b/release/QPSXSerial.exe
new file mode 100644
index 0000000..bc8b44e
--- /dev/null
+++ b/release/QPSXSerial.exe
Binary files differ
diff --git a/release/QPSXSerial_20072017_Win32.zip b/release/QPSXSerial_20072017_Win32.zip
new file mode 100644
index 0000000..4af6eb5
--- /dev/null
+++ b/release/QPSXSerial_20072017_Win32.zip
Binary files differ