From 7ed17bc94983a07d0e4cd51e1b01bcb836239193 Mon Sep 17 00:00:00 2001 From: Herwig Birke Date: Fri, 12 Aug 2022 14:30:27 +0200 Subject: [PATCH] initial commit --- .gitignore | 103 +++--- ckeystonecomm.cpp | 788 +++++++++++++++++++++++++++++++++++++++++++ ckeystonecomm.h | 80 +++++ cmainwindow.cpp | 38 +++ cmainwindow.h | 32 ++ cmainwindow.ui | 45 +++ main.cpp | 24 ++ monkeyRadio.pro | 31 ++ monkeyRadio_de_AT.ts | 3 + 9 files changed, 1103 insertions(+), 41 deletions(-) create mode 100644 ckeystonecomm.cpp create mode 100644 ckeystonecomm.h create mode 100644 cmainwindow.cpp create mode 100644 cmainwindow.h create mode 100644 cmainwindow.ui create mode 100644 main.cpp create mode 100644 monkeyRadio.pro create mode 100644 monkeyRadio_de_AT.ts diff --git a/.gitignore b/.gitignore index f147edf..fab7372 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,73 @@ -# C++ objects and libs -*.slo -*.lo -*.o +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave *.a -*.la -*.lai +*.core +*.moc +*.o +*.obj +*.orig +*.rej *.so *.so.* -*.dll -*.dylib - -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc /.qmake.cache /.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* -*.moc -moc_*.cpp -moc_*.h -qrc_*.cpp -ui_*.h -*.qmlc -*.jsc -Makefile* -*build-* -*.qm -*.prl -# Qt unit tests -target_wrapper.* +# qtcreator generated files +*.pro.user* -# QtCreator -*.autosave +# xemacs temporary files +*.flc -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* +# Vim temporary files +.*.swp -# QtCreator CMake -CMakeLists.txt.user* +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* -# QtCreator 4.8< compilation database -compile_commands.json +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe -# QtCreator local machine specific files for imported projects -*creator.user* diff --git a/ckeystonecomm.cpp b/ckeystonecomm.cpp new file mode 100644 index 0000000..8ac1cf7 --- /dev/null +++ b/ckeystonecomm.cpp @@ -0,0 +1,788 @@ +#include "ckeystonecomm.h" + +#ifdef QT_DEBUG +//#define OUTPUT_DEBUG +#endif + +#ifdef Q_OS_WIN +#include +#endif +#include +#include + +#define HEAD 0xFE +#define END 0xFD + +#define MSC_DATA_LENGTH (100 * 1024) +#define MAX_SEGMENT_SIZE 8191 +#define MAX_IMAGE_SIZE 100 * 1024 // bytes, ETSI TS 101 499 +#define MAX_NAME_LENGTH 100 +#define EXPECTED_IMAGE_LENGTH 1000 + +// Set GPIO function +#define DATA_IN 0 +#define DATA_OUT 1 +#define MUTE 2 +#define I2S_DATA_IN 3 +#define I2S_LRCLK_IN 4 +#define I2S_SSCLK_IN 5 +#define I2S_BCLK_IN 6 +#define I2S_DATA_OUT 7 +#define I2S_LRCLK_OUT 8 +#define I2S_SSCLK_OUT 9 +#define I2S_BCLK_OUT 10 +#define SPDIF_OUT 11 +#define SPI_DO 12 +#define SPI_CLK 13 +#define SPI_CS 14 +#define SPI_DI 15 + +// Driving strength(0~3) +#define DRIVE_2MA 0 +#define DRIVE_4MA 1 +#define DRIVE_6MA 2 +#define DRIVE_8MA 3 + +#define ANTENNA_RELAY_PIN 11 + + +cKeyStoneCOMM::cKeyStoneCOMM(const QString& commPort, QObject *parent) : + QObject{parent}, + m_commPort{commPort}, + m_serialPort{nullptr}, + m_serialReadError{false}, + m_hardMute{false}, + m_initialized{false}, + m_totalProgram{0}, + m_mutePrevVolume{0} +{ +} + +cKeyStoneCOMM::~cKeyStoneCOMM() +{ + close(); +} + +bool cKeyStoneCOMM::open(bool _hardMute) +{ + close(); + + m_hardMute = _hardMute; + m_serialPort = new QSerialPort(m_commPort, this); + if(!m_serialPort) + return(false); + + m_serialPort->setBaudRate(QSerialPort::Baud115200); + m_serialPort->setDataBits(QSerialPort::Data8); + m_serialPort->setStopBits(QSerialPort::OneStop); + m_serialPort->setParity(QSerialPort::NoParity); + m_serialPort->setFlowControl(QSerialPort::NoFlowControl); + + if(!m_serialPort->open(QIODevice::ReadWrite)) + { + qDebug() << "open failed: " << m_serialPort->errorString(); + close(); + return(false); + } +#ifdef OUTPUT_DEBUG + qDebug() << "open succeeded."; +#endif + + m_serialPort->setBaudRate(QSerialPort::Baud115200); + m_serialPort->setDataBits(QSerialPort::Data8); + m_serialPort->setStopBits(QSerialPort::OneStop); + m_serialPort->setParity(QSerialPort::NoParity); + m_serialPort->setFlowControl(QSerialPort::NoFlowControl); + +#ifdef OUTPUT_DEBUG + qDebug() << "*** Baud Rate: " << m_serialPort->baudRate(); + qDebug() << "*** Data Bits: " << m_serialPort->dataBits(); + qDebug() << "*** Stop Bits: " << m_serialPort->stopBits(); + qDebug() << "*** Parity Bits: " << m_serialPort->parity(); + qDebug() << "*** Flow Control: " << m_serialPort->flowControl(); +#endif + + connect(m_serialPort, &QSerialPort::readyRead, this, &cKeyStoneCOMM::serialReadReady); + connect(m_serialPort, &QSerialPort::errorOccurred, this, &cKeyStoneCOMM::serialReadError); + + if(m_hardMute) + hardMute(); + else + hardUnmute(); + + QThread::msleep(800); + + if(!isSysReady()) + { + for(int i = 0;i < 2;i++) + { + if(hardResetRadio()) + { + for(int x = 0;x < 2;x++) + { + if(isSysReady()) + { + // Enable Pin 11 for antenna switching + GPIO_SetFunction(ANTENNA_RELAY_PIN, DATA_OUT, DRIVE_8MA); + m_totalProgram = getTotalProgram(); + m_initialized = true; + qDebug() << "Initialized. Current programs: " << m_totalProgram; + return(true); + } + } + } + } + return(false); + } + else + { + // Enable Pin 11 for antenna switching + GPIO_SetFunction(ANTENNA_RELAY_PIN, DATA_OUT, DRIVE_8MA); + m_totalProgram = getTotalProgram(); + } + + m_initialized = true; + +#ifdef OUTPUT_DEBUG + qDebug() << "Initialized. Current programs: " << m_totalProgram; +#endif + + return(true); +} + +void cKeyStoneCOMM::close() +{ + if(m_serialPort) + { + if(m_serialPort->isOpen()) + { + stopStream(); + m_serialPort->close(); + } + delete m_serialPort; + m_serialPort = nullptr; + } + m_initialized = false; +} + +int16_t cKeyStoneCOMM::channelCount() +{ + return(m_totalProgram); +} + +bool cKeyStoneCOMM::setVolume(int8_t volume) +{ + uint16_t dwBytes; + unsigned char output[] = {HEAD,0x01,0x22,0x01,0x00,0x01,0x00,END}; + unsigned char input[8] = {0}; + + if((volume < 0) || (volume > 16)) + return(false); // Volume out of range + + output[6] = volume; + + if(volume == 0) + if(m_hardMute) + hardMute(); + + if(!writeSerialBytes(output, 8, &dwBytes)) + return(false); + + if(dwBytes != 8) + return(false); + + // need to check the return + if(!readSerialBytes(input, &dwBytes)) + return(false); + + m_currentVolume = volume; + + return(true); +} + +bool cKeyStoneCOMM::startStream(STREAM_MODE mode, uint16_t channel) +{ + uint16_t dwBytes; + unsigned char input[8] = {0}; + unsigned char output[] = {HEAD,0x01,0x00,0x01,0x00,0x05,0x00,0x00,0x00,0x00,0x00,END}; + unsigned char strChannel[4]; + + if(mode == 0) + if(m_hardMute) + hardMute(); + + if((mode < 0) || (mode > 1)) + return(false); + + output[6] = mode; + + if(mode == 0) + { + //DAB GPIO 11 set to LOW for antenna switching + GPIO_SetLevel(ANTENNA_RELAY_PIN, 0); + output[10] = (unsigned char)channel; // WARNING - This is not very safe, TODO + } + else + { + //FM GPIO 11 set to HIGH for antenna switching + GPIO_SetLevel(ANTENNA_RELAY_PIN, 1); + if(channel < 20000) + { + memcpy(&strChannel[0], &channel, sizeof(long)); + output[7] = strChannel[3]; + output[8] = strChannel[2]; + output[9] = strChannel[1]; + output[10] = strChannel[0]; + } + else + return(false); + } + + if(!writeSerialBytes(output, 12, &dwBytes)) + return(false); + + if(dwBytes != 12) + return(false); + + // need to check the return + if(!readSerialBytes(input, &dwBytes)) + return(false); + + return(true); +} + +bool cKeyStoneCOMM::stopStream() +{ + uint16_t dwBytes; + unsigned char output[] = {HEAD,0x01,0x02,0x01,0x00,0x00,END}; + unsigned char input[8] = {0}; + + if(m_hardMute) + hardMute(); + + if(!writeSerialBytes(output, 7, &dwBytes)) + return(false); + + if(dwBytes != 7) + return(false); + + if(!readSerialBytes(input, &dwBytes)) + return(false); + + if(goodHeader(input, dwBytes)) + { + if(input[2] == 0x01) + return(true); + else + return(false); + } + else + return(false); +} + +bool cKeyStoneCOMM::nextStream() +{ + long channel = 0; + char currentMode = playMode(); + + if(currentMode == STREAM_MODE_DAB) + { + channel = playIndex(); + if(channel < m_totalProgram-1) + channel++; + else + channel = 0; + + startStream(STREAM_MODE_DAB, channel); + return(true); + } + + if(currentMode == STREAM_MODE_FM) + { +//HERWIG FMSearch(1); + return(true); + + } + return(false); +} + +bool cKeyStoneCOMM::prevStream() +{ + long channel = 0; + char currentMode = playMode(); + + if(currentMode == STREAM_MODE_DAB) + { + channel = playIndex(); + if(channel > 0) + channel--; + else + channel = m_totalProgram-1; + + startStream(STREAM_MODE_DAB, channel); + return(true); + } + + if(currentMode == STREAM_MODE_FM) + { +//HERWIG FMSearch(0); + return(true); + + } + return(false); +} + +cKeyStoneCOMM::STREAM_MODE cKeyStoneCOMM::playMode() +{ + uint16_t dwBytes; + unsigned char input[8] = {0}; + unsigned char output[] = {HEAD,0x01,0x11,0x01,0x00,0x00,END}; + + if(!writeSerialBytes(output, 7, &dwBytes)) + return(STREAM_MODE_NONE); + + if(dwBytes != 7) + return(STREAM_MODE_NONE); + + if(!readSerialBytes(input, &dwBytes)) + return(STREAM_MODE_NONE); + + if(!goodHeader(input, dwBytes)) + return(STREAM_MODE_NONE); + else + { + if((input[1] == 0x01) && (input[2] == 0x11)) + return((STREAM_MODE)input[6]); + else + return(STREAM_MODE_NONE); + } +} + +int16_t cKeyStoneCOMM::playIndex() +{ + uint16_t dwBytes; + unsigned char output[] = {HEAD,0x01,0x12,0x01,0x00,0x00,END}; + unsigned char input[11] = {0}; + + if(!writeSerialBytes(output, 7, &dwBytes)) + return(-1); + + if(!readSerialBytes(input, &dwBytes)) + return(-1); + else + { + if(goodHeader(input, dwBytes)) + { + long channel = (0xFF & input[6]) << 24 | (0xFF & input[7]) << 16 | (0xFF & input[8]) << 8 | (0xFF & input[9]); + return(channel); + + } + else + return(-1); + } +} + +int8_t cKeyStoneCOMM::volumePlus() +{ + char currentVolume = volume(); + if(currentVolume < 16) + currentVolume++; + + if(setVolume(currentVolume)) + return(currentVolume); + else + return(-1); +} + +int8_t cKeyStoneCOMM::volumeMinus() +{ + char currentVolume = volume(); + if(currentVolume > 0) + currentVolume--; + + if(setVolume(currentVolume)) + return(currentVolume); + else + return(-1); +} + +void cKeyStoneCOMM::volumeMute() +{ + char currentVolume = volume(); + if(currentVolume == 0) + setVolume(m_mutePrevVolume); + else + { + m_mutePrevVolume = currentVolume; + setVolume(0); + } +} + +int8_t cKeyStoneCOMM::volume() +{ + uint16_t dwBytes; + unsigned char output[] = {HEAD,0x01,0x23,0x01,0x00,0x00,END}; + unsigned char input[8] = {0}; + + if(!writeSerialBytes(output, 7, &dwBytes)) + return(-1); + + if(dwBytes != 7) + return(-1); + + if(!readSerialBytes(input, &dwBytes)) + return(-1); + else + { + if(goodHeader(input, dwBytes)) + { + m_currentVolume = input[6]; + return(input[6]); + } + else + return(-1); + } +} + +int8_t cKeyStoneCOMM::signalStrength() +{ + int biterror; + return(getSignalStrength(&biterror)); +} + +bool cKeyStoneCOMM::hardMute() +{ + m_hardMute = true; + +#ifdef Q_OS_WIN + if(!::EscapeCommFunction(m_serialPort->handle(), CLRRTS)) + return(false); + if(!::EscapeCommFunction(m_serialPort->handle(), CLRDTR)) + return(false); +#elif defined Q_OS_LINUX + int status; + ioctl(m_serialPort->handle, TIOCMGET, &status); + status &= ~TIOCM_RTS; + ioctl(m_serialPort->handle, TIOCMSET, &status); +#endif + + QThread::msleep(350); + + return(true); +} + +bool cKeyStoneCOMM::hardUnmute() +{ + QThread::msleep(850); + +#ifdef Q_OS_WIN + if(!::EscapeCommFunction(m_serialPort->handle(), SETRTS)) + return(false); + if(!::EscapeCommFunction(m_serialPort->handle(), CLRDTR)) + return(false); +#elif defined Q_OS_LINUX + int status; + ioctl(m_serialPort->handle(), TIOCMGET, &status); + status |= TIOCM_RTS; + ioctl(m_serialPort->handle(), TIOCMSET, &status); +#endif + + m_hardMute = false; + + return(true); +} + +bool cKeyStoneCOMM::hardResetRadio() +{ +#ifdef Q_OS_WIN + if(EscapeCommFunction(m_serialPort->handle(), SETRTS)) + { + EscapeCommFunction(m_serialPort->handle(), SETDTR); + Sleep(100); + if (EscapeCommFunction(m_serialPort->handle(), SETRTS)) + { + EscapeCommFunction(m_serialPort->handle(), CLRDTR); + QThread::msleep(1000); + + return(true); + } + else + return(false); + } + else + return(false); +#elif defined Q_OS_LINUX + int status; + ioctl(m_serialPort->handle(), TIOCMGET, &status); + status |= TIOCM_DTR; // set DTR pin low to reset module + ioctl(m_serialPort->handle(), TIOCMSET, &status); + usleep(100000); + status &= ~TIOCM_DTR; // set DTR pin HIGH to disable RESET + ioctl(m_serialPort->handle(), TIOCMSET, &status); + usleep(1000000); // delay 1 sec to wait for module to ready +#endif +} + +bool cKeyStoneCOMM::isSysReady() +{ + uint16_t dwBytes; + + unsigned char input[8] = {0}; + unsigned char output[] = {HEAD,0x00,0x00,0x01,0x00,0x00,END}; + + if(m_serialPort && m_serialPort->isOpen()) + { + if(!writeSerialBytes(output, 7, &dwBytes)) + return(false); + + if(!readSerialBytes(input, &dwBytes)) + return(false); + + if(dwBytes < 7) + return(false); + + if(goodHeader(input, dwBytes)) + { + if(input[2] == 0x01) + return(true); + else + return(false); + } + else + return(false); + } + else + return(false); +} + +bool cKeyStoneCOMM::readSerialBytes(unsigned char* buffer, uint16_t* bytesreadreturn) +{ + m_readData.clear(); + m_cntReadData = 0; + m_serialReadError = false; + + while(m_serialPort->waitForReadyRead(100)); + + if(m_serialReadError) + { + *bytesreadreturn = 0; + qDebug() << "error"; + return(false); + } + *bytesreadreturn = m_readData.count(); + std::memcpy(buffer, m_readData.data(), *bytesreadreturn); + + return(true); +} + +bool cKeyStoneCOMM::writeSerialBytes(unsigned char* buffer, uint16_t nNumberOfBytesToWrite, uint16_t* lpNumberOfBytesWritten) +{ + int i; + + i = m_serialPort->write(reinterpret_cast(buffer), nNumberOfBytesToWrite); + if(i != nNumberOfBytesToWrite) + return(false); + + *lpNumberOfBytesWritten = i; + return(true); +} + +bool cKeyStoneCOMM::goodHeader(unsigned char* input, uint16_t dwBytes) +{ + if((input[0] == HEAD) && (input[dwBytes-1] == END)) + return(true); + else + return(false); +} + +bool cKeyStoneCOMM::GPIO_SetLevel(char pin, char level) +{ + uint16_t dwBytes; + unsigned char input[7] = { 0 }; + unsigned char output[] = { HEAD,0x08,0x01,0x00,0x00,0x02,0x00,0x00,END }; + + output[6] = pin; + output[7] = level; + + if (!writeSerialBytes(output, 9, &dwBytes)) + return(false); + + if(dwBytes != 9) + return(false); + + if(!readSerialBytes(input, &dwBytes)) + return(false); + + if(!goodHeader(input, dwBytes)) + return(false); + else + { + if((input[1] == 0x00) && (input[2] == 0x01)) + return(true); + else + return(false); + } +} + +bool cKeyStoneCOMM::GPIO_GetLevel(char pin, char* level) +{ + uint16_t dwBytes; + unsigned char input[8] = { 0 }; + unsigned char output[] = { HEAD,0x08,0x02,0x00,0x00,0x01,0x00,END }; + + output[6] = pin; + + if(!writeSerialBytes(output, 9, &dwBytes)) + return(false); + + if(dwBytes != 9) + return(false); + + if(!readSerialBytes(input, &dwBytes)) + return(false); + + if(!goodHeader(input, dwBytes)) + return(false); + else + { + if((input[1] == 0x08) && (input[2] == 0x02)) + { + *level = input[6]; + return(true); + } + else + return(false); + } +} + +bool cKeyStoneCOMM::GPIO_SetFunction(char pin, char pinfunction, char drive) +{ + uint16_t dwBytes; + unsigned char input[7] = { 0 }; + unsigned char output[] = { HEAD,0x08,0x00,0x00,0x00,0x03,0x00,0x00,0x00,END }; + + output[6] = pin; + output[7] = pinfunction; + output[8] = drive; + + if(!writeSerialBytes(output, 10, &dwBytes)) + return(false); + + if(dwBytes != 10) + return(false); + + if(!readSerialBytes(input, &dwBytes)) + return(false); + + if(!goodHeader(input, dwBytes)) + return(false); + else + { + if((input[1] == 0x00) && (input[2] == 0x01)) + { + return(true); + } + else + return(false); + } +} + +int16_t cKeyStoneCOMM::getTotalProgram() +{ + uint16_t dwBytes; + unsigned char output[] = {HEAD,0x01,0x13,0x01,0x00,0x00,END}; + unsigned char input[11] = {0}; + + if(!writeSerialBytes(output, 7, &dwBytes)) + return(0); + + if(!readSerialBytes(input, &dwBytes)) + return(0); + else + { + if(goodHeader(input, dwBytes)) + { + if(input[1] == 0x01) + { + uint16_t total = (0xFF & input[6]) << 24 | (0xFF & input[7]) << 16 | (0xFF & input[8]) << 8 |(0xFF & input[9]); + m_totalProgram = total; + return(total); + } + else + return(0); + } + else + return(0); + } +} + +int8_t cKeyStoneCOMM::getSignalStrength(int* biterror) +{ + uint16_t dwBytes; + char dabStrength = 0; + unsigned char input[10] = {0}; + unsigned char output[] = {HEAD,0x01,0x15,0x01,0x00,0x00,END}; + double temp; + + if(!writeSerialBytes(output, 7, &dwBytes)) + return(-1); + + if(dwBytes != 7) + return(-1); + + if(!readSerialBytes(input, &dwBytes)) + return(-1); + + if(dwBytes < 8) + return(-1); + + if(goodHeader(input, dwBytes)) + { + if(input[5] == 0x01) + { + *biterror = 0; + return(input[6]); //FM Strength + } + + if(input[5] == 0x03) + { + if(input[6] > 0) + { + // calculate percentage and return bit error + *biterror = (0xFF & input[7]) << 8 |(0xFF & input[8]); + temp = 100.00/18.00; + temp = temp * input[6]; + dabStrength = (char)temp; + + return(dabStrength); + } + else + return(0); + } + + return(-1); + } + else + return(-1); +} + +void cKeyStoneCOMM::serialReadReady() +{ + m_readData.append(m_serialPort->readAll()); +} + +//void cKeyStoneCOMM::handleTimeout() +//{ +//} + +void cKeyStoneCOMM::serialReadError(QSerialPort::SerialPortError error) +{ + if(error == QSerialPort::ReadError) + { + m_serialReadError = true; + m_serialPortError = error; +#ifdef OUTPUT_DEBUG + qDebug() << error; +#endif + } +} diff --git a/ckeystonecomm.h b/ckeystonecomm.h new file mode 100644 index 0000000..5213ebc --- /dev/null +++ b/ckeystonecomm.h @@ -0,0 +1,80 @@ +#ifndef CKEYSTONECOMM_H +#define CKEYSTONECOMM_H + + +#include + +#include +#include + + +class cKeyStoneCOMM : public QObject +{ + Q_OBJECT + +public: + enum STREAM_MODE + { + STREAM_MODE_NONE = -1, + STREAM_MODE_DAB = 0, + STREAM_MODE_FM = 1, + }; + + explicit cKeyStoneCOMM(const QString& commPort, QObject *parent = nullptr); + ~cKeyStoneCOMM(); + + bool open(bool _hardMute = false); + void close(); + + int16_t channelCount(); + STREAM_MODE playMode(); + int16_t playIndex(); + bool setVolume(int8_t volume); + bool startStream(STREAM_MODE mode, uint16_t channel); + bool stopStream(); + bool nextStream(); + bool prevStream(); + int8_t volumePlus(); + int8_t volumeMinus(); + void volumeMute(); + int8_t volume(); + int8_t signalStrength(); +signals: + +private: + QString m_commPort; + QSerialPort* m_serialPort; + bool m_serialReadError; + QSerialPort::SerialPortError m_serialPortError; + bool m_hardMute; + + bool m_initialized; + + QByteArray m_readData; + int m_cntReadData; + + uint16_t m_totalProgram; + int8_t m_currentVolume; + int8_t m_mutePrevVolume; + + bool hardMute(); + bool hardUnmute(); + bool hardResetRadio(); + + bool readSerialBytes (unsigned char* buffer, uint16_t* bytesreadreturn); + bool writeSerialBytes(unsigned char* buffer, uint16_t nNumberOfBytesToWrite, uint16_t* lpNumberOfBytesWritten); + bool goodHeader(unsigned char* input, uint16_t dwBytes); + + bool isSysReady(); + bool GPIO_SetLevel(char pin, char level); + bool GPIO_GetLevel(char pin, char* level); + bool GPIO_SetFunction(char pin, char pinfunction, char drive); + + int16_t getTotalProgram(); + int8_t getSignalStrength(int* biterror); +private slots: + void serialReadReady(); + void serialReadError(QSerialPort::SerialPortError error); +}; + +#endif // CKEYSTONECOMM_H diff --git a/cmainwindow.cpp b/cmainwindow.cpp new file mode 100644 index 0000000..d5ca111 --- /dev/null +++ b/cmainwindow.cpp @@ -0,0 +1,38 @@ +#include "cmainwindow.h" +#include "ui_cmainwindow.h" + + +cMainWindow::cMainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::cMainWindow), + m_timerSignalStrength(nullptr), + m_keystoneCOMM(nullptr) +{ + ui->setupUi(this); + + m_keystoneCOMM = new cKeyStoneCOMM("COM7", this); + + m_timerSignalStrength = new QTimer(this); + connect(m_timerSignalStrength, &QTimer::timeout, this, &cMainWindow::updateSignalStrength); + m_timerSignalStrength->start(1000); + + m_keystoneCOMM->open(); + m_keystoneCOMM->startStream(cKeyStoneCOMM::STREAM_MODE_DAB, 2); +} + +cMainWindow::~cMainWindow() +{ + if(m_timerSignalStrength) + delete m_timerSignalStrength; + + if(m_keystoneCOMM) + delete m_keystoneCOMM; + + delete ui; +} + +void cMainWindow::updateSignalStrength() +{ + int8_t signalStrength = m_keystoneCOMM->signalStrength(); + ui->m_signalStrength->setText(QString("%1").arg(signalStrength)); +} diff --git a/cmainwindow.h b/cmainwindow.h new file mode 100644 index 0000000..41182bf --- /dev/null +++ b/cmainwindow.h @@ -0,0 +1,32 @@ +#ifndef CMAINWINDOW_H +#define CMAINWINDOW_H + +#include +#include + +#include "ckeystonecomm.h" + + + +QT_BEGIN_NAMESPACE +namespace Ui { class cMainWindow; } +QT_END_NAMESPACE + +class cMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + cMainWindow(QWidget *parent = nullptr); + ~cMainWindow(); + +private: + Ui::cMainWindow* ui; + QTimer* m_timerSignalStrength; + cKeyStoneCOMM* m_keystoneCOMM; + +public slots: + void updateSignalStrength(); +}; + +#endif // CMAINWINDOW_H diff --git a/cmainwindow.ui b/cmainwindow.ui new file mode 100644 index 0000000..0c0c5d6 --- /dev/null +++ b/cmainwindow.ui @@ -0,0 +1,45 @@ + + + cMainWindow + + + + 0 + 0 + 800 + 600 + + + + cMainWindow + + + + + + 20 + 20 + 49 + 16 + + + + TextLabel + + + + + + + 0 + 0 + 800 + 22 + + + + + + + + diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..6456121 --- /dev/null +++ b/main.cpp @@ -0,0 +1,24 @@ +#include "cmainwindow.h" + +#include +#include +#include + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + QTranslator translator; + const QStringList uiLanguages = QLocale::system().uiLanguages(); + for (const QString &locale : uiLanguages) { + const QString baseName = "monkeyRadio_" + QLocale(locale).name(); + if (translator.load(":/i18n/" + baseName)) { + a.installTranslator(&translator); + break; + } + } + cMainWindow w; + w.show(); + return a.exec(); +} diff --git a/monkeyRadio.pro b/monkeyRadio.pro new file mode 100644 index 0000000..9a9654f --- /dev/null +++ b/monkeyRadio.pro @@ -0,0 +1,31 @@ +QT += core gui serialport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + ckeystonecomm.cpp \ + main.cpp \ + cmainwindow.cpp + +HEADERS += \ + ckeystonecomm.h \ + cmainwindow.h + +FORMS += \ + cmainwindow.ui + +TRANSLATIONS += \ + monkeyRadio_de_AT.ts +CONFIG += lrelease +CONFIG += embed_translations + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/monkeyRadio_de_AT.ts b/monkeyRadio_de_AT.ts new file mode 100644 index 0000000..b01af89 --- /dev/null +++ b/monkeyRadio_de_AT.ts @@ -0,0 +1,3 @@ + + +