From a9041d417d6adeaad6cbd5af2f10647f75d54c44 Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Wed, 8 Nov 2023 13:02:26 +0100 Subject: [PATCH] Start repository --- CArunGUI/CArunGUI.pro | 54 + CArunGUI/datei.cpp | 945 +++++++ CArunGUI/datei.h | 208 ++ CArunGUI/guidefs.h | 24 + CArunGUI/main.cpp | 43 + CArunGUI/mainwindow.cpp | 438 ++++ CArunGUI/mainwindow.h | 72 + CArunGUI/plugin.h | 6 + CArunGUI/stepList.h | 210 ++ CArunGUI/subwindows.cpp | 267 ++ CArunGUI/subwindows.h | 161 ++ CArunGUI/tslib.cpp | 1016 ++++++++ CArunGUI/tslib.h | 168 ++ CArunGUI/versionHistory.txt | 13 + CArunGUI/win01_com.cpp | 578 +++++ CArunGUI/win01_com.h | 107 + DCLibraries.pri | 118 + DCLibraries.pro | 6 + dCArun/dCArun.pro | 58 + dCArun/datei.cpp | 944 +++++++ dCArun/datei.h | 209 ++ dCArun/guidefs.h | 24 + dCArun/main.cpp | 43 + dCArun/mainwindow.cpp | 438 ++++ dCArun/mainwindow.h | 72 + dCArun/plugin.h | 5 + dCArun/stepList.h | 210 ++ dCArun/subwindows.cpp | 267 ++ dCArun/subwindows.h | 161 ++ dCArun/tslib.cpp | 1016 ++++++++ dCArun/tslib.h | 168 ++ dCArun/versionHistory.txt | 13 + dCArun/win01_com.cpp | 578 +++++ dCArun/win01_com.h | 107 + include/com.h | 107 + include/controlBus.h | 213 ++ include/datIf.h | 206 ++ include/datei.h | 201 ++ include/dcBL.h | 122 + include/dc_result.h | 55 + include/globdefs.h | 305 +++ include/hwapi.h | 1386 ++++++++++ include/interfaces.h | 1683 ++++++++++++ include/plugin.h | 6 + include/prot.h | 134 + include/runProc.h | 86 + include/sendWRcmd.h | 262 ++ include/shared_mem_buffer.h | 351 +++ include/storeINdata.h | 614 +++++ include/tslib.h | 93 + lib_ca_master/lib_ca_master.pro | 10 + lib_ca_slave/lib_ca_slave.pro | 10 + src/com.cpp | 429 ++++ src/controlBus.cpp | 510 ++++ src/datIf.cpp | 1333 ++++++++++ src/datei.cpp | 943 +++++++ src/dcBL.cpp | 1528 +++++++++++ src/dc_plugin_error.cpp | 0 src/dc_result.cpp | 91 + src/hwapi.cpp | 4236 +++++++++++++++++++++++++++++++ src/main.cpp | 9 + src/prot.cpp | 623 +++++ src/runProc.cpp | 748 ++++++ src/sendWRcmd sm.cpp | 811 ++++++ src/sendWRcmd.cpp | 842 ++++++ src/shared_mem_buffer.cpp | 101 + src/storeINdata sm.cpp | 2053 +++++++++++++++ src/storeINdata.cpp | 2344 +++++++++++++++++ src/tslib.cpp | 612 +++++ 69 files changed, 31804 insertions(+) create mode 100644 CArunGUI/CArunGUI.pro create mode 100755 CArunGUI/datei.cpp create mode 100755 CArunGUI/datei.h create mode 100755 CArunGUI/guidefs.h create mode 100755 CArunGUI/main.cpp create mode 100755 CArunGUI/mainwindow.cpp create mode 100755 CArunGUI/mainwindow.h create mode 100755 CArunGUI/plugin.h create mode 100755 CArunGUI/stepList.h create mode 100755 CArunGUI/subwindows.cpp create mode 100755 CArunGUI/subwindows.h create mode 100755 CArunGUI/tslib.cpp create mode 100755 CArunGUI/tslib.h create mode 100755 CArunGUI/versionHistory.txt create mode 100755 CArunGUI/win01_com.cpp create mode 100755 CArunGUI/win01_com.h create mode 100644 DCLibraries.pri create mode 100644 DCLibraries.pro create mode 100644 dCArun/dCArun.pro create mode 100755 dCArun/datei.cpp create mode 100755 dCArun/datei.h create mode 100755 dCArun/guidefs.h create mode 100755 dCArun/main.cpp create mode 100755 dCArun/mainwindow.cpp create mode 100755 dCArun/mainwindow.h create mode 100755 dCArun/plugin.h create mode 100755 dCArun/stepList.h create mode 100755 dCArun/subwindows.cpp create mode 100755 dCArun/subwindows.h create mode 100755 dCArun/tslib.cpp create mode 100755 dCArun/tslib.h create mode 100755 dCArun/versionHistory.txt create mode 100755 dCArun/win01_com.cpp create mode 100755 dCArun/win01_com.h create mode 100644 include/com.h create mode 100644 include/controlBus.h create mode 100644 include/datIf.h create mode 100644 include/datei.h create mode 100644 include/dcBL.h create mode 100644 include/dc_result.h create mode 100755 include/globdefs.h create mode 100644 include/hwapi.h create mode 100755 include/interfaces.h create mode 100755 include/plugin.h create mode 100644 include/prot.h create mode 100755 include/runProc.h create mode 100644 include/sendWRcmd.h create mode 100644 include/shared_mem_buffer.h create mode 100644 include/storeINdata.h create mode 100644 include/tslib.h create mode 100644 lib_ca_master/lib_ca_master.pro create mode 100644 lib_ca_slave/lib_ca_slave.pro create mode 100644 src/com.cpp create mode 100644 src/controlBus.cpp create mode 100644 src/datIf.cpp create mode 100644 src/datei.cpp create mode 100644 src/dcBL.cpp create mode 100644 src/dc_plugin_error.cpp create mode 100644 src/dc_result.cpp create mode 100644 src/hwapi.cpp create mode 100644 src/main.cpp create mode 100644 src/prot.cpp create mode 100755 src/runProc.cpp create mode 100755 src/sendWRcmd sm.cpp create mode 100644 src/sendWRcmd.cpp create mode 100644 src/shared_mem_buffer.cpp create mode 100755 src/storeINdata sm.cpp create mode 100644 src/storeINdata.cpp create mode 100644 src/tslib.cpp diff --git a/CArunGUI/CArunGUI.pro b/CArunGUI/CArunGUI.pro new file mode 100644 index 0000000..cbed800 --- /dev/null +++ b/CArunGUI/CArunGUI.pro @@ -0,0 +1,54 @@ +QT += core gui +QT +=widgets serialport +QT +=network + # for TCP-IP + +TARGET = CArunGui +DESTDIR=$${_PRO_FILE_PWD_}/../build + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 +CONFIG += PTU5 +# _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp] +QMAKE_CXXFLAGS += -O +INCLUDEPATH += ../include + +win32 { + BUILD_DATE=$$system("date /t") + BUILD_TIME=$$system("time /t") +} else { + BUILD_DATE=$$system("date +%d-%m-%y") + BUILD_TIME=$$system("date +%H:%M:%S") +} + +GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1") + +EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}" + +DEFINES+=APP_VERSION=\\\"$$VERSION\\\" +DEFINES+=APP_BUILD_DATE=\\\"$$BUILD_DATE\\\" +DEFINES+=APP_BUILD_TIME=\\\"$$BUILD_TIME\\\" +DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\" + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + tslib.cpp \ + win01_com.cpp \ + datei.cpp + +HEADERS += \ + guidefs.h \ + mainwindow.h \ + stepList.h \ + tslib.h \ + versionHistory.txt \ + win01_com.h \ + datei.h \ + plugin.h + +# 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/CArunGUI/datei.cpp b/CArunGUI/datei.cpp new file mode 100755 index 0000000..423fbac --- /dev/null +++ b/CArunGUI/datei.cpp @@ -0,0 +1,945 @@ +// written by Thomas Sax, Jan.2022 +#include +#include "datei.h" + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +QByteArray datei_writeArray, datei_tempArray; + +void csv_startCreatingFile(void) +{ + datei_writeArray.clear(); + datei_tempArray.clear(); +} + +void csv_addTextToFile(QString myText) +{ + datei_writeArray.append(myText.toLatin1()); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addIntToFile(int myValue) +{ + //qulonglong ullt=12345678901234567890; // max 1,844 x10^19 + datei_tempArray.setNum(myValue,10); // accepted types: short, ushort, int, uint, + // qlonglong, qulonglong, float, double + // numerbase can be 2...36(!),10=dec + + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addUintToFile(uint myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + + +void csv_addLongvalToFile(qlonglong myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addUlongvalToFile(qulonglong myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +/* +void csv_addCurrentTimeToFile(void) +{ + uint8_t hour, minute, sec, ui8buf[20]; + char buf[20]; + + config_getSysTime(&hour, &minute, &sec); + GetTimeString(hour, minute, sec, 0, 1, ui8buf); + for (uint8_t nn=0; nn<20; nn++) + buf[nn]=char(ui8buf[nn]); + datei_writeArray.append(buf,8); // time string + datei_writeArray.append(FILESEPERATOR); + +} + +void csv_addCurrentDateToFile(void) +{ + uint16_t year; + uint8_t month, day, ui8buf[20]; + char buf[20]; + + config_getSystemDate(&year, &month, &day); + //qDebug()<<"date year: "<1) + filSize=uint32_t(filLen); + else + return 0; + + // 1) find position of seperators + for (uint32_t ii=0; iiMAXNUMBEROFSEQUENCES) + return ""; + + // 1) find position of seperators + for (ii=0; ii0) + { + start=sepPos[sequNr-1]+1; + ende=sepPos[sequNr]; + } + + //qDebug()<<"datei getOneFileSequence start/ende: "<=ende) + return ""; + //return "-err3-"; + sequence.clear(); + //batmp.clear(); + pp=0; + for (ii=start; ii=int(filSize)) + mm=0; + oneByt=sourceFile.at(mm); + sequence.append(oneByt); + } + return sequence; +} + +int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA, myVA; + int entry=0; + bool ok; + + myVA.clear(); + myBA = csv_getOneFileSequence(sourceFile, sequNr); + //qDebug()<<"datei getEntryAsInt, sequence: " << myBA; + + entry=myBA.toInt(&ok,16); + if (ok) + { + //qDebug()<<"datei getEntryAsInt, number: " << entry; + return entry; + } + //qDebug()<<"datei getEntryAsInt, error " << myBA; + return 0; +} + +int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + long entry=0; + bool ok; + + entry=myBA.toLong(&ok,10); + if (ok) + return entry; + return 0; +} + +uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint8_t entry=0; + bool ok; + + entry=uint8_t(myBA.toUShort(&ok,10)); + if (ok) + return entry; + return 0; +} + +uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint16_t entry=0; + bool ok; + + entry=uint16_t(myBA.toUInt(&ok,10)); + if (ok) + return entry; + return 0; +} + +uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint32_t entry=0; + bool ok; + + entry=myBA.toULong(&ok,10); + if (ok) + return entry; + return 0; +} + +uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint64_t entry=0; + bool ok; + + entry=myBA.toULongLong(&ok,10); + if (ok) + return entry; + return 0; +} + + + +QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + QString entry; + + //qDebug()<<"datei getEntryAsString, sequence: " << myBA; + entry=myBA.toStdString().c_str(); + return entry; +} + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create Json file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +/* + example +QString str = "{" + " \"Herausgeber\": \"Xema\"," + " \"Nummer\": \"1234-5678-9012-3456\"," + " \"Deckung\": 2e+6," + " \"Währung\": \"EURO\"," + " \"Inhaber\": {" + " \"Name\": \"Mustermann\"," + " \"Vorname\": \"Max\"," + " \"männlich\": true," + " \"Hobbys\": [ \"Reiten\", \"Golfen\", \"Lesen\" ]," + " \"Alter\": 42," + " \"Kinder\": []," + " \"Partner\": null" + " }" + "}"; + +*/ + +QString myJsonCon; +QString tmpStr; + +void json_startRecord(void) +{ + myJsonCon.clear(); + tmpStr.clear(); + myJsonCon.append('{'); +} + +void json_enterIntToRecord(QString attribute, ulong i_value) +{ + tmpStr.clear(); + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + tmpStr.setNum(i_value); + myJsonCon.append(tmpStr); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); +} + +void json_enterTextToRecord(QString attribute, QString txt_value) +{ + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + myJsonCon.append(txt_value); + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); +} +/* +void json_addCurrentTimeToRecord(QString attribute) +{ + uint8_t hour, minute, sec, ui8buf[20]; + //char buf[20]; + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + + datei_getSysTime(&hour, &minute, &sec); + GetTimeString(hour, minute, sec, 0, 1, ui8buf); + for (uint8_t nn=0; nn<8; nn++) + myJsonCon.append(ui8buf[nn]); + + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); + +} + +void json_addCurrentDateToRecord(QString attribute) +{ + uint16_t year; + uint8_t month, day, ui8buf[20]; + //char buf[20]; + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + + datei_getSystemDate(&year, &month, &day); + GetDateString(day, month, 0x20, uint8_t(year%100), 0, 0, ui8buf); + for (uint8_t nn=0; nn<10; nn++) + myJsonCon.append(ui8buf[nn]); + + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); + +} +*/ + +void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals) +{ + // add array of numbers with "nrofVals" elements + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('['); // eckig!!! + for (ulong ul=0; ulMAXNROFARRAYVALUES) + nrOfPairs=MAXNROFARRAYVALUES; + + for (ii=0; iiMaxBufferSize) + { + ok=false; // got not all + nrOfPairs=MaxBufferSize; + } + for (int ii=0; ii +#include +#include +#include "tslib.h" +#include +#include +#include +#include +#include + + // create csv file with: +#define FILESEPERATOR ',' + + // pasre csv with: +#define FILESEP1 ',' +#define FILESEP2 ';' + +#define NEWLINEINFILE '\n' +#define MAXNUMBEROFSEQUENCES 200 + // only for csv files + + +// all seting-files located in sudirectory "static machine data - smd" +// all generated files located in sudirectory "dynamic machine data - dmd" + +#define FILENAME_COMPORT "../comport.csv" +#define FILENAME_CONFIG "/own/work2023/PSA1256ptu5/smd/DC2C_conf.json" +#define FILENAME_DEVICE "/own/work2023/PSA1256ptu5/smd/DC2C_device.json" +#define FILENAME_CASH "/own/work2023/PSA1256ptu5/smd/DC2C_cash.json" +#define FILENAME_PRINT "/own/work2023/PSA1256ptu5/smd/DC2C_print32.json" +#define FILENAME_APSERVCONF "../APserviceConfig.csv" + + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + + +// create array with strings and values (to be written to file) +void csv_startCreatingFile(void); +void csv_addTextToFile(QString myText); +void csv_addIntToFile(int myValue); +void csv_addUintToFile(uint myValue); +void csv_addLongvalToFile(qlonglong myValue); +void csv_addUlongvalToFile(qulonglong myValue); +//void csv_addCurrentTimeToFile(void); +//void csv_addCurrentDateToFile(void); +void csv_addNewlineToFile(void); +QByteArray csv_readbackArray(void); + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ parse csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + + +// return number of entries in the just read file (entries are seperated by +// comma or line-feed) +uint32_t csv_nrOfEntriesInFile(QByteArray readFromFile); + +// before: QByteArray sourceFile=datei_readFromFile(filename); + +QByteArray csv_getOneFileSequence(QByteArray sourceFile, uint32_t sequNr); +// not needed, just for test // sequNr: 0....(size-1) + +// get single entries of of the just read fie: +int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create Json Record ------------------------------- +// ------------------------------------------------------------------------------------------------- + +void json_startRecord(void); + // clear buffer and write opening curly bracket { + +void json_enterIntToRecord(QString attribute, ulong i_value); + // example: "parameter":1234567890 + +void json_enterTextToRecord(QString attribute, QString txt_value); + // example: "parameter":"slow" + +//void json_addCurrentTimeToRecord(QString attribute); + // example: if attribute=myTime: "myTime":"hh_mm_ss" + +//void json_addCurrentDateToRecord(QString attribute); + // example: if attribute=myDate: "myDate":"dd.mm.yyyy" + // also / possible as seperator + // further possible forms: + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + +void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals); + // add array of numbers with "nrofVals" elements + +void json_enterStructToRecord(QString attribute); + // every call must be concluded with an extra "json_finishFile()" + // example: "sname":{ + +void json_finishStruct(void); + +void json_finishRecord(void); + // close curly bracket + + +QString json_readbackRecordStr(void); + +QByteArray json_readbackRecordBa(void); + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ parse Json file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +// first: QByteArray datei_readFromFile(QString filename); + +//void datei_json_readTestFile(QString filename); + +int json_nrOfPairsInFile(QByteArray filename); + +bool json_exists(QByteArray filename, QString searchForKey); + // look for "searchForKey" =name of the pair (left of : ) + // retval true if exists + +bool json_remove(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and remove the record from file + // retval true if removed + +QString json_searchForStringInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_searchForIntInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +//....................... + +QJsonObject json_searchForObjectInFile(QByteArray filename, QString searchFor); + // return an object from the json file + +int json_nrOfPairsInObject(QJsonObject objname); + +QString json_searchForStringInObject(QJsonObject objname, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_searchForIntInObject(QJsonObject objname, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +//....................... + +QJsonArray json_searchForArrayInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_nrOfValuesInArray(QJsonArray arrayname); + +bool json_getValuesOfArray(QJsonArray arrayname, int *buf, int MaxBufferSize); + // assuming that the array consists of integers + + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ read, write, copy files ------------------- +// ------------------------------------------------------------------------------------------------- + +void datei_closeFile(QString filename); + +// read content of an exiting file: +QByteArray datei_readFromFile(QString filename); + +bool datei_ifFileExists(QString filename); + +char datei_writeToFile(QString filename, QByteArray content); + // retval=0 if successful 1: no write access allowed + // 2:cannot open to append 3:cannot create new file + +bool datei_copyFile(QString currentFileName, QString newFileName); + // retval=true if successful + +bool datei_clearFile(QString filename); + // retval=true if successful + +#endif // DATEI_H diff --git a/CArunGUI/guidefs.h b/CArunGUI/guidefs.h new file mode 100755 index 0000000..fb65802 --- /dev/null +++ b/CArunGUI/guidefs.h @@ -0,0 +1,24 @@ +#ifndef GUIDEFS_H +#define GUIDEFS_H + +#define PIXELSIZE_BUTTONS 18 +#define PIXELSIZE_LABEL 18 +#define PIXELSIZE_DATA 16 + +#define PIXELSIZE_BIGFONT 22 +#define PIXELSIZE_SMALLFONT 14 + +#define BUTTONCOLOR "background-color: rgb(150,250,150)" + +#define COLORGREEN "background-color: rgb(160,250,190)" +#define COLOR_RED "background-color: rgb(150,0,0)" +#define COLOR_LIGHTRED "background-color: rgb(250,150,150)" +//#define COLORGREY "background-color: rgb(160,250,190)" +#define COLORGREY "background-color: grey" +#define COLORYELLOW "background-color: yellow" +#define COLORWHITE "background-color: white" + +// "background-color: lightgrey" + + +#endif diff --git a/CArunGUI/main.cpp b/CArunGUI/main.cpp new file mode 100755 index 0000000..7a29373 --- /dev/null +++ b/CArunGUI/main.cpp @@ -0,0 +1,43 @@ +#include "mainwindow.h" +//#include "message_handler.h" +#include + +int thisisglobal; + +int main(int argc, char *argv[]) +{ + int ret; + QApplication myapp(argc, argv); + QApplication::setApplicationName("CArunGui"); + QApplication::setApplicationVersion(APP_VERSION); + +/* + if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling + atbInstallMessageHandler(atbDebugOutput); + setDebugLevel(QtMsgType::QtDebugMsg); + //setDebugLevel(QtMsgType::QtDebugMsg); + } +*/ + MainWindow myMainWin; + QSize myMainSize={800, 480}; // breite, höhe, PTU: 800x440 + myMainWin.setMinimumSize(myMainSize); + myMainWin.setMaximumSize(myMainSize); + myMainWin.setWindowTitle("CArun_V4.2 run cash agent master lib"); + myMainWin.show(); + + ret=myapp.exec(); + + return ret; +} + + + +//QApplication a(argc, argv); +//MainWindow CatMW; +//QSize myMainSize={800, 480}; // breite, höhe +//CatMW.setMinimumSize(myMainSize); +//CatMW.setMaximumSize(myMainSize); +//CatMW.setWindowTitle("ATB CashAgent V2.0"); +// QPalette mainPal; +// mainPal.setColor(QPalette::Window, Qt::red ); +// CatMW.setPalette(mainPal); sieht man nicht mehr diff --git a/CArunGUI/mainwindow.cpp b/CArunGUI/mainwindow.cpp new file mode 100755 index 0000000..e7ebc86 --- /dev/null +++ b/CArunGUI/mainwindow.cpp @@ -0,0 +1,438 @@ +#include "mainwindow.h" + +char MainWindow::loadPlugIn(char lade1_entlade2) +{ + plugInDir.cd("plugins"); + QPluginLoader *pluginLoader = new QPluginLoader(); + +// select system: + //pluginLoader->setFileName("../MasterPlug/libCAmaster.so"); // for suse + //pluginLoader->setFileName("../SlavePlug/libCAslave.so"); // for ptu5 + //pluginLoader->setFileName("../../MasterPlug/CAmaster.dll"); // for windows + pluginLoader->setFileName("CAmaster.dll"); // for windows + + if (lade1_entlade2==2) + { + pluginLoader->unload(); + return 0; + } + + if (!pluginLoader->load()) + { + qDebug()<<"cannot load plugin"; + } else + qDebug() <<"loaded plugin: " << pluginLoader->fileName(); + + if (!pluginLoader->isLoaded()) + { + qDebug()<errorString(); + return 0; + } + + QObject *plugin = pluginLoader->instance(); + if ( plugin == nullptr) + { + // make instance of the root component (which can hold more then one clases) + // also loads the lib if not yet done + qDebug()<<"cannot start instance"; + return 0; + } + + //int rr=hwapi->giveVal(2); funktioniert :)) + //qDebug()<<"got value from plugin"<(plugin); + // make instance to class "hwinf" in dll_HWapi.h over "interfaces.h" + + qDebug()<<"loadPlugIn, HWAccess: " << HWaccess; + return 0; + +} + + + + +#define WINCTRMIN 0 + // 0 is always the home screen + +#define WINCTRMAX 30 + // number of needed application screens, up to 255 + // All screens must be defined below in mainwindow-class first before increasing the nr + // numbers must be consecutively from 0 always, 0 is the home screen always + +#define FORMWIDTH 725 +//#define FORMWIDTH 690 + // this width is the same for ALL windows + +#define FORMHEIGHT 440 +// this height is the same for ALL windows + +#define NAVIBUTTONHEIGHT 70 +#define NAVIBUTTONWIDHT 50 + +#define HOMEPAGE_BACKGROUND_COLOR "background-color: lightgrey" + +#define BUTTON_COLOR "background-color: rgb(160,250,190)" + +#define ACTIVE_NAVI_COLOR "background-color: rgb(160,250,190)" +#define DISABL_NAVI_COLOR "background-color: grey" + +#define APPPAGE_BACKGROUND_COLOR "background-color: lightgrey" + +#define UPDATE_PERIOD_MS 100 + // period to call chain steps + +#define VENDINGTIMEOUT_MS 30000 + // after this time without any operation the program returns to idle state + // time in ms, that means 30.000 gives 30seconds + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) +{ + loadPlugIn(1); + + // define all working moduls (besides gui) here, call ini and working in chainControl() (~Line 1000) + //mifCard = new T_Mifare(HWaccess); // ganz wichtig: HWaccess an sub-Konstruktor übergeben + // sonst crash bei HW-Zugriff!!!! + //diary = new T_lib_diary(); absturz!!!!!! + //conf = new T_lib_config(HWaccess); + + timerChainCtrl = new QTimer(this); + connect(timerChainCtrl, SIGNAL(timeout()), this, SLOT(chainControl())); + timerChainCtrl->setSingleShot(0); + timerChainCtrl->start(UPDATE_PERIOD_MS); // 1000: call every 1000ms + + timerVendingTimeout = new QTimer(this); + connect(timerVendingTimeout, SIGNAL(timeout()), this, SLOT(vendingTimeout())); + timerVendingTimeout->setSingleShot(true); + timerVendingTimeout->start(VENDINGTIMEOUT_MS); // in ms + + // ########################################################################################## + // für jedes anzuzeigende Fenster eine eigene Groupbox mit eigenem Grid anlegen: + + frame01 = new QGroupBox; + frame01->setStyleSheet(APPPAGE_BACKGROUND_COLOR); + frame01->setMinimumSize(FORMWIDTH,FORMHEIGHT); + QVBoxLayout *smallLay01 = new QVBoxLayout; + frame01->setLayout(smallLay01); + // Fensterinhalt aus externer Klasse einfügen: + myFenster01 = new T_winComPort(HWaccess); // HWaccess damit auf das HW-Plugin zugegriffen werden kann, sonst crash + smallLay01->addWidget(myFenster01); + + // ########################################################################################## + // draw Mainwindow: + bigGroupbox = new QGroupBox; + bigGroupbox->setStyleSheet("background-color: grey"); + bigGroupbox->setMinimumSize(800,480); +// bigLayout = new QVBoxLayout; // navi buttons on bottom side + bigLayout = new QHBoxLayout; // navi buttons right hand + + // ########################################################################################## + // add all windows (but display only one) + // display only one: then all windows are shown at the same place + // display more then one: the windows are listed in vertical order + + bigLayout->addWidget(frame01); + + bigGroupbox->setLayout(bigLayout); + switchScreen(1); + //HideAllWindows(); + + // ########################################################################################## + // Steuer Leiste + + //QHBoxLayout *ButtonLayout = new QHBoxLayout(); + QVBoxLayout *ButtonLayout = new QVBoxLayout(); + QFont myTabFont; + myTabFont.setPixelSize(26); + + pBback = new QPushButton("<"); //b\na\nc\nk"); + pBback->setFont(myTabFont); + pBback->setStyleSheet(ACTIVE_NAVI_COLOR); + pBback->setMinimumHeight(NAVIBUTTONHEIGHT); + pBback->setMaximumWidth(NAVIBUTTONWIDHT); + connect(pBback, SIGNAL( clicked() ), myFenster01, SLOT( Nav_back())); + + myTabFont.setPixelSize(22); + pBhome = new QPushButton("<<"); //h\no\nm\ne"); + pBhome->setFont(myTabFont); + pBhome->setStyleSheet(ACTIVE_NAVI_COLOR); + pBhome->setMinimumHeight(NAVIBUTTONHEIGHT); + pBhome->setMaximumWidth(NAVIBUTTONWIDHT); + connect(pBhome, SIGNAL( clicked() ), myFenster01, SLOT( Nav_home())); + + myTabFont.setPixelSize(26); + pBforward = new QPushButton(">"); //n\ne\nx\nt"); + pBforward->setFont(myTabFont); + pBforward->setStyleSheet(ACTIVE_NAVI_COLOR); + pBforward->setMinimumHeight(NAVIBUTTONHEIGHT); + pBforward->setMaximumWidth(NAVIBUTTONWIDHT); + connect(pBforward, SIGNAL( clicked() ), myFenster01, SLOT( Nav_next())); + + QLabel *buttonSpace = new QLabel(" "); + ButtonLayout->addWidget(pBback); + ButtonLayout->addWidget(buttonSpace); + //ButtonLayout->addWidget(buttonSpace); + ButtonLayout->addWidget(pBhome); + ButtonLayout->addWidget(buttonSpace); + //ButtonLayout->addWidget(buttonSpace); + ButtonLayout->addWidget(pBforward); + QLabel *bottomSpace = new QLabel(" "); + ButtonLayout->addWidget(bottomSpace); + + bigLayout->addLayout(ButtonLayout); + + setCentralWidget(bigGroupbox); + + // AUTOSTART serial transmission + //HWaccess->dc_openSerial(5,"115200","ttyS0",1); // my suse computer + //HWaccess->dc_openSerial(1,"9600","COM5",1); // my suse computer + //HWaccess->dc_openSerial(5,"115200","ttymxc2",1); // ptu5 + //HWaccess->dc_autoRequest(true); + //myFenster01->setButtons4autoStart(); + //HWaccess->alarm_switchSiren(0); // test + + enableNaviButtons(BACKBUTTON,true); + enableNaviButtons(HOMEBUTTON,true); + enableNaviButtons(FORWBUTTON,true); + this->chainIni(); + + //connect(myFenster02, SIGNAL(quitMyApp()), this, SLOT(close())); + +} + +MainWindow::~MainWindow() +{ + loadPlugIn(2); +} + + +void MainWindow::HideAllWindows() +{ + // vorsicht: Fenster muss oben definiert sein sonst Programmabsturz ohne Kommentar + + frame01->setEnabled(false); + frame01->setVisible(false); +} + + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Call Windows +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void MainWindow::switchScreen(uint16_t winNr) // 0...30 +{ + + HideAllWindows(); + //qDebug()<<"switch screen to " << winNr; + + switch (winNr) + { + case 1: + frame01->setEnabled(true); + frame01->setVisible(true); + break; + default: + break; + + } + +} + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Navigation buttons +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void MainWindow::enableNaviButtons(uint8_t switchBitwise) +{ + // switchBitwise=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + + if (switchBitwise &1) + { + pBforward->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBforward->setText("next"); + pBforward->setEnabled(true); + } else + if (switchBitwise &2) + { + pBforward->setStyleSheet(DISABL_NAVI_COLOR); + //pBforward->setText(" "); + pBforward->setEnabled(false); + } + + if (switchBitwise &4) + { + pBhome->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBhome->setText("home"); + pBhome->setEnabled(true); + } else + if (switchBitwise &8) + { + pBhome->setStyleSheet(DISABL_NAVI_COLOR); + //pBhome->setText(" "); + pBhome->setEnabled(false); + } + + if (switchBitwise &16) + { + pBback->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBback->setText("back"); + pBback->setEnabled(true); + } else + if (switchBitwise &32) + { + pBback->setStyleSheet(DISABL_NAVI_COLOR); + //pBback->setText(" "); + pBback->setEnabled(false); + } + + + +} + +void MainWindow::enableNaviButtons(uint8_t buttonNr, bool enabled) +{ + if (buttonNr==1) + { + if (enabled) + { + pBback->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBback->setText("back"); + pBback->setEnabled(true); + } else + { + pBback->setStyleSheet(DISABL_NAVI_COLOR); + //pBback->setText(" "); + pBback->setEnabled(false); + } + } else + if (buttonNr==2) + { + if (enabled) + { + pBhome->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBhome->setText("home"); + pBhome->setEnabled(true); + } else + { + pBhome->setStyleSheet(DISABL_NAVI_COLOR); + //pBhome->setText(" "); + pBhome->setEnabled(false); + } + } else + if (buttonNr==3) + { + if (enabled) + { + pBforward->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBforward->setText("next"); + pBforward->setEnabled(true); + } else + { + pBforward->setStyleSheet(DISABL_NAVI_COLOR); + //pBforward->setText(" "); + pBforward->setEnabled(false); + } + } + +} + + + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// control work flow by Finite state machine +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +static uint16_t chainCurrentStep, chainNextStep; +static bool chain_stepIni; + +void MainWindow::chainIni(void) +{ + // called once after power-up by constructor + chainCurrentStep=WCS_STARTSCREEN; // start screen + chainNextStep=chainCurrentStep; + switchScreen(chainCurrentStep); + chain_stepIni=true; +//qDebug()<<"chain ini, call step "<stop(); + timerVendingTimeout->start(VENDINGTIMEOUT_MS); + } + //qDebug()<<"found new sreen"; + chainCurrentStep=chainNextStep; + switchScreen(chainCurrentStep); + chain_stepIni=true; + + } + + if (chainCurrentStep==1) + { + if (chain_stepIni) + busy=myFenster01->work_ini(&nextScreen, &useNavi); + else + busy=myFenster01->working(&nextScreen, &useNavi); + } else + + { + // error undefined step + qDebug()<<"error main chain control, wrong step ("<0) + { + // call next chain step + //qDebug()<<"chain control: new step selected: "<< nextScreen; + + chainNextStep=nextScreen; + } + if (useNavi>0) + { + //qDebug()<<"chain control: navi buttons "<< useNavi; + enableNaviButtons(useNavi); + } + + if (busy>0) + { + // reset time-out + timerVendingTimeout->start(); + } + +} + + + +void MainWindow::vendingTimeout(void) +{ + // there was no user operation for 30s so return to start screen +// uint16_t nextScreen=WCS_STARTSCREEN; +// chainNextStep=nextScreen; erstmal stilllegen, stört bei IBN + //qDebug()<<"chain control: vending TO"; + timerVendingTimeout->stop(); +} + + + diff --git a/CArunGUI/mainwindow.h b/CArunGUI/mainwindow.h new file mode 100755 index 0000000..5c13e16 --- /dev/null +++ b/CArunGUI/mainwindow.h @@ -0,0 +1,72 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "plugin.h" +#include "stepList.h" +//#include "stepList.h" // define all working chain steps here +#include "win01_com.h" + + +class MainWindow : public QMainWindow +{ + Q_OBJECT + + QPushButton *pBback; + QPushButton *pBhome; + QPushButton *pBforward; + QGroupBox *bigGroupbox; + QHBoxLayout *bigLayout; + QTimer *timerChainCtrl; + QTimer *timerVendingTimeout; + + QGroupBox *frame01; + T_winComPort *myFenster01; + + void HideAllWindows(); + void switchScreen(uint16_t winNr); + char loadPlugIn(char lade1_entlade2); + QDir plugInDir; + void chainIni(void); + +public: + hwinf *HWaccess=nullptr; // global pointer to plugin-class + + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +#define BACKBUTTON 1 +#define HOMEBUTTON 2 +#define FORWBUTTON 3 + void enableNaviButtons(uint8_t buttonNr, bool enabled); + void enableNaviButtons(uint8_t switchBitwise); + +private slots: + void chainControl(); + void vendingTimeout(); + +}; + + + + +#endif // MAINWINDOW_H diff --git a/CArunGUI/plugin.h b/CArunGUI/plugin.h new file mode 100755 index 0000000..50a40b3 --- /dev/null +++ b/CArunGUI/plugin.h @@ -0,0 +1,6 @@ +#ifndef PLUGIN_H +#define PLUGIN_H + +#include "interfaces.h" + +#endif diff --git a/CArunGUI/stepList.h b/CArunGUI/stepList.h new file mode 100755 index 0000000..1d553b2 --- /dev/null +++ b/CArunGUI/stepList.h @@ -0,0 +1,210 @@ +#ifndef STEPLIST_H +#define STEPLIST_H + + +// define all working chain steps +// every FSM-Step get's a frame in MainWindow with the same number and a self-designed GUI +// labels are used for switchScreen( label=nr ); +// numbers are important: e.g. number 3 calls frame3 and frame3 includes subClass "T_fenster03" +// so best solution: label = same name like class (in example: Fenster03). Label is fixed bound to number, never change! + +// numbers are fixed assosiated with the function (e.g. ComPort), can't be changed. +// but screen order can be called in step chain randomly + + +// Windownumbers for certain function, never change +#define PAGE_COMPORT 1 +#define PAGE_SERVICEMAIN 2 +#define PAGE_TIMEDATEVERSION 3 +#define PAGE_MACHINESTATUS 4 +#define PAGE_CHECKDOORS 5 +#define PAGE_PRINTER 6 +#define PAGE_COINMECHANIC 7 +#define PAGE_MIFARE 8 +#define PAGE_MODEM 9 +#define PAGE_COINPAYMENT 10 +#define PAGE_VAULTRECORD 11 +#define PAGE_BOOTLOADER 12 +#define PAGE_PROG_JSON 13 +#define PAGE_COINCHANGER 14 +#define PAGE_BILLREADER 15 +#define PAGE_NEXT16 16 +#define PAGE_NEXT17 17 +#define PAGE_NEXT18 18 +#define PAGE_NEXT19 19 +#define PAGE_NEXT20 20 + +// fix: customize: +#define WCS_STARTSCREEN PAGE_COMPORT + +// PAGE_COMPORT: +#define WCS_WIN01BAK PAGE_COMPORT +#define WCS_WIN01MID PAGE_SERVICEMAIN +#define WCS_WIN01FWD PAGE_SERVICEMAIN + +// PAGE_SERVICEMAIN: +#define WCS_WIN02BAK PAGE_COMPORT +#define WCS_WIN02MID PAGE_SERVICEMAIN +#define WCS_WIN02FWD PAGE_TIMEDATEVERSION + +// PAGE_TIMEDATEVERSION: +#define WCS_WIN03BAK PAGE_SERVICEMAIN +#define WCS_WIN03MID PAGE_SERVICEMAIN +#define WCS_WIN03FWD PAGE_MACHINESTATUS + +// PAGE_MACHINESTATUS: +#define WCS_WIN04BAK PAGE_TIMEDATEVERSION +#define WCS_WIN04MID PAGE_SERVICEMAIN +#define WCS_WIN04FWD PAGE_CHECKDOORS + + +// PAGE_CHECKDOORS: +#define WCS_WIN05BAK PAGE_MACHINESTATUS +#define WCS_WIN05MID PAGE_SERVICEMAIN +#define WCS_WIN05FWD PAGE_COINMECHANIC + +// PAGE_COINMECHANIC: +#define WCS_WIN07BAK PAGE_CHECKDOORS +#define WCS_WIN07MID PAGE_SERVICEMAIN +#define WCS_WIN07FWD PAGE_COINPAYMENT + +// PAGE_COINPAYMENT: +#define WCS_WIN10BAK PAGE_COINMECHANIC +#define WCS_WIN10MID PAGE_SERVICEMAIN +#define WCS_WIN10FWD PAGE_COINCHANGER + +// PAGE_COINCHANGER: +#define WCS_WIN14BAK PAGE_COINPAYMENT +#define WCS_WIN14MID PAGE_SERVICEMAIN +#define WCS_WIN14FWD PAGE_BILLREADER + + +// PAGE_BILLREADER: +#define WCS_WIN15BAK PAGE_COINCHANGER +#define WCS_WIN15MID PAGE_SERVICEMAIN +#define WCS_WIN15FWD PAGE_PRINTER + +// PAGE_PRINTER: +#define WCS_WIN06BAK PAGE_BILLREADER +#define WCS_WIN06MID PAGE_SERVICEMAIN +#define WCS_WIN06FWD PAGE_MIFARE + +// PAGE_MIFARE: +#define WCS_WIN08BAK PAGE_PRINTER +#define WCS_WIN08MID PAGE_SERVICEMAIN +#define WCS_WIN08FWD PAGE_MODEM + +// PAGE_MODEM: +#define WCS_WIN09BAK PAGE_MIFARE +#define WCS_WIN09MID PAGE_SERVICEMAIN +#define WCS_WIN09FWD PAGE_VAULTRECORD + + +// PAGE_VAULTRECORD: +#define WCS_WIN11BAK PAGE_MODEM +#define WCS_WIN11MID PAGE_SERVICEMAIN +#define WCS_WIN11FWD PAGE_PROG_JSON + +// PAGE_PROG_JSON: +#define WCS_WIN13BAK PAGE_VAULTRECORD +#define WCS_WIN13MID PAGE_SERVICEMAIN +#define WCS_WIN13FWD PAGE_BOOTLOADER + +// PAGE_BOOTLOADER: +#define WCS_WIN12BAK PAGE_PROG_JSON +#define WCS_WIN12MID PAGE_SERVICEMAIN +#define WCS_WIN12FWD PAGE_NEXT16 + + +// PAGE_NEXT16 +#define WCS_WIN16BAK PAGE_BOOTLOADER +#define WCS_WIN16MID PAGE_SERVICEMAIN +#define WCS_WIN16FWD PAGE_NEXT17 + +// PAGE_NEXT17 +#define WCS_WIN17BAK PAGE_NEXT16 +#define WCS_WIN17MID PAGE_SERVICEMAIN +#define WCS_WIN17FWD PAGE_NEXT18 + +// PAGE_NEXT18 +#define WCS_WIN18BAK PAGE_NEXT17 +#define WCS_WIN18MID PAGE_SERVICEMAIN +#define WCS_WIN18FWD PAGE_NEXT19 + +// PAGE_NEXT19 +#define WCS_WIN19BAK PAGE_NEXT18 +#define WCS_WIN19MID PAGE_SERVICEMAIN +#define WCS_WIN19FWD PAGE_NEXT20 + +// PAGE_NEXT20 +#define WCS_WIN20BAK PAGE_NEXT19 +#define WCS_WIN20MID PAGE_SERVICEMAIN +#define WCS_WIN20FWD PAGE_SERVICEMAIN + +// just for Template +#define WCS_WIN99BAK PAGE_SERVICEMAIN +#define WCS_WIN99MID PAGE_SERVICEMAIN +#define WCS_WIN99FWD PAGE_SERVICEMAIN + + + +#define WIN02_LABEL_SHORT01 " Status" +#define WCS_WIN02SHORT01 PAGE_MACHINESTATUS +#define WIN02_LABEL_SHORT02 " Doors " +#define WCS_WIN02SHORT02 PAGE_CHECKDOORS +#define WIN02_LABEL_SHORT03 "Coin mech" +#define WCS_WIN02SHORT03 PAGE_COINMECHANIC +#define WIN02_LABEL_SHORT04 "Payment" +#define WCS_WIN02SHORT04 PAGE_COINPAYMENT + +#define WIN02_LABEL_SHORT05 "Changer" +#define WCS_WIN02SHORT05 PAGE_COINCHANGER +#define WIN02_LABEL_SHORT06 " Bill " +#define WCS_WIN02SHORT06 PAGE_BILLREADER +#define WIN02_LABEL_SHORT07 "Printer" +#define WCS_WIN02SHORT07 PAGE_PRINTER + +#define WIN02_LABEL_SHORT08 "Program" +#define WCS_WIN02SHORT08 PAGE_VAULTRECORD +#define WIN02_LABEL_SHORT09 " " +#define WCS_WIN02SHORT09 PAGE_SERVICEMAIN +#define WIN02_LABEL_SHORT10 " " +#define WCS_WIN02SHORT10 PAGE_SERVICEMAIN + + + + + + + +// set needed navigation buttons, use | to combine more then one: +#define SWITCH_NEXT_ON 1 +#define SWITCH_NEXT_OFF 2 +#define SWITCH_HOME_ON 4 +#define SWITCH_HOME_OFF 8 +#define SWITCH_BACK_ON 16 +#define SWITCH_BACK_OFF 32 +// example: *useNavi=SWITCH_BACK_ON; // change only this one, or set all: +// *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_ON; + + + +// some defines for Widget design: + +#define TS_VALUEBOX_FRAMESTYLE 0x0032 +#define TS_VALUEBOX_LINEWIDTH 3 + +//genDatPort->setFrameStyle(QFrame::Panel | QFrame::Sunken ); funktioniert aber gibt unverständliche Warnung +// QFrame::Panel = 0x0002 QFrame::Sunken=0x0030 +//genDatPort->setFrameStyle(0x0032); // funktioniert und gibt keine Warnung +//genDatPort->setFrameStyle(TS_VALUEBOX_FRAMESTYLE); // funktioniert und gibt keine Warnung + +#define TS_LED_FRAMESTYLE 0x0031 +// QFrame::Box | QFrame::Sunken + + + + + + +#endif // STEPLIST_H diff --git a/CArunGUI/subwindows.cpp b/CArunGUI/subwindows.cpp new file mode 100755 index 0000000..a78317d --- /dev/null +++ b/CArunGUI/subwindows.cpp @@ -0,0 +1,267 @@ +#include "subwindows.h" + + + + + + + + + +/* + +// %%%%%%%%%%%%%%%%%%%% TabChanger + +T_fenster12::T_fenster12(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Coin Changer"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster12::updateGui(void) +{ + +} + + +// %%%%%%%%%%%%%%%%%%%% TabBill +T_fenster13::T_fenster13(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Bank note acceptor"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster13::updateGui(void) +{ + +} + +T_fenster14::T_fenster14(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 14"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster14::updateGui(void) +{ + +} + +T_fenster15::T_fenster15(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 15"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster15::updateGui(void) +{ + +} + +T_fenster16::T_fenster16(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 16"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster16::updateGui(void) +{ + +} + +T_fenster17::T_fenster17(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 17"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster17::updateGui(void) +{ + +} + +T_fenster18::T_fenster18(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 18"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster18::updateGui(void) +{ + +} + +T_fenster19::T_fenster19(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 19"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster19::updateGui(void) +{ + +} + +T_fenster20::T_fenster20(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 20"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster20::updateGui(void) +{ + +} + + + +T_fenster21::T_fenster21(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 21"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster21::updateGui(void) +{ + +} + +T_fenster22::T_fenster22(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 22"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster22::updateGui(void) +{ + +} + +T_fenster23::T_fenster23(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 23"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster23::updateGui(void) +{ + +} + +T_fenster24::T_fenster24(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 24"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster24::updateGui(void) +{ + +} + +T_fenster25::T_fenster25(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 25"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster25::updateGui(void) +{ + +} + +T_fenster26::T_fenster26(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 26"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster26::updateGui(void) +{ + +} + +T_fenster27::T_fenster27(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 27"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster27::updateGui(void) +{ + +} + +T_fenster28::T_fenster28(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 28"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster28::updateGui(void) +{ + +} + +T_fenster29::T_fenster29(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 29"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster29::updateGui(void) +{ + +} + +T_fenster30::T_fenster30(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 30"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster30::updateGui(void) +{ + +} + +*/ + diff --git a/CArunGUI/subwindows.h b/CArunGUI/subwindows.h new file mode 100755 index 0000000..061ca8c --- /dev/null +++ b/CArunGUI/subwindows.h @@ -0,0 +1,161 @@ +#ifndef SUBWINDOWS_H +#define SUBWINDOWS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tslib.h" +#include "stepList.h" // define all working chain steps here +#include "../plugins/interfaces.h" + + + +class T_fenster12 : public QWidget // TabChanger +{ + public: + explicit T_fenster12(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster13 : public QWidget // TabBill +{ + public: + explicit T_fenster13(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster14 : public QWidget +{ + public: + explicit T_fenster14(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster15 : public QWidget +{ + public: + explicit T_fenster15(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster16 : public QWidget +{ + public: + explicit T_fenster16(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster17 : public QWidget +{ + public: + explicit T_fenster17(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster18 : public QWidget +{ + public: + explicit T_fenster18(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster19 : public QWidget +{ + public: + explicit T_fenster19(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster20 : public QWidget +{ + public: + explicit T_fenster20(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; + +class T_fenster21 : public QWidget +{ + public: + explicit T_fenster21(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster22 : public QWidget +{ + public: + explicit T_fenster22(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster23 : public QWidget +{ + public: + explicit T_fenster23(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster24 : public QWidget +{ + public: + explicit T_fenster24(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster25 : public QWidget +{ + public: + explicit T_fenster25(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster26 : public QWidget +{ + public: + explicit T_fenster26(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster27 : public QWidget +{ + public: + explicit T_fenster27(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster28 : public QWidget +{ + public: + explicit T_fenster28(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster29 : public QWidget +{ + public: + explicit T_fenster29(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster30 : public QWidget +{ + public: + explicit T_fenster30(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; + +#endif diff --git a/CArunGUI/tslib.cpp b/CArunGUI/tslib.cpp new file mode 100755 index 0000000..d70c1fc --- /dev/null +++ b/CArunGUI/tslib.cpp @@ -0,0 +1,1016 @@ +#include "tslib.h" +#include + + +//tslib::tslib() +//{ + + +//} + + +/* +uint16_t tslib::uchar2uint(uint8_t Highbyte, uint8_t Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint8_t tslib::uint2uchar(uint16_t uival, bool getHighB) +{ + // getHighB: low=GetLowByte + uint16_t uitmp=uival; + if (getHighB==0) + return uint8_t(uitmp); + uitmp>>=8; + return uint8_t(uitmp); + +}*/ + +uint16_t uchar2uint(char Highbyte, char Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte) +{ + uint32_t ultmp=0; + + ultmp |= uint8_t(Highbyte); + ultmp<<=8; + ultmp |= uint8_t(MHbyte); + ultmp<<=8; + ultmp |= uint8_t(MLbyte); + ultmp<<=8; + ultmp |= uint8_t(Lowbyte); + return ultmp; +} + +uint8_t uint2uchar(uint16_t uival, bool getHighB) +{ + // getHighB: low=GetLowByte + uint16_t uitmp=uival; + if (getHighB==0) + return uint8_t(uitmp); + uitmp>>=8; + return uint8_t(uitmp); + +} + + +void delay(uint16_t MilliSec) +{ + QThread::msleep(uint32_t(MilliSec)); +} + + +void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf) +{ + // Zahlenwerte in String wandeln, 12/24h-Format // 12byte für buf! + uint8_t usa; + uint16_t jj; + uint8_t hh, mm, ss, with_sec; + + // buf[0]= ganz linkes Zeichen + hh=hours; + mm=minutes; + ss=seconds; + + // 15.10.12, Plausibilitätsprüfung -------------------------------------------------- + if (hh>23) hh=0; + if (mm>59) mm=0; + if (ss>59) ss=0; + + with_sec=ShowSec; + for (jj=0; jj<12; jj++) buf[jj]=0; + usa = System12h; // 1:12h 0:24h + + // Stunden: + if (usa) + { + // 12h System + if (hh==0 || hh==12) + { + // 12AM (Mitternacht) oder 12PM (Mittag) + buf[0]=0x31; + buf[1]=0x32; + } else + if (hh<12) + { + // 1..11AM + buf[0]=hh/10+0x30; + buf[1]=hh%10+0x30; + } else + { + //13:00 bis 23Uhr + buf[0]=(hh-12)/10+0x30; + buf[1]=(hh-12)%10+0x30; + } + } else + { + // 24h System + buf[0]=hh/10+0x30; + buf[1]=hh%10+0x30; + } + + // Minuten: + buf[2]=':'; + //buf[2]='_'; // : not allowed in JsonFormat + buf[3]=mm/10+0x30; + buf[4]=mm%10+0x30; + + jj=5; + if (with_sec) + { + buf[jj++]=':'; + //buf[jj++]='_'; // : not allowed in JsonFormat + buf[jj++]=ss/10+0x30; + buf[jj++]=ss%10+0x30; + } + if (usa) + { + buf[jj++]=' '; + if (hh<12) + buf[jj++]='A'; + else + buf[jj++]='P'; + buf[jj++]='M'; + } + +} + +// ------------------- ******************************************************************************** + +void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf) +{ + // generate date as ascii string from integers day/month/year + // yearhigh: 10..29, in europe always 20 (not in arabia!) comes as hex number, e.g. 0x20 + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + + uint8_t tag, mon, jahr, d10, d1, m10, m1, y1000, y100, y10, y1; + uint8_t slash; + + + y100= (yearhigh & 0x0F)+0x30; + y1000=((yearhigh & 0xF0)>>4)+0x30; +// if (yearhigh>=20) +// { +// y1000='2'; +// y100=28+yearhigh; // '0' + (yearhigh-20) +// } else +// if (yearhigh<20) +// { +// y1000='1'; +// y100=38-yearhigh; // '9' - (19-yearhigh) +// } + + tag=day; + mon=month; + jahr=yearlow; + + if (mon>12 || mon==0) mon=1; // 23.10.12 + if (tag>31 || tag==0) tag=1; + if (jahr>50 || jahr<11) jahr=1; + + if (sep==0) + slash='.'; // slash==0 + else if (sep==1) + slash='/'; + else + if (sep>=0x20) + slash=sep; + else + slash='.'; + + d10 =tag/10; + d1 =tag%10; + m10 =mon/10; + m1 =mon%10; + y10 =jahr/10; + y1 =jahr%10; + + d10 +=0x30; // in Asccii wandeln + d1 +=0x30; + m10 +=0x30; + m1 +=0x30; + y10 +=0x30; + y1 +=0x30; + + switch (format) + { + // 0: dd.mm.yyyy + case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash; + buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break; + + // 1: mm.dd.yyyy + case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash; + buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break; + + // 2: yyyy.mm.dd + case 2: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=m10; + buf[6]=m1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break; + + // 3: dd.yyyy.mm + case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=y1000; buf[4]=y100; + buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break; + + // 4: mm.yyyy.dd + case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=y1000; buf[4]=y100; + buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break; + + // 5: yyyy.dd.mm + case 5: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=d10; + buf[6]=d1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break; + + } + buf[10]=0; + + +} + +// ------------------- ******************************************************************************** + +void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf) +{ + // generate date as ascii string from integers day/month/year + // format= 0: dd.mm.yy (deutsch) + // 1: mm.dd.yy (amerika) + // 2: yy.mm.dd (Iran, Dubai) + // 3: dd.yy.mm + // 4: mm.yy.dd + // 5: yy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + + uint8_t tag, mon, jahr, d10, d1, m10, m1, y10, y1; + uint8_t slash; + + + tag=day; + mon=month; + jahr=yearlow; + + if (mon>12 || mon==0) mon=1; // 23.10.12 + if (tag>31 || tag==0) tag=1; + if (jahr>50 || jahr<11) jahr=1; + + if (sep==0) + slash='.'; // slash==0 + else if (sep==1) + slash='/'; + else if (sep>=0x20) + slash=sep; + else + slash='.'; + + d10 =tag/10; + d1 =tag%10; + m10 =mon/10; + m1 =mon%10; + y10 =jahr/10; + y1 =jahr%10; + + d10 +=0x30; // in Asccii wandeln + d1 +=0x30; + m10 +=0x30; + m1 +=0x30; + y10 +=0x30; + y1 +=0x30; + + switch (format) + { + // 0: dd.mm.yyyy + case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash; + buf[6]=y10; buf[7]=y1; break; + + // 1: mm.dd.yyyy + case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash; + buf[6]=y10; buf[7]=y1; break; + + // 2: yyyy.mm.dd + case 2: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=m10; + buf[4]=m1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break; + + // 3: dd.yyyy.mm + case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash; + buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break; + + // 4: mm.yyyy.dd + case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash; + buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break; + + // 5: yyyy.dd.mm + case 5: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=d10; + buf[4]=d1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break; + + } + buf[8]=0; + + +} + +uint16_t tslib_strlen(char *buf) +{ + uint16_t nn; + + for (nn=0; nn<0xFFF0; nn++) + if (buf[nn]==0) + return nn; + return 0; +} + +void tslib_strclr(char *buf, char clrsign, uint16_t len) +{ + uint16_t nn; + + for (nn=0; nn=0x30 && sign<=0x39) + return true; + return false; +} + +bool tslib_isHexAsciiNumber(char sign) +{ + if (sign>=0x30 && sign<=0x39) + return true; + if (sign>=0x61 && sign<=0x66) // a...f + return true; + if (sign>=0x41 && sign<=0x46) // A...F + return true; + return false; +} + +int tslib_getMinimum(int val1, int val2) +{ + if (val1maxArayLen) LL=maxArayLen; + for (ii=0; ii> (7 - nn)) & 0x01); + if (B15H) + { + crc ^= 0x1021; + } + } + } + + for (nn = 0; nn < 16; nn++) + { + B15H = 0; + if(crc & 0x8000) + B15H = 1; + crc = (crc << 1) | 0x00; + if (B15H) + { + crc ^= 0x1021; + } + } + return crc; + +} + +static uint8_t LastBLcmd; // stored the last sent cmd in order to analys response + // cmd echo'ed: error cmd or'ed with 0x80: OK + +uint8_t tslib_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) +{ + // make BL protocol, retval = outbuf length (5...133) + // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum + // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 + // Data length = 0...64 + // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 + // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + + uint8_t myBuf[140], pp=0, nn, uctmp, currLen=0; + uint16_t calcCrc; + + tslib_strclr(myBuf, 0, 140); + + myBuf[pp++]=2; // STX + myBuf[pp++]=Cmd; + LastBLcmd=Cmd; + + // append data: + for (nn=0; nn>8) & 0x00FF); + myBuf[pp++]=3; + currLen=pp; + + return currLen; +} + +// some special commands (right out of bootloader manual) +uint8_t tslib_readBLversion(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData); +} + +uint8_t tslib_readFWversion(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x12, 0, myBuf, sendData); +} + +uint8_t tslib_exitBL(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x18, 0, myBuf, sendData); +} + +uint8_t tslib_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData) +{ + // minimum size of sendData-buffer: 13byte retval: length (9...13) + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData); +} +*/ + +// ----------------------------------------------------------------------------------------------- + +bool tslib_plausiChkTime(uint8_t hour, uint8_t min, uint8_t sec ) +{ + // retval: true: time is OK + bool ret=true; + + if (hour>23) ret=false; + if (min>59) ret=false; + if (sec>59) ret=false; + + return ret; +} + +// ----------------------------------------------------------------------------------------------- + +bool tslib_plausiChkDate(uint8_t year, uint8_t month, uint8_t dom ) +{ + // retval: true: time is OK + bool ret=true; + + if (year<23) ret=false; + if (month<1 || month>12) ret=false; + if (dom<1 || dom>31) ret=false; + + return ret; +} + +// ----------------------------------------------------------------------------------------------- + +UCHAR swl_LengthCurrentMonth(UCHAR month, UCHAR year) +{ + // return nr of days for this month, respecting leap years + if (month==2) + { + // Sonderfall Februar: + if (year%4) + return 28; // Rest wenn durch 4 geteilt wird + else + return 29; // durch 4 teilbar ohne Rest + } else + if (month==1 || month==3 || month==5 || month==7 || + month==8 || month==10 || month==12) + { + return 31; + } else + return 30; + +} + +// ----------------------------------------------------------------------------------------------- + +UINT swl_GetDaysOfaCompleteYear(UCHAR year) +{ + // year: 0=2000 4=2004 99=2099 + // retval: 365 or 366 (leap year) + UCHAR jahr; + + jahr=year; + if (jahr & 3) // wenn bits 0 und 1 low sind dann Vielfaches von 4 + { + // dann kein Schaltjahr + return(365); + } else + { + // Schaltjahr + return(366); + } + +} + +// ----------------------------------------------------------------------------------------------- + +UINT swl_GetDaysOfYear(UCHAR year, UCHAR month, UCHAR day) +{ + // number of days of momentary year from 1. Jan until + // (inclusive) given date with respect to leap years + // year: 0..99 month=1..12 day=1..31 + + int summe=0; + UCHAR mo, ta, yy, mm, uctmp; + + yy=year; + mo=month; + ta=day; + if (mo==0 || mo>12 || ta==0 || ta>31 || yy>99) + return(0); // Fehler + + // Beispiel: mo=5: summiere Tage des Jan, Feb, März und April + // der Mai ist noch nicht komplett abgelaufen! + mm=1; // start mit Januar + while (mo>1) + { + uctmp=swl_LengthCurrentMonth(mm,yy); + summe += (int)uctmp; + mo--; mm++; + } + + summe+=ta; + return(summe); +} + +// ----------------------------------------------------------------------------------------------- + +unsigned long swl_getNrOfDaysSince2000Jan1(UCHAR thisYear, UCHAR thisMonth, UCHAR thisDay) +{ + // till today + ULONG ultmp=0; + UCHAR jj; + + for (jj=0; jj +#include + +typedef uint8_t UCHAR; +typedef uint16_t UINT; +typedef uint32_t ULONG; + +#define LOWBYTE false +#define HIGHBYTE true + +uint16_t uchar2uint(char Highbyte, char Lowbyte); +uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte); +uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte); + +uint8_t uint2uchar(uint16_t uival, bool getHighB); + + +void delay(uint16_t MilliSec); + +#define MITSEK 1 +#define OHNESEK 0 +#define HourSys12h 1 +#define HourSys24h 0 + +void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf); + // generate time as ascii string from integers hours/minutes/seconds + // System12h=0: 24h system =1: 12h System + // ShowSec=0: String has 5 digits (hh:mm) =1: String has 8 digits (hh:mm:ss) + // return String in *buf // 12 byte für buf! + +#define DateFormatDeutsch 0 +#define DateFormatAmerica 1 +#define UsePointSeperator 0 +#define UseSlashSeperator 1 + + +void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf); + // generate date as ascii string from integers day/month/year + // yearhigh in europe always 20 (not in arabia) + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11 byte für buf! + + +void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf); + // generate date as ascii string from integers day/month/year + // format= 0: dd.mm.yy (deutsch) + // 1: mm.dd.yy (amerika) + // 2: yy.mm.dd (Iran, Dubai) + // 3: dd.yy.mm + // 4: mm.yy.dd + // 5: yy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + +uint16_t tslib_strlen(char *buf); + +void tslib_strclr(char *buf, char clrsign, uint16_t len); +void tslib_strclr(uint8_t *buf, char clrsign, uint16_t len); + +void tslib_strcpy(char *srcbuf, char *destbuf, uint16_t len); +void tslib_strcpy(char *srcbuf, uint8_t *destbuf, uint16_t len); +void tslib_strcpy(uint8_t *srcbuf, uint8_t *destbuf, uint16_t len); + + +uint16_t tslib_calcCrcCcitt(uint16_t BufLength, uint8_t *buf); + +bool tslib_isDecAsciiNumber(char sign); +bool tslib_isHexAsciiNumber(char sign); + + +int tslib_getMinimum(int val1, int val2); + +void tslib_text2array(QByteArray text, char *aray, uint16_t maxArayLen); + // usage: tslib_text2array("my text", ctmp, 50); + +bool tslib_strComp(uint8_t *buf, char *compStr); + +bool tslib_plausiChkTime(uint8_t hour, uint8_t min, uint8_t sec ); + // retval: true: time is OK + +bool tslib_plausiChkDate(uint8_t year, uint8_t month, uint8_t dom ); + // retval: true: time is OK + +UCHAR swl_LengthCurrentMonth(UCHAR month, UCHAR year); + // return nr of days for this month, respecting leap years + +UINT swl_GetDaysOfaCompleteYear(UCHAR year); + // year: 0=2000 4=2004 99=2099 + // retval: 365 or 366 (leap year) + +UINT swl_GetDaysOfYear(UCHAR year, UCHAR month, UCHAR day); + // number of days of momentary year from 1. Jan until + // (inclusive) given date with respect to leap years + // year: 0..99 month=1..12 day=1..31 + +unsigned long swl_getNrOfDaysSince2000Jan1(UCHAR thisYear, UCHAR thisMonth, UCHAR thisDay); + // till today + +unsigned long swl_getNrOfHoursSince_Midnight2000Jan1(UCHAR thisYear, UCHAR thisMonth, UCHAR thisDay, UCHAR hoursNow); + +unsigned long swl_getNrOfMinutesSince_Midnight2000Jan1(UCHAR thisYear, \ + UCHAR thisMonth, UCHAR thisDay, UCHAR hoursNow, UCHAR minuteNow); + +unsigned long swl_getNrOfSecondsSince_Midnight2000Jan1(UCHAR thisYear, \ + UCHAR thisMonth, UCHAR thisDay, UCHAR hoursNow, UCHAR minuteNow, UCHAR secondNow); + +char swl_isLeap(UCHAR year); + +UCHAR swl_getNextLeapYear(UCHAR year); + +UCHAR swl_getLastLeapYear(UCHAR year); + +UCHAR swl_hoursOfThisWeek(UCHAR dow, UCHAR hoursNow); + // always calculate from monday 0 o'clock + // dow: 1=monday 7=sunday + +UINT swl_minutesOfThisWeek(UCHAR dow, UCHAR hoursNow, UCHAR minutesNow); + // always calculate from monday 0 o'clock + // dow: 1=monday 7=sunday + +UINT swl_hoursOfThisMonth(UCHAR thisDay, UCHAR hoursNow); + +UINT swl_minutesOfThisMonth(UCHAR thisDay, UCHAR hoursNow, UCHAR minutesNow); + +UINT swl_GetHoursOfYear(UCHAR year, UCHAR month, UCHAR day, UCHAR hourNow); + +ULONG swl_GetMinutesOfYear(UCHAR year, UCHAR month, UCHAR day, UCHAR hourNow, UCHAR minutesNow); + +UCHAR swl_weekday(UCHAR year, UCHAR month, UCHAR dayOfMonth); + // return 1...7 = monday...sunday, starting from 1.1.2000 + +QString swl_int2str(int val); +QString swl_hex2str(double val); + +void swl_text2ui8buf(QString text, uint8_t *outbuf, uint16_t length); + // copy text byte-by-byte to outbuf + +QString swl_ulong2str(uint32_t val); + +QString swl_long2str(long val); + +uint16_t swl_str2uint(QString myIntStr); + +uint32_t swl_str2ulong(QString myIntStr); + +QString swl_labelAndValToStr(QString label, uint32_t val); + +QString swl_8valInaRowToStr(QString label, uint8_t val[8]); + +QString swl_8valInaRowToStr(QString label, uint16_t val[8]); + +QString swl_8intsInaRowToStr(QString label, int val[8]); + +QString swl_centToEuroString(uint32_t amount_in_cent); + +#endif // TSLIB_H + +// qDebug << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) << QByteArray((const char*)dataSendBuf,dataBufLen).toHex(':'); + diff --git a/CArunGUI/versionHistory.txt b/CArunGUI/versionHistory.txt new file mode 100755 index 0000000..7b996ca --- /dev/null +++ b/CArunGUI/versionHistory.txt @@ -0,0 +1,13 @@ +#ifndef VERSIONHISTORY_H +#define VERSIONHISTORY_H + +APservice3.0 bis September2023 fuer DBM, Szeged + + +APservice3.2 12.10.23 + screen Abfolge komplett mit defines aufgebaut, kann jetzt in "stepList.h" veraendert werden + Neuen Screen Muenzwechsler und Banknote + passend zu CashAgent-Plugin: "Atb.Psa1256ptu5.software.HWapi/5.0" + Farben und Schriftgroessen vereinheitlichen (guidefs.h) + +#endif diff --git a/CArunGUI/win01_com.cpp b/CArunGUI/win01_com.cpp new file mode 100755 index 0000000..e8ee85d --- /dev/null +++ b/CArunGUI/win01_com.cpp @@ -0,0 +1,578 @@ +#include "win01_com.h" +#include "stepList.h" // define all working chain steps here +#include "datei.h" +//#include "globVars.h" + + + +// %%%%%%%%%%%%%%%%%%%% TabComPort + +Console::Console(QWidget *parent) : QPlainTextEdit(parent) +{ + document()->setMaximumBlockCount(100); + QPalette p = palette(); + p.setColor(QPalette::Base, Qt::black); //geht nicht weil untergrund schon farbig + p.setColor(QPalette::Text, Qt::blue); + setPalette(p); + +} + +void Console::putData(const QByteArray &data) +{ + insertPlainText(data); + insertPlainText("\n"); + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); +} + +void Console::putText(QString text) +{ + insertPlainText(text); + insertPlainText("\n"); + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); +} + +void T_winComPort::subPortInfo() +{ + + // Port Info Anzeige Feld, 2. Zeile links + QStringList myStringList; + QStringList comboPortList; + + const auto infos = QSerialPortInfo::availablePorts(); + for (const QSerialPortInfo &info : infos) + { + myStringList.append(QObject::tr(" \n Port: ") + info.portName() ); + myStringList.append(QObject::tr("Location: ") + info.systemLocation()); // + "\n"); + myStringList.append(QObject::tr("Description: ") + info.description() ); + myStringList.append(QObject::tr("Manufacturer: ") + info.manufacturer()); + myStringList.append(QObject::tr("Serial number: ") + info.serialNumber()); + myStringList.append (QObject::tr("Vendor Id: ") + QString::number(info.vendorIdentifier(), 16)); + myStringList.append(QObject::tr("Product Id: ") +QString::number(info.productIdentifier(), 16)); + //myStringList.append(QObject::tr("Busy: ") + (info.isBusy() ? QObject::tr("Yes") : QObject::tr("No"))); + comboPortList.append(info.portName()); // wenn Comport im System vorhanden dann in die Liste eintragen + } + QListWidget *myListWidget = new QListWidget; + myListWidget->insertItems(0, myStringList); + myListWidget->setMaximumWidth(250); + myTabComLayout->addWidget(myListWidget,1,0); + + + // ComboBox Comport Nr: + CB_portSel = new QComboBox(); + CB_portSel->addItems(comboPortList); // string Liste mit addItems (s am Schluss) ! + CB_portSel->setMinimumHeight(30); + CB_portSel->setMaximumWidth(150); + QFont myCBfont; + //myCBfont.setBold(true); + myCBfont.setPixelSize(15); + CB_portSel->setFont(myCBfont); + CB_portSel->setCurrentIndex(2); // default 3. Comport in der Liste = ttymxc2 in PTU5 + myTabComLayout->addWidget(CB_portSel, 4,0); + +} + +void T_winComPort::callOpenSerial() +{ + // Taste Connect wurde gedrückt, eine Klasse/einen Slot aus einer übergeordneten Klasse: + // openSerialPort(); + // kann man nicht aufrufen. deshalb: speichere ComPort, Baudrate und Startbefehl global. + // Von dort wird mit einem zyklischen Timer ausgelesen + + int br, ci; + QString bs, cn; + //br=CB_baudSel->currentIndex(); + //bs=CB_baudSel->currentText(); + br=5; + bs="115200"; + cn=CB_portSel->currentText(); + ci=CB_portSel->currentIndex(); + + // aktuell: br=5 bs=115200 cn=0 (=Com5) + //epi_setSerial(5,"115200","COM5",1); + // epi_setSerial(br, bs, cn, 1); + + // new: save values for next time + QByteArray myBA, tmpBA; + myBA.clear(); tmpBA.clear(); + myBA.append('s'); // start sign, not used + myBA.append(FILESEPERATOR); + tmpBA.setNum(br,10); + myBA.append(tmpBA); + myBA.append(FILESEPERATOR); + myBA.append(bs.toLatin1()); + myBA.append(FILESEPERATOR); + myBA.append(cn.toLatin1()); + myBA.append(FILESEPERATOR); + tmpBA.clear(); + tmpBA.setNum(ci,10); + myBA.append(tmpBA); + myBA.append(FILESEPERATOR); + + datei_clearFile(FILENAME_COMPORT); + datei_writeToFile(FILENAME_COMPORT, myBA); + qDebug() << "winComPort opening serial with: " << br << " " << bs << " " << cn; + HWaccess->dc_openSerial(br, bs, cn, 1);// same function with hwapi + // void dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) + // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 + // BaudStr: for exapmle "19200" + // ComName: for example "COM48" + // connect: 0, 1 + + emit connectButtonPressed(); +} + +void T_winComPort::callCloseSerial() +{ + HWaccess->dc_closeSerial(); + // epi_closeSerial(); // same function without hwapi + emit closeButtonPressed(); +} + +void T_winComPort::callAutoSend() +{ + if (AutSendButton->isChecked()) + { + HWaccess->dc_autoRequest(1); + emit autoSendButtonIsOn(); + } else + { + HWaccess->dc_autoRequest(0); + + emit autoSendButtonIsOff(); + } + +} + +void T_winComPort::callRefresh(void) +{ + subPortInfo(); +} + +void T_winComPort::callConnectToggle() +{ + if (connectButton->isChecked()) + { + //qDebug() << "down"; + + callOpenSerial(); + } else + { + //qDebug() << "released"; + callCloseSerial(); + } + +} + +void T_winComPort::getDcTestRS232() +{ + //qDebug() << "request test response..."; + HWaccess->dc_requTestResponse(); + + +} + + +void T_winComPort::newBaud(void) +{ + + qDebug() << "new baud selected..."; + +} + +void T_winComPort::setButtons4autoStart() +{ + connectButton->setEnabled(true); + connectButton->setDown(true); + connectButton->setChecked(true); + + AutSendButton->setEnabled(true); + AutSendButton->setDown(true); + AutSendButton->setChecked(true); + + +} + + +T_winComPort::T_winComPort(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + this->HWaccess = HWaccess; + + myTabComLayout = new QGridLayout; + //QGridLayout *myGridLayout = new QGridLayout(); + + // Ãœberschrift linke Spalte + QLabel *portListLabel2 = new QLabel(tr("in System available Ports:")); + myTabComLayout->addWidget(portListLabel2, 0,0); + + // Ãœberschrift rechte Spalte + QLabel *lab_headlineR = new QLabel(tr("Serial traffic:")); + myTabComLayout->addWidget(lab_headlineR, 0, 1); + + subPortInfo(); + // sende-empfangs-Rohdaten-Fenster, 2. Zeile rechts + myDiagWindow = new Console(); + myDiagWindow->setReadOnly(true); + myDiagWindow->setEnabled(true); + //myDiagWindow->setLocalEchoEnabled(p.localEchoEnabled); + //myDiagWindow->setMinimumWidth(300); + //myDiagWindow->putData("ongoing serial traffic: "); + myTabComLayout->addWidget(myDiagWindow, 1,1); + +// links: + // refresh button: + refreshButton = new QPushButton(tr("&refresh")); + refreshButton->setCheckable(false); // true = toggle button + refreshButton->setAutoDefault(false); // beim start aus + //refreshButton->setMaximumWidth(90); + myTabComLayout->addWidget(refreshButton, 2,0); + //connect(refreshButton, &QAbstractButton::clicked, this, &T_fenster01::callRefresh); + connect(refreshButton, SIGNAL(clicked()), this, SLOT(callRefresh())); + + + QLabel *Label3 = new QLabel(tr("Port:")); + myTabComLayout->addWidget(Label3, 3,0); + + + + QLabel *Label4 = new QLabel(tr("Baud:")); + myTabComLayout->addWidget(Label4, 5,0); + + // ComboBox Baudrate: + QFont my2CBfont; + //my2CBfont.setBold(true); + my2CBfont.setPixelSize(15); +/* + CB_baudSel = new QComboBox(); + CB_baudSel->addItem(tr("1200")); + CB_baudSel->addItem(tr("9600")); + CB_baudSel->addItem(tr("19200")); + CB_baudSel->addItem(tr("38400")); + CB_baudSel->addItem(tr("57600")); + CB_baudSel->addItem(tr("115200")); + CB_baudSel->setMinimumHeight(30); + CB_baudSel->setMaximumWidth(150); + CB_baudSel->setFont(my2CBfont); + CB_baudSel->setCurrentIndex(5); // default 115k baud + //CB_baudSel->setCurrentIndex(1); // default 9600 baud + myTabComLayout->addWidget(CB_baudSel, 6,0); + //connect(CB_baudSel, SIGNAL(currentIndexChanged(int)), this, SLOT(newBaud())); + connect(CB_baudSel, SIGNAL(currentIndexChanged(int)), this, SLOT(newBaud())); +*/ + // Statuszeile COM Port (serial Port) + LabelComState = new QLabel(tr("not connected")); + myTabComLayout->addWidget(LabelComState, 7,0); + + // Connect button: + connectButton = new QPushButton(tr("&Connect")); + connectButton->setCheckable(true); // true = toggle button + connectButton->setAutoDefault(true); // beim start ein + connectButton->setMaximumWidth(90); + connectButton->setMinimumHeight(50); + myTabComLayout->addWidget(connectButton, 8,0); + //connect(connectButton, &QAbstractButton::clicked, this, &T_fenster01::callConnectToggle); + connect(connectButton, SIGNAL(clicked()), this, SLOT(callConnectToggle())); + + +// rechts: + + // test serial line: + TestButton = new QPushButton(tr("test Connection")); + TestButton->setMaximumWidth(150); + myTabComLayout->addWidget(TestButton,2,1); + TestButton->setCheckable(false); // true = toggle button + TestButton->setAutoDefault(false); // beim start aus +// connect(TestButton, &QAbstractButton::clicked, this, &T_fenster01::getDcTestRS232); + connect(TestButton, SIGNAL(clicked()), this, SLOT(getDcTestRS232())); + + // I Statuszeile Handshakes (serial Control) flow.cpp + // geht überhaupt was raus? kommt überhaupt was zurück? + //LabelHandshakes = new QLabel(tr("control line")); + LabelHandshakes = new QLabel("HS"); // not used + myTabComLayout->addWidget(LabelHandshakes, 3,1); + + // II Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) + LabelRecieveFrame = new QLabel(tr("slave receive")); + myTabComLayout->addWidget(LabelRecieveFrame, 4,1); + + // III Anzeige der Slave-Results (Datif) + LabelResults = new QLabel(tr("results line")); + myTabComLayout->addWidget(LabelResults, 5,1); + + // IV Statuszeile Sende- und Empfangsdaten brauchbar? (Datif) + LabelDataState = new QLabel(tr("datif line")); + myTabComLayout->addWidget(LabelDataState, 6,1); + + // V + LabelDatif = new QLabel(tr("datif line")); + myTabComLayout->addWidget(LabelDatif, 7,1); + + // Autosend: + AutSendButton = new QPushButton(tr("&Automatic reading")); // &A --> also keycode Alt-A possible + //AutSendButton->setMaximumWidth(90); + myTabComLayout->addWidget(AutSendButton,8,1); + AutSendButton->setCheckable(true); // true = toggle button + AutSendButton->setAutoDefault(true); // beim start aus + AutSendButton->setMinimumHeight(50); +// connect(AutSendButton, &QAbstractButton::clicked, this, &T_fenster01::callAutoSend); + connect(AutSendButton, SIGNAL(clicked()), this, SLOT(callAutoSend())); + + setLayout(myTabComLayout); + myNextStep=0; + myStep=0; + callConnectToggle(); + callAutoSend(); + + myTO = new QTimer(); + myTO->setSingleShot(true); + myTO->start(2000); + + +} + +// not needed: +T_winComPort::~T_winComPort() +{ + close(); +} + +void T_winComPort::Nav_back(void) +{ + myNextStep=WCS_WIN01BAK; +} +void T_winComPort::Nav_home(void) +{ + myNextStep=WCS_WIN01MID; +} +void T_winComPort::Nav_next(void) +{ + myNextStep=WCS_WIN01FWD; +} + +bool T_winComPort::work_ini(uint16_t *nextScreen, uint8_t *useNavi) +{ + // one state of the vending/operating FSM + // called ONE time after selecting this state (initialization) + // useNavi=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + + *nextScreen=0; // needed 0=no change +// *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_ON; + *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_OFF; // bei CArun alle aus + return false; +} + +bool T_winComPort::working(uint16_t *nextScreen, uint8_t *useNavi) +{ + // one state of the vending/operating FSM + // called cyclic until this state changes intentionally to another state + // display informations for human operator, react on operators inputs or wait for payment media + + // useNavi=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + + this->updateGui(); + *nextScreen=0; // 0=no change + *useNavi=0; + + if (myStep==0) + { + // load and use last settings: -------------------- + QByteArray myBA; + myBA=datei_readFromFile(FILENAME_COMPORT); + + //uint32_t len= datei_nrOfEntriesInFile(myBA); + //uint64_t ulltmp=csv_getEntryAs2Ulong(myBA,0); + //qDebug()<<"win_startup load long numer: "<dc_openSerial(br,bs,cn,1); + //CB_baudSel->setCurrentIndex(br); // im BR auswahlfenster diese Baud vorgeben + CB_portSel->setCurrentIndex(ci); // den Port aus der Datei hier vorgeben + connectButton->setChecked(true); // connect Taste "druecken" + + myTO->start(100); // restart + myStep++; + } else + + if (myStep==1) + { + if (!myTO->isActive()) + { + if (HWaccess->dc_isPortOpen()) + myStep++; + else + myStep=99; // stop automatic connection and wait for manual start + myTO->start(100); + } + } else + + if (myStep==2) + { + if (!myTO->isActive()) + { + HWaccess->dc_requTestResponse(); + myStep++; + myTO->start(100); + } + } else + + if (myStep==3) + { + if (!myTO->isActive()) + { + if (HWaccess->dc_readAnswTestResponse()) + myStep++; // response was correct + else + myStep=99; // stop automatic connection and wait for manual start + myTO->start(100); + } + + } else + + if (myStep==4) + { + HWaccess->dc_autoRequest(1); + AutSendButton->setChecked(true); // taste "druecken" + myStep++; + } else + + if (myStep==5) + { + // got next screen: + //myNextStep=2; // nicht bei CArun + myStep++; + + } else + + if (myStep==6) + { + // stop here, everything done + } else + + if (myStep==7) + { + + } else + { + + } + + if (myNextStep) + { + //qDebug()<<"fenster1 working: "<< myNextStep; + *nextScreen=myNextStep; + myNextStep=0; + } + return false; +} + + +void T_winComPort::updateGui(void) +{ + QByteArray myBA; + QString ms; + + ms=HWaccess->dc_getTxt4RsDiagWin(); + if (ms.length()>1) // sonst ständig scrolling + { + myDiagWindow->putText(ms); + HWaccess->dc_clrTxt4RsDiagWin(); + } + + ms=HWaccess->dc_get2ndTxt4RsDiagWin(); + if (ms.length()>1) // sonst ständig scrolling + { + myDiagWindow->putText(ms); + HWaccess->dc_clr2ndTxt4RsDiagWin(); + } + + // state of the COM Port (open, closed) + ms=HWaccess->dc_getSerialState(); + if (ms.length()>1) // sonst ständig scrolling + { + LabelComState->setText(ms); + } + + // -------------------------------------------------------------------------- + // I Statuszeile Handshakes (serial Control) + + ms=HWaccess->dc_getTxt4HsStateLine(); + if (!connectButton->isChecked()) + ms=""; + if (ms.length()>1) // sonst ständig scrolling + { + LabelHandshakes->setText(ms); + HWaccess->dc_clrTxt4HsStateLine(); + // clear to avoid multiple displaying + } + + + // II Master receive state (empfangenes Telgramm OK? crc? length? ) + // Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) + + ms=HWaccess->dc_getTxt4masterStateLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelRecieveFrame->setText(ms); + HWaccess->dc_clrTxt4masterStateLine(); + } + + + + // III Slave receive (from Master) OK? if then show results, if not then show errors + // entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR + // Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch + // nicht verwenden und nichts ausgeben oder einlesen + + ms=HWaccess->dc_getTxt4resultStateLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelResults->setText(ms); + HWaccess->dc_clrTxt4resultStateLine(); + } + + + // IV Statuszeile Empfangsdaten + + ms=HWaccess->dc_getdataStateLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelDataState->setText(ms); + HWaccess->dc_clrTxt4dataStateLine(); + // clear to avoid multiple displaying + } + + + // 5. Zeile: Datif Ergebnis, Daten brauchbar? + + ms=HWaccess->dc_getdatifLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelDatif->setText(ms); + HWaccess->dc_clrTxt4datifLine(); + } + + // ----------------------------------------------------------------------------- + +} + + diff --git a/CArunGUI/win01_com.h b/CArunGUI/win01_com.h new file mode 100755 index 0000000..c535948 --- /dev/null +++ b/CArunGUI/win01_com.h @@ -0,0 +1,107 @@ +#ifndef WINCOMPORT_H +#define WINCOMPORT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include "tslib.h" +//#include "stepList.h" // define all working chain steps here +//#include "datei.h" +#include "plugin.h" +//#include "globVars.h" + +class Console : public QPlainTextEdit +{ + Q_OBJECT + +public: + explicit Console(QWidget *parent = nullptr); + + void putData(const QByteArray &data); + void putText(QString text); +}; + +class T_winComPort : public QWidget // former TabComport +{ + Q_OBJECT + Console *myDiagWindow; // Ausgabefenster + QComboBox *CB_portSel; + //QComboBox *CB_baudSel; + QPushButton *connectButton; + QPushButton *AutSendButton; + QPushButton *TestButton; + QPushButton *refreshButton; + + QLabel *LabelComState; // Statusanzeige + QLabel *LabelPort; + QLabel *LabelHandshakes; + QLabel *LabelRecieveFrame; + QLabel *LabelResults; + QLabel *LabelDataState; + QLabel *LabelDatif; + + QGridLayout *myTabComLayout; + void subPortInfo(); + hwinf *HWaccess; + void updateGui(void); + uint16_t myNextStep; + uint8_t myStep; + QTimer *myTO; + +private slots: + void callOpenSerial(); + void callCloseSerial(); + void callAutoSend(); + //void tabComTime100ms(); + void callConnectToggle(); + void getDcTestRS232(); + void callRefresh(void); + +public: + explicit T_winComPort(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + bool work_ini(uint16_t *nextScreen, uint8_t *useNavi); + // useNavi=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + bool working (uint16_t *nextScreen, uint8_t *useNavi); + ~T_winComPort(); + + void writeRSdiagBytes(const QByteArray &bytarray); + void writeRSdiagText(QString text); + void writeComState(const QString text); + void writeDataState(const QString text); + void setButtons4autoStart(); + +signals: + void connectButtonPressed(); + void closeButtonPressed(); + void autoSendButtonIsOn(); + void autoSendButtonIsOff(); + +private slots: + void newBaud(void); // just for test + +public slots: + void Nav_back(void); + void Nav_home(void); + void Nav_next(void); + +}; + +#endif diff --git a/DCLibraries.pri b/DCLibraries.pri new file mode 100644 index 0000000..7d0008a --- /dev/null +++ b/DCLibraries.pri @@ -0,0 +1,118 @@ +CONFIG += plugin +QT -= gui +QT += widgets serialport + +win32 { + BUILD_DATE=$$system("date /t") + BUILD_TIME=$$system("time /t") +} else { + BUILD_DATE=$$system("date +%d-%m-%y") + BUILD_TIME=$$system("date +%H:%M:%S") +} + +GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1") + +EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}" + +INCLUDEPATH += $${PWD}/include + +DEPENDPATH += $${PWD} +DESTDIR=$${_PRO_FILE_PWD_}/build + +CONFIG += c++11 + +DEFINES+=APP_VERSION=\\\"$$VERSION\\\" +DEFINES+=APP_BUILD_DATE=\\\"$$BUILD_DATE\\\" +DEFINES+=APP_BUILD_TIME=\\\"$$BUILD_TIME\\\" +DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\" + +# keep comments, as /* fall through */ +QMAKE_CXXFLAGS += -C +# _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp] +QMAKE_CXXFLAGS += -O +QMAKE_CXXFLAGS += -g +QMAKE_CXXFLAGS += -Wno-deprecated-copy + +# default +ARCH = PTU5 +CONFIG += PTU5 + +contains( CONFIG, DesktopLinux ) { + # QMAKE_CC = ccache $$QMAKE_CC + # QMAKE_CXX = ccache $$QMAKE_CXX + QMAKE_CXXFLAGS += -std=c++17 + # QMAKE_CXXFLAGS += -Wno-deprecated-ctor + linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments } + ARCH = DesktopLinux +} + +contains( CONFIG, PTU5 ) { + # QMAKE_CC = ccache $$QMAKE_CC + # QMAKE_CXX = ccache $$QMAKE_CXX + QMAKE_CXXFLAGS += -std=c++17 + linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments } + CONFIG += link_pkgconfig + ARCH = PTU5 +} + +contains( CONFIG, PTU5_YOCTO ) { + greaterThan(QT_MAJOR_VERSION, 4): QT += serialport + PTU5BASEPATH = /opt/devel/ptu5 + ARCH = PTU5 + # add qmqtt lib + #LIBS += -lQt5Qmqtt +} + +HEADERS += \ + $${PWD}/include/com.h \ + $${PWD}/include/datei.h \ + $${PWD}/include/runProc.h \ + $${PWD}/include/controlBus.h \ + $${PWD}/include/datIf.h \ + $${PWD}/include/dcBL.h \ + $${PWD}/include/hwapi.h \ + $${PWD}/include/interfaces.h \ + $${PWD}/include/prot.h \ + $${PWD}/include/sendWRcmd.h \ + $${PWD}/include/storeINdata.h \ + $${PWD}/include/tslib.h \ + $${PWD}/include/shared_mem_buffer.h + +SOURCES += \ + $${PWD}/src/com.cpp \ + $$PWD/src/datei.cpp \ + $$PWD/src/runProc.cpp \ + $$PWD/src/main.cpp \ + $${PWD}/src/controlBus.cpp \ + $${PWD}/src/datIf.cpp \ + $${PWD}/src/dcBL.cpp \ + $${PWD}/src/hwapi.cpp \ + $${PWD}/src/prot.cpp \ + $${PWD}/src/sendWRcmd.cpp \ + $${PWD}/src/storeINdata.cpp \ + $${PWD}/src/tslib.cpp \ + $${PWD}/src/shared_mem_buffer.cpp + + +# INTERFACE = DeviceController +# INTERFACE_DEFINITION = $${PWD}/include/ATBAPP/DeviceControllerInterface.h +# +# DISTFILES += \ +# generate-version.sh + + +# Define how to create version.h +# VERSION_H = $$PWD/include/version.h +# version.output = $$PWD/include/version.h +# version.commands = $$PWD/generate-version.sh $${ARCH} $${TARGET} $${INTERFACE} $${INTERFACE_DEFINITION} $${VERSION_H} +# version.depends = FORCE +# version.input = VERSION_H +# version.variable_out = HEADERS +# QMAKE_EXTRA_COMPILERS += version +# QMAKE_CLEAN += $${PWD}/include/version.h + + +# 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/DCLibraries.pro b/DCLibraries.pro new file mode 100644 index 0000000..d04d005 --- /dev/null +++ b/DCLibraries.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = lib_ca_master lib_ca_slave CArunGUI dCArun + +CArunGUI.depends = lib_ca_master lib_ca_slave +dCArun.depends = lib_ca_master lib_ca_slave diff --git a/dCArun/dCArun.pro b/dCArun/dCArun.pro new file mode 100644 index 0000000..e39fb62 --- /dev/null +++ b/dCArun/dCArun.pro @@ -0,0 +1,58 @@ +QT += core gui +QT +=widgets serialport +QT +=network + # for TCP-IP + +TARGET = dCArun +DESTDIR=$${_PRO_FILE_PWD_}/../build + + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++11 +CONFIG += PTU5 + +# _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp] +QMAKE_CXXFLAGS += -O + +INCLUDEPATH += ../include + + +win32 { + BUILD_DATE=$$system("date /t") + BUILD_TIME=$$system("time /t") +} else { + BUILD_DATE=$$system("date +%d-%m-%y") + BUILD_TIME=$$system("date +%H:%M:%S") +} + +GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1") + +EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}" + +DEFINES+=APP_VERSION=\\\"$$VERSION\\\" +DEFINES+=APP_BUILD_DATE=\\\"$$BUILD_DATE\\\" +DEFINES+=APP_BUILD_TIME=\\\"$$BUILD_TIME\\\" +DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\" + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + tslib.cpp \ + win01_com.cpp \ + datei.cpp + +HEADERS += \ + guidefs.h \ + mainwindow.h \ + stepList.h \ + tslib.h \ + versionHistory.txt \ + win01_com.h \ + datei.h \ + plugin.h + +# 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/dCArun/datei.cpp b/dCArun/datei.cpp new file mode 100755 index 0000000..69a3812 --- /dev/null +++ b/dCArun/datei.cpp @@ -0,0 +1,944 @@ +// written by Thomas Sax, Jan.2022 +#include "datei.h" + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +QByteArray datei_writeArray, datei_tempArray; + +void csv_startCreatingFile(void) +{ + datei_writeArray.clear(); + datei_tempArray.clear(); +} + +void csv_addTextToFile(QString myText) +{ + datei_writeArray.append(myText.toLatin1()); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addIntToFile(int myValue) +{ + //qulonglong ullt=12345678901234567890; // max 1,844 x10^19 + datei_tempArray.setNum(myValue,10); // accepted types: short, ushort, int, uint, + // qlonglong, qulonglong, float, double + // numerbase can be 2...36(!),10=dec + + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addUintToFile(uint myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + + +void csv_addLongvalToFile(qlonglong myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addUlongvalToFile(qulonglong myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +/* +void csv_addCurrentTimeToFile(void) +{ + uint8_t hour, minute, sec, ui8buf[20]; + char buf[20]; + + config_getSysTime(&hour, &minute, &sec); + GetTimeString(hour, minute, sec, 0, 1, ui8buf); + for (uint8_t nn=0; nn<20; nn++) + buf[nn]=char(ui8buf[nn]); + datei_writeArray.append(buf,8); // time string + datei_writeArray.append(FILESEPERATOR); + +} + +void csv_addCurrentDateToFile(void) +{ + uint16_t year; + uint8_t month, day, ui8buf[20]; + char buf[20]; + + config_getSystemDate(&year, &month, &day); + //qDebug()<<"date year: "<1) + filSize=uint32_t(filLen); + else + return 0; + + // 1) find position of seperators + for (uint32_t ii=0; iiMAXNUMBEROFSEQUENCES) + return ""; + + // 1) find position of seperators + for (ii=0; ii0) + { + start=sepPos[sequNr-1]+1; + ende=sepPos[sequNr]; + } + + //qDebug()<<"datei getOneFileSequence start/ende: "<=ende) + return ""; + //return "-err3-"; + sequence.clear(); + //batmp.clear(); + pp=0; + for (ii=start; ii=int(filSize)) + mm=0; + oneByt=sourceFile.at(mm); + sequence.append(oneByt); + } + return sequence; +} + +int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA, myVA; + int entry=0; + bool ok; + + myVA.clear(); + myBA = csv_getOneFileSequence(sourceFile, sequNr); + //qDebug()<<"datei getEntryAsInt, sequence: " << myBA; + + entry=myBA.toInt(&ok,16); + if (ok) + { + //qDebug()<<"datei getEntryAsInt, number: " << entry; + return entry; + } + //qDebug()<<"datei getEntryAsInt, error " << myBA; + return 0; +} + +int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + long entry=0; + bool ok; + + entry=myBA.toLong(&ok,10); + if (ok) + return entry; + return 0; +} + +uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint8_t entry=0; + bool ok; + + entry=uint8_t(myBA.toUShort(&ok,10)); + if (ok) + return entry; + return 0; +} + +uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint16_t entry=0; + bool ok; + + entry=uint16_t(myBA.toUInt(&ok,10)); + if (ok) + return entry; + return 0; +} + +uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint32_t entry=0; + bool ok; + + entry=myBA.toULong(&ok,10); + if (ok) + return entry; + return 0; +} + +uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint64_t entry=0; + bool ok; + + entry=myBA.toULongLong(&ok,10); + if (ok) + return entry; + return 0; +} + + + +QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + QString entry; + + //qDebug()<<"datei getEntryAsString, sequence: " << myBA; + entry=myBA.toStdString().c_str(); + return entry; +} + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create Json file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +/* + example +QString str = "{" + " \"Herausgeber\": \"Xema\"," + " \"Nummer\": \"1234-5678-9012-3456\"," + " \"Deckung\": 2e+6," + " \"Währung\": \"EURO\"," + " \"Inhaber\": {" + " \"Name\": \"Mustermann\"," + " \"Vorname\": \"Max\"," + " \"männlich\": true," + " \"Hobbys\": [ \"Reiten\", \"Golfen\", \"Lesen\" ]," + " \"Alter\": 42," + " \"Kinder\": []," + " \"Partner\": null" + " }" + "}"; + +*/ + +QString myJsonCon; +QString tmpStr; + +void json_startRecord(void) +{ + myJsonCon.clear(); + tmpStr.clear(); + myJsonCon.append('{'); +} + +void json_enterIntToRecord(QString attribute, ulong i_value) +{ + tmpStr.clear(); + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + tmpStr.setNum(i_value); + myJsonCon.append(tmpStr); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); +} + +void json_enterTextToRecord(QString attribute, QString txt_value) +{ + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + myJsonCon.append(txt_value); + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); +} +/* +void json_addCurrentTimeToRecord(QString attribute) +{ + uint8_t hour, minute, sec, ui8buf[20]; + //char buf[20]; + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + + datei_getSysTime(&hour, &minute, &sec); + GetTimeString(hour, minute, sec, 0, 1, ui8buf); + for (uint8_t nn=0; nn<8; nn++) + myJsonCon.append(ui8buf[nn]); + + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); + +} + +void json_addCurrentDateToRecord(QString attribute) +{ + uint16_t year; + uint8_t month, day, ui8buf[20]; + //char buf[20]; + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + + datei_getSystemDate(&year, &month, &day); + GetDateString(day, month, 0x20, uint8_t(year%100), 0, 0, ui8buf); + for (uint8_t nn=0; nn<10; nn++) + myJsonCon.append(ui8buf[nn]); + + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); + +} +*/ + +void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals) +{ + // add array of numbers with "nrofVals" elements + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('['); // eckig!!! + for (ulong ul=0; ulMAXNROFARRAYVALUES) + nrOfPairs=MAXNROFARRAYVALUES; + + for (ii=0; iiMaxBufferSize) + { + ok=false; // got not all + nrOfPairs=MaxBufferSize; + } + for (int ii=0; ii +#include +#include +#include +#include "tslib.h" +#include +#include +#include +#include +#include + + // create csv file with: +#define FILESEPERATOR ',' + + // pasre csv with: +#define FILESEP1 ',' +#define FILESEP2 ';' + +#define NEWLINEINFILE '\n' +#define MAXNUMBEROFSEQUENCES 200 + // only for csv files + + +// all seting-files located in sudirectory "static machine data - smd" +// all generated files located in sudirectory "dynamic machine data - dmd" + +#define FILENAME_COMPORT "../comport.csv" +#define FILENAME_CONFIG "/own/work2023/PSA1256ptu5/smd/DC2C_conf.json" +#define FILENAME_DEVICE "/own/work2023/PSA1256ptu5/smd/DC2C_device.json" +#define FILENAME_CASH "/own/work2023/PSA1256ptu5/smd/DC2C_cash.json" +#define FILENAME_PRINT "/own/work2023/PSA1256ptu5/smd/DC2C_print32.json" +#define FILENAME_APSERVCONF "../APserviceConfig.csv" + + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + + +// create array with strings and values (to be written to file) +void csv_startCreatingFile(void); +void csv_addTextToFile(QString myText); +void csv_addIntToFile(int myValue); +void csv_addUintToFile(uint myValue); +void csv_addLongvalToFile(qlonglong myValue); +void csv_addUlongvalToFile(qulonglong myValue); +//void csv_addCurrentTimeToFile(void); +//void csv_addCurrentDateToFile(void); +void csv_addNewlineToFile(void); +QByteArray csv_readbackArray(void); + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ parse csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + + +// return number of entries in the just read file (entries are seperated by +// comma or line-feed) +uint32_t csv_nrOfEntriesInFile(QByteArray readFromFile); + +// before: QByteArray sourceFile=datei_readFromFile(filename); + +QByteArray csv_getOneFileSequence(QByteArray sourceFile, uint32_t sequNr); +// not needed, just for test // sequNr: 0....(size-1) + +// get single entries of of the just read fie: +int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create Json Record ------------------------------- +// ------------------------------------------------------------------------------------------------- + +void json_startRecord(void); + // clear buffer and write opening curly bracket { + +void json_enterIntToRecord(QString attribute, ulong i_value); + // example: "parameter":1234567890 + +void json_enterTextToRecord(QString attribute, QString txt_value); + // example: "parameter":"slow" + +//void json_addCurrentTimeToRecord(QString attribute); + // example: if attribute=myTime: "myTime":"hh_mm_ss" + +//void json_addCurrentDateToRecord(QString attribute); + // example: if attribute=myDate: "myDate":"dd.mm.yyyy" + // also / possible as seperator + // further possible forms: + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + +void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals); + // add array of numbers with "nrofVals" elements + +void json_enterStructToRecord(QString attribute); + // every call must be concluded with an extra "json_finishFile()" + // example: "sname":{ + +void json_finishStruct(void); + +void json_finishRecord(void); + // close curly bracket + + +QString json_readbackRecordStr(void); + +QByteArray json_readbackRecordBa(void); + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ parse Json file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +// first: QByteArray datei_readFromFile(QString filename); + +//void datei_json_readTestFile(QString filename); + +int json_nrOfPairsInFile(QByteArray filename); + +bool json_exists(QByteArray filename, QString searchForKey); + // look for "searchForKey" =name of the pair (left of : ) + // retval true if exists + +bool json_remove(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and remove the record from file + // retval true if removed + +QString json_searchForStringInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_searchForIntInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +//....................... + +QJsonObject json_searchForObjectInFile(QByteArray filename, QString searchFor); + // return an object from the json file + +int json_nrOfPairsInObject(QJsonObject objname); + +QString json_searchForStringInObject(QJsonObject objname, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_searchForIntInObject(QJsonObject objname, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +//....................... + +QJsonArray json_searchForArrayInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_nrOfValuesInArray(QJsonArray arrayname); + +bool json_getValuesOfArray(QJsonArray arrayname, int *buf, int MaxBufferSize); + // assuming that the array consists of integers + + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ read, write, copy files ------------------- +// ------------------------------------------------------------------------------------------------- + +void datei_closeFile(QString filename); + +// read content of an exiting file: +QByteArray datei_readFromFile(QString filename); + +bool datei_ifFileExists(QString filename); + +char datei_writeToFile(QString filename, QByteArray content); + // retval=0 if successful 1: no write access allowed + // 2:cannot open to append 3:cannot create new file + +bool datei_copyFile(QString currentFileName, QString newFileName); + // retval=true if successful + +bool datei_clearFile(QString filename); + // retval=true if successful + +#endif // DATEI_H diff --git a/dCArun/guidefs.h b/dCArun/guidefs.h new file mode 100755 index 0000000..fb65802 --- /dev/null +++ b/dCArun/guidefs.h @@ -0,0 +1,24 @@ +#ifndef GUIDEFS_H +#define GUIDEFS_H + +#define PIXELSIZE_BUTTONS 18 +#define PIXELSIZE_LABEL 18 +#define PIXELSIZE_DATA 16 + +#define PIXELSIZE_BIGFONT 22 +#define PIXELSIZE_SMALLFONT 14 + +#define BUTTONCOLOR "background-color: rgb(150,250,150)" + +#define COLORGREEN "background-color: rgb(160,250,190)" +#define COLOR_RED "background-color: rgb(150,0,0)" +#define COLOR_LIGHTRED "background-color: rgb(250,150,150)" +//#define COLORGREY "background-color: rgb(160,250,190)" +#define COLORGREY "background-color: grey" +#define COLORYELLOW "background-color: yellow" +#define COLORWHITE "background-color: white" + +// "background-color: lightgrey" + + +#endif diff --git a/dCArun/main.cpp b/dCArun/main.cpp new file mode 100755 index 0000000..f7a4eac --- /dev/null +++ b/dCArun/main.cpp @@ -0,0 +1,43 @@ +#include "mainwindow.h" +//#include "message_handler.h" +#include + +int thisisglobal; + +int main(int argc, char *argv[]) +{ + int ret; + QApplication myapp(argc, argv); + QApplication::setApplicationName("CArunGui"); + QApplication::setApplicationVersion(APP_VERSION); + +/* + if (!messageHandlerInstalled()) { // change internal qt-QDebug-handling + atbInstallMessageHandler(atbDebugOutput); + setDebugLevel(QtMsgType::QtDebugMsg); + //setDebugLevel(QtMsgType::QtDebugMsg); + } +*/ + MainWindow myMainWin; + QSize myMainSize={800, 480}; // breite, höhe, PTU: 800x440 + myMainWin.setMinimumSize(myMainSize); + myMainWin.setMaximumSize(myMainSize); + myMainWin.setWindowTitle("CArun_V4.2 run cash agent master lib"); + //myMainWin.show(); + + ret=myapp.exec(); + + return ret; +} + + + +//QApplication a(argc, argv); +//MainWindow CatMW; +//QSize myMainSize={800, 480}; // breite, höhe +//CatMW.setMinimumSize(myMainSize); +//CatMW.setMaximumSize(myMainSize); +//CatMW.setWindowTitle("ATB CashAgent V2.0"); +// QPalette mainPal; +// mainPal.setColor(QPalette::Window, Qt::red ); +// CatMW.setPalette(mainPal); sieht man nicht mehr diff --git a/dCArun/mainwindow.cpp b/dCArun/mainwindow.cpp new file mode 100755 index 0000000..e7ebc86 --- /dev/null +++ b/dCArun/mainwindow.cpp @@ -0,0 +1,438 @@ +#include "mainwindow.h" + +char MainWindow::loadPlugIn(char lade1_entlade2) +{ + plugInDir.cd("plugins"); + QPluginLoader *pluginLoader = new QPluginLoader(); + +// select system: + //pluginLoader->setFileName("../MasterPlug/libCAmaster.so"); // for suse + //pluginLoader->setFileName("../SlavePlug/libCAslave.so"); // for ptu5 + //pluginLoader->setFileName("../../MasterPlug/CAmaster.dll"); // for windows + pluginLoader->setFileName("CAmaster.dll"); // for windows + + if (lade1_entlade2==2) + { + pluginLoader->unload(); + return 0; + } + + if (!pluginLoader->load()) + { + qDebug()<<"cannot load plugin"; + } else + qDebug() <<"loaded plugin: " << pluginLoader->fileName(); + + if (!pluginLoader->isLoaded()) + { + qDebug()<errorString(); + return 0; + } + + QObject *plugin = pluginLoader->instance(); + if ( plugin == nullptr) + { + // make instance of the root component (which can hold more then one clases) + // also loads the lib if not yet done + qDebug()<<"cannot start instance"; + return 0; + } + + //int rr=hwapi->giveVal(2); funktioniert :)) + //qDebug()<<"got value from plugin"<(plugin); + // make instance to class "hwinf" in dll_HWapi.h over "interfaces.h" + + qDebug()<<"loadPlugIn, HWAccess: " << HWaccess; + return 0; + +} + + + + +#define WINCTRMIN 0 + // 0 is always the home screen + +#define WINCTRMAX 30 + // number of needed application screens, up to 255 + // All screens must be defined below in mainwindow-class first before increasing the nr + // numbers must be consecutively from 0 always, 0 is the home screen always + +#define FORMWIDTH 725 +//#define FORMWIDTH 690 + // this width is the same for ALL windows + +#define FORMHEIGHT 440 +// this height is the same for ALL windows + +#define NAVIBUTTONHEIGHT 70 +#define NAVIBUTTONWIDHT 50 + +#define HOMEPAGE_BACKGROUND_COLOR "background-color: lightgrey" + +#define BUTTON_COLOR "background-color: rgb(160,250,190)" + +#define ACTIVE_NAVI_COLOR "background-color: rgb(160,250,190)" +#define DISABL_NAVI_COLOR "background-color: grey" + +#define APPPAGE_BACKGROUND_COLOR "background-color: lightgrey" + +#define UPDATE_PERIOD_MS 100 + // period to call chain steps + +#define VENDINGTIMEOUT_MS 30000 + // after this time without any operation the program returns to idle state + // time in ms, that means 30.000 gives 30seconds + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) +{ + loadPlugIn(1); + + // define all working moduls (besides gui) here, call ini and working in chainControl() (~Line 1000) + //mifCard = new T_Mifare(HWaccess); // ganz wichtig: HWaccess an sub-Konstruktor übergeben + // sonst crash bei HW-Zugriff!!!! + //diary = new T_lib_diary(); absturz!!!!!! + //conf = new T_lib_config(HWaccess); + + timerChainCtrl = new QTimer(this); + connect(timerChainCtrl, SIGNAL(timeout()), this, SLOT(chainControl())); + timerChainCtrl->setSingleShot(0); + timerChainCtrl->start(UPDATE_PERIOD_MS); // 1000: call every 1000ms + + timerVendingTimeout = new QTimer(this); + connect(timerVendingTimeout, SIGNAL(timeout()), this, SLOT(vendingTimeout())); + timerVendingTimeout->setSingleShot(true); + timerVendingTimeout->start(VENDINGTIMEOUT_MS); // in ms + + // ########################################################################################## + // für jedes anzuzeigende Fenster eine eigene Groupbox mit eigenem Grid anlegen: + + frame01 = new QGroupBox; + frame01->setStyleSheet(APPPAGE_BACKGROUND_COLOR); + frame01->setMinimumSize(FORMWIDTH,FORMHEIGHT); + QVBoxLayout *smallLay01 = new QVBoxLayout; + frame01->setLayout(smallLay01); + // Fensterinhalt aus externer Klasse einfügen: + myFenster01 = new T_winComPort(HWaccess); // HWaccess damit auf das HW-Plugin zugegriffen werden kann, sonst crash + smallLay01->addWidget(myFenster01); + + // ########################################################################################## + // draw Mainwindow: + bigGroupbox = new QGroupBox; + bigGroupbox->setStyleSheet("background-color: grey"); + bigGroupbox->setMinimumSize(800,480); +// bigLayout = new QVBoxLayout; // navi buttons on bottom side + bigLayout = new QHBoxLayout; // navi buttons right hand + + // ########################################################################################## + // add all windows (but display only one) + // display only one: then all windows are shown at the same place + // display more then one: the windows are listed in vertical order + + bigLayout->addWidget(frame01); + + bigGroupbox->setLayout(bigLayout); + switchScreen(1); + //HideAllWindows(); + + // ########################################################################################## + // Steuer Leiste + + //QHBoxLayout *ButtonLayout = new QHBoxLayout(); + QVBoxLayout *ButtonLayout = new QVBoxLayout(); + QFont myTabFont; + myTabFont.setPixelSize(26); + + pBback = new QPushButton("<"); //b\na\nc\nk"); + pBback->setFont(myTabFont); + pBback->setStyleSheet(ACTIVE_NAVI_COLOR); + pBback->setMinimumHeight(NAVIBUTTONHEIGHT); + pBback->setMaximumWidth(NAVIBUTTONWIDHT); + connect(pBback, SIGNAL( clicked() ), myFenster01, SLOT( Nav_back())); + + myTabFont.setPixelSize(22); + pBhome = new QPushButton("<<"); //h\no\nm\ne"); + pBhome->setFont(myTabFont); + pBhome->setStyleSheet(ACTIVE_NAVI_COLOR); + pBhome->setMinimumHeight(NAVIBUTTONHEIGHT); + pBhome->setMaximumWidth(NAVIBUTTONWIDHT); + connect(pBhome, SIGNAL( clicked() ), myFenster01, SLOT( Nav_home())); + + myTabFont.setPixelSize(26); + pBforward = new QPushButton(">"); //n\ne\nx\nt"); + pBforward->setFont(myTabFont); + pBforward->setStyleSheet(ACTIVE_NAVI_COLOR); + pBforward->setMinimumHeight(NAVIBUTTONHEIGHT); + pBforward->setMaximumWidth(NAVIBUTTONWIDHT); + connect(pBforward, SIGNAL( clicked() ), myFenster01, SLOT( Nav_next())); + + QLabel *buttonSpace = new QLabel(" "); + ButtonLayout->addWidget(pBback); + ButtonLayout->addWidget(buttonSpace); + //ButtonLayout->addWidget(buttonSpace); + ButtonLayout->addWidget(pBhome); + ButtonLayout->addWidget(buttonSpace); + //ButtonLayout->addWidget(buttonSpace); + ButtonLayout->addWidget(pBforward); + QLabel *bottomSpace = new QLabel(" "); + ButtonLayout->addWidget(bottomSpace); + + bigLayout->addLayout(ButtonLayout); + + setCentralWidget(bigGroupbox); + + // AUTOSTART serial transmission + //HWaccess->dc_openSerial(5,"115200","ttyS0",1); // my suse computer + //HWaccess->dc_openSerial(1,"9600","COM5",1); // my suse computer + //HWaccess->dc_openSerial(5,"115200","ttymxc2",1); // ptu5 + //HWaccess->dc_autoRequest(true); + //myFenster01->setButtons4autoStart(); + //HWaccess->alarm_switchSiren(0); // test + + enableNaviButtons(BACKBUTTON,true); + enableNaviButtons(HOMEBUTTON,true); + enableNaviButtons(FORWBUTTON,true); + this->chainIni(); + + //connect(myFenster02, SIGNAL(quitMyApp()), this, SLOT(close())); + +} + +MainWindow::~MainWindow() +{ + loadPlugIn(2); +} + + +void MainWindow::HideAllWindows() +{ + // vorsicht: Fenster muss oben definiert sein sonst Programmabsturz ohne Kommentar + + frame01->setEnabled(false); + frame01->setVisible(false); +} + + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Call Windows +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void MainWindow::switchScreen(uint16_t winNr) // 0...30 +{ + + HideAllWindows(); + //qDebug()<<"switch screen to " << winNr; + + switch (winNr) + { + case 1: + frame01->setEnabled(true); + frame01->setVisible(true); + break; + default: + break; + + } + +} + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// Navigation buttons +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void MainWindow::enableNaviButtons(uint8_t switchBitwise) +{ + // switchBitwise=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + + if (switchBitwise &1) + { + pBforward->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBforward->setText("next"); + pBforward->setEnabled(true); + } else + if (switchBitwise &2) + { + pBforward->setStyleSheet(DISABL_NAVI_COLOR); + //pBforward->setText(" "); + pBforward->setEnabled(false); + } + + if (switchBitwise &4) + { + pBhome->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBhome->setText("home"); + pBhome->setEnabled(true); + } else + if (switchBitwise &8) + { + pBhome->setStyleSheet(DISABL_NAVI_COLOR); + //pBhome->setText(" "); + pBhome->setEnabled(false); + } + + if (switchBitwise &16) + { + pBback->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBback->setText("back"); + pBback->setEnabled(true); + } else + if (switchBitwise &32) + { + pBback->setStyleSheet(DISABL_NAVI_COLOR); + //pBback->setText(" "); + pBback->setEnabled(false); + } + + + +} + +void MainWindow::enableNaviButtons(uint8_t buttonNr, bool enabled) +{ + if (buttonNr==1) + { + if (enabled) + { + pBback->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBback->setText("back"); + pBback->setEnabled(true); + } else + { + pBback->setStyleSheet(DISABL_NAVI_COLOR); + //pBback->setText(" "); + pBback->setEnabled(false); + } + } else + if (buttonNr==2) + { + if (enabled) + { + pBhome->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBhome->setText("home"); + pBhome->setEnabled(true); + } else + { + pBhome->setStyleSheet(DISABL_NAVI_COLOR); + //pBhome->setText(" "); + pBhome->setEnabled(false); + } + } else + if (buttonNr==3) + { + if (enabled) + { + pBforward->setStyleSheet(ACTIVE_NAVI_COLOR); + //pBforward->setText("next"); + pBforward->setEnabled(true); + } else + { + pBforward->setStyleSheet(DISABL_NAVI_COLOR); + //pBforward->setText(" "); + pBforward->setEnabled(false); + } + } + +} + + + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// control work flow by Finite state machine +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +static uint16_t chainCurrentStep, chainNextStep; +static bool chain_stepIni; + +void MainWindow::chainIni(void) +{ + // called once after power-up by constructor + chainCurrentStep=WCS_STARTSCREEN; // start screen + chainNextStep=chainCurrentStep; + switchScreen(chainCurrentStep); + chain_stepIni=true; +//qDebug()<<"chain ini, call step "<stop(); + timerVendingTimeout->start(VENDINGTIMEOUT_MS); + } + //qDebug()<<"found new sreen"; + chainCurrentStep=chainNextStep; + switchScreen(chainCurrentStep); + chain_stepIni=true; + + } + + if (chainCurrentStep==1) + { + if (chain_stepIni) + busy=myFenster01->work_ini(&nextScreen, &useNavi); + else + busy=myFenster01->working(&nextScreen, &useNavi); + } else + + { + // error undefined step + qDebug()<<"error main chain control, wrong step ("<0) + { + // call next chain step + //qDebug()<<"chain control: new step selected: "<< nextScreen; + + chainNextStep=nextScreen; + } + if (useNavi>0) + { + //qDebug()<<"chain control: navi buttons "<< useNavi; + enableNaviButtons(useNavi); + } + + if (busy>0) + { + // reset time-out + timerVendingTimeout->start(); + } + +} + + + +void MainWindow::vendingTimeout(void) +{ + // there was no user operation for 30s so return to start screen +// uint16_t nextScreen=WCS_STARTSCREEN; +// chainNextStep=nextScreen; erstmal stilllegen, stört bei IBN + //qDebug()<<"chain control: vending TO"; + timerVendingTimeout->stop(); +} + + + diff --git a/dCArun/mainwindow.h b/dCArun/mainwindow.h new file mode 100755 index 0000000..5c13e16 --- /dev/null +++ b/dCArun/mainwindow.h @@ -0,0 +1,72 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "plugin.h" +#include "stepList.h" +//#include "stepList.h" // define all working chain steps here +#include "win01_com.h" + + +class MainWindow : public QMainWindow +{ + Q_OBJECT + + QPushButton *pBback; + QPushButton *pBhome; + QPushButton *pBforward; + QGroupBox *bigGroupbox; + QHBoxLayout *bigLayout; + QTimer *timerChainCtrl; + QTimer *timerVendingTimeout; + + QGroupBox *frame01; + T_winComPort *myFenster01; + + void HideAllWindows(); + void switchScreen(uint16_t winNr); + char loadPlugIn(char lade1_entlade2); + QDir plugInDir; + void chainIni(void); + +public: + hwinf *HWaccess=nullptr; // global pointer to plugin-class + + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +#define BACKBUTTON 1 +#define HOMEBUTTON 2 +#define FORWBUTTON 3 + void enableNaviButtons(uint8_t buttonNr, bool enabled); + void enableNaviButtons(uint8_t switchBitwise); + +private slots: + void chainControl(); + void vendingTimeout(); + +}; + + + + +#endif // MAINWINDOW_H diff --git a/dCArun/plugin.h b/dCArun/plugin.h new file mode 100755 index 0000000..aec497c --- /dev/null +++ b/dCArun/plugin.h @@ -0,0 +1,5 @@ +#ifndef PLUGIN_H +#define PLUGIN_H +#include "interfaces.h" + +#endif diff --git a/dCArun/stepList.h b/dCArun/stepList.h new file mode 100755 index 0000000..1d553b2 --- /dev/null +++ b/dCArun/stepList.h @@ -0,0 +1,210 @@ +#ifndef STEPLIST_H +#define STEPLIST_H + + +// define all working chain steps +// every FSM-Step get's a frame in MainWindow with the same number and a self-designed GUI +// labels are used for switchScreen( label=nr ); +// numbers are important: e.g. number 3 calls frame3 and frame3 includes subClass "T_fenster03" +// so best solution: label = same name like class (in example: Fenster03). Label is fixed bound to number, never change! + +// numbers are fixed assosiated with the function (e.g. ComPort), can't be changed. +// but screen order can be called in step chain randomly + + +// Windownumbers for certain function, never change +#define PAGE_COMPORT 1 +#define PAGE_SERVICEMAIN 2 +#define PAGE_TIMEDATEVERSION 3 +#define PAGE_MACHINESTATUS 4 +#define PAGE_CHECKDOORS 5 +#define PAGE_PRINTER 6 +#define PAGE_COINMECHANIC 7 +#define PAGE_MIFARE 8 +#define PAGE_MODEM 9 +#define PAGE_COINPAYMENT 10 +#define PAGE_VAULTRECORD 11 +#define PAGE_BOOTLOADER 12 +#define PAGE_PROG_JSON 13 +#define PAGE_COINCHANGER 14 +#define PAGE_BILLREADER 15 +#define PAGE_NEXT16 16 +#define PAGE_NEXT17 17 +#define PAGE_NEXT18 18 +#define PAGE_NEXT19 19 +#define PAGE_NEXT20 20 + +// fix: customize: +#define WCS_STARTSCREEN PAGE_COMPORT + +// PAGE_COMPORT: +#define WCS_WIN01BAK PAGE_COMPORT +#define WCS_WIN01MID PAGE_SERVICEMAIN +#define WCS_WIN01FWD PAGE_SERVICEMAIN + +// PAGE_SERVICEMAIN: +#define WCS_WIN02BAK PAGE_COMPORT +#define WCS_WIN02MID PAGE_SERVICEMAIN +#define WCS_WIN02FWD PAGE_TIMEDATEVERSION + +// PAGE_TIMEDATEVERSION: +#define WCS_WIN03BAK PAGE_SERVICEMAIN +#define WCS_WIN03MID PAGE_SERVICEMAIN +#define WCS_WIN03FWD PAGE_MACHINESTATUS + +// PAGE_MACHINESTATUS: +#define WCS_WIN04BAK PAGE_TIMEDATEVERSION +#define WCS_WIN04MID PAGE_SERVICEMAIN +#define WCS_WIN04FWD PAGE_CHECKDOORS + + +// PAGE_CHECKDOORS: +#define WCS_WIN05BAK PAGE_MACHINESTATUS +#define WCS_WIN05MID PAGE_SERVICEMAIN +#define WCS_WIN05FWD PAGE_COINMECHANIC + +// PAGE_COINMECHANIC: +#define WCS_WIN07BAK PAGE_CHECKDOORS +#define WCS_WIN07MID PAGE_SERVICEMAIN +#define WCS_WIN07FWD PAGE_COINPAYMENT + +// PAGE_COINPAYMENT: +#define WCS_WIN10BAK PAGE_COINMECHANIC +#define WCS_WIN10MID PAGE_SERVICEMAIN +#define WCS_WIN10FWD PAGE_COINCHANGER + +// PAGE_COINCHANGER: +#define WCS_WIN14BAK PAGE_COINPAYMENT +#define WCS_WIN14MID PAGE_SERVICEMAIN +#define WCS_WIN14FWD PAGE_BILLREADER + + +// PAGE_BILLREADER: +#define WCS_WIN15BAK PAGE_COINCHANGER +#define WCS_WIN15MID PAGE_SERVICEMAIN +#define WCS_WIN15FWD PAGE_PRINTER + +// PAGE_PRINTER: +#define WCS_WIN06BAK PAGE_BILLREADER +#define WCS_WIN06MID PAGE_SERVICEMAIN +#define WCS_WIN06FWD PAGE_MIFARE + +// PAGE_MIFARE: +#define WCS_WIN08BAK PAGE_PRINTER +#define WCS_WIN08MID PAGE_SERVICEMAIN +#define WCS_WIN08FWD PAGE_MODEM + +// PAGE_MODEM: +#define WCS_WIN09BAK PAGE_MIFARE +#define WCS_WIN09MID PAGE_SERVICEMAIN +#define WCS_WIN09FWD PAGE_VAULTRECORD + + +// PAGE_VAULTRECORD: +#define WCS_WIN11BAK PAGE_MODEM +#define WCS_WIN11MID PAGE_SERVICEMAIN +#define WCS_WIN11FWD PAGE_PROG_JSON + +// PAGE_PROG_JSON: +#define WCS_WIN13BAK PAGE_VAULTRECORD +#define WCS_WIN13MID PAGE_SERVICEMAIN +#define WCS_WIN13FWD PAGE_BOOTLOADER + +// PAGE_BOOTLOADER: +#define WCS_WIN12BAK PAGE_PROG_JSON +#define WCS_WIN12MID PAGE_SERVICEMAIN +#define WCS_WIN12FWD PAGE_NEXT16 + + +// PAGE_NEXT16 +#define WCS_WIN16BAK PAGE_BOOTLOADER +#define WCS_WIN16MID PAGE_SERVICEMAIN +#define WCS_WIN16FWD PAGE_NEXT17 + +// PAGE_NEXT17 +#define WCS_WIN17BAK PAGE_NEXT16 +#define WCS_WIN17MID PAGE_SERVICEMAIN +#define WCS_WIN17FWD PAGE_NEXT18 + +// PAGE_NEXT18 +#define WCS_WIN18BAK PAGE_NEXT17 +#define WCS_WIN18MID PAGE_SERVICEMAIN +#define WCS_WIN18FWD PAGE_NEXT19 + +// PAGE_NEXT19 +#define WCS_WIN19BAK PAGE_NEXT18 +#define WCS_WIN19MID PAGE_SERVICEMAIN +#define WCS_WIN19FWD PAGE_NEXT20 + +// PAGE_NEXT20 +#define WCS_WIN20BAK PAGE_NEXT19 +#define WCS_WIN20MID PAGE_SERVICEMAIN +#define WCS_WIN20FWD PAGE_SERVICEMAIN + +// just for Template +#define WCS_WIN99BAK PAGE_SERVICEMAIN +#define WCS_WIN99MID PAGE_SERVICEMAIN +#define WCS_WIN99FWD PAGE_SERVICEMAIN + + + +#define WIN02_LABEL_SHORT01 " Status" +#define WCS_WIN02SHORT01 PAGE_MACHINESTATUS +#define WIN02_LABEL_SHORT02 " Doors " +#define WCS_WIN02SHORT02 PAGE_CHECKDOORS +#define WIN02_LABEL_SHORT03 "Coin mech" +#define WCS_WIN02SHORT03 PAGE_COINMECHANIC +#define WIN02_LABEL_SHORT04 "Payment" +#define WCS_WIN02SHORT04 PAGE_COINPAYMENT + +#define WIN02_LABEL_SHORT05 "Changer" +#define WCS_WIN02SHORT05 PAGE_COINCHANGER +#define WIN02_LABEL_SHORT06 " Bill " +#define WCS_WIN02SHORT06 PAGE_BILLREADER +#define WIN02_LABEL_SHORT07 "Printer" +#define WCS_WIN02SHORT07 PAGE_PRINTER + +#define WIN02_LABEL_SHORT08 "Program" +#define WCS_WIN02SHORT08 PAGE_VAULTRECORD +#define WIN02_LABEL_SHORT09 " " +#define WCS_WIN02SHORT09 PAGE_SERVICEMAIN +#define WIN02_LABEL_SHORT10 " " +#define WCS_WIN02SHORT10 PAGE_SERVICEMAIN + + + + + + + +// set needed navigation buttons, use | to combine more then one: +#define SWITCH_NEXT_ON 1 +#define SWITCH_NEXT_OFF 2 +#define SWITCH_HOME_ON 4 +#define SWITCH_HOME_OFF 8 +#define SWITCH_BACK_ON 16 +#define SWITCH_BACK_OFF 32 +// example: *useNavi=SWITCH_BACK_ON; // change only this one, or set all: +// *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_ON; + + + +// some defines for Widget design: + +#define TS_VALUEBOX_FRAMESTYLE 0x0032 +#define TS_VALUEBOX_LINEWIDTH 3 + +//genDatPort->setFrameStyle(QFrame::Panel | QFrame::Sunken ); funktioniert aber gibt unverständliche Warnung +// QFrame::Panel = 0x0002 QFrame::Sunken=0x0030 +//genDatPort->setFrameStyle(0x0032); // funktioniert und gibt keine Warnung +//genDatPort->setFrameStyle(TS_VALUEBOX_FRAMESTYLE); // funktioniert und gibt keine Warnung + +#define TS_LED_FRAMESTYLE 0x0031 +// QFrame::Box | QFrame::Sunken + + + + + + +#endif // STEPLIST_H diff --git a/dCArun/subwindows.cpp b/dCArun/subwindows.cpp new file mode 100755 index 0000000..a78317d --- /dev/null +++ b/dCArun/subwindows.cpp @@ -0,0 +1,267 @@ +#include "subwindows.h" + + + + + + + + + +/* + +// %%%%%%%%%%%%%%%%%%%% TabChanger + +T_fenster12::T_fenster12(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Coin Changer"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster12::updateGui(void) +{ + +} + + +// %%%%%%%%%%%%%%%%%%%% TabBill +T_fenster13::T_fenster13(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Bank note acceptor"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster13::updateGui(void) +{ + +} + +T_fenster14::T_fenster14(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 14"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster14::updateGui(void) +{ + +} + +T_fenster15::T_fenster15(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 15"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster15::updateGui(void) +{ + +} + +T_fenster16::T_fenster16(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 16"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster16::updateGui(void) +{ + +} + +T_fenster17::T_fenster17(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 17"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster17::updateGui(void) +{ + +} + +T_fenster18::T_fenster18(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 18"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster18::updateGui(void) +{ + +} + +T_fenster19::T_fenster19(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 19"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster19::updateGui(void) +{ + +} + +T_fenster20::T_fenster20(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 20"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster20::updateGui(void) +{ + +} + + + +T_fenster21::T_fenster21(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 21"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster21::updateGui(void) +{ + +} + +T_fenster22::T_fenster22(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 22"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster22::updateGui(void) +{ + +} + +T_fenster23::T_fenster23(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 23"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster23::updateGui(void) +{ + +} + +T_fenster24::T_fenster24(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 24"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster24::updateGui(void) +{ + +} + +T_fenster25::T_fenster25(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 25"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster25::updateGui(void) +{ + +} + +T_fenster26::T_fenster26(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 26"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster26::updateGui(void) +{ + +} + +T_fenster27::T_fenster27(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 27"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster27::updateGui(void) +{ + +} + +T_fenster28::T_fenster28(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 28"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster28::updateGui(void) +{ + +} + +T_fenster29::T_fenster29(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 29"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster29::updateGui(void) +{ + +} + +T_fenster30::T_fenster30(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + QGridLayout *myLayout = new QGridLayout(); + QLabel *Lab1 = new QLabel("Dialog 30"); + myLayout->addWidget(Lab1,1,1); + setLayout(myLayout); +} + +void T_fenster30::updateGui(void) +{ + +} + +*/ + diff --git a/dCArun/subwindows.h b/dCArun/subwindows.h new file mode 100755 index 0000000..061ca8c --- /dev/null +++ b/dCArun/subwindows.h @@ -0,0 +1,161 @@ +#ifndef SUBWINDOWS_H +#define SUBWINDOWS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tslib.h" +#include "stepList.h" // define all working chain steps here +#include "../plugins/interfaces.h" + + + +class T_fenster12 : public QWidget // TabChanger +{ + public: + explicit T_fenster12(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster13 : public QWidget // TabBill +{ + public: + explicit T_fenster13(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster14 : public QWidget +{ + public: + explicit T_fenster14(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster15 : public QWidget +{ + public: + explicit T_fenster15(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster16 : public QWidget +{ + public: + explicit T_fenster16(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster17 : public QWidget +{ + public: + explicit T_fenster17(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster18 : public QWidget +{ + public: + explicit T_fenster18(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster19 : public QWidget +{ + public: + explicit T_fenster19(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster20 : public QWidget +{ + public: + explicit T_fenster20(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; + +class T_fenster21 : public QWidget +{ + public: + explicit T_fenster21(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster22 : public QWidget +{ + public: + explicit T_fenster22(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster23 : public QWidget +{ + public: + explicit T_fenster23(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster24 : public QWidget +{ + public: + explicit T_fenster24(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster25 : public QWidget +{ + public: + explicit T_fenster25(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster26 : public QWidget +{ + public: + explicit T_fenster26(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster27 : public QWidget +{ + public: + explicit T_fenster27(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster28 : public QWidget +{ + public: + explicit T_fenster28(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster29 : public QWidget +{ + public: + explicit T_fenster29(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; +class T_fenster30 : public QWidget +{ + public: + explicit T_fenster30(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + void updateGui(void); + +}; + +#endif diff --git a/dCArun/tslib.cpp b/dCArun/tslib.cpp new file mode 100755 index 0000000..d70c1fc --- /dev/null +++ b/dCArun/tslib.cpp @@ -0,0 +1,1016 @@ +#include "tslib.h" +#include + + +//tslib::tslib() +//{ + + +//} + + +/* +uint16_t tslib::uchar2uint(uint8_t Highbyte, uint8_t Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint8_t tslib::uint2uchar(uint16_t uival, bool getHighB) +{ + // getHighB: low=GetLowByte + uint16_t uitmp=uival; + if (getHighB==0) + return uint8_t(uitmp); + uitmp>>=8; + return uint8_t(uitmp); + +}*/ + +uint16_t uchar2uint(char Highbyte, char Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte) +{ + uint32_t ultmp=0; + + ultmp |= uint8_t(Highbyte); + ultmp<<=8; + ultmp |= uint8_t(MHbyte); + ultmp<<=8; + ultmp |= uint8_t(MLbyte); + ultmp<<=8; + ultmp |= uint8_t(Lowbyte); + return ultmp; +} + +uint8_t uint2uchar(uint16_t uival, bool getHighB) +{ + // getHighB: low=GetLowByte + uint16_t uitmp=uival; + if (getHighB==0) + return uint8_t(uitmp); + uitmp>>=8; + return uint8_t(uitmp); + +} + + +void delay(uint16_t MilliSec) +{ + QThread::msleep(uint32_t(MilliSec)); +} + + +void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf) +{ + // Zahlenwerte in String wandeln, 12/24h-Format // 12byte für buf! + uint8_t usa; + uint16_t jj; + uint8_t hh, mm, ss, with_sec; + + // buf[0]= ganz linkes Zeichen + hh=hours; + mm=minutes; + ss=seconds; + + // 15.10.12, Plausibilitätsprüfung -------------------------------------------------- + if (hh>23) hh=0; + if (mm>59) mm=0; + if (ss>59) ss=0; + + with_sec=ShowSec; + for (jj=0; jj<12; jj++) buf[jj]=0; + usa = System12h; // 1:12h 0:24h + + // Stunden: + if (usa) + { + // 12h System + if (hh==0 || hh==12) + { + // 12AM (Mitternacht) oder 12PM (Mittag) + buf[0]=0x31; + buf[1]=0x32; + } else + if (hh<12) + { + // 1..11AM + buf[0]=hh/10+0x30; + buf[1]=hh%10+0x30; + } else + { + //13:00 bis 23Uhr + buf[0]=(hh-12)/10+0x30; + buf[1]=(hh-12)%10+0x30; + } + } else + { + // 24h System + buf[0]=hh/10+0x30; + buf[1]=hh%10+0x30; + } + + // Minuten: + buf[2]=':'; + //buf[2]='_'; // : not allowed in JsonFormat + buf[3]=mm/10+0x30; + buf[4]=mm%10+0x30; + + jj=5; + if (with_sec) + { + buf[jj++]=':'; + //buf[jj++]='_'; // : not allowed in JsonFormat + buf[jj++]=ss/10+0x30; + buf[jj++]=ss%10+0x30; + } + if (usa) + { + buf[jj++]=' '; + if (hh<12) + buf[jj++]='A'; + else + buf[jj++]='P'; + buf[jj++]='M'; + } + +} + +// ------------------- ******************************************************************************** + +void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf) +{ + // generate date as ascii string from integers day/month/year + // yearhigh: 10..29, in europe always 20 (not in arabia!) comes as hex number, e.g. 0x20 + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + + uint8_t tag, mon, jahr, d10, d1, m10, m1, y1000, y100, y10, y1; + uint8_t slash; + + + y100= (yearhigh & 0x0F)+0x30; + y1000=((yearhigh & 0xF0)>>4)+0x30; +// if (yearhigh>=20) +// { +// y1000='2'; +// y100=28+yearhigh; // '0' + (yearhigh-20) +// } else +// if (yearhigh<20) +// { +// y1000='1'; +// y100=38-yearhigh; // '9' - (19-yearhigh) +// } + + tag=day; + mon=month; + jahr=yearlow; + + if (mon>12 || mon==0) mon=1; // 23.10.12 + if (tag>31 || tag==0) tag=1; + if (jahr>50 || jahr<11) jahr=1; + + if (sep==0) + slash='.'; // slash==0 + else if (sep==1) + slash='/'; + else + if (sep>=0x20) + slash=sep; + else + slash='.'; + + d10 =tag/10; + d1 =tag%10; + m10 =mon/10; + m1 =mon%10; + y10 =jahr/10; + y1 =jahr%10; + + d10 +=0x30; // in Asccii wandeln + d1 +=0x30; + m10 +=0x30; + m1 +=0x30; + y10 +=0x30; + y1 +=0x30; + + switch (format) + { + // 0: dd.mm.yyyy + case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash; + buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break; + + // 1: mm.dd.yyyy + case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash; + buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break; + + // 2: yyyy.mm.dd + case 2: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=m10; + buf[6]=m1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break; + + // 3: dd.yyyy.mm + case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=y1000; buf[4]=y100; + buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break; + + // 4: mm.yyyy.dd + case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=y1000; buf[4]=y100; + buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break; + + // 5: yyyy.dd.mm + case 5: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=d10; + buf[6]=d1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break; + + } + buf[10]=0; + + +} + +// ------------------- ******************************************************************************** + +void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf) +{ + // generate date as ascii string from integers day/month/year + // format= 0: dd.mm.yy (deutsch) + // 1: mm.dd.yy (amerika) + // 2: yy.mm.dd (Iran, Dubai) + // 3: dd.yy.mm + // 4: mm.yy.dd + // 5: yy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + + uint8_t tag, mon, jahr, d10, d1, m10, m1, y10, y1; + uint8_t slash; + + + tag=day; + mon=month; + jahr=yearlow; + + if (mon>12 || mon==0) mon=1; // 23.10.12 + if (tag>31 || tag==0) tag=1; + if (jahr>50 || jahr<11) jahr=1; + + if (sep==0) + slash='.'; // slash==0 + else if (sep==1) + slash='/'; + else if (sep>=0x20) + slash=sep; + else + slash='.'; + + d10 =tag/10; + d1 =tag%10; + m10 =mon/10; + m1 =mon%10; + y10 =jahr/10; + y1 =jahr%10; + + d10 +=0x30; // in Asccii wandeln + d1 +=0x30; + m10 +=0x30; + m1 +=0x30; + y10 +=0x30; + y1 +=0x30; + + switch (format) + { + // 0: dd.mm.yyyy + case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash; + buf[6]=y10; buf[7]=y1; break; + + // 1: mm.dd.yyyy + case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash; + buf[6]=y10; buf[7]=y1; break; + + // 2: yyyy.mm.dd + case 2: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=m10; + buf[4]=m1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break; + + // 3: dd.yyyy.mm + case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash; + buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break; + + // 4: mm.yyyy.dd + case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash; + buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break; + + // 5: yyyy.dd.mm + case 5: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=d10; + buf[4]=d1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break; + + } + buf[8]=0; + + +} + +uint16_t tslib_strlen(char *buf) +{ + uint16_t nn; + + for (nn=0; nn<0xFFF0; nn++) + if (buf[nn]==0) + return nn; + return 0; +} + +void tslib_strclr(char *buf, char clrsign, uint16_t len) +{ + uint16_t nn; + + for (nn=0; nn=0x30 && sign<=0x39) + return true; + return false; +} + +bool tslib_isHexAsciiNumber(char sign) +{ + if (sign>=0x30 && sign<=0x39) + return true; + if (sign>=0x61 && sign<=0x66) // a...f + return true; + if (sign>=0x41 && sign<=0x46) // A...F + return true; + return false; +} + +int tslib_getMinimum(int val1, int val2) +{ + if (val1maxArayLen) LL=maxArayLen; + for (ii=0; ii> (7 - nn)) & 0x01); + if (B15H) + { + crc ^= 0x1021; + } + } + } + + for (nn = 0; nn < 16; nn++) + { + B15H = 0; + if(crc & 0x8000) + B15H = 1; + crc = (crc << 1) | 0x00; + if (B15H) + { + crc ^= 0x1021; + } + } + return crc; + +} + +static uint8_t LastBLcmd; // stored the last sent cmd in order to analys response + // cmd echo'ed: error cmd or'ed with 0x80: OK + +uint8_t tslib_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) +{ + // make BL protocol, retval = outbuf length (5...133) + // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum + // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 + // Data length = 0...64 + // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 + // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + + uint8_t myBuf[140], pp=0, nn, uctmp, currLen=0; + uint16_t calcCrc; + + tslib_strclr(myBuf, 0, 140); + + myBuf[pp++]=2; // STX + myBuf[pp++]=Cmd; + LastBLcmd=Cmd; + + // append data: + for (nn=0; nn>8) & 0x00FF); + myBuf[pp++]=3; + currLen=pp; + + return currLen; +} + +// some special commands (right out of bootloader manual) +uint8_t tslib_readBLversion(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData); +} + +uint8_t tslib_readFWversion(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x12, 0, myBuf, sendData); +} + +uint8_t tslib_exitBL(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x18, 0, myBuf, sendData); +} + +uint8_t tslib_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData) +{ + // minimum size of sendData-buffer: 13byte retval: length (9...13) + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData); +} +*/ + +// ----------------------------------------------------------------------------------------------- + +bool tslib_plausiChkTime(uint8_t hour, uint8_t min, uint8_t sec ) +{ + // retval: true: time is OK + bool ret=true; + + if (hour>23) ret=false; + if (min>59) ret=false; + if (sec>59) ret=false; + + return ret; +} + +// ----------------------------------------------------------------------------------------------- + +bool tslib_plausiChkDate(uint8_t year, uint8_t month, uint8_t dom ) +{ + // retval: true: time is OK + bool ret=true; + + if (year<23) ret=false; + if (month<1 || month>12) ret=false; + if (dom<1 || dom>31) ret=false; + + return ret; +} + +// ----------------------------------------------------------------------------------------------- + +UCHAR swl_LengthCurrentMonth(UCHAR month, UCHAR year) +{ + // return nr of days for this month, respecting leap years + if (month==2) + { + // Sonderfall Februar: + if (year%4) + return 28; // Rest wenn durch 4 geteilt wird + else + return 29; // durch 4 teilbar ohne Rest + } else + if (month==1 || month==3 || month==5 || month==7 || + month==8 || month==10 || month==12) + { + return 31; + } else + return 30; + +} + +// ----------------------------------------------------------------------------------------------- + +UINT swl_GetDaysOfaCompleteYear(UCHAR year) +{ + // year: 0=2000 4=2004 99=2099 + // retval: 365 or 366 (leap year) + UCHAR jahr; + + jahr=year; + if (jahr & 3) // wenn bits 0 und 1 low sind dann Vielfaches von 4 + { + // dann kein Schaltjahr + return(365); + } else + { + // Schaltjahr + return(366); + } + +} + +// ----------------------------------------------------------------------------------------------- + +UINT swl_GetDaysOfYear(UCHAR year, UCHAR month, UCHAR day) +{ + // number of days of momentary year from 1. Jan until + // (inclusive) given date with respect to leap years + // year: 0..99 month=1..12 day=1..31 + + int summe=0; + UCHAR mo, ta, yy, mm, uctmp; + + yy=year; + mo=month; + ta=day; + if (mo==0 || mo>12 || ta==0 || ta>31 || yy>99) + return(0); // Fehler + + // Beispiel: mo=5: summiere Tage des Jan, Feb, März und April + // der Mai ist noch nicht komplett abgelaufen! + mm=1; // start mit Januar + while (mo>1) + { + uctmp=swl_LengthCurrentMonth(mm,yy); + summe += (int)uctmp; + mo--; mm++; + } + + summe+=ta; + return(summe); +} + +// ----------------------------------------------------------------------------------------------- + +unsigned long swl_getNrOfDaysSince2000Jan1(UCHAR thisYear, UCHAR thisMonth, UCHAR thisDay) +{ + // till today + ULONG ultmp=0; + UCHAR jj; + + for (jj=0; jj +#include + +typedef uint8_t UCHAR; +typedef uint16_t UINT; +typedef uint32_t ULONG; + +#define LOWBYTE false +#define HIGHBYTE true + +uint16_t uchar2uint(char Highbyte, char Lowbyte); +uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte); +uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte); + +uint8_t uint2uchar(uint16_t uival, bool getHighB); + + +void delay(uint16_t MilliSec); + +#define MITSEK 1 +#define OHNESEK 0 +#define HourSys12h 1 +#define HourSys24h 0 + +void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf); + // generate time as ascii string from integers hours/minutes/seconds + // System12h=0: 24h system =1: 12h System + // ShowSec=0: String has 5 digits (hh:mm) =1: String has 8 digits (hh:mm:ss) + // return String in *buf // 12 byte für buf! + +#define DateFormatDeutsch 0 +#define DateFormatAmerica 1 +#define UsePointSeperator 0 +#define UseSlashSeperator 1 + + +void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf); + // generate date as ascii string from integers day/month/year + // yearhigh in europe always 20 (not in arabia) + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11 byte für buf! + + +void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf); + // generate date as ascii string from integers day/month/year + // format= 0: dd.mm.yy (deutsch) + // 1: mm.dd.yy (amerika) + // 2: yy.mm.dd (Iran, Dubai) + // 3: dd.yy.mm + // 4: mm.yy.dd + // 5: yy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + +uint16_t tslib_strlen(char *buf); + +void tslib_strclr(char *buf, char clrsign, uint16_t len); +void tslib_strclr(uint8_t *buf, char clrsign, uint16_t len); + +void tslib_strcpy(char *srcbuf, char *destbuf, uint16_t len); +void tslib_strcpy(char *srcbuf, uint8_t *destbuf, uint16_t len); +void tslib_strcpy(uint8_t *srcbuf, uint8_t *destbuf, uint16_t len); + + +uint16_t tslib_calcCrcCcitt(uint16_t BufLength, uint8_t *buf); + +bool tslib_isDecAsciiNumber(char sign); +bool tslib_isHexAsciiNumber(char sign); + + +int tslib_getMinimum(int val1, int val2); + +void tslib_text2array(QByteArray text, char *aray, uint16_t maxArayLen); + // usage: tslib_text2array("my text", ctmp, 50); + +bool tslib_strComp(uint8_t *buf, char *compStr); + +bool tslib_plausiChkTime(uint8_t hour, uint8_t min, uint8_t sec ); + // retval: true: time is OK + +bool tslib_plausiChkDate(uint8_t year, uint8_t month, uint8_t dom ); + // retval: true: time is OK + +UCHAR swl_LengthCurrentMonth(UCHAR month, UCHAR year); + // return nr of days for this month, respecting leap years + +UINT swl_GetDaysOfaCompleteYear(UCHAR year); + // year: 0=2000 4=2004 99=2099 + // retval: 365 or 366 (leap year) + +UINT swl_GetDaysOfYear(UCHAR year, UCHAR month, UCHAR day); + // number of days of momentary year from 1. Jan until + // (inclusive) given date with respect to leap years + // year: 0..99 month=1..12 day=1..31 + +unsigned long swl_getNrOfDaysSince2000Jan1(UCHAR thisYear, UCHAR thisMonth, UCHAR thisDay); + // till today + +unsigned long swl_getNrOfHoursSince_Midnight2000Jan1(UCHAR thisYear, UCHAR thisMonth, UCHAR thisDay, UCHAR hoursNow); + +unsigned long swl_getNrOfMinutesSince_Midnight2000Jan1(UCHAR thisYear, \ + UCHAR thisMonth, UCHAR thisDay, UCHAR hoursNow, UCHAR minuteNow); + +unsigned long swl_getNrOfSecondsSince_Midnight2000Jan1(UCHAR thisYear, \ + UCHAR thisMonth, UCHAR thisDay, UCHAR hoursNow, UCHAR minuteNow, UCHAR secondNow); + +char swl_isLeap(UCHAR year); + +UCHAR swl_getNextLeapYear(UCHAR year); + +UCHAR swl_getLastLeapYear(UCHAR year); + +UCHAR swl_hoursOfThisWeek(UCHAR dow, UCHAR hoursNow); + // always calculate from monday 0 o'clock + // dow: 1=monday 7=sunday + +UINT swl_minutesOfThisWeek(UCHAR dow, UCHAR hoursNow, UCHAR minutesNow); + // always calculate from monday 0 o'clock + // dow: 1=monday 7=sunday + +UINT swl_hoursOfThisMonth(UCHAR thisDay, UCHAR hoursNow); + +UINT swl_minutesOfThisMonth(UCHAR thisDay, UCHAR hoursNow, UCHAR minutesNow); + +UINT swl_GetHoursOfYear(UCHAR year, UCHAR month, UCHAR day, UCHAR hourNow); + +ULONG swl_GetMinutesOfYear(UCHAR year, UCHAR month, UCHAR day, UCHAR hourNow, UCHAR minutesNow); + +UCHAR swl_weekday(UCHAR year, UCHAR month, UCHAR dayOfMonth); + // return 1...7 = monday...sunday, starting from 1.1.2000 + +QString swl_int2str(int val); +QString swl_hex2str(double val); + +void swl_text2ui8buf(QString text, uint8_t *outbuf, uint16_t length); + // copy text byte-by-byte to outbuf + +QString swl_ulong2str(uint32_t val); + +QString swl_long2str(long val); + +uint16_t swl_str2uint(QString myIntStr); + +uint32_t swl_str2ulong(QString myIntStr); + +QString swl_labelAndValToStr(QString label, uint32_t val); + +QString swl_8valInaRowToStr(QString label, uint8_t val[8]); + +QString swl_8valInaRowToStr(QString label, uint16_t val[8]); + +QString swl_8intsInaRowToStr(QString label, int val[8]); + +QString swl_centToEuroString(uint32_t amount_in_cent); + +#endif // TSLIB_H + +// qDebug << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) << QByteArray((const char*)dataSendBuf,dataBufLen).toHex(':'); + diff --git a/dCArun/versionHistory.txt b/dCArun/versionHistory.txt new file mode 100755 index 0000000..7b996ca --- /dev/null +++ b/dCArun/versionHistory.txt @@ -0,0 +1,13 @@ +#ifndef VERSIONHISTORY_H +#define VERSIONHISTORY_H + +APservice3.0 bis September2023 fuer DBM, Szeged + + +APservice3.2 12.10.23 + screen Abfolge komplett mit defines aufgebaut, kann jetzt in "stepList.h" veraendert werden + Neuen Screen Muenzwechsler und Banknote + passend zu CashAgent-Plugin: "Atb.Psa1256ptu5.software.HWapi/5.0" + Farben und Schriftgroessen vereinheitlichen (guidefs.h) + +#endif diff --git a/dCArun/win01_com.cpp b/dCArun/win01_com.cpp new file mode 100755 index 0000000..e8ee85d --- /dev/null +++ b/dCArun/win01_com.cpp @@ -0,0 +1,578 @@ +#include "win01_com.h" +#include "stepList.h" // define all working chain steps here +#include "datei.h" +//#include "globVars.h" + + + +// %%%%%%%%%%%%%%%%%%%% TabComPort + +Console::Console(QWidget *parent) : QPlainTextEdit(parent) +{ + document()->setMaximumBlockCount(100); + QPalette p = palette(); + p.setColor(QPalette::Base, Qt::black); //geht nicht weil untergrund schon farbig + p.setColor(QPalette::Text, Qt::blue); + setPalette(p); + +} + +void Console::putData(const QByteArray &data) +{ + insertPlainText(data); + insertPlainText("\n"); + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); +} + +void Console::putText(QString text) +{ + insertPlainText(text); + insertPlainText("\n"); + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); +} + +void T_winComPort::subPortInfo() +{ + + // Port Info Anzeige Feld, 2. Zeile links + QStringList myStringList; + QStringList comboPortList; + + const auto infos = QSerialPortInfo::availablePorts(); + for (const QSerialPortInfo &info : infos) + { + myStringList.append(QObject::tr(" \n Port: ") + info.portName() ); + myStringList.append(QObject::tr("Location: ") + info.systemLocation()); // + "\n"); + myStringList.append(QObject::tr("Description: ") + info.description() ); + myStringList.append(QObject::tr("Manufacturer: ") + info.manufacturer()); + myStringList.append(QObject::tr("Serial number: ") + info.serialNumber()); + myStringList.append (QObject::tr("Vendor Id: ") + QString::number(info.vendorIdentifier(), 16)); + myStringList.append(QObject::tr("Product Id: ") +QString::number(info.productIdentifier(), 16)); + //myStringList.append(QObject::tr("Busy: ") + (info.isBusy() ? QObject::tr("Yes") : QObject::tr("No"))); + comboPortList.append(info.portName()); // wenn Comport im System vorhanden dann in die Liste eintragen + } + QListWidget *myListWidget = new QListWidget; + myListWidget->insertItems(0, myStringList); + myListWidget->setMaximumWidth(250); + myTabComLayout->addWidget(myListWidget,1,0); + + + // ComboBox Comport Nr: + CB_portSel = new QComboBox(); + CB_portSel->addItems(comboPortList); // string Liste mit addItems (s am Schluss) ! + CB_portSel->setMinimumHeight(30); + CB_portSel->setMaximumWidth(150); + QFont myCBfont; + //myCBfont.setBold(true); + myCBfont.setPixelSize(15); + CB_portSel->setFont(myCBfont); + CB_portSel->setCurrentIndex(2); // default 3. Comport in der Liste = ttymxc2 in PTU5 + myTabComLayout->addWidget(CB_portSel, 4,0); + +} + +void T_winComPort::callOpenSerial() +{ + // Taste Connect wurde gedrückt, eine Klasse/einen Slot aus einer übergeordneten Klasse: + // openSerialPort(); + // kann man nicht aufrufen. deshalb: speichere ComPort, Baudrate und Startbefehl global. + // Von dort wird mit einem zyklischen Timer ausgelesen + + int br, ci; + QString bs, cn; + //br=CB_baudSel->currentIndex(); + //bs=CB_baudSel->currentText(); + br=5; + bs="115200"; + cn=CB_portSel->currentText(); + ci=CB_portSel->currentIndex(); + + // aktuell: br=5 bs=115200 cn=0 (=Com5) + //epi_setSerial(5,"115200","COM5",1); + // epi_setSerial(br, bs, cn, 1); + + // new: save values for next time + QByteArray myBA, tmpBA; + myBA.clear(); tmpBA.clear(); + myBA.append('s'); // start sign, not used + myBA.append(FILESEPERATOR); + tmpBA.setNum(br,10); + myBA.append(tmpBA); + myBA.append(FILESEPERATOR); + myBA.append(bs.toLatin1()); + myBA.append(FILESEPERATOR); + myBA.append(cn.toLatin1()); + myBA.append(FILESEPERATOR); + tmpBA.clear(); + tmpBA.setNum(ci,10); + myBA.append(tmpBA); + myBA.append(FILESEPERATOR); + + datei_clearFile(FILENAME_COMPORT); + datei_writeToFile(FILENAME_COMPORT, myBA); + qDebug() << "winComPort opening serial with: " << br << " " << bs << " " << cn; + HWaccess->dc_openSerial(br, bs, cn, 1);// same function with hwapi + // void dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) + // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 + // BaudStr: for exapmle "19200" + // ComName: for example "COM48" + // connect: 0, 1 + + emit connectButtonPressed(); +} + +void T_winComPort::callCloseSerial() +{ + HWaccess->dc_closeSerial(); + // epi_closeSerial(); // same function without hwapi + emit closeButtonPressed(); +} + +void T_winComPort::callAutoSend() +{ + if (AutSendButton->isChecked()) + { + HWaccess->dc_autoRequest(1); + emit autoSendButtonIsOn(); + } else + { + HWaccess->dc_autoRequest(0); + + emit autoSendButtonIsOff(); + } + +} + +void T_winComPort::callRefresh(void) +{ + subPortInfo(); +} + +void T_winComPort::callConnectToggle() +{ + if (connectButton->isChecked()) + { + //qDebug() << "down"; + + callOpenSerial(); + } else + { + //qDebug() << "released"; + callCloseSerial(); + } + +} + +void T_winComPort::getDcTestRS232() +{ + //qDebug() << "request test response..."; + HWaccess->dc_requTestResponse(); + + +} + + +void T_winComPort::newBaud(void) +{ + + qDebug() << "new baud selected..."; + +} + +void T_winComPort::setButtons4autoStart() +{ + connectButton->setEnabled(true); + connectButton->setDown(true); + connectButton->setChecked(true); + + AutSendButton->setEnabled(true); + AutSendButton->setDown(true); + AutSendButton->setChecked(true); + + +} + + +T_winComPort::T_winComPort(hwinf *HWaccess, QWidget *parent) : QWidget(parent) +{ + this->HWaccess = HWaccess; + + myTabComLayout = new QGridLayout; + //QGridLayout *myGridLayout = new QGridLayout(); + + // Ãœberschrift linke Spalte + QLabel *portListLabel2 = new QLabel(tr("in System available Ports:")); + myTabComLayout->addWidget(portListLabel2, 0,0); + + // Ãœberschrift rechte Spalte + QLabel *lab_headlineR = new QLabel(tr("Serial traffic:")); + myTabComLayout->addWidget(lab_headlineR, 0, 1); + + subPortInfo(); + // sende-empfangs-Rohdaten-Fenster, 2. Zeile rechts + myDiagWindow = new Console(); + myDiagWindow->setReadOnly(true); + myDiagWindow->setEnabled(true); + //myDiagWindow->setLocalEchoEnabled(p.localEchoEnabled); + //myDiagWindow->setMinimumWidth(300); + //myDiagWindow->putData("ongoing serial traffic: "); + myTabComLayout->addWidget(myDiagWindow, 1,1); + +// links: + // refresh button: + refreshButton = new QPushButton(tr("&refresh")); + refreshButton->setCheckable(false); // true = toggle button + refreshButton->setAutoDefault(false); // beim start aus + //refreshButton->setMaximumWidth(90); + myTabComLayout->addWidget(refreshButton, 2,0); + //connect(refreshButton, &QAbstractButton::clicked, this, &T_fenster01::callRefresh); + connect(refreshButton, SIGNAL(clicked()), this, SLOT(callRefresh())); + + + QLabel *Label3 = new QLabel(tr("Port:")); + myTabComLayout->addWidget(Label3, 3,0); + + + + QLabel *Label4 = new QLabel(tr("Baud:")); + myTabComLayout->addWidget(Label4, 5,0); + + // ComboBox Baudrate: + QFont my2CBfont; + //my2CBfont.setBold(true); + my2CBfont.setPixelSize(15); +/* + CB_baudSel = new QComboBox(); + CB_baudSel->addItem(tr("1200")); + CB_baudSel->addItem(tr("9600")); + CB_baudSel->addItem(tr("19200")); + CB_baudSel->addItem(tr("38400")); + CB_baudSel->addItem(tr("57600")); + CB_baudSel->addItem(tr("115200")); + CB_baudSel->setMinimumHeight(30); + CB_baudSel->setMaximumWidth(150); + CB_baudSel->setFont(my2CBfont); + CB_baudSel->setCurrentIndex(5); // default 115k baud + //CB_baudSel->setCurrentIndex(1); // default 9600 baud + myTabComLayout->addWidget(CB_baudSel, 6,0); + //connect(CB_baudSel, SIGNAL(currentIndexChanged(int)), this, SLOT(newBaud())); + connect(CB_baudSel, SIGNAL(currentIndexChanged(int)), this, SLOT(newBaud())); +*/ + // Statuszeile COM Port (serial Port) + LabelComState = new QLabel(tr("not connected")); + myTabComLayout->addWidget(LabelComState, 7,0); + + // Connect button: + connectButton = new QPushButton(tr("&Connect")); + connectButton->setCheckable(true); // true = toggle button + connectButton->setAutoDefault(true); // beim start ein + connectButton->setMaximumWidth(90); + connectButton->setMinimumHeight(50); + myTabComLayout->addWidget(connectButton, 8,0); + //connect(connectButton, &QAbstractButton::clicked, this, &T_fenster01::callConnectToggle); + connect(connectButton, SIGNAL(clicked()), this, SLOT(callConnectToggle())); + + +// rechts: + + // test serial line: + TestButton = new QPushButton(tr("test Connection")); + TestButton->setMaximumWidth(150); + myTabComLayout->addWidget(TestButton,2,1); + TestButton->setCheckable(false); // true = toggle button + TestButton->setAutoDefault(false); // beim start aus +// connect(TestButton, &QAbstractButton::clicked, this, &T_fenster01::getDcTestRS232); + connect(TestButton, SIGNAL(clicked()), this, SLOT(getDcTestRS232())); + + // I Statuszeile Handshakes (serial Control) flow.cpp + // geht überhaupt was raus? kommt überhaupt was zurück? + //LabelHandshakes = new QLabel(tr("control line")); + LabelHandshakes = new QLabel("HS"); // not used + myTabComLayout->addWidget(LabelHandshakes, 3,1); + + // II Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) + LabelRecieveFrame = new QLabel(tr("slave receive")); + myTabComLayout->addWidget(LabelRecieveFrame, 4,1); + + // III Anzeige der Slave-Results (Datif) + LabelResults = new QLabel(tr("results line")); + myTabComLayout->addWidget(LabelResults, 5,1); + + // IV Statuszeile Sende- und Empfangsdaten brauchbar? (Datif) + LabelDataState = new QLabel(tr("datif line")); + myTabComLayout->addWidget(LabelDataState, 6,1); + + // V + LabelDatif = new QLabel(tr("datif line")); + myTabComLayout->addWidget(LabelDatif, 7,1); + + // Autosend: + AutSendButton = new QPushButton(tr("&Automatic reading")); // &A --> also keycode Alt-A possible + //AutSendButton->setMaximumWidth(90); + myTabComLayout->addWidget(AutSendButton,8,1); + AutSendButton->setCheckable(true); // true = toggle button + AutSendButton->setAutoDefault(true); // beim start aus + AutSendButton->setMinimumHeight(50); +// connect(AutSendButton, &QAbstractButton::clicked, this, &T_fenster01::callAutoSend); + connect(AutSendButton, SIGNAL(clicked()), this, SLOT(callAutoSend())); + + setLayout(myTabComLayout); + myNextStep=0; + myStep=0; + callConnectToggle(); + callAutoSend(); + + myTO = new QTimer(); + myTO->setSingleShot(true); + myTO->start(2000); + + +} + +// not needed: +T_winComPort::~T_winComPort() +{ + close(); +} + +void T_winComPort::Nav_back(void) +{ + myNextStep=WCS_WIN01BAK; +} +void T_winComPort::Nav_home(void) +{ + myNextStep=WCS_WIN01MID; +} +void T_winComPort::Nav_next(void) +{ + myNextStep=WCS_WIN01FWD; +} + +bool T_winComPort::work_ini(uint16_t *nextScreen, uint8_t *useNavi) +{ + // one state of the vending/operating FSM + // called ONE time after selecting this state (initialization) + // useNavi=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + + *nextScreen=0; // needed 0=no change +// *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_ON; + *useNavi=SWITCH_BACK_OFF | SWITCH_HOME_OFF | SWITCH_NEXT_OFF; // bei CArun alle aus + return false; +} + +bool T_winComPort::working(uint16_t *nextScreen, uint8_t *useNavi) +{ + // one state of the vending/operating FSM + // called cyclic until this state changes intentionally to another state + // display informations for human operator, react on operators inputs or wait for payment media + + // useNavi=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + + this->updateGui(); + *nextScreen=0; // 0=no change + *useNavi=0; + + if (myStep==0) + { + // load and use last settings: -------------------- + QByteArray myBA; + myBA=datei_readFromFile(FILENAME_COMPORT); + + //uint32_t len= datei_nrOfEntriesInFile(myBA); + //uint64_t ulltmp=csv_getEntryAs2Ulong(myBA,0); + //qDebug()<<"win_startup load long numer: "<dc_openSerial(br,bs,cn,1); + //CB_baudSel->setCurrentIndex(br); // im BR auswahlfenster diese Baud vorgeben + CB_portSel->setCurrentIndex(ci); // den Port aus der Datei hier vorgeben + connectButton->setChecked(true); // connect Taste "druecken" + + myTO->start(100); // restart + myStep++; + } else + + if (myStep==1) + { + if (!myTO->isActive()) + { + if (HWaccess->dc_isPortOpen()) + myStep++; + else + myStep=99; // stop automatic connection and wait for manual start + myTO->start(100); + } + } else + + if (myStep==2) + { + if (!myTO->isActive()) + { + HWaccess->dc_requTestResponse(); + myStep++; + myTO->start(100); + } + } else + + if (myStep==3) + { + if (!myTO->isActive()) + { + if (HWaccess->dc_readAnswTestResponse()) + myStep++; // response was correct + else + myStep=99; // stop automatic connection and wait for manual start + myTO->start(100); + } + + } else + + if (myStep==4) + { + HWaccess->dc_autoRequest(1); + AutSendButton->setChecked(true); // taste "druecken" + myStep++; + } else + + if (myStep==5) + { + // got next screen: + //myNextStep=2; // nicht bei CArun + myStep++; + + } else + + if (myStep==6) + { + // stop here, everything done + } else + + if (myStep==7) + { + + } else + { + + } + + if (myNextStep) + { + //qDebug()<<"fenster1 working: "<< myNextStep; + *nextScreen=myNextStep; + myNextStep=0; + } + return false; +} + + +void T_winComPort::updateGui(void) +{ + QByteArray myBA; + QString ms; + + ms=HWaccess->dc_getTxt4RsDiagWin(); + if (ms.length()>1) // sonst ständig scrolling + { + myDiagWindow->putText(ms); + HWaccess->dc_clrTxt4RsDiagWin(); + } + + ms=HWaccess->dc_get2ndTxt4RsDiagWin(); + if (ms.length()>1) // sonst ständig scrolling + { + myDiagWindow->putText(ms); + HWaccess->dc_clr2ndTxt4RsDiagWin(); + } + + // state of the COM Port (open, closed) + ms=HWaccess->dc_getSerialState(); + if (ms.length()>1) // sonst ständig scrolling + { + LabelComState->setText(ms); + } + + // -------------------------------------------------------------------------- + // I Statuszeile Handshakes (serial Control) + + ms=HWaccess->dc_getTxt4HsStateLine(); + if (!connectButton->isChecked()) + ms=""; + if (ms.length()>1) // sonst ständig scrolling + { + LabelHandshakes->setText(ms); + HWaccess->dc_clrTxt4HsStateLine(); + // clear to avoid multiple displaying + } + + + // II Master receive state (empfangenes Telgramm OK? crc? length? ) + // Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) + + ms=HWaccess->dc_getTxt4masterStateLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelRecieveFrame->setText(ms); + HWaccess->dc_clrTxt4masterStateLine(); + } + + + + // III Slave receive (from Master) OK? if then show results, if not then show errors + // entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR + // Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch + // nicht verwenden und nichts ausgeben oder einlesen + + ms=HWaccess->dc_getTxt4resultStateLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelResults->setText(ms); + HWaccess->dc_clrTxt4resultStateLine(); + } + + + // IV Statuszeile Empfangsdaten + + ms=HWaccess->dc_getdataStateLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelDataState->setText(ms); + HWaccess->dc_clrTxt4dataStateLine(); + // clear to avoid multiple displaying + } + + + // 5. Zeile: Datif Ergebnis, Daten brauchbar? + + ms=HWaccess->dc_getdatifLine(); + if (!connectButton->isChecked()) + ms="---"; + if (ms.length()>1) // sonst ständig scrolling + { + LabelDatif->setText(ms); + HWaccess->dc_clrTxt4datifLine(); + } + + // ----------------------------------------------------------------------------- + +} + + diff --git a/dCArun/win01_com.h b/dCArun/win01_com.h new file mode 100755 index 0000000..c535948 --- /dev/null +++ b/dCArun/win01_com.h @@ -0,0 +1,107 @@ +#ifndef WINCOMPORT_H +#define WINCOMPORT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include "tslib.h" +//#include "stepList.h" // define all working chain steps here +//#include "datei.h" +#include "plugin.h" +//#include "globVars.h" + +class Console : public QPlainTextEdit +{ + Q_OBJECT + +public: + explicit Console(QWidget *parent = nullptr); + + void putData(const QByteArray &data); + void putText(QString text); +}; + +class T_winComPort : public QWidget // former TabComport +{ + Q_OBJECT + Console *myDiagWindow; // Ausgabefenster + QComboBox *CB_portSel; + //QComboBox *CB_baudSel; + QPushButton *connectButton; + QPushButton *AutSendButton; + QPushButton *TestButton; + QPushButton *refreshButton; + + QLabel *LabelComState; // Statusanzeige + QLabel *LabelPort; + QLabel *LabelHandshakes; + QLabel *LabelRecieveFrame; + QLabel *LabelResults; + QLabel *LabelDataState; + QLabel *LabelDatif; + + QGridLayout *myTabComLayout; + void subPortInfo(); + hwinf *HWaccess; + void updateGui(void); + uint16_t myNextStep; + uint8_t myStep; + QTimer *myTO; + +private slots: + void callOpenSerial(); + void callCloseSerial(); + void callAutoSend(); + //void tabComTime100ms(); + void callConnectToggle(); + void getDcTestRS232(); + void callRefresh(void); + +public: + explicit T_winComPort(hwinf *HWaccess = nullptr, QWidget *parent = nullptr); + bool work_ini(uint16_t *nextScreen, uint8_t *useNavi); + // useNavi=0: no change + // bit0,1: enable/disable button "next" + // bit2,3: enable/disable button "home" + // bit4,5: enable/disable button "back" + bool working (uint16_t *nextScreen, uint8_t *useNavi); + ~T_winComPort(); + + void writeRSdiagBytes(const QByteArray &bytarray); + void writeRSdiagText(QString text); + void writeComState(const QString text); + void writeDataState(const QString text); + void setButtons4autoStart(); + +signals: + void connectButtonPressed(); + void closeButtonPressed(); + void autoSendButtonIsOn(); + void autoSendButtonIsOff(); + +private slots: + void newBaud(void); // just for test + +public slots: + void Nav_back(void); + void Nav_home(void); + void Nav_next(void); + +}; + +#endif diff --git a/include/com.h b/include/com.h new file mode 100644 index 0000000..9942131 --- /dev/null +++ b/include/com.h @@ -0,0 +1,107 @@ +//CAT is always master, no receive before request + +#ifndef SER_H +#define SER_H +#include +#include +//#include +#include +#include +#include "tslib.h" +#include "controlBus.h" +#include "interfaces.h" + + +#define MAXTELEGRAMLEN 90 + +// display all inputs and outputs in output window: +//#define PRINTALLDEBUGS 1 + +class T_com : public QObject //, public QPlainTextEdit +{ + Q_OBJECT + + // complete send message (protocol frame) + QByteArray sendBuffer; //[MAXTELEGRAMLEN]; + uint16_t sendLen; // >0: Daten Sendebereit, nach senden wieder auf 0 setzen + + // right after reception: + QByteArray rawInput; //[MAXTELEGRAMLEN]; + uint16_t rawInLen; // 0: keine neuen Daten erhalten + +// QSerialPort *CatSerial = nullptr; + QSerialPort *CatSerial; + + //char oeffneSerialPort(); + char open_Serial_Port(); + void closeSerialPort(); + void receiveByLength(void); + +private slots: + void readSomeBytes(void); + void serialSendComplete(void); + //void incomingWake(void); //bool LevelOfTheBit); + void receiveTO(void); + void ser_ISR100ms(); + + + +public: + T_com(QObject *parent = nullptr); + ~T_com(); + + QTimer *serRecTime; + + bool isPortOpen(void); + + void writeToSerial(const QByteArray &data, uint16_t sendLength); + + void receiveFixLen(int64_t nrOfbytesToReceive); + + bool readFromSerial(QByteArray &data, uint16_t &sendLength); + // retval: true: data available + +/* + uint8_t getAllPortPins(void); + // rs232pins: all signals bitwise coded in one byte: + // readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output) + // unused inputs: bit1=RxD bit 3=DCD bit 5 = RING + // handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80) + + bool getHSin_CTS(void); + // return the CTS Handshake input): true= high level (+8V) + + bool getHSin_DSR(void); + // return the DSR Handshake input): true= high level (+8V) + + bool setHSout_RTS(bool hsout); + // hsout true=positiv voltage +12V false= -12V + // retval: true=setting OK + + bool setHSout_DTR(bool hsout); + // hsout true=positiv voltage +12V false= -12V + // retval: true=setting OK +*/ + +signals: + void receivingFinished(); + void sendingFinished(); + //void wasWokenBySerialHandshake(); + +}; + + + +#endif // SER_H + + + + + + + + + + + + diff --git a/include/controlBus.h b/include/controlBus.h new file mode 100644 index 0000000..85503a2 --- /dev/null +++ b/include/controlBus.h @@ -0,0 +1,213 @@ +#ifndef CONTROLBUS_H +#define CONTROLBUS_H + + +#include "tslib.h" +#include +#include "interfaces.h" +//#include "hwapi.h" +#include +#include "shared_mem_buffer.h" + + +// /////////////////////////////////////////////////////////////////////////////////// +// control serial interface gui <--> serial +// /////////////////////////////////////////////////////////////////////////////////// + + +void epi_setSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect); + // Actions: open serial port with parameters + +void epi_closeSerial(void); +// Actions: close serial port + +// Port -> API +void gpi_serialChanged(void); + // serial confirms that port was closed or opened + +// Actions, API -> serialPort +uint8_t gpi_getSerialConn(void); // connect if 1, disconnect if 0 + +int gpi_getBaudNr(void); + +QString gpi_getComPortName(void); + +//#endif + +void gpi_serialIsOpen(bool offen); + +bool epi_isSerialPortOpen(); + // true: port is open false: port is closed + + + +// Actions, GUI Buttons -> API, start cyclic transmission +void epi_startEmmision(bool start); // 1: start sending activated + +// Meldung von TabCom an Datif: starte zyklische Sendung: +bool gpi_isEmmisionOn(void); + + + +// /////////////////////////////////////////////////////////////////////////////////// +// Status Display gui <--> serial +// /////////////////////////////////////////////////////////////////////////////////// + + + // Statuszeile COM Port (serial Port) (open, closed) +// Display in tab_com +QString epi_getTxt4comStateLine(void); +void epi_clrTxt4comStateLine(); + // GUI: get Text for serial Comport-State Line + +//--------------------- +// Statuszeile Handshakes (serial Control) flow.cpp +// geht überhaupt was raus? kommt überhaupt was zurück? +// I +QString epi_getTxt4HsStateLine(void); +void epi_clrTxt4HsStateLine(); + // GUI: get Text + +// II Master receive state (empfangenes Telgramm OK? crc? length? ) +// Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) +QString epi_getTxt4masterStateLine(void); +void epi_clrTxt4masterStateLine(); + +// III Slave receive (from Master) OK? if then show results, if not then show errors +// entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR +// Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch +// nicht verwenden und nichts ausgeben oder einlesen +QString epi_getTxt4resultStateLine(void); +void epi_clrTxt4resultStateLine(); + +// IV Statuszeile Sende- und Empfangsdaten (Datif) +// Display in tab_com +QString epi_getTxt4dataStateLine(void); +void epi_clrTxt4dataStateLine(); +// GUI: get Text for serial Comport-State Line + +// V, unten, Datif +QString epi_getTxt4datifLine(void); +void epi_clrTxt4datifLine(); + +//--------------------- + + // sende-empfangs-Rohdaten-Fenster +// Display in tab_com +QString epi_getTxt4RsDiagWin(void); +void epi_clrTxt4RsDiagWin(); + +QString epi_get2ndTxt4RsDiagWin(void); +void epi_clr2ndTxt4RsDiagWin(); + + +// Statuszeile COM Port (serial Port) (open, closed) +// Display in tab_com +void gpi_setTxt4comStateLine(QString txtline); + // serial: write Text to be displayed in serial Comport-State line (like "connected") + // used in vcp.cpp, links in tabCom + + +// Statuszeile Handshakes (serial Control) +// I obere Zeile +void gpi_setTxt4HsStateLine(QString txtline); + // used in flow.cc + +// II +void gpi_setTxt4masterStateLine(QString txtline); + +// III +void gpi_setTxt4resultStateLine(QString txtline); + +// IV +void gpi_setTxt4dataStateLine(QString txtline); + // serial: write Text to be displayed in serial Comport-State line (like "connected") + // used in prot.cpp + +// V unten: +void gpi_setTxt4datifLine(QString txtline); + + +// sende-empfangs-Rohdaten-Fenster +// Display in tab_com +void gpi_setTxt4RsDiagWin(QString txtline); +void gpi_set2ndTxt4RsDiagWin(QString txtline); + +//#endif + +// /////////////////////////////////////////////////////////////////////////////////// +// Memory for Slave responses, common data +// /////////////////////////////////////////////////////////////////////////////////// + +bool epi_getResult_serialTestOK(); +// retval: true: test was successful, got right response + + +// result of serial line test, slave sent fixed string +void gpi_storeResult_serialTestOK(bool wasOn); + + +// /////////////////////////////////////////////////////////////////////////////////// +// restore just received data +// /////////////////////////////////////////////////////////////////////////////////// + + +void gpi_startNewRequest(); + // called by Datif + +void gpi_storeResultOfLastRequest(bool answisok); + // written by Datif + +uint8_t epi_getResultOfLastRequest(); + // retval: 0: in progress 1: OK 2: error + +void gpi_storeRecPayLoad(uint8_t RdDlen, uint8_t *receivedData); + // stored by Datif + +uint16_t epi_getLastPayLoad(uint16_t plBufSiz, uint8_t *payLoad); + // get data back in *pl, max 64 byte + // retval = nr of bytes received. If host buffer too small then + // only plBufSíz bytes are copied to pl + // plBufSíz=size of host buffer + +void gpi_storeSlaveSerParams(uint8_t slaveBaudRate, uint8_t NrDataBits, + uint8_t parity, uint8_t NrStopBits); + +void epi_getSlaveSerParams(uint8_t *slaveBaudRate, uint8_t *NrDataBits, + uint8_t *parity, uint8_t *NrStopBits); + +QString epi_getSlaveParamSTR(); + + +void gpi_storeLastResult(uint8_t letzteAntwort); + +uint8_t epi_getLastResult(void); + // return: 0xFF: result unknown 0=OK + // 1= wrong length 2=wrong start sign 5= wrong crc + // 6= slave: master cmd was wrong 7: slave: could not write/read data + // 8=timeout, got no response from slave + + +void epi_startSupervision(); +bool gpi_wantToResetSupervision(); + + + +void gpi_storeOverallResult(uint8_t letzteAntwort); + +uint8_t epi_getBatchResult(void ); + // 0xFF: no command sent by now + // 0: started, in progress + // 1: done and OK + // done and error + + +#endif + + + + + + + + diff --git a/include/datIf.h b/include/datIf.h new file mode 100644 index 0000000..42e442c --- /dev/null +++ b/include/datIf.h @@ -0,0 +1,206 @@ +// Data Interface between slave (DC) and pi buffer +// determines sending and receiving order of data +// cares for storing input data and restoring output data + + + +#ifndef DIF_H +#define DIF_H +#include "tslib.h" +#include "prot.h" +#include "dcBL.h" +//#include +#include +#include +#include +#include +#include +#include +#include "interfaces.h" + + + + +#define CMD2DC_sendTime 20 +#define CMD2DC_setWakeFrequ 112 +#define CMD2DC_MOV_UPLOCK 113 +#define CMD2DC_MOV_DNLOCK 114 +#define CMD2DC_UPPER_DOOR 115 +#define CMD2DC_LOWER_DOOR 116 +#define CMD2DC_VAULT_DOOR 117 +#define CMD2DC_REJMOT_ON 118 +#define CMD2DC_REJMOT_RUN 119 +#define CMD2DC_LED_COIN 100 +#define CMD2DC_LED_ILLU 101 +#define CMD2DC_LED_TICKET 102 +#define CMD2DC_LED_START 104 +#define CMD2DC_LED_PIN 103 +#define CMD2DC_LED_IN 105 +#define CMD2DC_FAN 106 +#define CMD2DC_SIREN 107 +#define CMD2DC_BARRIER 108 +#define CMD2DC_WAKEPTU 109 +#define CMD2DC_SWITCHAUXPWR 110 +#define CMD2DC_SWITCHAUXDDR 18 +#define CMD2DC_SWITCHAUXOUT 19 +#define CMD2DC_UCONTACTON 111 +#define CMD2DC_DEVICE_PARAM 23 +#define CMD2DC_SEND_MACH_ID 11 +#define CMD2DC_RDBK_DEV_PARA 14 + +#define CMD2DC_RDBK_MACH_ID 15 + +#define CMD2DC_MDB_ON 120 +#define CMD2DC_MDB_GET_STATE 107 // REQ +#define CMD2DC_MDB_DORESET 121 +#define CMD2DC_MDB_SETWAK 122 +#define CMD2DC_MDB_SENDCMD 123 +#define CMD2DC_MDB_SENDMSG 12 +#define CMD2DC_MDB_GETRESP 22 // REQ + +#define CMD2DC_EMP_SET 24 +#define CMD2DC_EMP_GET_ALL 23 // REQ +#define CMD2DC_EMP_STARTPOLL 124 +#define CMD2DC_EMP_STARTPAY 125 +#define CMD2DC_EMP_STOPPAY 126 +#define CMD2DC_EMP_GOTCOIN 108 // REQ +#define CMD2DC_SHUTTER_OPEN 129 +#define CMD2DC_ESCR_OPEN 132 +#define CMD2DC_ESCR_TAKE 133 +#define CMD2DC_ESCR_RETURN 134 +#define CMD2DC_MOD_ON 135 +#define CMD2DC_MOD_WAK 136 +#define CMD2DC_CRED_ON 137 +#define CMD2DC_CRED_WAK 138 + +// READ Commands ((e.g. get input) +#define CMD2DC_TestSerial 10 +#define CMD2DC_GetSerialConfig 105 +#define CMD2DC_RdBkHWversion 11 +#define CMD2DC_RdBkSWversion 12 +#define CMD2DC_RdBkDCstate 101 +#define CMD2DC_RdBkUID 18 +#define CMD2DC_RdBkTime 104 +#define CMD2DC_RdBkAnalog 106 +#define CMD2DC_GetAllInputs 102 +#define CMD2DC_RdBkAllOutputs 103 +#define CMD2DC_MIFREADERON 127 +#define CMD2DC_ATB_CREATE 128 + + + + +// Mif read data: +//#define CMD2DC_RdBk_MifState 109 +//#define CMD2DC_RdBk_MifData 24 + + + + +#define CMD2DC_RdBk_AtbCardType 25 +#define CMD2DC_SHUTTER_COIN 131 +#define CMD2DC_SHUTTER_OPEN3S 130 +//#define CMD2DC_SEND_SHUT_TIME 0x2915 +#define CMD2DC_ESCR_TAKE 133 +#define CMD2DC_ESCR_RETURN 134 +#define CMD2DC_PRINTERON 139 +#define CMD2DC_RdBk_PrnState 110 +#define CMD2DC_RdBk_PrnFonts 26 +#define CMD2DC_RdBk_AllPrnData 27 + // nr of params: +#define CMD2DC_PRI_SYS_CMD 25 // 3 +#define CMD2DC_PRI_ESC_CMD 26 // 4 +#define CMD2DC_PRI_SETUP 27 // 5 +#define CMD2DC_PRI_MOVE 140 // 2 +#define CMD2DC_PRI_SETFONT 141 // 4 +#define CMD2DC_PRI_SETLETTER 142 // 3 +#define CMD2DC_PRI_CUT 143 // 1 +#define CMD2DC_PRI_PRINT_TXT 13 // 64 +#define CMD2DC_PRI_LF 144 // 1 +#define CMD2DC_PRI_PRIFONTTABLE 145 +#define CMD2DC_PRI_BARCODE 14 // ca 15...25 +#define CMD2DC_STOR_QR_DATA 15 // 150 +#define CMD2DC_PRI_QR_CODE 146 // 0 +#define CMD2DC_PRI_LOGOFROMFLASH 147 // 2 +#define CMD2DC_PRI_STORE_DOC 16 // 1 +#define CMD2DC_PRI_DOCUMENT_NR 17 // 1 + 64 +#define CMD2DC_PRI_CLEAR_DOC 148 // 1 + + + +#define FIX_SLAVE_ADDR 0 +#define SEND_ATONCE 1 +#define SENDCOMBINED 0 + + + + +class T_datif : public QObject +{ + Q_OBJECT + + char sendINrequestsAutomatic(void); + // sende alle Befehle um die Eingangsdaten abzufragen der Reihe nach + char loadRecDataFromFrame(); + void datif_startSending(void); + void datif_sendIOrequest(uint16_t WRcmd, uint16_t RDcmd, uint8_t nrOfWrData); + + void datif_send8byteOutCmd(uint16_t WRcmd, uint16_t RDcmd); + + bool verifyLineTestresponse(uint8_t RdDlen, uint8_t *receivedData); + void datif_OUT_setTime(void); + uint8_t datif_OUT_SendRandomData(uint8_t *buf, uint8_t Length); + + //void datif_send64byteOutCmd(uint16_t WRcmd, uint16_t addr, uint16_t RDcmd); + + void datif_sendToMemory(uint16_t WRcmd, uint16_t docNr, uint16_t blockNr, uint8_t *data64); + // send printer documents to DC2 memory + // docNr: 0...15(31) with 1280 byte each (20 blocks a 64byte) + // blockNr=0...19 with 64byte each + // docNr =transmitted in WRITEADDRESS high byte + // blockNr=transmitted in WRITEADDRESS low byte + + int datif_noResponseCtr; + + T_prot *myDCIF; + QTimer *datif_trigger; + uint8_t selectedSlaveAddr; + +private slots: + char datif_cycleSend(); + void StoredRecData(); + +public: + T_datif(QObject *parent = nullptr); + + void resetChain(void); + char isPortOpen(void); + //void sendWRcommand(uint16_t nxtAsCmd); + // Sende Schreibbefehle die bereits vorher asynchron gespeichert wurden + //void send_requests(uint16_t nextWrCmd); + //void sendHighLevel(uint16_t nxtHLCmd); + + void startSupervision(void); + //void getOverallResult(void); + // 0xFF: no command sent by now + // 0: started, in progress + // 1: done and OK + // 2: done and error + + void getOverallResult(void); + + +signals: + void ResponseRecieved(); + //the requested data are stored in peripheral image + // can be loaded with epi + + void datif_templatePrintFinished_OK(); + void datif_templatePrintFinished_Err(); + + void datif_gotNewCoin(); + +}; + + +#endif // CI_H diff --git a/include/datei.h b/include/datei.h new file mode 100644 index 0000000..4ac62df --- /dev/null +++ b/include/datei.h @@ -0,0 +1,201 @@ +#ifndef DATEI_H +#define DATEI_H + +#include +#include +#include +#include "tslib.h" +#include +#include +#include +#include +#include + + // create csv file with: +#define FILESEPERATOR ',' + + // pasre csv with: +#define FILESEP1 ',' +#define FILESEP2 ';' + +#define NEWLINEINFILE '\n' +#define MAXNUMBEROFSEQUENCES 200 + // only for csv files + + +// all generated files located in sudirectory "dynamic machine data - dmd" + +#define FILENAME_SHAREDDATA "../dmd/DCshare.csv" +#define FILENAME_SHARED_UID "../dmd/DC_UID.csv" + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + + +// create array with strings and values (to be written to file) +void csv_startCreatingFile(void); +void csv_addTextToFile(QString myText); +void csv_addIntToFile(int myValue); +void csv_addUintToFile(uint myValue); +void csv_addLongvalToFile(qlonglong myValue); +void csv_addUlongvalToFile(qulonglong myValue); +//void csv_addCurrentTimeToFile(void); +//void csv_addCurrentDateToFile(void); +void csv_addNewlineToFile(void); +QByteArray csv_readbackArray(void); + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ parse csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + + +// return number of entries in the just read file (entries are seperated by +// comma or line-feed) +uint32_t csv_nrOfEntriesInFile(QByteArray readFromFile); + +// before: QByteArray sourceFile=datei_readFromFile(filename); + +QByteArray csv_getOneFileSequence(QByteArray sourceFile, uint32_t sequNr); +// not needed, just for test // sequNr: 0....(size-1) + +// get single entries of of the just read file: +int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + +QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr); + // sequNr: 0....(size-1) + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create Json Record ------------------------------- +// ------------------------------------------------------------------------------------------------- + +void json_startRecord(void); + // clear buffer and write opening curly bracket { + +void json_enterIntToRecord(QString attribute, ulong i_value); + // example: "parameter":1234567890 + +void json_enterTextToRecord(QString attribute, QString txt_value); + // example: "parameter":"slow" + +//void json_addCurrentTimeToRecord(QString attribute); + // example: if attribute=myTime: "myTime":"hh_mm_ss" + +//void json_addCurrentDateToRecord(QString attribute); + // example: if attribute=myDate: "myDate":"dd.mm.yyyy" + // also / possible as seperator + // further possible forms: + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + +void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals); + // add array of numbers with "nrofVals" elements + +void json_enterStructToRecord(QString attribute); + // every call must be concluded with an extra "json_finishFile()" + // example: "sname":{ + +void json_finishStruct(void); + +void json_finishRecord(void); + // close curly bracket + + +QString json_readbackRecordStr(void); + +QByteArray json_readbackRecordBa(void); + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ parse Json file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +// first: QByteArray datei_readFromFile(QString filename); + +//void datei_json_readTestFile(QString filename); + +int json_nrOfPairsInFile(QByteArray filename); + +bool json_exists(QByteArray filename, QString searchForKey); + // look for "searchForKey" =name of the pair (left of : ) + // retval true if exists + +bool json_remove(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and remove the record from file + // retval true if removed + +QString json_searchForStringInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_searchForIntInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +//....................... + +QJsonObject json_searchForObjectInFile(QByteArray filename, QString searchFor); + // return an object from the json file + +int json_nrOfPairsInObject(QJsonObject objname); + +QString json_searchForStringInObject(QJsonObject objname, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_searchForIntInObject(QJsonObject objname, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +//....................... + +QJsonArray json_searchForArrayInFile(QByteArray filename, QString searchFor); + // look for "searchFor" =name of the pair (left of : ) and return value of this pair (right of : ) as String + +int json_nrOfValuesInArray(QJsonArray arrayname); + +bool json_getValuesOfArray(QJsonArray arrayname, int *buf, int MaxBufferSize); + // assuming that the array consists of integers + + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ read, write, copy files ------------------- +// ------------------------------------------------------------------------------------------------- + +void datei_closeFile(QString filename); + +// read content of an exiting file: +QByteArray datei_readFromFile(QString filename); + +bool datei_ifFileExists(QString filename); + +char datei_writeToFile(QString filename, QByteArray content); + // retval=0 if successful 1: no write access allowed + // 2:cannot open to append 3:cannot create new file + +bool datei_copyFile(QString currentFileName, QString newFileName); + // retval=true if successful + +bool datei_clearFile(QString filename); + // retval=true if successful + +#endif // DATEI_H diff --git a/include/dcBL.h b/include/dcBL.h new file mode 100644 index 0000000..dc24743 --- /dev/null +++ b/include/dcBL.h @@ -0,0 +1,122 @@ +#ifndef DCBL_H +#define DCBL_H +#include "qbytearray.h" +#include "qstring.h" +#include +#include "storeINdata.h" + + +uint8_t dcBL_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf); +// make BL protocol, retval = outbuf length (5...133) +// bring data in correct form: start always with 0x02 finish with 0x03 and append checksum +// 0x02 Cmd < ...sendData ..> CRC CRC 0x03 +// Data length = 0...64 +// special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 +// so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + +uint8_t dcBL_readBLversion(uint8_t *sendData); + // minimum size of sendData-buffer: 5byte retval: length + +uint8_t dcBL_readFWversion(uint8_t *sendData); + // minimum size of sendData-buffer: 5byte retval: length + +uint8_t dcBL_exitBL(uint8_t *sendData); + // minimum size of sendData-buffer: 5byte retval: length + +uint8_t dcBL_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData); + // minimum size of sendData-buffer: 13byte retval: length (9...13) + +uint8_t dcBL_writeLastPage(uint8_t *sendData); + // minimum size of sendData-buffer: 5byte retval: length + +uint8_t dcBL_restartDC(uint8_t *sendData); + // minimum size of sendData-buffer: 20 byte retval: length + +uint8_t dcBL_activatBootloader(uint8_t *sendData); + // minimum size of sendData-buffer: 20 byte retval: length + + +bool dcBL_responseOK(); + // retval: 0: response OK (cmd |0x80) 1: response error (cmd or "0xe0") + +bool dcBL_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl); + +char dcBL_loadBinSafe(QString fileName); + + +bool dcBL_isTextMemFree(void); + +void dcBL_writeText(QString newTxt); + +bool dcBL_checkForText(void); + // if pointer at 0 then no more content + +QString dcBL_readText(void); + // read from 0...9 (oldest first) + +uint16_t dcBL_getNrOfBlocks(void); + // size of the loaded bin file in 64byte blocks + +uint16_t dcBL_getFileCrc(void); + // checksum of the loaded bin file + +uint32_t dcBL_getFileSize(void); + // length of the loaded bin file in byte + +uint8_t dcBL_getSizeOfLastBlock(void); + +bool dcBL_sendOneBlockCpl(uint16_t blockNumber); + +int8_t dcBL_getBlockResult(void); + +char dcBL_cycle(void); + // to be called cyclic every 100ms + + + +/* +void dcBL_iniChain(void); + +uint8_t dcBL_startChain(void); + +uint8_t dcBL_runChain(void); + +void dcBL_iniLoading(void); + +void dcBL_startLoading(void); + +uint8_t dcBL_sendHexfile(void); + + +uint8_t dcBL_getResult(void); +// call after every step to see what's going on.... +// 1: connected to BL +// 2: transmission started +// 3: transmission successful +*/ + +/* move to storeINdata and use shared mem as ptu-updater uses CAslave Lib 6.9.23TS +#define RAW_BL_DATALEN 150 +void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t *receivedData); + +uint8_t epi_getRawReceivedData(uint8_t *receivedData); + // retval=length, will be zeroed after first reading + +uint8_t epi_getRawRecLength(void); + // retval=length + +//QString epi_getRawReceivedString(); + // not used + +void epi_clrRawReceivedString(); +*/ + +uint8_t dcBL_sendSuccess(uint8_t lastCommand); + // return val: 0: no response by now 1:error 10: OK + // lastCommand=0x21 for sendAddr or 0x22 for send data + +char dcBL_loadBinary(char withDisplay); + + + +#endif // DCBL_H diff --git a/include/dc_result.h b/include/dc_result.h new file mode 100644 index 0000000..d91f59e --- /dev/null +++ b/include/dc_result.h @@ -0,0 +1,55 @@ +#ifndef DC_RESULT_H_INCLUDED +#define DC_RESULT_H_INCLUDED + + +#include +#include +#include + +class DCResult { +public: + enum class PLUGIN_STATE : quint8 { + NOT_INITIALIZED = 0, + INITIALIZED = 1 + }; + + enum class RESULT_STATE : quint8 { + SUCCESS = 1, // operation was successfull + ERROR_BACKEND, // error from backend (e.g. backend replies with error) + ERROR_TIMEOUT, // the operation timed out + ERROR_PROCESS, // internal plugin error, should not occur (this is a bug in implementation) + ERROR_RETRY, // retry operation + INFO // informational (e.g. display a message, log something etc.) + }; + + enum class CASH_STATE : quint8 { + CACHE_EMPTY, // Cache still empty, default state + CACHE_INPUT, // Coins are in Cache + OVERPAYED, + NOT_AVAILABLE + /* t.b.d. */ + }; + + explicit DCResult(); + explicit DCResult(PLUGIN_STATE, RESULT_STATE, QString errorCode = "", + QString errorDescription = "", + QString cashValue = ""); + explicit DCResult(PLUGIN_STATE, RESULT_STATE, CASH_STATE, + QString errorCode = "", + QString errorDescription = "", + QString cashValue = ""); + + PLUGIN_STATE m_pluginState; + RESULT_STATE m_resultState; + CASH_STATE m_cashState; + + QString m_errorCode; + QString m_errorDescription; + QString m_newCashValue; +}; + +QDebug operator<<(QDebug d, DCResult const &result); + +Q_DECLARE_METATYPE(DCResult) + +#endif // DC_RESULT_H_INCLUDED diff --git a/include/globdefs.h b/include/globdefs.h new file mode 100755 index 0000000..0349ab6 --- /dev/null +++ b/include/globdefs.h @@ -0,0 +1,305 @@ +// global defines +// ab 6.Juli2020: neuese Board DC2b + +#ifndef GLOBDEFS_H +#define GLOBDEFS_H + +#include + +//#define VERSION_DC_HW "DC2b_25.02.2020" +#define VERSION_DC_HW "DC2c_oct2022" +//#define VERSION_PO_HW "PO2d_27.03.2020" +#define VERSION_PO_HW "PO2e_nov2022" +#define VERSION_SW "DC2c.04.12 06.04.2023" +//#define VERSION_SW "DC2c.04.04b14.02.2023" +//#define VERSION_SW "DC2c.04.04c14.02.2023" + + +#define USE1256MODE 1 +#define SEND_DIAG_TO_MASTER 1 + +#define MAX_DATA_FROM_MASTER 64 +#define MAX_RECLEN_FROM_MASTER MAX_DATA_FROM_MASTER+20 + +#define MAX_DATA_TO_MASTER 64 +#define MAX_SENDLEN_TO_MASTER MAX_DATA_TO_MASTER+16 + +#define WORK_WITHOUT_HANDSHAKES + +#define PAGEBUFFERSIZE 1026 +extern UCHAR PageBuffer[PAGEBUFFERSIZE]; + +#define WAKESRC_NONE 0 +#define WAKESRC_MDB 1 +#define WAKESRC_COIN 2 +#define WAKESRC_MASTER 3 +#define WAKESRC_RTC 4 +#define WAKESRC_DOOR 5 +#define WAKESRC_DIAG 6 +#define WAKESRC_HB 7 + +struct T_power +{ + char busy; + char sleepAllowed; + UCHAR WakeSource; + char everythingUP; + char WokenByDevice; + char NoExternalEventNow; + char WakePulseNowActive; + UCHAR DC_status; // 0:POR 1:board ini 2:running HWtest 3: device ini 4: start-up-test + // 5: SW Module ini + UCHAR storeWakeReason[6]; + char blockRS2forMif; + char blockRS1forPrinter; +}; + + +struct T_globTime +{ + UCHAR Year; + UCHAR Month; + UCHAR Day; + UCHAR DOW; // 1(Mo)....7(So) + UCHAR Hours; + UCHAR Min; + UCHAR Sec; + UINT MinOfDay; // Anzahl Minuten des Tages 0...1439 + ULONG SecOfDay; + //UCHAR IsLeap; + //UCHAR aktuell; // 0,1 der der liest kann es auf 0 setzen + // und sieht dann wanns wieder aktuell +}; +extern struct T_globTime GlobTime; + +extern UCHAR main_getWakeEvent(void); + +struct T_out // für alle Levels +{ + UINT WrCmd; // was soll gemacht/gesetzt werden + UINT address; // z.B. bei Datenspeicher. Binär. + UCHAR datLen; // Anzahl nachfolgender Datenbytes + UCHAR inBuf[MAX_DATA_FROM_MASTER]; // kam so vom Master rein, soll ausgegeben werden +}; + + + +struct T_in // für alle Levels +{ + UINT RdCmd; // was soll gemacht/gesetzt werden + UINT address; // z.B. bei Datenspeicher. Binär. +}; + + + + +struct T_serial +{ + // basic machine settings ("DIP-Switches") + // to be stored in eeprom + UCHAR crcCheckOn; // 1,0 + UCHAR baudRate; // 1...8 + UCHAR parity; // 'E' 'O' 'N' + //UCHAR myAddr; // not needed + //UCHAR NowTestmode; // 1=on + UCHAR dataBits; // 8 + UCHAR stopBits; // 1 + UCHAR pad6; +}; + + +struct T_devices +{ + // set by master, used(1) or notused (0) or type 2....20 + // to be stored in eeprom + UCHAR kindOfPrinter; // 0:off 1:Gebe + UCHAR kindOfCoinChecker; // 0: without 1=EMP820 2=EMP900 3=currenza c² (MW) + UCHAR kindOfMifareReader; // by now only stronglink SL025 =1 + UCHAR suppressSleepMode; // 0:sleep allowed 1: no sleep + + UCHAR kindOfModem; // 0:off 1:Sunlink + UCHAR kindOfCreditcard; // 0:off 1:Feig NFC + UCHAR CoinEscrow; + UCHAR CoinRejectUnit; + + UCHAR CoinShutter; + UCHAR BillAcceptor; + UCHAR usevaultLock; + UCHAR autoAlarm; // 1: switch on siren for 1min in doors opened unauthorized + + UCHAR autoOpen; // 1: open door covers after valid ATBcard + UCHAR printAccReceipt; // 0/1 + UCHAR printDoorReceipt; + UCHAR printTokenTicket; + + UINT VaultFullWarnLevel; + UINT VaultFullErrorLevel; + +}; + +/* +struct T_cashAccept // 1.version des cash.json files +{ + // Values come from Json File + UINT coinsToAccept; // bit 15...0, je 1=accept 0=do not + UCHAR billsToAccept; // bit 7...0, je 1=accept 0=do not + UCHAR tokenChannel; + + ULONG exchgRate; // Multiplikator local -->foreign currency + // eg: hungary: 380 (380Ft = 1EUR) + + UINT foreignCoinValue[8]; + UINT localCoinValues[8]; // read from coin checker + +}; */ + +struct T_cashAccept +{ + // all Values come from Json File + // struct will be stored in eeprom. respect 4byte-borders + + UINT CoinDenomination[16]; // 15...8 =foreign coins 7..0 =local coins + UINT CoinValues[16]; // 15...8 =foreign coins 7..0 =local coins + // bei der lokalen Landeswährung wird der Wert eines Geldstückes + // direkt verwendet, da steht genau das gleiche drin wie in "Denom" + // Die ausländischen Münzen werden hier umgerechnet, z.B. 100cent=378Huf + //char Coins2Accept[16]; + // kommt jetzt direkt aus Json und ersetzt: + UINT coinAcceptance; // bit 15...0, je 1=accept 0=do not + + ULONG exchgRate; // Multiplikator local -->foreign currency + // eg: hungary: 380 (380Ft = 1EUR) + UCHAR tokenChannel; // 0=off, oder 1..16 + UCHAR res1; + UCHAR res2; + UCHAR res3; + + UINT billValues[8]; + + //UCHAR localTaxRate; + //UCHAR foreignTaxRate; + + //UINT surcharge; + //UINT discount; + //UINT res4; + //UINT res5; + +}; + +struct T_machID +{ + // liegen im int. eeprom + // to be stored in eeprom + UINT customerNumber; + UINT machineNumber; + UINT borough; // =group + UINT zone; + UINT alias; // for example another machine number for customer + UINT firstrun; + UCHAR location[32]; + +}; + +struct T_moduleCondition +{ + // store conditon of all system components, hold in RAM + // 0 means unknown, not yet tested/used + // 1 means OK + // 50..99 = HINT / Notification + // 100..150 = WARNING + // 200..250 = ERROR + + UCHAR structStart; // always first!!! + UCHAR ram; // v + UCHAR intEe; // v + UCHAR extEe; // v + + UCHAR rtc; // 1: time/date OK 100: time not plausible 200: hardware error + UCHAR boardHw; // v + UCHAR printer; // v + UCHAR modem; // v + + UCHAR signal; // 1...99 + UCHAR regist; // 100:not 1:reg 2:ping OK 3:gotTime + UCHAR mdbBus; + UCHAR coinChecker; // EMP, OMP or mei-cashflow + + UCHAR coinEscrow; // v + UCHAR mifareReader; // v + UCHAR creditTerm; // not available + UCHAR coinReject; // v + + UCHAR coinSafe; // v + UCHAR billSafe; // v + UCHAR voltage; // v // 1:11..14V + UCHAR temper; // v + + UCHAR poweronTest; + UCHAR doorState; // 1: alles zu 200: tür offen + bit1(S) +bit2(CB) + bit3(CB) + UCHAR doorWasOpened; // 1: all doors are closed 200: any door was just opened + UCHAR changer; // can only be tested by usage + + UCHAR coinBlocker; // can only be tested by usage + UCHAR billReader; // can only be tested by usage + UCHAR ResetReason; + UCHAR allModulesChecked; + + UCHAR alarmState; + UCHAR res11; + UCHAR res12; + UCHAR res13; + +}; + +struct T_dynamicCondition +{ + // dynamic conditions, change rapidly and frequently + // these are values for the Heartbeat + + // Türschalter entprellt: + char upperDoor; // 0:fehlt 1:drin + char middleDoor; + char lowerDoor; + char coinBox; + + char billBox; + char modeAbrech; + char onAlarm; + char nowCardTest; + + char nowPayment; + char lastMifCardType; + char openedAuthorized; + char allDoorsDebounced; + + UCHAR lastSDoorState; + UCHAR lastVDoorState; + UCHAR CBinDebounced; + UCHAR lastCBstate; + + char paymentInProgress; + char res1; + char res2; + char res3; + + UINT U_Batt; + UINT Temperatur; + + UINT cash_storedaccNumbers[8]; // List all stored accounting numbers in ext. eeprom + + UINT nrCoinsInBox; + UINT resui1; + + ULONG amountInBox; + ULONG amountJustPaid; + + UINT lastInsCoinType; // wahrscheinlich uchar + UINT resui2; + + ULONG totalTransVolume; + ULONG totalNrOfVends; + +}; + +#endif + diff --git a/include/hwapi.h b/include/hwapi.h new file mode 100644 index 0000000..098ffdf --- /dev/null +++ b/include/hwapi.h @@ -0,0 +1,1386 @@ +/* +matching interfaces.h: + +// History +// 11.10.2021: V1.0 222 functions +// 23.12.2021: V1.1 added block-parameter to function "read mifare data" +// 30.12.2021: V1.2 added function: mif_clearDataBuffer(), mif_isBlockAvailable(uint8_t blkNr) and mif_getAvailableDataBlocks() +// 1.1.2022: V1.3 Mifare extended. ( background: read 16 x 48byte from card to DC, read 12 x 64byte from DC to CA) +// new: read full card with 768bytes from HWapi without block borders +// added: mif_getNrOfAvailableDataBytes mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize) +// mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize) +// mif_getCardDataStr(bool useHexFormat, char seperator) +// 29.03.2023: V3.1 some extensions for PSA1256_ptu5, +// V3.2 Bootloader improvement +// 12.04.2023: V3.3 new features extended: loading and using Json-files, cash-collection, cash-data-logging + +//#define HWINF_iid "Atb.Psa2020.software.HWapi/3.1" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.1" +#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.3" + +V4.0 6.9.2023: activating DC-Bootloader in slve-lib (SM) + +*/ + + +#ifndef hwapi_H +#define hwapi_H + +#include +#include +#include +#include +#include "tslib.h" +#include "datIf.h" +#include +#include "sendWRcmd.h" +#include "controlBus.h" +#include "storeINdata.h" +#include "dcBL.h" +#include "interfaces.h" +#include "shared_mem_buffer.h" +#include "runProc.h" + + +/* + * select Plugin Type here + * + * CashAgent (CA) Master Library: + * uses a serial port to communicate with device controller (DC) + * stores all received data into shared memory (SM) and writes all output data + * from SM to DC + * use interfaces.h to read/write data from/into SM + * CAmaster must be used only ONE time, as there is only one serial port hardware + * and only ONE DC. Using multiple will lead to a crash. + * + * CAslave Library: + * provides all the same functions as Master + * use interfaces.h to read/write data from/into SM + * May be used multiple times with one restriction: + * Output commands can be set double and ambigious but + * the output itself can only have ONE state!! + * Library users must know and coordinate this. + * + * The only difference between CAslave and CAmaster + * (apart from following define) + * is the *.pro file with different Target name and Path + * + * ATB, Thomas Sax, 21.06.2023 + */ + +//for CAslave: +//#undef THIS_IS_CA_MASTER + +//for CAmaster: + +class QSharedMemory; + +class hwapi : public QObject, + public hwinf +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "Atb.Psa2020.software.HWapi/1.0" ) //FILE "HWapi.json") + Q_INTERFACES(hwinf) + +private: + void sub_storeSendingText(QByteArray *buf) const; + QTimer *hwapi_TimerPayment; + QSharedMemory *m_sharedMem; + //QTimer *hwapi_triggerBL; + +public: + explicit hwapi(QWidget *parent = nullptr); + + + #ifdef THIS_IS_CA_MASTER + T_datif *myDatif; + #endif + + T_runProc *runProcess; + + // ------------------------------------------------------------------------------ + // commands, interface + // open, close, change serial interface + // actually not neccessary as it is opened automatically on program start + // start automatic READ requests + // ------------------------------------------------------------------------------ + + bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const override; + // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 + // BaudStr: for exapmle "19200" + // ComName: for example "COM48" + // connect: 0, 1 + + void dc_closeSerial(void) const override; + + + bool dc_isPortOpen(void) const override ; + + void dc_autoRequest(bool on) const override ; + // select if READ-Requests are sent manually one by one or automatically + // automatically request ALL digital and analog sensors, get time/date, get status information + + void dc_requTestResponse() const override; + // tell DC2 to return his TestString in order + // to test the serial and the baudrate + // must always be triggered manually, is never sent automatically + + bool dc_readAnswTestResponse() const override; + // retval: true: test was successful, got right response + + uint8_t dc_isRequestDone(void) const override; + // retval: 0: request is still in progress + // 1: answer from DC2 was OK + // 2: wrong answer from DC2 + + uint16_t dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const override; + // get data back in *pl, max 64 byte, can be used for diagnosis + // retval = nr of bytes received. If host buffer too small then + // only plBufSíz bytes are copied to pl + // plBufSíz=size of host buffer + + void dc_setWakeFrequency(uint8_t period) const override; + // RTC wakes DC2 (and PTU) by hardware signal every 32seconds + // change wake signal period to 1...64s + + void dc_OrderToReset(void) const override; + // want DC2 to reset (in order to start Bootloader) + + + QString dc_getSerialState(void) const override; + + void dc_clrSerialStateText(void) const override; + + + void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const override; + // send without protocol frame, needed for the DC bootloader + + uint8_t getRawRecLength(void) const override; + + uint8_t getRawReceivedData(uint8_t *receivedData) const override; + + QString dc_getSerialParams(void) const override; + + QString dc_getHWversion(void) const override; + + QString dc_getSWversion(void) const override; + + QString dc_getState(void) const override; + + +// ---------------------------------------------------------------------------------------------------------- +// Date and Time +// ---------------------------------------------------------------------------------------------------------- + + uint8_t rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const override; + + uint8_t rtc_setDateTime(void) const override; + // synch DC2 with PC or PTU system time and date + + void rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const override; + // get time directly + + void rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const override; + // get date directly + + uint8_t rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const override; + // dow=day of week, 1=monday...7 + // minOfToday: 0=midnight...1439= 23:59 + // secOfToday: 0=midnight...86399= 23:59:59 + + bool rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const override; + // retval true: this year is leap year + + bool rtc_isLeapYear() const override; + + void rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const override; + // DayOfWeek: 1=monday...7 + // HoursOfWeek: 0=Monday 0:00 o'clock...167=Sunday 23:00 + // MinutesOfWeek: 0=Monday 0:00 o'clock...10079=Sunday 23:59 + + void rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const override; + // DayOfMonth: 1...31 + // HoursOfMonth: 0 = 0:00o'clock of 1.day in month up to 743 + // MinutesOfMonth:0 = 0:00o'clock of 1.day in month up to 44639 + + void rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const override; + // DayOfYear: 1...366 1= 1.Jan of this current year + // HoursOfYear: 0=1.Jan 0:00o'clock ...8783=31.12 23 o'clock + // MinutesOfYear: 0=1.Jan 0:00o'clock ...527039=31.12 23:59 o'clock + + QString rtc_getTimStr(void) const override; + QString rtc_getDatStr(void) const override; + QString rtc_getTimDatStr(void) const override; + + // UID + void dc_getUID8byte(uint8_t *buf8byteUid) const override; + QString dc_getUIDstr() const override; + uint64_t dc_getUIDnumber(void) const override; + +// ---------------------------------------------------------------------------------------------------------- +// analogs +// ---------------------------------------------------------------------------------------------------------- + + // Analog inputs: + uint32_t dc_getTemperature(void) const override; // in Sax-Format 0...400 (0=-50,0°C 100=0,0°C 141=20,5°C 400=150,0°C) + QString dc_getTemperaturStr(void) const override; + + uint32_t dc_getVoltage(void) const override; // in mV, 0...65,535V + QString dc_getVoltagStr(void) const override; + + bool dc_mainFuseIsOk(void) const override; + +// ------------------------------------------------------------------------------ +// digital outputs +// ------------------------------------------------------------------------------ + + // Locks move until stop cmd (0) + uint8_t lock_switchUpperLock(uint8_t dir) const override; + // dir 0=off 1=up 2=down + uint8_t lock_switchLowerLock(uint8_t dir) const override; + // dir 0=off 1=up 2=down + void lock_switchVaultDoor(void) const override; + + void coin_switchRejectMotor(uint8_t dir) const override; + + void coin_rejectCoins(void) const override; + + // LEDs + void led_switchLedService(uint8_t on) const override; + void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const override; + void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const override; + void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const override; + void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const override; + + void fan_switchFan(bool on) const override; + void alarm_switchSiren(bool on) const override; + void bar_OpenBarrier(bool open) const override; + void ptu_switchWake(bool WAKEACTIVE) const override; + + void aux_power(bool on) const override; + void aux_setUsage(uint8_t PinDirection) const override; + void aux_setOutputs(uint8_t PinIsHigh) const override; + + void lock_switchContactPower(bool on) const override; + + void prn_switchPower(bool on) const override; + + void mif_readerOn(bool on) const override; + + void mif_creatAtbCard(uint8_t cardType) const override; + + void mod_switchPower(bool on) const override; + + void mod_switchWake(bool WAKEACTIVE) const override; + + void mdb_switchPower(bool on) const override; + + void mdb_switchWake(bool WAKEACTIVE) const override; + + void credit_switchPower(bool on) const override; + + void credit_switchWake(bool WAKEACTIVE) const override; + + void shut_move(bool open) const override; + + void esc_moveFlaps(uint8_t flap ) const override; + // 0: close both 1: open take-flap 2: open return + + + +// ------------------------------------------------------------------------------ +// door, cashbox and lock switches +// ------------------------------------------------------------------------------ + + uint8_t door_getSwitches(void) const override; + // retval: bit0: upper door 1: low door 2:vault door + + bool door_isUpperDoorOpen(void) const override; + + bool door_isLowerDoorOpen(void) const override; + + bool vault_isVaultDoorOpen(void) const override; + + uint8_t vault_getSwitches(void) const override; + // retval bit0: cash box, bit 1: bill box + + bool vault_isCoinVaultIn(void) const override; + + bool vault_isBillVaultIn(void) const override; + + uint8_t door_getLocks(void) const override; + // retval bit0: upper lever is up + // bit1: upper lever is down + // bit2: lower lever is up + // bit3: lower lever is down + + bool door_upperDoorIsLocked(void) const override; + + bool door_upperDoorIsUnlocked(void) const override; + + bool door_lowerDoorIsLocked(void) const override; + + bool door_lowerDoorIsUnlocked(void) const override; + + bool bar_optoIn1isOn(void) const override; + + bool bar_optoIn2isOn(void) const override; + + uint8_t aux_getAuxInputs(void) const override; + + bool ptu_WakeINisActive(void) const override; + + bool mdb_WakeINisActive(void) const override; + + bool prn_readyINisActive(void) const override; + + bool coid_isAttached(void) const override; + + bool coin_escrowIsOpen(void) const override; + + bool mif_cardIsAttached(void) const override; + +//bool hwapi::mod_WakeINisActive(void); + + bool door_isContactPowerOn(void) const override; + + bool mif_isMifarePowerOn(void) const override; + + bool mdb_testIsmdbTxDon(void) const override; + + bool aux_isAuxPowerOn(void) const override; + + bool mod_isGsmPowerOn(void) const override; + + bool cred_isCreditPowerOn(void) const override; + + bool prn_isPrinterPowerOn(void) const override; + + uint8_t prn_PrnFuseIsOk(void) const override; + //retval: 0: fuse blown 1: fuse OK 2:unknown as printer power is off + + bool mdb_isMdbPowerOn(void) const override; + + bool cash_getRejectMotorHomePos(void) const override; + + uint8_t cash_getLowPaperSensor(void) const override; + // 0: Sensor sees paper 1: no paper 99: off + + + // ------------------------------------------------------------------------------ + // request commands + // ------------------------------------------------------------------------------ + + // all read-requests can be sent manually by the following functions + // or automatically in background by: void hwapi::dc_autoRequest(bool on) + + void request_DC2serialConfig() const override; + void request_DC2_HWversion() const override; + void request_DC2_SWversion() const override; + void request_DC2_condition() const override; + void request_DC2_UID() const override; + void request_DC2_TimeAndDate() const override; + void request_DC2_analogues() const override; + void request_DC2_digitalInputs() const override; + void request_DC2_digitalOutputs() const override; + + // ------------------------------------------------------------------------------ + // the folowing device state requests are deploed only if device is powered up: + void request_PrinterHwState() const override; + void request_PrinterCurrentFonts() const override; + void request_PrinterStateComplete() const override; + + void request_MifareReaderState() const override; + void request_MifareCardType() const override; + void request_MifareAtbType() const override; + void request_MifareID() const override; + void request_MifareData(uint8_t dataBlockNumber) const override; + // dataBlockNumber must be 0....11, returns 64byte of data + + void request_MDB_Status() const override; + void request_MDB_lastResponse() const override; + void request_EMP_allParameters() const override; + void request_EMP_lastCoin() const override; + + + + // ------------------------------------------------------------------------------ + // readback digital outputs of connected devices + // these functions are not needed for normal operation + // but can be used to test and verify conditions + // ------------------------------------------------------------------------------ + + bool test_getDO_mdbRXtst(void) const override; + + uint8_t lock_getDO_motors(void) const override; + // bit0: upper lock forward bit 1 backward + // bit2: lower lock forward bit 3 backward + + //virtual uint8_t test_serialState(void) const =0; ??? + uint8_t test_serialState(void) const override; + // test on-board signals for the serials + // serial drv on/off, Serial mux1, Serial mux2 + + //virtual bool test_serialIsOn(void) const =0; ???? + bool test_serialIsOn(void) const override; + + bool test_serialMux1isSetToPrinter(void) const override; + bool test_serialMux1isSetToModem(void) const override; + bool test_serialMux2isSetToCredit(void) const override; + bool test_serialMux2isSetToMifare(void) const override; + + bool led_coinIsOn(void) const override; + bool led_frontIsOn(void) const override; + bool led_ticketIsOn(void) const override; + bool led_pinIsOn(void) const override; + bool led_StartIsOn(void) const override; + bool led_insideIsOn(void) const override; + + bool fan_isOn(void) const override; + bool siren_isOn(void) const override; + bool bar_relayIsOn(void) const override; + bool ptu_WakeOutIsOn(void) const override; + + bool aux_powerIsOn(void) const override; + + bool coin_shutterIsOpen(void) const override; + bool coin_shutterTestOutput(void) const override; + + uint8_t coin_escrowFlapOpened(void) const override; + // retval: 1:return flap is open 2:take flap is open 0:closed + + + +// ------------------------------------------------------------------------------ +// devices are operated by DC +// processes with more then one devices +// timer controlled or long term processes +// ------------------------------------------------------------------------------ + + + void sendDeviceSettings(uint8_t kindOfPrinter, uint8_t kindOfCoinChecker, + uint8_t kindOfMifareReader, uint8_t suppressSleep, + uint8_t kindOfModem, uint8_t kindOfCredit ) const override; + // enable hardware in device controller: + // kindOfPrinter: 0:off 1: GPT4672 (only this one implemented) + // kindOfCoinChecker: 0:off 1:EMP820 2:EMP900 3: C²_changer + // kindOfMifareReader: 0:off 1: SL025 (only this one implemented) + // suppressSleep: 0:sleep allowed 1: sleep surpressed for special reason + // kindOfModem: 0:off 1: ATB_Sunlink_LTE (not yet implemented) + // kindOfCredit: 0:off 1: cVendTopp 2:cVendPin (not yet implemented) + + void request_ReadbackDeviceSettings() const override; + + void readback_DeviceSettings(uint8_t *length, uint8_t *data) const override; + // refer to DC2 manual for exact content + // state 5.5.21: byte[0]=kindOfPrinter byte[1]=kindOfCoinChecker + // byte[2]=kindOfMifarereadr byte[3]=suppress sleep mode + // byte[4]=kindOfModem byte[5]=kind of cc terminal + + void sendMachineID(uint16_t customerNr, uint16_t machineNr, + uint16_t borough, uint16_t zone, + uint16_t alias, char *location) const override; + + void request_ReadbackMachineID() const override; + + void readback_machineIDdata(uint8_t *length, uint8_t *data) const override; + // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number + // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name + // byte[10...41]=location + + // Locks stops automatically at end switch or by timeout + uint8_t lock_openUpperDoor(void) const override; + uint8_t lock_closeUpperDoor(void) const override; + + uint8_t lock_openLowerDoor(void) const override; + uint8_t lock_closeLowerDoor(void) const override; + + void shut_openOnce(void) const override; + // and close automatic after shutter time + + void shut_openForCoin(bool start) const override; + // open flap if coin is attached + // once process is started it runs until stop command + + void shut_sendOpeningTime(uint16_t timeIn_ms ) const override; + // after this time without retrigger the flap is closed + + void esc_takeMoney(void) const override; + // and close automatically after escrow time (1s) + + void esc_returnMoney(void) const override; + // and close automatically after escrow time (1s) + + +// ---------------------------------------------------------------------------------------------------------- +// --------------------------------------------- MIFARE ----------------------------------------------------- +// ---------------------------------------------------------------------------------------------------------- + + // obsolete + uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const override; + // retval 0=OK 1=error host buffer too small + /* data description, new fast version: + byte 0= still the same: current read state: + 0=power off 1=reader-fault 2=ready + 3=just reading 4=read complete + 5=read partial, removed too early + 6=state unknown + + byte 1: reader state 1=ok 0=nok + byte 2: card preent (0,1) + byte 3: card selected (0) + byte 4: card type: 0...5 + byte 5: card allowed (0=no 1=MifareClassic 1k or 4k) + byte 6: CardSize: 1 or 4 (kB) + byte 7: length of UID 4 or 7 (byte) + */ + + bool mif_readerIsOK(void) const override; + + bool mif_cardAttached(void) const override; + + uint8_t mif_readResult(void) const override; + // result: 0: unknown or still in progress + // 1: card read successful + // 2: reading error + + QString mif_cardUID(void) const override; + + uint8_t mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const override; + + QString mif_getCardDataStr(uint8_t blockNumber) const override; + // with blockNumber=0...11 + + + + + // ---------------------------------------------------------------------------------------------------------- + // --------------------------------------------- PRINTER ---------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------- + + // read printer condition and settings + + uint8_t prn_getHwState(struct Tprn_hw_state *prn_hw_state) const override; + // retval: status byte + // byte 0 = 0: prnter OK, >0: error + // bit0: paper low 1: no paper 2: temperature error + // 3: head open 4: paper jam in cutter + // 6: no response 7: bad response from printer + // and return struct "Tprn_hw_state" + + bool prn_isUpAndReady(void) const override; + // true: printer is powered, serial is ok, no error, printer is connected and resonding + + void prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const override; + + + // send Commands to printer: + + void prn_sendText(QByteArray *buf) const override; + // up to 1280 bytes + + void prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const override; + // send three byte through to printer, see printers manual + + void prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const override; + // send four byte through to printer, see printers manual + + + void prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density, uint8_t alignment, uint8_t orientation) const override; + // send 5 byte: byte 0,1: speed 5...250 mm/s + // byte2: density 0....(25)....50 + // byte3: alignment 'l', 'c', 'r' = left, center, right + // byte4: orientation 0, 90, 180 = 0°, 90°, 180° rotation (by now not supported!) + // not batched! don't use twice within 100ms + + void prn_movePaper(uint8_t wayInMm, uint8_t direction) const override; + //direction: 1=forward 2=backward + // + void prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const override; + // font = kind of font 5...11 (0..22) + // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge + // width: 0...4 0=1x 1=2x 2=4x (huge!) 3=8x 4=16x (3,4 make no sense) + // heigth: 0...7 = 1x...8x only 0,1,2,(3) make sense + + void prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const override; + // bold: 0/1 + // invers: 0/1 + // underlined: 0/1 + + void prn_cut(uint8_t kindof) const override; + // kindof: 1=full cut 2=partial cut 3=eject (5xLF + full cut) + + void prn_newLine(uint8_t nrOfLines) const override; + + void prn_printCompleteFontTable(void) const override; + + + void prn_printBarcode(uint8_t kindOf, uint8_t withText, uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const override; + // kind of barcode: 0=Code39 1=Code128 2=EAN13 3= 2/5interleaved 4=UPC-A 5=EAN8 + // withText: print readable text below + // offset: move by pixel from left border + // rotation + // dataLeng in byte + + void prn_sendQRdata(QByteArray *buf) const override; + // maximal 150 alphanummeric bytes + + void prn_printQRcode(void) const override; + // QRcode may have 1...150 alphanummeric data, must be transfered in advance + + + void prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const override; + // nrOfLogo: 1..4 in flash 5...8 in Ram + // offset: in mm form left border + + + + // ......................................................... + // Parking Ticket (print-out document) designer TD - obsolete + // ......................................................... + + // Predefine document Layout (e.g. parking ticket) in advance and stroe it for quick and easy use + // in opposite to the above "single" commands you need only one or a few commands at vending time. + // Stored text is just send to printer once the printing command is issued + // stored commands within the text are interpreted and executed right at the place (in ticket) they are + // example: start bold, , stop bold + // Predefinition of up to 16 ticket Layouts is possible, 0...1280 byte each + // Number 0..15, al keept non-volatile + // up to 8 dynamic values can be defined in the template ("print val3 here") and will be sent with printing command + // example: print current time at this point (the time of printing not the storage time!!) + + //void pri_startTicketDesign(void) const override; + // start for every new printer document, reseting collecting buffer + + // all further functions write/append text, numbers and command to the ticket-buffer, up to 1278 bytes allowed + // return val of the appending functions: true=ok false=too long, buffer full + + //int pri_TD_getCurrentSize(void) const override; + // retval: 0...1278 + + //bool pri_TD_addText(QByteArray text) const override; + // example: pri_TD_addText("Hello") const override; + // example: pri_TD_addText(tempStr) const override; + // retval: true=ok false=too long, buffer full + + //bool pri_TD_addValue(int val) const override; + // +/- 0...2^(31) + + //bool pri_TD_addNewLine(void) const override; + + //bool pri_TD_addSign(char sign) const override; + // example: '.' ' ' 0x20 'W' '$' + + //bool pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const override; + // always add 8 byte to the ticket layout: ESC & group & attribute & parameter1...5 + /* complete list of possible commands: + group 50 : paper + attribute 10 : move forward + p1: wayInMm p2: direction + attribute 11 : cut + p1: kind of, 1=full 2=partial, 3=eject + attribute 12 : new line(s) + p1: nr of lines 1...100 + + group 51 : fonts + attribute 10 : kind of font see description above + p1: 0...8 + attribute 11 : font size + p1: 6...20 + attribute 12 : font width + p1: 0...4 + attribute 13 : font heigth + p1: 0...7 + attribute 14 : switch bold print on/off + p1: 0=off 1=on + attribute 15 : switch invers print on/off + p1: 0=off 1=on + attribute 16 : switch underlined print on/off + p1: 0=off 1=on + + group 52 : print graphics + attribute 10 : print barcode with dynamic data 6 and 7 + p1...p5 = kindOf, withText, offset, rotation, dataLeng, see description above + attribute 11 : print QRcode with preset data + + attribute 12 : print Logo + p1=nrOfLogo, p2=offset + + group 53 : print dynamics + attribute 10 : + p1: 1...8 = print dynData 0..7 at this place + + */ + + //char prn_clearDocument(uint8_t documentNumber) const override; + // clear memory buffer for ONE document + // function takes a second! don't send right before "store doc" + + //bool prn_store_Document(uint8_t documentNumber ) const override; + + // send the predefined Layout (generated with above TD functions) to DeviceController to save + // documentNumber=0...15 + // maximal 1280 bytes each + // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc) + // 0x1B=start of embedded command (next 7bytes = command) + + // with a print command a set of 8 dynamic strings can be sent + // the place in the ticket layout is predefined (already in DC memory) + // the dynamics are first calculated at printing time + + //bool prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const override; + + + + + + // ---------------------------------------------------------------------------------------------------------- + // --------------------------------------------- MDB Bus ---------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------- + + void mdb_sendBusReset(void) const override; + + void mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const override; + // send one bus command directly over mdb bus, refer to mdb manual for commands + // this command is not needed in normal operation, just for new or special things + + void mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const override; + // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs + // same as mdb_sendCommand, just with data + + bool mdb_busIsReadyToWork() const override; + + bool mdb_deviceVoltageOK() const override; + + bool mdb_busVoltageOk() const override; + + uint8_t mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest, + uint8_t *responseLength, uint8_t *responseBuffer) const override; + // fromDevice: device nr from which data was requested 0,1,2,3 + // lastRequest: sent mdb command + // responseLength: nr of payload data (after mdb-ack) 0...34 + // responseBuffer holds payload data (answer from mdb device) + // return val: mdb result of this request: 1=got ACK 2=got 3xNAK 3=no or bad response 4:got Data (after ACK) + + + + + + // ---------------------------------------------------------------------------------------------------------- + // ---------------------------------- Electronic Coin Validator EMP ----------------------------------------- + // ---------------------------------------------------------------------------------------------------------- + + + void emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const override; + // coinAcceptance: bit0=coin1 (lowest donomination) bit15=coin16 bitH=accept bit L = deny coin (no validation) + // tokenChannel 0...31: if this signal comes from emp then a token was inserted + // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...) + + void emp_pollingOnOff(uint8_t on) const override; + + void emp_startCoinAcceptance(void) const override; + + void emp_stopCoinAcceptance(void) const override; + + void emp_getAllParameters(struct T_emp *emp) const override; + // see struct in hwapi.h + // usage example: + // hwapi *HWaccess const override; + // HWaccess = new hwapi() const override; + // struct T_emp myEmp const override; + // HWaccess->emp_getAllParameters(&myEmp) const override; + // readval=myEmp.pollingRunning const override; + + uint8_t emp_chkIfCoinInserted(void) const override; + // retval: 0...16 coins left in FIFO + + void emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const override; + // with every call ONE coin is taken out of FIFO and pointer decremented + // valid: should be 1 + // signal: comes right from coin checker, 0...15 (0=first programmed coin type) 0xFF=no signal + // error: was reported from EMP as dynamic signal right after coin insertion (instead of + // coin signal), example: 3=unknown coin 4=coin is blocked by host. 0xFF=no error + // value: of the coin. Depends on parameter "coinDenomination" in function "emp_sendSettings" + // if coinDenomination[coin 0..15] = 0 then the value programmed in coin checker is taken + // if coinDenomination > 0 then this value is taken. + // Useful in case of two currencies (adapt to local currency) or for token. + + // function gives more details as "emp getLastCoin()" but "emp getLastCoin()" is easier to use + + // alternativ to emp_getNewCoinRecord( ): + uint8_t emp_giveLastCoin(uint16_t *value, uint8_t *signal) const override; + // retval: 0: NO coin stored 1: valid coin 2: got wrong coin or coin denied + // value: if retval1: value of the coin if reval=2: error number + // 0xFF means NO error or NO signal (as 0 is a valid error/signal) + // signal: channel nr reported from checker 0...15 + + + uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const override; + // use for changer + + +//#ifdef THIS_IS_CA_MASTER + QString dc_getTxt4RsDiagWin(void) const override; + void dc_clrTxt4RsDiagWin(void) const override; + QString dc_get2ndTxt4RsDiagWin(void) const override; + void dc_clr2ndTxt4RsDiagWin(void) const override; + QString dc_getTxt4HsStateLine(void) const override; + void dc_clrTxt4HsStateLine(void) const override; + QString dc_getTxt4masterStateLine(void) const override; + void dc_clrTxt4masterStateLine(void) const override; + QString dc_getTxt4resultStateLine(void) const override; + void dc_clrTxt4resultStateLine(void) const override; + QString dc_getdataStateLine(void) const override; + void dc_clrTxt4dataStateLine(void) const override; + QString dc_getdatifLine(void) const override; + void dc_clrTxt4datifLine(void) const override; +//#endif + + + + +// ---------------------------------------------------------------------------------------------------------- +// -------- DC Bootloader 1.Version +// ---------------------------------------------------------------------------------------------------------- + + // using DC2 Bootloader + void bl_iniChain(void) const override; + bool bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const override; + uint8_t bl_activatBootloader(uint8_t *sendData) const override; + uint8_t bl_startChain(void) const override; + uint8_t bl_readBLversion(uint8_t *sendData) const override; + // minimum size of sendData-buffer: 5byte retval: length + uint8_t bl_readFWversion(uint8_t *sendData) const override; + // minimum size of sendData-buffer: 5byte retval: length + + uint8_t bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const override; + // make BL protocol, retval = outbuf length (5...133) + // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum + // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 + // Data length = 0...64 + // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 + // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + + uint8_t bl_exitBL(uint8_t *sendData) const override; + // minimum size of sendData-buffer: 5byte retval: length + + + + void led_switchLedIllumination(uint8_t on) const override; + + + +// ------------------------------------------------------------------------------------ +// 27.3.2023: Use Device-Controller's Bootloader to send hex-file +// ------------------------------------------------------------------------------------ + + void bl_rebootDC(void) const override; + + void bl_startBL(void) const override; + void bl_checkBL(void) const override; + bool bl_isUp(void) const override; + // return true is bl is up and running + // also initializes "sendFile" + + void bl_sendAddress(uint16_t blockNumber) const override; + // send start address, nr of 64byte-block, start with 0 + // will be sent only for folling block-numbers: + // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte + + uint8_t bl_wasSendingAddOK(void) const override; + // return val: 0: no response by now 1:error 10: OK + + void bl_openBinary(void) const override; + + void bl_sendDataBlock(uint8_t length, uint8_t *buffer) const override; + // send 64 byte from bin file + + void bl_sendLastBlock(void) const override; + + uint8_t bl_wasSendingDataOK(void) const override; + // return val: 0: no response by now 1:error 10: OK + + void bl_stopBL(void) const override; + + +// ------------------------------------------------------------------------------------ +// 6.4.2023: new functions for coin collection and printing +// some new system functions +// ------------------------------------------------------------------------------------ + + + bool rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const override; + // return true if successful. could fail if more the 8 commands are waiting + + bool rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const override; + + bool rtc_getExtendedTime(struct T_extTime *exTime) const override; + + bool sys_runCompleteTest(void) const override; + // warning: lasts 20s in one pace + + bool sys_ready4sending(void) const override; + // return true if a Json-file can be sent + + bool sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const override; + // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer + // nrOfTemplate=1...32 if kindOfFile==6 + // content = content of the Json file, max 800byte ascii signs + // file is 0-terminated! + // return false if sending is not possible, wait a second + + bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const override; + // dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string + // like: char prn_dynPrnVal[8][8]; + // return true if sending, false if cmd-stack is full + + bool prn_printTemplate(uint8_t nrOftemplate) const override; + // print one of the templates loaded by Json prior + // nr = 1..32 + // return true if sending, false if cmd-stack is full + + void log_getHoldAccountNumbers(uint8_t *nrOfVals, uint16_t *accNr ) const override; + // returns all acc nrs of the backuped vault records + // use: uint16_t backupedAccNumbers[8] + // will be requested automatically + + bool log_selectVaultRecord(uint16_t accountNr ) const override; + // return true if sending, false if cmd-stack is full + // and trigger transfer + + bool log_chkIfVaultRecordAvailable(void) const override; + // return true if completly received + + bool log_getVaultRecord(struct T_vaultRecord *retVR) const override; + // which was selected by: log_selectVaultRecord() + // to be forwarded to Ismas + + bool prn_printAccountReceipt(void) const override; + // return true if sending to DC OK, false if cmd-stack is full + + bool prn_printTestTicket(void) const override; + // return true if sending to DC OK, false if cmd-stack is full + + + + + bool cash_startPayment(uint32_t amount) const override; + // 17.4.23TS: extended to 32bit + + uint8_t cash_paymentProcessing(void) const override; + // run this function periodically while coin payment process to generate necessary signals + // return value: + // 0: stopped 1: starting up 2: coin collection + // 3: finished by User (Push button) 4: finished, Max-Value collected + // 5: finished by escrow + // 10,11: error cannot start + // 12: timeout while payment, coins returned + // 13: stopped by unexpected error + + uint32_t getInsertedAmount(void) const override; + + uint16_t getLastInsertedCoin(void) const override; + + bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const override; + // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64 + + + bool cash_cancelPayment(void) const override; + // and return coins + + bool cash_stopPayment(void) const override; + // and keep coins in escrow + + + // after ticket/goods issue: + bool vend_success(void) const override; + // conclude payment process, encash all inserted coins to vault. Printing was successful + // if possible return change + + bool vend_failed(void) const override; + // conclude payment process and return all inserted coins + + + + + + uint8_t mif_getCardType(QString *cardholder) const override; + // return 1,2,3,4 = upper, lower access card, printer test, coin test + // cardholder: 7byte Name-String + + uint64_t sys_getWakeSource(void) const override; + // retval: 6 bytes, bit coded, 1=event keeps DC awake + + uint8_t sys_getWakeReason(void) const override; + // Master was woken by following reason: + // 1: MDB Event + // 2: Coin Event + // ( 3: Master Event) - will not set the wake line + // ( 4: 32s pulse) - will not set the wake line + // 5: Door Event + // ( 6: Diag Event) - will not set the wake line + // 7: 30min-Pulse for HB + + void sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const override; + + void sys_getDeviceConditions(struct T_moduleCondition *devCond) const override; + + void sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const override; + + void sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const override; + + + uint32_t cash_getAmountInVault(void) const override; + + uint16_t cash_getNrCoinsInVault(void) const override; + + uint8_t prn_getPrintResult() const override; + // return: 0: unknown + // 1: OK - last template was printed succesful + // 2: error - last template was not printed + + uint8_t prn_getCurrentPrinterState() const override; + // 0: printer OK + // bit0: near paper end bit1: no paper + // bit2: temperature error bit3: error head open + // bit4: paper jam in cutter + // bit6: no response bit7: serial rec. error + // bit5: printer not ready + + + void sys_sendDeviceParameter(struct T_devices *deviceSettings) const override; + + void sys_restoreDeviceParameter(struct T_devices *deviceSettings) const override; + // attention: only applies if function "sys_sendDeviceParameter()" was used to send this settings before + // cannot be used to see settings programmed by JsonFile + + bool sys_areDCdataValid(void) const override; + + bool sys_sendingTest(void) const override; + + void prn_requestCurrentDynData(void) const override; + + bool prn_getCurrentDynamicPrnValuesFromDC(uint8_t *dynPrnVal ) const override; + // which was sent with: bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const override; + + bool prn_dynDataAreEqual(uint8_t *buf) const override; + + bool prn_printKombiticket(uint8_t nrOfKombi) const override; + // print four of the templates loaded by Json prior + // nr = 1..8 + + void lock_triggerUpperSolenoid(void) const override; + + void lock_triggerLowerSolenoid(void) const override; + + bool doors_supervise(void) const override; + + bool dc_isAutoRequestOn(void) const override; + + uint16_t log_getLatestAccountNumber(void) const override; + // new function 27.6.2023 + // latest = highest + + + uint8_t log_getAvailableVaultBlocks(void) const override; + // return 0x0011 1111 if all 6 blocks arer loaded (one bit per block) + + uint8_t log_getAnswerToLastSlaveRequest(void) const override; + // use only for ONE request/command + + // return: 0xFF: result unknown by now as sending is ongoing + // 0=OK + // 1= wrong length 2=wrong start sign 5= wrong crc + // 6= slave: master cmd was wrong 7: slave: could not write/read data + // 8=timeout, got no response from slave + + + // use for important and extended commands (print more templates, print ticket...) + void log_startSupervision(void) const override; + + uint8_t log_getAnswerToLastCmdBatch(void) const override; + // 0xFF: no command sent by now + // 0: started, in progress + // 1: done and OK + // 2: done and error + + bool log_getVaultData(uint8_t *data) const override; + // get vault record in linear 8bit buffer with 384 byte + + + + + + // new from 1.8.23 + bool prn_printOneAccountReceipt(uint16_t accountNr) const override; + // print one out of eight stored last accounting receipts + // function log_getHoldAccountNumbers() gives a list of acc-Nr. of the stored receipts + + bool prn_printAllAvailAccountReceipts(void) const override; + // same as: prn_printAccountReceipt() from line 1153 + // return true if sending to DC OK, false if cmd-stack is full + + bool log_verifyVaultRecordByCrc(void) const override; + // return true if CRC16 is correct, data are 100% OK. Security level 1:65536 + // verification is strongly recommended before further processing + // in case of "false"-result please reload from DC + + uint16_t log_DC_getNextAccountNumber(void) const override; + // the current cash box content will be backuped with this number on next cashbox-change + + void log_DC_setNextAccountNumber(uint16_t newAccountingNumber) const override; + // the current cash box content will be backuped with this number on next cashbox-change + // use only in case of hardware replacements or errors which derailed the number + + void log_DC_deleteAllVaultrecordsInDc(void) const override; + // use only in case of hardware replacements or errors which derailed the number + + void log_DC_deleteAllTotalCounters(void) const override; + // use only in case of hardware replacements or errors which derailed the number + + void dc_setNewCustomerNumber(uint16_t newCustNr) const override; + + void dc_setNewMachineNumber(uint16_t newMachNr) const override; + + void dc_setNewBorough(uint16_t newBorough) const override; + + void dc_setNewZone(uint16_t newZone) const override; + + + // new functions from 8.9.23 + QString mif_getReaderType(void) const override; + + void mif_getCardSize(uint8_t *cardSize, uint8_t *idLeng) const override; + // cardSize=1k or 4kByte + // idLeng =4Byte or 7 byte + + char mif_getAtbCardData(uint8_t *buf, uint8_t maxBuffSiz) const override; + // return complete buffer binary, just for test purpose + + bool mif_isValidAtbCard(void) const override; + + uint32_t mif_getAtbCardCuNu(void) const override; + + uint8_t mif_getAtbCardTyp(void) const override; + // return 1=upper door card 1=lower door 3=printer-test 4=coin-test + // 0: not a valid atb2020 card + + QString mif_getAtbCardPerso(void) const override; + // e.g. "PNsax001" used for personal number, name shortcode, card number + // free to use, can be set in AtbMcw23.exe tool + + void mif_getAtbCardExpire(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute) const override; + + + + + // ------------------------------------------------------------------------------------ + // Device-Controller-Bootloader convenient version 21.09.2023 + // ------------------------------------------------------------------------------------ + + // use this to jump to BL: + //void hwapi::bl_rebootDC(void) const + + // use this to start BL: + // void hwapi::bl_startBL(void) const + + // call this in order to get response from BL: + //void hwapi::bl_checkBL(void) const + + // evaluate BL response: + //bool hwapi::bl_isUp(void) const + + // 29.9.23: new: "completeStart" function, replaces bl_rebootDC(), bl_startBL() and bl_checkBL() + // result can be verified with bl_isUp() as before + bool bl_completeStart(void) const override; + // must be used in DC's normal operation + + // select binfile-name in GUI + + // send binfile-name to BL-processor: + bool bl_storeFirmware(QString fileName) const override; + // load binary file 3x and compare + // return true if loaded correctly + // return false: error, could not load correctly + + // request the number of blocks for this file + uint16_t bl_getNrOfFirmwareBlocks(void) const override; + // size of the loaded bin file in 64byte blocks + // call after bl_storeFirmware() + + // call this function with "blockNumber"=0,1,2,3.....bl_getNrOfFirmwareBlocks + //the last block "bl_getNrOfFirmwareBlocks()" is sent as conclusion command (important!) + bool bl_blockAutoLoad(uint16_t blockNumber) const override; + // call in loop from block number 0 up to <= "dcBL_getNrOfBlocks()" + // but after every call WAIT (!) for response "bl_blockAutoResponse()" !!!! + // data will be sent to DC, if neccesary addr will be sent additionally + // if neccesary sending will automatically repeat up to 3times + // retval: false if blockNumber>4095, true else + + // check out this response after every block-sending, wait until >0!!! + int8_t bl_blockAutoResponse(void) const override; + // after every "bl_blockAutoLoad()" call this until response + // retval 0: wait 1: OK, blk was sent 2: OK, transfer complete + // 3: error despite repeating, cancel. probably bin file corrupted + // Max duration: 3x no response from BL = 900ms + + + // -------------- end of bootloader --------------------------------------------------- + + + + // new from 28.9.23 and earliest from DC version 4.45 + // get all versions of the DC-Jsons + void sys_requestJsonVersions(uint8_t jsonNr) const override; + // send one request for every single version + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + + void sys_getJsonVersions(uint8_t jsonNr, char *versionString) const override; + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + // length of buffer is always 16 byte + + + // ------------------------------------------------------------------------------------ + // Coin Changer + // ------------------------------------------------------------------------------------ + + void changer_returnCoins(uint32_t amountInCent) const override; + + void changer_requestChangeResult(void) const override; + + uint8_t changer_getChangeResult(uint32_t *returnedAmount) const override; + + void changer_getAllParameters(struct T_changer *mw) const override; + + void changer_requestTubelevel(void) const override; + + void changer_getTubelevel(struct T_chg_Tub *tubLevel) const override; + + + + + // ------------------------------------------------------------------------------------ + // bank note acceptor + // ------------------------------------------------------------------------------------ + + void bna_sendSettings(uint16_t notesToAccept, uint16_t parameters, + uint16_t *billDenomination, + uint32_t acceptanceLimit) const override; + // notesToAccept: bit0=bill1 (lowest donomination) bitH=accept bit L = deny + // parameters: e.g. use escrow function for some notes + // billDenomination = array of 16 bill values (e.g. 5, 10, 20...) + // these can be set alternatively by Json-File DC2C_cash.json + // acceptanceLimit: device will stop acceptance once this amount is reached and + // optionally keep last bill in escrow until vend_success() + // is called (put bill to stacker) or vend_failed() is called (return bill) + + void bna_setCurrentAcceptance(uint16_t notesToAccept) const override; + // can be used to block notes dynamically, example: from now only 5€ bills are allowed (if only 3€ are to be paid) + + void bna_requestParameters(void) const override; + // send command to DC in order to get static invariable device parameters like currency + // device must be powered and polled to get these + + bool bna_getAllParameters(struct T_bna *bna) const override; + // get all constant data from reader (e.g. currency) + // and actual Host-Settings (sent with bna_sendSettings() or json) + // retval = true if data are valid + + void bna_requestCurrentNotes(void) const override; + // send command to DC in order to get transaction data + + uint8_t bna_getCurrentNotes(uint16_t latestBill, uint16_t *currentNotes) const override; + // returns number of collected bank notes since start-command (current transaction) + // latestBill: last accepted bank note, value in cent + // currentNotes an array with up to 16 (further) notes collected + + void bna_requestStackerLevel(void) const override; + + uint16_t bna_getStackerLevel(uint32_t *amountInStacker, uint16_t *countOfBills) const override; + // return val: nr of bills in stacker + // countOfBills: array of up to 16 sums, countOfBills[0]=nr of 5€-bills in stacker + // countOfBills[1] for 10€ and so on + + + + +signals: + void hwapi_templatePrintFinished_OK(void) const override; + void hwapi_templatePrintFinished_Err(void) const override; + + void hwapi_coinCollectionJustStarted(void) const override; + void hwapi_coinCollectionAborted(void) const override; + + void hwapi_gotNewCoin(void) const override; + void hwapi_payStopByMax(void) const override; + void hwapi_payStopByPushbutton(void) const override; + + void hwapi_payStopByEscrow(void) const override; + void hwapi_payStopByError(void) const override; + void hwapi_payStopByTimeout(void) const override; + void hwapi_payCancelled(void) const override; + void hwapi_coinProcessJustStopped(void) const override; + + // new from 2023.06.12 + void hwapi_doorServiceDoorOpened(void) const override; + void hwapi_doorVaultDoorOpened(void) const override; + void hwapi_doorCoinBoxRemoved(void) const override; + void hwapi_doorCoinBoxInserted(void) const override; + void hwapi_doorCBinAndAllDoorsClosed(void) const override; + void hwapi_doorAllDoorsClosed(void) const override; + + + + + + private slots: + //void hwapi_slotPrintFinished_OK(void); + //void hwapi_slotPrintFinished_Err(void); + //void hwapi_slotGotCoin(void); + void hwapi_slotPayProc(void); + //bool bl_performComplStart(void); + + void sub_slotCoin01(void); + void sub_slotCoin02(void); + void sub_slotCoin03(void); + void sub_slotCoin04(void); + void sub_slotCoin05(void); + void sub_slotCoin06(void); + void sub_slotCoin07(void); + void sub_slotCoin08(void); + void sub_slotCoin09(void); + void sub_slotCoin10(void); + + + void sub_slotCoin11(void); + void sub_slotCoin12(void); + void sub_slotCoin13(void); + void sub_slotCoin14(void); + void sub_slotCoin15(void); + void sub_slotCoin16(void); + + + + +}; + + +#endif + + + + + + + + + + + + + + + + diff --git a/include/interfaces.h b/include/interfaces.h new file mode 100755 index 0000000..fbda6e5 --- /dev/null +++ b/include/interfaces.h @@ -0,0 +1,1683 @@ +#ifndef INTERFACE_H +#define INTERFACE_H + +#include + + + +struct T_emp +{ + + // Fixdata from EMP: + uint8_t shaft; // = changer level + uint16_t countryCode; + uint8_t scale; + uint8_t decimals; + uint8_t coinValues[16]; + uint16_t routing; + + // Master specs: + uint8_t gotSetup; // 1: got specifications from master 0: no specs + uint16_t coinAccept; // bit 0 = coin1 bit H=accept + uint8_t tokenChannel; + uint16_t denomination[16]; + + // dynamic: + uint8_t state; // step counter of EMP (electronic coin checker) FSM (finite state machine): + // 0=start command + // 1=powered, do emp ini, send reset + // 2=delay + // 3=wait for response, requesting status after response + // 4,5 through, startup + // 6: wait for status + // 7: through, startup + // 8: IDLE state. EMP is up and ready, polling is running + // 9: polling on, payment not yet on + // 10: payment, check coins + // 11: through + // 12: wait 1s for last coin + // 90: stop all, 1s delay + // 99: off, all stopped + + + uint8_t pollingRunning; + uint8_t paymentRunning; + +}; + +struct Trtc_DateTime +{ + uint8_t rtc_hour; + uint8_t rtc_min; + uint8_t rtc_sec; + uint8_t rtc_dayOfMonth; + uint8_t rtc_month; + uint8_t rtc_year; + uint8_t rtc_dayOfWeek; +}; + +struct Tprn_hw_state +{ + // hardware (IO's) + bool powerRdBk; // prn pwr is on + bool rsSwOk; // serial switch (printer or modem) is set to printer + bool rsDrvOk; // RS232 converter for PTU, Printer and Modem in on + + bool ReadyLine; // HW signal from printer showing ready + bool inIdle; // powered and free from errors + bool paperNearEnd; // paper roll runs out + bool noPaper; + bool ErrorTemp; + bool HeadOpen; + bool cutterJam; + bool noResponse; // printer is not connected, cable broken, wrong baudrate + bool badResponse; +}; + + struct Tprn_currentSettings +{ + uint8_t currFont; + uint8_t currSize; + uint8_t currHeigth; + uint8_t currWidth; + bool nowBold; + bool nowInvers; + bool nowUnderlined; + uint8_t currDensity; + uint8_t currSpeed; + bool nowAligned; +}; + +// obsolete + struct T_dynDat +{ + uint8_t licensePlate[8]; + uint8_t vendingPrice[8]; + uint8_t parkingEnd[8]; + uint8_t currentTime[8]; + uint8_t currentDate[8]; + uint8_t dynDat5[8]; + uint8_t dynDat6[8]; + uint8_t dynDat7[8]; +}; + + +struct T_vaultRecord +{ + + // Kassenbeleg (Abrechnungsdatensatz = Kassenwechsel-Datensatz) + char startbuffer[4]; // Psa> // never move or change this 1st entry + uint16_t AccountingNumber; + uint16_t CUNU; + uint16_t MANU; + uint16_t resint1; + //uint16_t resint2; + + char label1buffer[4]; // tim> + uint8_t year; + uint8_t month; + uint8_t dom; + uint8_t hour; + uint8_t min; + uint8_t sec; + uint8_t DoW; + uint8_t reschar3; + + char label2buffer[4]; // abs> + uint32_t AbsIncome1; + uint32_t AbsReserve; + uint32_t AbsNrOfCuts; + + char label3buffer[4]; // mw > + + // Verkauf, Tuer zu: + uint32_t VKcoinsInserted[16]; // nur fuer Wechsler, soviel wurde eingeworfen + uint32_t VKcoinsReturned[6]; // nur fuer Wechsler, Anzahl Muenzen pro Typ, soviel wurde zurueckgegeben + + // Service, Tuer offen: + uint16_t ServCoinsInserted[16]; // nur fuer Wechsler, soviel wurde eingeworfen + uint16_t ServCoinsReturned[6]; // nur fuer Wechsler, Anzahl Muenzen pro Typ, soviel wurde zurueckgegeben + uint16_t resint3; + uint16_t resint4; + uint16_t currentTubeContent[6]; // nur fuer Wechsler, aktueller Fuellstand + uint16_t resint5; + uint16_t resint6; + + char label4buffer[4]; // box> + uint16_t coinsInVault[16]; + uint16_t billsInStacker[8]; + + char label5buffer[4]; // val> + // actually constant unless exchange rate is changed + uint16_t coinDenomination[16]; // 5..50000 (z.B. 2? sind in Ungarn 760Ft) + uint16_t billDenom[8]; + uint16_t tubeDenom[6]; + uint16_t exchangeRate; + uint16_t resint9; + + // new from 1.8.23 + uint32_t cutsSinceCBchange; + uint32_t CBcontent_cent; + uint32_t CBnrofCoins; + + char endofblock[4]; // end +// 332 bytes + + uint16_t CRC16; // Xmodem16 from startbuffer[0] to endofblock[3] + uint16_t resint11; + char endofRecord[4]; // ---- + +}; + +struct T_moduleCondition +{ + // store conditon of all system components, hold in RAM + // 0 means unknown, not yet tested/used + // 1 means OK + // 50..99 = HINT / Notification + // 100..150 = WARNING + // 200..250 = ERROR + + uint8_t ram; + uint8_t intEe; + uint8_t extEe; + + uint8_t rtc; // 1: time/date OK 100: time not plausible 200: hardware error + uint8_t boardHw; + uint8_t printer; + uint8_t modem; + + uint8_t signal; // 1...99 + uint8_t regist; // 100:not 1:reg 2:ping OK 3:gotTime + uint8_t mdbBus; + uint8_t coinChecker; // EMP, OMP or mei-cashflow + + uint8_t coinEscrow; + uint8_t mifareReader; // 0: unknown 1=OK 200=no response 201=wrong response 202: Reader reports HW-error + uint8_t creditTerm; + uint8_t coinReject; + + uint8_t coinSafe; + uint8_t billSafe; + uint8_t voltage; // 1:11..14V + uint8_t temper; + + uint8_t poweronTest; + uint8_t doorState; // 1: alles zu 200: tuer offen + bit1(S) +bit2(CB) + bit3(CB) + uint8_t doorWasOpened; // 1: all doors are closed 200: any door was just opened + uint8_t changer; // can only be tested by usage + + uint8_t coinBlocker; // can only be tested by usage + uint8_t billReader; // can only be tested by usage + uint8_t ResetReason; + uint8_t allModulesChecked; + + uint8_t alarmState; + uint8_t res11; + uint8_t res12; + uint8_t res13; +// 31 +}; + +struct T_dynamicCondition +{ + char allDoorsDebounced; + char openedAuthorized; + uint8_t CBinDebounced; // 0:fehlt 1:drin + char upperDoor; // 99: undefined 0:closed 1:open + char middleDoor; // 99: undefined 0:closed 1:open + char lowerDoor; // 99: undefined 0:closed 1:open + char reserve; + char billBox; + char modeAbrech; + char onAlarm; // 0:alarm aus 1:alarm 2:alarm mit Sirene 3: Sirenentest + char nowCardTest; + char nowPayment; // not used, always 0 + char lastMifCardType; + uint8_t lastSDoorState; + uint8_t lastVDoorState; + uint8_t lastCBstate; + char paymentInProgress; + // 0: stopped by timeout + // 1: running 2: wait4lastCoin + // 3: payment stopped manually, coins in Escrow + // 4: payment stopped autom, amount collected, coins in Escrow + // 5: payment stopped, escrow full, coins in Escrow + // 6: coins encashed 7:coins returned + // 8: CoinChecker or MDB on Error + + + char res1; + uint16_t U_Batt; + uint16_t Temperatur; + uint16_t nrCoinsInBox; + uint32_t amountInBox; + uint32_t totalTransVolume; + uint32_t totalNrOfVends; + char jsonValid_config; + char jsonValid_device; + char jsonValid_cash; + char jsonValid_print; + char jsonValid_serial; + char jsonValid_time; + char lastFileType; +// 44 + uint8_t MifCardHolder[8]; + uint8_t resultOfLastTemplPrint; + // 0: unknown or printing in progress + // 1: OK, doc was printed 2: error, doc was not printed + uint8_t lastPrinterStatus; + // 0: printer OK + // bit0: near paper end bit1: no paper + // bit2: temperature error bit3: error head open + // bit4: paper jam in cutter + // bit6: no response bit7: serial rec. error + // bit5: printer not ready + uint8_t startupTestIsRunning; + + //54 +}; + +struct T_extTime +{ + uint8_t Hours; + uint8_t Min; + uint8_t Sec; + uint8_t Year; + uint8_t Month; + uint8_t Day; + uint8_t DOW; + uint8_t res1; + uint16_t MinOfDay; + uint16_t res2; + uint32_t SecOfDay; + uint8_t isLeapYear; + uint8_t nxtLeapYear; + uint8_t lastLeapYear; + uint8_t hoursOfThisWeek; + uint16_t minutesOfThisWeek; + uint16_t hoursOfThisMonth; + uint16_t daysOfThisYear; + uint16_t GetHoursOfYear; + uint16_t res3; + uint32_t GetMinutesOfYear; + uint8_t getWakeIntvSec; + uint8_t res4; + uint16_t res5; + uint32_t MinutesOfMillenium; + +}; + + +typedef uint8_t UCHAR; +typedef uint16_t UINT; + +struct T_devices +{ + // set by master, used(1) or notused (0) or type 2....20 + + UCHAR kindOfPrinter; // 0:off 1:Gebe + UCHAR kindOfCoinChecker; // 0: without 1=EMP820 2=EMP900 3=currenza Csquare (MW) + UCHAR kindOfMifareReader; // by now only stronglink SL025 =1 + UCHAR solarPower; // 1:sleep allowed 0: no sleep + //UCHAR suppressSleepMode; // 0:sleep allowed 1: no sleep + + UCHAR kindOfModem; // 0:off 1:Sunlink + UCHAR kindOfCreditcard; // 0:off 1:Feig NFC + UCHAR CoinEscrow; + UCHAR CoinRejectUnit; + + UCHAR CoinShutter; + UCHAR BillAcceptor; + UCHAR usevaultLock; + UCHAR autoAlarm; // 1: switch on siren for 1min in doors opened unauthorized + + UCHAR autoOpen; // 1: open door covers after valid ATBcard + UCHAR printAccReceipt; // 0/1 + UCHAR printDoorReceipt; + UCHAR printTokenTicket; + + UINT VaultFullWarnLevel; + UINT VaultFullErrorLevel; + UINT BattEmptyWarnLevel; + UINT BattEmptyErrorLevel; + +}; + +struct T_chg_Tub +{ + + uint8_t tubeLevel[8]; // [0]=nr coins of lowest value + uint8_t tubeFull[8]; // 1=full 0 else + uint16_t tubeValues[8]; // in cent [0]=lowest value 5c or 10cent + uint16_t tubeFilled[8]; // nr of every coin inserted + uint16_t tubeDispens[8]; // nr of every coin dispensed + // 64 byte +}; + +struct T_changer +{ + // Fixdata from Coin Changer + uint8_t setup; // always 1 + uint8_t state; // step of state machine + // 0..12 like EMP, 13...30 for coin dispense + + uint8_t level; // mdb-level, always 3 + uint16_t countryCode; + uint8_t scale; + uint8_t decimals; + uint8_t coinSetup[16]; // [0]=lowest coin, multiply with scale + uint16_t intendedAcceptance; //bitwise 0,1 1=accept coin, came from master + uint8_t tokenChannel; + uint8_t pollingRunning; // 1: emp is polled 0:not + uint8_t paymentRunning; // 1: coins are accepted + uint16_t denomination[16]; + uint16_t availableTubes; //bitwise 0,1 1=av. bit0 = lowest coin value +}; + +struct T_bna +{ + +}; + +class hwinf +{ + +public: + virtual ~hwinf() {} + + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Use serial interface and protocol stack in Cashagent-Library + // Sending Output data to DeviceController DC2b + // Sending input requests to DC2 (single or auto-batch) + // Getting input data as receiver payload + // Furthermore the Cashagent-Library answers with status strings about sending and reading result + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + virtual bool dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const =0; + // Command: open serial interface + // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 + // BaudStr: for exapmle "19200" + // ComName: for example "COM48" + // connect: 0, 1 + + virtual void dc_closeSerial(void) const =0; + // Command: close serial interface in order to save power while power down + // or if another port must be used + + + virtual bool dc_isPortOpen(void) const =0; + // returns true if port open (don't send unless open. Sending to closed port will crash program) + + virtual void dc_autoRequest(bool on) const =0; + // on = true: select that all READ-Requests are sent automatically + // on = false: select that all READ-Requests are sent manually one by one + // Every input information from DC2 must be requested + // ( digital and analog sensors, get time/date, get status information ) + + virtual void dc_requTestResponse() const =0; + // tell DC2 to send a test-string, useful to see if cable and baudrate is OK + + virtual bool dc_readAnswTestResponse() const =0; + // retval: true: test was successful, got right response + + virtual uint8_t dc_isRequestDone(void) const =0; + // retval: 0: request is still in progress + // 1: answer from DC2 was OK + // 2: wrong answer from DC2 + + virtual uint16_t dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const =0; + // get data back in "payLoad", max 64 byte, can be used for diagnosis + // retval = nr of bytes received. If host buffer too small then + // only plBufSiz bytes are copied to "payLoad" + // plBufSiz = size of host buffer + + virtual void dc_setWakeFrequency(uint8_t period) const =0; + // RTC wakes DC2 (and PTU) by hardware signal every 32seconds + // change wake signal period to 1...64s + + virtual void dc_OrderToReset(void) const =0; + // want DC2 to reset (in order to start Bootloader) + + + virtual QString dc_getSerialState(void) const =0; + // get result of opening-command like "ttyS0 opened with 115200 8N1! + // or error messages like "comport not available..." + // was saved by last opening event, can be passed for 100ms + + virtual void dc_clrSerialStateText(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const =0; + // send without protocol frame, needed for the DC bootloader + + virtual uint8_t getRawRecLength(void) const =0; + // only needed if protocol stack in Cashagent-Library is bypassed + + virtual uint8_t getRawReceivedData(uint8_t *receivedData) const =0; + // only needed if protocol stack in Cashagent-Library is bypassed + + virtual QString dc_getSerialParams(void) const =0; + // get DC2 serial settings (not very meaningful as they will not come if different from master settings) + + virtual QString dc_getHWversion(void) const =0; + // get DC2 hardware version + + virtual QString dc_getSWversion(void) const =0; + // get DC2 software version + + virtual QString dc_getState(void) const =0; + // get DC2 status (every OK or any error/warning? ) + + +// ---------------------------------------------------------------------------------------------------------- +// Date and Time +// ---------------------------------------------------------------------------------------------------------- + + virtual uint8_t rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const =0; + + virtual uint8_t rtc_setDateTime(void) const =0; + // synch DC2 with PC or PTU system time and date + + virtual void rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const =0; + // get time directly + + virtual void rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const =0; + // get date directly + + virtual uint8_t rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const =0; + // dow=day of week, 1=monday...7 + // minOfToday: 0=midnight...1439= 23:59 + // secOfToday: 0=midnight...86399= 23:59:59 + + virtual bool rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const =0; + // retval true: this year is leap year + + virtual bool rtc_isLeapYear() const =0; + + virtual void rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const =0; + // DayOfWeek: 1=monday...7 + // HoursOfWeek: 0=Monday 0:00 o'clock...167=Sunday 23:00 + // MinutesOfWeek: 0=Monday 0:00 o'clock...10079=Sunday 23:59 + + virtual void rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const =0; + // DayOfMonth: 1...31 + // HoursOfMonth: 0 = 0:00o'clock of 1.day in month up to 743 + // MinutesOfMonth:0 = 0:00o'clock of 1.day in month up to 44639 + + virtual void rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const =0; + // DayOfYear: 1...366 1= 1.Jan of this current year + // HoursOfYear: 0=1.Jan 0:00o'clock ...8783=31.12 23 o'clock + // MinutesOfYear: 0=1.Jan 0:00o'clock ...527039=31.12 23:59 o'clock + + virtual QString rtc_getTimStr(void) const =0; + virtual QString rtc_getDatStr(void) const =0; + virtual QString rtc_getTimDatStr(void) const =0; + + + // UID - unique number, different in every DC + virtual void dc_getUID8byte(uint8_t *buf8byteUid) const =0; + // get 8 single bytes in buffer + + virtual QString dc_getUIDstr() const =0; + // get as string + + virtual uint64_t dc_getUIDnumber(void) const =0; + // get UID as one long number + +// ---------------------------------------------------------------------------------------------------------- +// analogs +// ---------------------------------------------------------------------------------------------------------- + + // Analog values: + virtual uint32_t dc_getTemperature(void) const =0; + // in Sax-Format 0...400 (0=-50,0degC 100=0,0degC 141=20,5degC 400=150,0degC) + + virtual QString dc_getTemperaturStr(void) const =0; + // as string like "-12,5degC" + + virtual uint32_t dc_getVoltage(void) const =0; + // as value in mV, 0...65,535V + + virtual QString dc_getVoltagStr(void) const =0; + // as string in mV + + virtual bool dc_mainFuseIsOk(void) const=0; + // true if 12V fuse is OK + // false: fuse blown, DC will continue working but no 12V device can be used! + +// ------------------------------------------------------------------------------ +// digital outputs +// ------------------------------------------------------------------------------ + + virtual uint8_t lock_switchUpperLock(uint8_t dir) const =0; + // dir 0=off 1=up 2=down + // move lock until stop cmd (0) + + virtual uint8_t lock_switchLowerLock(uint8_t dir) const =0; + // dir 0=off 1=up 2=down + // move lock until stop cmd (0) + + virtual void lock_switchVaultDoor(void) const =0; + + virtual void coin_switchRejectMotor(uint8_t dir) const =0; + + virtual void coin_rejectCoins(void) const =0; + + // LEDs + virtual void led_switchLedService(uint8_t on) const =0; + virtual void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const =0; + + virtual void fan_switchFan(bool on) const =0; + virtual void alarm_switchSiren(bool on) const =0; + virtual void bar_OpenBarrier(bool open) const =0; + virtual void ptu_switchWake(bool WAKEACTIVE) const =0; + + virtual void aux_power(bool on) const =0; + virtual void aux_setUsage(uint8_t PinDirection) const =0; + virtual void aux_setOutputs(uint8_t PinIsHigh) const =0; + + virtual void lock_switchContactPower(bool on) const =0; + + virtual void prn_switchPower(bool on) const =0; + + virtual void mif_readerOn(bool on) const =0; + + virtual void mif_creatAtbCard(uint8_t cardType) const =0; + + virtual void mod_switchPower(bool on) const=0; + + virtual void mod_switchWake(bool WAKEACTIVE) const=0; + + virtual void mdb_switchPower(bool on) const =0; + + virtual void mdb_switchWake(bool WAKEACTIVE) const =0; + + virtual void credit_switchPower(bool on) const =0; + // the same as modem power + + virtual void credit_switchWake(bool WAKEACTIVE) const =0; + + virtual void shut_move(bool open) const =0; + + virtual void esc_moveFlaps(uint8_t flap ) const =0; + // 0: close both 1: open take-flap 2: open return + + +// ------------------------------------------------------------------------------ +// door, cashbox and lock switches +// ------------------------------------------------------------------------------ + + virtual uint8_t door_getSwitches(void) const =0; + // retval: bit0: upper door 1: low door 2:vault door + + virtual bool door_isUpperDoorOpen(void) const =0; + + virtual bool door_isLowerDoorOpen(void) const =0; + + virtual bool vault_isVaultDoorOpen(void) const =0; + + virtual uint8_t vault_getSwitches(void) const =0; + // retval bit0: cash box, bit 1: bill box + + virtual bool vault_isCoinVaultIn(void) const =0; + + virtual bool vault_isBillVaultIn(void) const =0; + + virtual uint8_t door_getLocks(void) const =0; + // retval bit0: upper lever is up (=open) + // bit1: upper lever is down (=locked) + // bit2: lower lever is up + // bit3: lower lever is down (=locked) + + virtual bool door_upperDoorIsLocked(void) const =0; + + virtual bool door_upperDoorIsUnlocked(void) const =0; + + virtual bool door_lowerDoorIsLocked(void) const =0; + + virtual bool door_lowerDoorIsUnlocked(void) const =0; + + virtual bool bar_optoIn1isOn(void) const =0; + + virtual bool bar_optoIn2isOn(void) const =0; + + virtual uint8_t aux_getAuxInputs(void) const =0; + + virtual bool ptu_WakeINisActive(void) const =0; + + virtual bool mdb_WakeINisActive(void) const =0; + + virtual bool prn_readyINisActive(void) const =0; + + virtual bool coid_isAttached(void) const =0; + + virtual bool coin_escrowIsOpen(void) const =0; + + virtual bool mif_cardIsAttached(void) const =0; + +//bool hwapi::mod_WakeINisActive(void); + + virtual bool door_isContactPowerOn(void) const =0; + + virtual bool mif_isMifarePowerOn(void) const =0; + + virtual bool mdb_testIsmdbTxDon(void) const =0; + + virtual bool aux_isAuxPowerOn(void) const =0; + + virtual bool mod_isGsmPowerOn(void) const =0; + + virtual bool cred_isCreditPowerOn(void) const =0; + + virtual bool prn_isPrinterPowerOn(void) const =0; + + virtual uint8_t prn_PrnFuseIsOk(void) const=0; + //retval: 0: fuse blown 1: fuse OK 2:unknown as printer power is off + + virtual bool mdb_isMdbPowerOn(void) const =0; + + virtual bool cash_getRejectMotorHomePos(void) const=0; + + virtual uint8_t cash_getLowPaperSensor(void) const=0; + // 0: Sensor sees paper 1: no paper 99: off + + + // ------------------------------------------------------------------------------ + // request commands + // ------------------------------------------------------------------------------ + + // all read-requests can be sent manually by the following functions + // or automatically in background by: void hwapi::dc_autoRequest(bool on) + + + virtual void request_DC2serialConfig() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + + virtual void request_DC2_HWversion() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + virtual void request_DC2_SWversion() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + virtual void request_DC2_condition() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + virtual void request_DC2_UID() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + virtual void request_DC2_TimeAndDate() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + virtual void request_DC2_analogues() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + virtual void request_DC2_digitalInputs() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + virtual void request_DC2_digitalOutputs() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + + // ------------------------------------------------------------------------------ + + // the following device state requests are deployed only if device is powered up: + virtual void request_PrinterHwState() const =0; + virtual void request_PrinterCurrentFonts() const =0; + virtual void request_PrinterStateComplete() const =0; + + virtual void request_MifareReaderState() const =0; + virtual void request_MifareCardType() const =0; + virtual void request_MifareAtbType() const =0; + virtual void request_MifareID() const =0; + virtual void request_MifareData(uint8_t dataBlockNumber) const =0; + //virtual void request_MifareData() const =0; + + virtual void request_MDB_Status() const =0; + virtual void request_MDB_lastResponse() const =0; + virtual void request_EMP_allParameters() const =0; + virtual void request_EMP_lastCoin() const =0; + + + // ------------------------------------------------------------------------------ + // readback digital outputs of connected devices + // these functions are not needed for normal operation + // but can be used to test and verify conditions + // ------------------------------------------------------------------------------ + + + virtual bool test_getDO_mdbRXtst(void) const =0; + // readback digital outputs of connected devices + // these functions are not needed for normal operation + // but can be used to test and verify conditions + + virtual uint8_t lock_getDO_motors(void) const =0; + // bit0: upper lock forward bit 1 backward + // bit2: lower lock forward bit 3 backward + + virtual uint8_t test_serialState(void) const =0; + // test on-board signals for the serials + // serial drv on/off, Serial mux1, Serial mux2 + + virtual bool test_serialIsOn(void) const =0; + + virtual bool test_serialMux1isSetToPrinter(void) const =0; + virtual bool test_serialMux1isSetToModem(void) const =0; + virtual bool test_serialMux2isSetToCredit(void) const =0; + virtual bool test_serialMux2isSetToMifare(void) const =0; + + virtual bool led_coinIsOn(void) const =0; + virtual bool led_frontIsOn(void) const =0; + virtual bool led_ticketIsOn(void) const =0; + virtual bool led_pinIsOn(void) const =0; + virtual bool led_StartIsOn(void) const =0; + virtual bool led_insideIsOn(void) const =0; + + virtual bool fan_isOn(void) const =0; + virtual bool siren_isOn(void) const =0; + virtual bool bar_relayIsOn(void) const =0; + virtual bool ptu_WakeOutIsOn(void) const =0; + + virtual bool aux_powerIsOn(void) const =0; + + virtual bool coin_shutterIsOpen(void) const =0; + virtual bool coin_shutterTestOutput(void) const =0; + + virtual uint8_t coin_escrowFlapOpened(void) const =0; + // retval: 1:return flap is open 2:take flap is open 0:closed + + + +// ------------------------------------------------------------------------------ +// devices are operated by DC +// processes with more then one devices +// timer controlled or long term processes +// ------------------------------------------------------------------------------ + + + virtual void sendDeviceSettings(uint8_t kindOfPrinter, uint8_t kindOfCoinChecker, + uint8_t kindOfMifareReader, uint8_t suppressSleep, + uint8_t kindOfModem, uint8_t kindOfCredit ) const =0; + // enable hardware in device controller: + // kindOfPrinter: 0:off 1: GPT4672 (only this one implemented) + // kindOfCoinChecker: 0:off 1:EMP820 2:EMP900 3: Csquare_changer + // kindOfMifareReader: 0:off 1: SL025 (only this one implemented) + // suppressSleep: 0:sleep allowed 1: sleep surpressed for special reason + // kindOfModem: 0:off 1: ATB_Sunlink_LTE (not yet implemented) + // kindOfCredit: 0:off 1: cVendTopp 2:cVendPin (not yet implemented) + + virtual void request_ReadbackDeviceSettings() const =0; + + virtual void readback_DeviceSettings(uint8_t *length, uint8_t *data) const =0; + // refer to DC2 manual for exact content + // state 5.5.21: byte[0]=kindOfPrinter byte[1]=kindOfCoinChecker + // byte[2]=kindOfMifarereadr byte[3]=suppress sleep mode + // byte[4]=kindOfModem byte[5]=kind of cc terminal + + virtual void sendMachineID(uint16_t customerNr, uint16_t machineNr, + uint16_t borough, uint16_t zone, + uint16_t alias, char *location) const =0; + + virtual void request_ReadbackMachineID() const =0; + + virtual void readback_machineIDdata(uint8_t *length, uint8_t *data) const =0; + // state 5.5.21: byte[0,1]=customer number byte[2,3]=machine number + // byte[4,5]=borough byte[6,7]=zone byte[8,9]=alias name + // byte[10...41]=location + + // Locks stops automatically at end switch or by timeout + virtual uint8_t lock_openUpperDoor(void) const =0; + virtual uint8_t lock_closeUpperDoor(void) const =0; + + virtual uint8_t lock_openLowerDoor(void) const =0; + virtual uint8_t lock_closeLowerDoor(void) const =0; + + virtual void shut_openOnce(void) const =0; + // and close automatic after shutter time + + virtual void shut_openForCoin(bool start) const =0; + // open flap if coin is attached + // once process is started it runs until stop command + + virtual void shut_sendOpeningTime(uint16_t timeIn_ms ) const =0; + // after this time without retrigger the flap is closed + + virtual void esc_takeMoney(void) const =0; + // and close automatically after escrow time (1s) + + virtual void esc_returnMoney(void) const =0; + // and close automatically after escrow time (1s) + + +// ---------------------------------------------------------------------------------------------------------- +// --------------------------------------------- MIFARE ----------------------------------------------------- +// ---------------------------------------------------------------------------------------------------------- + +// obsolete + virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0; + // retval 0=OK 1=error host buffer too small + /* data description, new fast version: + byte 0= still the same: current read state: + 0=power off 1=reader-fault 2=ready + 3=just reading 4=read complete + 5=read partial, removed too early + 6=state unknown + + byte 1: reader state 1=ok 0=nok + byte 2: card preent (0,1) + byte 3: card selected (0) + byte 4: card type: 0...5 + byte 5: card allowed (0=no 1=MifareClassic 1k or 4k) + byte 6: CardSize: 1 or 4 (kB) + byte 7: length of UID 4 or 7 (byte) + */ + + virtual bool mif_readerIsOK(void) const =0; + + virtual bool mif_cardAttached(void) const =0; + // not working! use mif_cardIsAttached() instead + + virtual uint8_t mif_readResult(void) const =0; + // result: 0: unknown or still in progress + // 1: card read successful + // 2: reading error + // not working! + + virtual QString mif_cardUID(void) const =0; + // not working + + virtual uint8_t mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const =0; + + virtual QString mif_getCardDataStr(uint8_t blockNumber) const =0; + // with blockNumber=0...11 + + + + // ---------------------------------------------------------------------------------------------------------- + // --------------------------------------------- PRINTER ---------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------- + + // read printer condition and settings + + virtual uint8_t prn_getHwState(struct Tprn_hw_state *prn_hw_state) const =0; + // retval: status byte + // byte 0 = 0: prnter OK, >0: error + // bit0: paper low 1: no paper 2: temperature error + // 3: head open 4: paper jam in cutter + // 6: no response 7: bad response from printer + // and return struct "Tprn_hw_state" + + virtual bool prn_isUpAndReady(void) const =0; + // true: printer is powered, serial is ok, no error, printer is connected and resonding + + virtual void prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const =0; + + + // send Commands to printer: + + virtual void prn_sendText(QByteArray *buf) const =0; + // up to 1280 bytes + + virtual void prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const =0; + // send three byte through to printer, see printers manual + + virtual void prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const =0; + // send four byte through to printer, see printers manual + + + virtual void prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density, uint8_t alignment, uint8_t orientation) const =0; + // send 5 byte: byte 0,1: speed 5...250 mm/s + // byte2: density 0....(25)....50 + // byte3: alignment 'l', 'c', 'r' = left, center, right + // byte4: orientation 0, 90, 180 = 0deg, 90deg, 180deg rotation (by now not supported!) + // not batched! don't use twice within 100ms + + virtual void prn_movePaper(uint8_t wayInMm, uint8_t direction) const =0; + //direction: 1=forward 2=backward + // + virtual void prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const =0; + // font = kind of font 5...11 (0..22) + // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge + // width: 0...4 0=1x 1=2x 2=4x (huge!) 3=8x 4=16x (3,4 make no sense) + // heigth: 0...7 = 1x...8x only 0,1,2,(3) make sense + + virtual void prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const =0; + // bold: 0/1 + // invers: 0/1 + // underlined: 0/1 + + virtual void prn_cut(uint8_t kindof) const =0; + // kindof: 1=full cut 2=partial cut 3=eject (5xLF + full cut) + + virtual void prn_newLine(uint8_t nrOfLines) const =0; + + virtual void prn_printCompleteFontTable(void) const =0; + + + virtual void prn_printBarcode(uint8_t kindOf, uint8_t withText, uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const =0; + // kind of barcode: 0=Code39 1=Code128 2=EAN13 3= 2/5interleaved 4=UPC-A 5=EAN8 + // withText: print readable text below + // offset: move by pixel from left border + // rotation + // dataLeng in byte + + virtual void prn_sendQRdata(QByteArray *buf) const =0; + // maximal 150 alphanummeric bytes + + virtual void prn_printQRcode(void) const =0; + // QRcode may have 1...150 alphanummeric data, must be transfered in advance + + + virtual void prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const =0; + // nrOfLogo: 1..4 in flash 5...8 in Ram + // offset: in mm form left border + + + // ......................................................... + // Parking Ticket (print-out document) designer TD - obsolete + // ......................................................... + + + + // ---------------------------------------------------------------------------------------------------------- + // --------------------------------------------- MDB Bus ---------------------------------------------------- + // ---------------------------------------------------------------------------------------------------------- + + virtual void mdb_sendBusReset(void) const =0; + + virtual void mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const =0; + // send one bus command directly over mdb bus, refer to mdb manual for commands + // this command is not needed in normal operation, just for new or special things + + virtual void mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const =0; + // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs + // same as mdb_sendCommand, just with data + + virtual bool mdb_busIsReadyToWork() const =0; + + virtual bool mdb_deviceVoltageOK() const =0; + + virtual bool mdb_busVoltageOk() const =0; + + virtual uint8_t mdb_getLastDeviceResponse(uint8_t *fromDevice, uint8_t *lastRequest, + uint8_t *responseLength, uint8_t *responseBuffer) const =0; + // fromDevice: device nr from which data was requested 0,1,2,3 + // lastRequest: sent mdb command + // responseLength: nr of payload data (after mdb-ack) 0...34 + // responseBuffer holds payload data (answer from mdb device) + // return val: mdb result of this request: 1=got ACK 2=got 3xNAK 3=no or bad response 4:got Data (after ACK) + + + // ---------------------------------------------------------------------------------------------------------- + // ---------------------------------- Electronic Coin Validator EMP ----------------------------------------- + // ---------------------------------------------------------------------------------------------------------- + + + virtual void emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const =0; + // coinAcceptance: bit0=coin1 (lowest donomination) bit15=coin16 bitH=accept bit L = deny coin (no validation) + // tokenChannel 0...31: if this signal comes from emp then a token was inserted + // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...) + + virtual void emp_pollingOnOff(uint8_t on) const =0; + + virtual void emp_startCoinAcceptance(void) const =0; + + virtual void emp_stopCoinAcceptance(void) const =0; + + virtual void emp_getAllParameters(struct T_emp *emp) const =0; + // see struct in hwapi.h + // usage example: + // hwapi *HWaccess const override; + // HWaccess = new hwapi() const override; + // struct T_emp myEmp const override; + // HWaccess->emp_getAllParameters(&myEmp) const override; + // readval=myEmp.pollingRunning const override; + + virtual uint8_t emp_chkIfCoinInserted(void) const =0; + // retval: 0...16 coins left in FIFO + + virtual void emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const =0; + // with every call ONE coin is taken out of FIFO and pointer decremented + // valid: should be 1 + // signal: comes right from coin checker, 0...15 (0=first programmed coin type) 0xFF=no signal + // error: was reported from EMP as dynamic signal right after coin insertion (instead of + // coin signal), example: 3=unknown coin 4=coin is blocked by host. 0xFF=no error + // value: of the coin. Depends on parameter "coinDenomination" in function "emp_sendSettings" + // if coinDenomination[coin 0..15] = 0 then the value programmed in coin checker is taken + // if coinDenomination > 0 then this value is taken. + // Useful in case of two currencies (adapt to local currency) or for token. + + // function gives more details as "emp getLastCoin()" but "emp getLastCoin()" is easier to use + + // alternativ to emp_getNewCoinRecord( ): + virtual uint8_t emp_giveLastCoin(uint16_t *value, uint8_t *signal) const =0; + // retval: 0: NO coin stored 1: valid coin 2: got wrong coin or coin denied + // value: if retval1: value of the coin if reval=2: error number + // 0xFF means NO error or NO signal (as 0 is a valid error/signal) + // signal: channel nr reported from checker 0...15 + + + virtual uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const =0; + // use for changer + + + + virtual QString dc_getTxt4RsDiagWin(void) const =0; + virtual void dc_clrTxt4RsDiagWin(void) const =0; + virtual QString dc_get2ndTxt4RsDiagWin(void) const =0; + virtual void dc_clr2ndTxt4RsDiagWin(void) const =0; + virtual QString dc_getTxt4HsStateLine(void) const =0; + virtual void dc_clrTxt4HsStateLine(void) const =0; + virtual QString dc_getTxt4masterStateLine(void) const =0; + virtual void dc_clrTxt4masterStateLine(void) const =0; + virtual QString dc_getTxt4resultStateLine(void) const =0; + virtual void dc_clrTxt4resultStateLine(void) const =0; + virtual QString dc_getdataStateLine(void) const =0; + virtual void dc_clrTxt4dataStateLine(void) const =0; + virtual QString dc_getdatifLine(void) const =0; + virtual void dc_clrTxt4datifLine(void) const =0; + + + +// ---------------------------------------------------------------------------------------------------------- +// -------- DC Bootloader 1.Version +// ---------------------------------------------------------------------------------------------------------- + + // using DC2 Bootloader + virtual void bl_iniChain(void) const =0; + virtual bool bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const =0; + virtual uint8_t bl_activatBootloader(uint8_t *sendData) const =0; + virtual uint8_t bl_startChain(void) const =0; + virtual uint8_t bl_readBLversion(uint8_t *sendData) const =0; + // minimum size of sendData-buffer: 5byte retval: length + virtual uint8_t bl_readFWversion(uint8_t *sendData) const =0; + // minimum size of sendData-buffer: 5byte retval: length + + virtual uint8_t bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const =0; + // make BL protocol, retval = outbuf length (5...133) + // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum + // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 + // Data length = 0...64 + // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 + // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + + virtual uint8_t bl_exitBL(uint8_t *sendData) const =0; + // minimum size of sendData-buffer: 5byte retval: length + + virtual void led_switchLedIllumination(uint8_t on) const =0; + + + + +// ------------------------------------------------------------------------------------ +// 27.3.2023: Use Device-Controller's Bootloader to send hex-file +// ------------------------------------------------------------------------------------ + + virtual void bl_rebootDC(void) const =0; + + virtual void bl_startBL(void) const =0; + virtual void bl_checkBL(void) const =0; + virtual bool bl_isUp(void) const =0; + // return true is bl is up and running + // also initializes "sendFile" + + virtual void bl_sendAddress(uint16_t blockNumber) const =0; + // send start address, nr of 64byte-block, start with 0 + // will be sent only for folling block-numbers: + // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte + + virtual uint8_t bl_wasSendingAddOK(void) const =0; + // return val: 0: no response by now 1:error 10: OK + + virtual void bl_openBinary(void) const =0; + + virtual void bl_sendDataBlock(uint8_t length, uint8_t *buffer) const =0; + // send 64 byte from bin file + + virtual void bl_sendLastBlock(void) const =0; + + virtual uint8_t bl_wasSendingDataOK(void) const =0; + // return val: 0: no response by now 1:error 10: OK + + virtual void bl_stopBL(void) const =0; + + +// ------------------------------------------------------------------------------------ +// 6.4.2023: new functions for coin collection and printing +// some new system functions +// ------------------------------------------------------------------------------------ + + + virtual bool rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const =0; + // return true if successful. could fail if more the 8 commands are waiting + + virtual bool rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const =0; + + virtual bool rtc_getExtendedTime(struct T_extTime *exTime) const =0; + + virtual bool sys_runCompleteTest(void) const =0; + // warning: lasts 20s in one pace + + virtual bool sys_ready4sending(void) const =0; + // return true if a Json-file can be sent + + virtual bool sys_sendJsonFileToDc(uint8_t kindOfFile, uint8_t nrOfTemplate, uint8_t *content ) const =0; + // kindOfFile: 1=config, 2=device, 3=cash, 4=serial, 5=time, 6=printer + // nrOfTemplate=1...32 if kindOfFile==6 + // content = content of the Json file, max 800byte ascii signs + // file is 0-terminated! + // return false if sending is not possible, wait a second + + virtual bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const =0; + // dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string + // like: char prn_dynPrnVal[8][8]; + // return true if sending, false if cmd-stack is full + + virtual bool prn_printTemplate(uint8_t nrOftemplate) const =0; + // print one of the templates loaded by Json prior + // nr = 1..32 + // return true if sending, false if cmd-stack is full + + virtual void log_getHoldAccountNumbers(uint8_t *nrOfVals, uint16_t *accNr ) const =0; + // returns all acc nrs of the backuped vault records + // use: uint16_t backupedAccNumbers[8] + + virtual bool log_selectVaultRecord(uint16_t accountNr ) const =0; + // return true if sending, false if cmd-stack is full + // and trigger transfer + + virtual bool log_chkIfVaultRecordAvailable(void) const =0; + // return true if completly received + + virtual bool log_getVaultRecord(struct T_vaultRecord *retVR) const =0; + // which was selected by: log_selectVaultRecord() + // to be forwarded to Ismas + + virtual bool prn_printAccountReceipt(void) const =0; + // print all 8 backuped accounting receipts + // return true if sending to DC OK, false if cmd-stack is full + + virtual bool prn_printTestTicket(void) const =0; + // return true if sending to DC OK, false if cmd-stack is full + + + virtual bool cash_startPayment(uint32_t amount) const =0; + // 17.4.23TS: extended to 32bit + + virtual uint8_t cash_paymentProcessing(void) const =0; + // run this function periodically while coin payment process to generate necessary signals + // return value: + // 0: stopped 1: starting up 2: coin collection + // 3: finished by User (Push button) 4: finished, Max-Value collected + // 5: finished by escrow + // 10,11: error cannot start + // 12: timeout while payment, coins returned + // 13: stopped by unexpected error + + virtual uint32_t getInsertedAmount(void) const =0; + + virtual uint16_t getLastInsertedCoin(void) const =0; + + virtual bool getAllInsertedCoins(uint16_t *types, uint16_t *values) const =0; + // alle bei diesem Verkauf eingeworfenen Muenzen sind gespeichert, max 64 + + + virtual bool cash_cancelPayment(void) const =0; + // and return coins + + virtual bool cash_stopPayment(void) const =0; + // and keep coins in escrow + + + // after ticket/goods issue: + virtual bool vend_success(void) const =0; + // conclude payment process, encash all inserted coins to vault. Printing was successful + // if possible return change + + virtual bool vend_failed(void) const =0; + // conclude payment process and return all inserted coins + + + + + + virtual uint8_t mif_getCardType(QString *cardholder) const =0; + // return 1,2,3,4 = upper, lower access card, printer test, coin test + // cardholder: 7byte Name-String + + virtual uint64_t sys_getWakeSource(void) const =0; + // retval: 6 bytes, bit coded, 1=event keeps DC awake + + virtual uint8_t sys_getWakeReason(void) const =0; + // Master was woken by following reason: + // 1: MDB Event + // 2: Coin Event + // ( 3: Master Event) - will not set the wake line + // ( 4: 32s pulse) - will not set the wake line + // 5: Door Event + // ( 6: Diag Event) - will not set the wake line + // 7: 30min-Pulse for HB + + virtual void sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const =0; + + virtual void sys_getDeviceConditions(struct T_moduleCondition *devCond) const =0; + + virtual void sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const =0; + + virtual void sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const =0; + + + virtual uint32_t cash_getAmountInVault(void) const =0; + + virtual uint16_t cash_getNrCoinsInVault(void) const =0; + + virtual uint8_t prn_getPrintResult() const =0; + + + + virtual uint8_t prn_getCurrentPrinterState() const =0; + // 0: printer OK + // bit0: near paper end bit1: no paper + // bit2: temperature error bit3: error head open + // bit4: paper jam in cutter + // bit6: no response bit7: serial rec. error + // bit5: printer not ready + + + virtual void sys_sendDeviceParameter(struct T_devices *deviceSettings) const =0; + + virtual void sys_restoreDeviceParameter(struct T_devices *deviceSettings) const =0; + // attention: only applies if function "sys_sendDeviceParameter()" was used to send this settings before + // cannot be used to see settings programmed by JsonFile + + virtual bool sys_areDCdataValid(void) const =0; + + virtual bool sys_sendingTest(void) const =0; + + virtual void prn_requestCurrentDynData(void) const =0; + + virtual bool prn_getCurrentDynamicPrnValuesFromDC(uint8_t *dynPrnVal ) const =0; + // which was sent with: bool prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const =0; + + virtual bool prn_dynDataAreEqual(uint8_t *buf) const =0; + + virtual bool prn_printKombiticket(uint8_t nrOfKombi) const =0; + // print four of the templates loaded by Json prior + // nr = 1..8 + + virtual void lock_triggerUpperSolenoid(void) const =0; + + virtual void lock_triggerLowerSolenoid(void) const =0; + + virtual bool doors_supervise(void) const =0; + + virtual bool dc_isAutoRequestOn(void) const =0; + + virtual uint16_t log_getLatestAccountNumber(void) const=0; + // new function 27.6.2023 + // latest = highest of the backup's + + virtual uint8_t log_getAvailableVaultBlocks(void) const=0; + // return 0x0011 1111 if all 6 blocks are loaded (one bit per block) + + virtual uint8_t log_getAnswerToLastSlaveRequest(void) const =0; + // use only for ONE request/command + // return: 0xFF: result unknown by now as sending is ongoing + // 0=OK + // 1= wrong length 2=wrong start sign 5= wrong crc + // 6= slave: master cmd was wrong 7: slave: could not write/read data + // 8=timeout, got no response from slave + // 0,8 work, 1..6 not yet tested. 8 comes immed. and stays 8 until reconnect + + // use for important and extended commands (print several templates, print ticket...) + virtual void log_startSupervision(void) const =0; + + virtual uint8_t log_getAnswerToLastCmdBatch(void) const =0; + // 0xFF: no command sent by now + // 0: started, in progress + // 1: done and OK + // 2: done and error + // not working properly, always 0 + + virtual bool log_getVaultData(uint8_t *data) const =0; + // get vault record in linear 8bit buffer with 384 byte + + + + // new from 1.8.23 + virtual bool prn_printOneAccountReceipt(uint16_t accountNr) const =0; + // print one out of eight stored last accounting receipts + // function log_getHoldAccountNumbers() gives a list of acc-Nr. of the stored receipts + + virtual bool prn_printAllAvailAccountReceipts(void) const =0; + // same as: prn_printAccountReceipt() from line 1153 + // return true if sending to DC OK, false if cmd-stack is full + + virtual bool log_verifyVaultRecordByCrc(void) const =0; + // return true if CRC16 is correct, data are 100% OK. Security level 1:65536 + // verification is strongly recommended before further processing + // in case of "false"-result please reload from DC + + + virtual uint16_t log_DC_getNextAccountNumber(void) const=0; + // the current cash box content will be backuped with this number on next cashbox-change + + virtual void log_DC_setNextAccountNumber(uint16_t newAccountingNumber) const=0; + // the current cash box content will be backuped with this number on next cashbox-change + // use only in case of hardware replacements or errors which derailed the number + + virtual void log_DC_deleteAllVaultrecordsInDc(void) const=0; + // use only in case of hardware replacements or errors which derailed the number + + virtual void log_DC_deleteAllTotalCounters(void) const=0; + // use only in case of hardware replacements or errors which derailed the number + + virtual void dc_setNewCustomerNumber(uint16_t newCustNr) const =0; + + virtual void dc_setNewMachineNumber(uint16_t newMachNr) const =0; + + virtual void dc_setNewBorough(uint16_t newBorough) const =0; + + virtual void dc_setNewZone(uint16_t newZone) const =0; + + + + // new functions from 8.9.23 + virtual QString mif_getReaderType(void) const =0; + // return "SL025" if correct reader is connected + + virtual void mif_getCardSize(uint8_t *cardSize, uint8_t *idLeng) const =0; + // cardSize=1k or 4kByte + // idLeng =4Byte or 7 byte + + virtual char mif_getAtbCardData(uint8_t *buf, uint8_t maxBuffSiz) const =0; + // return complete buffer binary, just for test purpose + + virtual bool mif_isValidAtbCard(void) const =0; + + virtual uint32_t mif_getAtbCardCuNu(void) const =0; + + virtual uint8_t mif_getAtbCardTyp(void) const =0; + // return 1=upper door card 1=lower door 3=printer-test 4=coin-test + // 0: not a valid atb2020 card + + virtual QString mif_getAtbCardPerso(void) const =0; + // e.g. "PNsax001" used for personal number, name shortcode, card number + // free to use, can be set in AtbMcw23.exe tool + + virtual void mif_getAtbCardExpire(uint8_t *year, uint8_t *month, uint8_t *day, uint8_t *hour, uint8_t *minute) const =0; + + + // ------------------------------------------------------------------------------------ + // Device-Controller-Bootloader convenient version 21.09.2023 + // ------------------------------------------------------------------------------------ + + // use this to jump to BL: + //void hwapi::bl_rebootDC(void) const + + // use this to start BL: + // void hwapi::bl_startBL(void) const + + // call this in order to get response from BL: + //void hwapi::bl_checkBL(void) const + + // evaluate BL response: + //bool hwapi::bl_isUp(void) const + + // 29.9.23: new: "completeStart" function, replaces bl_rebootDC(), bl_startBL() and bl_checkBL() + // result can be verified with bl_isUp() as before + virtual bool bl_completeStart(void) const =0; + // must be used in DC's normal operation + + // select binfile-name in GUI + + // send binfile-name to BL-processor: + virtual bool bl_storeFirmware(QString fileName) const =0; + // load binary file 3x and compare + // return true if loaded correctly + // return false: error, could not load correctly + + // request the number of blocks for this file + virtual uint16_t bl_getNrOfFirmwareBlocks(void) const =0; + // size of the loaded bin file in 64byte blocks + // call after bl_storeFirmware() + + // call the next two function's repetitive with "blockNumber"=0,1,2,3....."bl_getNrOfFirmwareBlocks()" + + virtual bool bl_blockAutoLoad(uint16_t blockNumber) const =0; + // call in loop from block number 0 up to <= "dcBL_getNrOfBlocks()" + //the last block "bl_getNrOfFirmwareBlocks()" is sent as conclusion command (important!) + // but after every call WAIT (!) for response "bl_blockAutoResponse()" !!!! + // data will be sent to DC, if neccesary addr will be sent additionally + // if neccesary sending will automatically repeat up to 3times + // retval: false if blockNumber>4095, true else + + // check out this response after every block-sending, wait until >0!!! + virtual int8_t bl_blockAutoResponse(void) const =0; + // after every "bl_blockAutoLoad()" call this until response + // retval 0: wait 1: OK, blk was sent 2: OK, transfer complete + // 3: error despite repeating, cancel. probably bin file corrupted + // Max duration: 3x no response from BL = 900ms + + + // finally call: + // void hwapi::bl_stopBL(void) const + // -------------- end of bootloader --------------------------------------------------- + + + + // new from 28.9.23 and earliest from DC version 4.45 + // get all versions of the DC-Jsons + virtual void sys_requestJsonVersions(uint8_t jsonNr) const =0; + // send one request for every single version + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + + virtual void sys_getJsonVersions(uint8_t jsonNr, char *versionString) const =0; + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + // length of buffer is always 16 byte + + // ------------------------------------------------------------------------------------ + // Coin Changer + // ------------------------------------------------------------------------------------ + + // find above (same as for coin checker (EMP)): + + // mdb_switchPower(true); // power on/off + // cash_startPayment(amount_cent); // start polling, enable coins, changer turns to green + + // getInsertedAmount() + // getLastInsertedCoin() + // getAllInsertedCoins(uint16_t *types, uint16_t *values) + // all inserted coins of this past transaction are stored, max 64 + + // cash_stopPayment(); // and wait for further command (changer blinks yellow) + // cash_cancelPayment(); // and return complete paid amount + + // after ticket/goods issue: + // vend_success() + // conclude payment process, keep all coins. Printing was successful + // return change (payment above start-amount), so it works only if + // Payment was started with real vending price (pre selection). + // if payment was started with maximum price (for direct coin insertion) + // then use "changer_returnCoins()", not vend_success() + + // vend_failed() + // conclude payment process and return complete paid amount + + // also valid for changer: + // emp_sendSettings(uint16_t coinAcceptance, uint8_t tokenChannel, uint16_t *coinDenomination ) const =0; + // coinAcceptance: bit0=coin1 (lowest donomination) bit15=coin16 bitH=accept bit L = deny coin (no validation) + // tokenChannel 0...31: if this signal comes from emp then a token was inserted + // coinDenomination = array of 16 coin values (e.g. 5, 10, 20...) + + virtual void changer_returnCoins(uint32_t amountInCent) const =0; + + virtual void changer_requestChangeResult(void) const =0; + + virtual uint8_t changer_getChangeResult(uint32_t *returnedAmount) const =0; + // get result of coin dispensing + // receivedData[0]: 0: not yet started 1:amount returned + // 2:only partial return 3: no return possible + // receivedData[2,3,4,5]: returned amount + + virtual void changer_getAllParameters(struct T_changer *mw) const =0; + // requested automatically with 23, same like EMP + + virtual void changer_requestTubelevel(void) const =0; + + virtual void changer_getTubelevel(struct T_chg_Tub *tubLevel) const =0; + // don't use tubeDispens[], it's not yet correct! + + + + // ------------------------------------------------------------------------------------ + // bank note acceptor + // ------------------------------------------------------------------------------------ + + // already defiened functions applying for BNA as well: + // mdb_switchPower(true); // power on/off + + // bank notes are integrated in the normal transaction process, so use the usual functions to run a vending cycle: + // cash_startPayment(amount_cent); // start polling, enable bills, reader shows green + // getInsertedAmount() + // cash_stopPayment(); + // cash_cancelPayment(); + // vend_success() + // vend_failed() + + virtual void bna_sendSettings(uint16_t notesToAccept, uint16_t parameters, + uint16_t *billDenomination, + uint32_t acceptanceLimit) const =0; + // notesToAccept: bit0=bill1 (lowest donomination) bitH=accept bit L = deny + // parameters: e.g. use escrow function for some notes + // billDenomination = array of 16 bill values (e.g. 5, 10, 20...) + // these can be set alternatively by Json-File DC2C_cash.json + // acceptanceLimit: device will stop acceptance once this amount is reached and + // optionally keep last bill in escrow until vend_success() + // is called (put bill to stacker) or vend_failed() is called (return bill) + + virtual void bna_setCurrentAcceptance(uint16_t notesToAccept) const =0; + // can be used to block notes dynamically, example: from now only 5€ bills are allowed (if only 3€ are to be paid) + + virtual void bna_requestParameters(void) const =0; + // send command to DC in order to get static invariable device parameters like currency + // device must be powered and polled to get these + + virtual bool bna_getAllParameters(struct T_bna *bna) const =0; + // get all constant data from reader (e.g. currency) + // and actual Host-Settings (sent with bna_sendSettings() or json) + // retval = true if data are valid + + virtual void bna_requestCurrentNotes(void) const =0; + // send command to DC in order to get transaction data + + virtual uint8_t bna_getCurrentNotes(uint16_t latestBill, uint16_t *currentNotes) const =0; + // returns number of collected bank notes since start-command (current transaction) + // latestBill: last accepted bank note, value in cent + // currentNotes an array with up to 16 (further) notes collected + + virtual void bna_requestStackerLevel(void) const =0; + + virtual uint16_t bna_getStackerLevel(uint32_t *amountInStacker, uint16_t *countOfBills) const =0; + // return val: nr of bills in stacker + // countOfBills: array of up to 16 sums, countOfBills[0]=nr of 5€-bills in stacker + // countOfBills[1] for 10€ and so on + + + + +signals: + virtual void hwapi_templatePrintFinished_OK(void) const=0; + virtual void hwapi_templatePrintFinished_Err(void) const=0; + + virtual void hwapi_coinCollectionJustStarted(void) const=0; + virtual void hwapi_coinCollectionAborted(void) const=0; + + virtual void hwapi_gotNewCoin(void) const=0; + virtual void hwapi_payStopByMax(void) const=0; + virtual void hwapi_payStopByPushbutton(void) const=0; + + virtual void hwapi_payStopByEscrow(void) const=0; + virtual void hwapi_payStopByError(void) const=0; + virtual void hwapi_payStopByTimeout(void) const=0; + virtual void hwapi_payCancelled(void) const=0; + virtual void hwapi_coinProcessJustStopped(void) const=0; + + virtual void hwapi_doorServiceDoorOpened(void) const=0; + virtual void hwapi_doorVaultDoorOpened(void) const=0; + virtual void hwapi_doorCoinBoxRemoved(void) const=0; + virtual void hwapi_doorCoinBoxInserted(void) const=0; + virtual void hwapi_doorCBinAndAllDoorsClosed(void) const=0; + virtual void hwapi_doorAllDoorsClosed(void) const=0; + + + +}; + + +// History +// 11.10.2021: V1.0 222 functions +// 23.12.2021: V1.1 added block-parameter to function "read mifare data" +// 30.12.2021: V1.2 added function: mif_clearDataBuffer(), mif_isBlockAvailable(uint8_t blkNr) and mif_getAvailableDataBlocks() +// 1.1.2022: V1.3 Mifare extended. ( background: read 16 x 48byte from card to DC, read 12 x 64byte from DC to CA) +// new: read full card with 768bytes from HWapi without block borders +// added: mif_getNrOfAvailableDataBytes mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize) +// mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize) +// mif_getCardDataStr(bool useHexFormat, char seperator) + +// 29.03.2023: V3.1 some extensions for PSA1256_ptu5, +// V3.2 Bootloader improvement +// 12.04.2023: V3.3 new features extended: loading and using Json-files, cash-collection, cash-data-logging +// 14.04.2023: V3.4 new features extended: sys_getDynMachineConditions, sys_getDeviceConditions and +// rtc_getExtendedTime return struct in addition. New function to select and get VaultRecord +// +// 19.04.2023: V3.5 new function: sys_getWakeReason(); +// 17.05.2023: V3.6 new function: cash_isCollectionActive(), cash_isPayProcessActive() +// new signals: hwapi_coinCollectionJustStopped, hwapi_coinCollectionJustStarted +// getAllInsertedCoins() fixed, also in datif and storeINdata + +// 15.06.2023 V4.2 bring into same order as hwapi in order to set the THIS_IS_CA_MASTER correct +// 19.06.2023 V4.3 added some qCriticals to see emits + +// 01.08.2023 V4.4 some new values at the end of struct T_vaultRecord +// two more values in struct T_devices +// 7 new functions at the end of the file + + +//#define HWINF_iid "Atb.Psa2020.software.HWapi/3.1" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.1" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.3" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.4" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.5" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/3.6" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.0" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.1" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.2" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.3" +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.4" + // 8.9.2023 two new functions (end of file) for mifare test +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.5" + // 18.9.2023 major improvements for DC data exchange + // verification of door and cash box signals + // intensive verification of Json-Programming Master-Slave (PTU to DC), 100% ok +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.6" + // 20.9.2023: speeding up door and cash box signals +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.7" + // 26.09.2023: added improved DC-bootloader files +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/4.8" +// 28.09.2023: added version request of DC-Json-Files +//#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/5.0" + // 10.10.2023: added coin changer + +#define HWINF_iid "Atb.Psa1256ptu5.software.HWapi/5.1" +// 20.10.2023: added bill validator + + +Q_DECLARE_INTERFACE(hwinf, HWINF_iid) + + +#endif + + + diff --git a/include/plugin.h b/include/plugin.h new file mode 100755 index 0000000..97debd9 --- /dev/null +++ b/include/plugin.h @@ -0,0 +1,6 @@ +#ifndef PLUGIN_H +#define PLUGIN_H +//#include "../plugins/interfaces.h" +#include "../MasterPlug/interfaces.h" + +#endif diff --git a/include/prot.h b/include/prot.h new file mode 100644 index 0000000..4fedf51 --- /dev/null +++ b/include/prot.h @@ -0,0 +1,134 @@ + +#ifndef SERIAL_FRAME_H +#define SERIAL_FRAME_H +#include +#include +#include +#include "tslib.h" +#include "com.h" +#include "interfaces.h" + + +/* + get's OUT-data from datif, + get's IN-data from datif + get's send command from datif + makes frame and calls: isSerialFree(), setSendData(), + if not free retrigger datif sending period (normally 500ms or 50ms for direct cmds) + + with control-signal: gotReceiveData(): + getRecData(); + send results to diag window/line + send IN-data to datif +*/ + +#define FRAME_DATALEN 64 +#define FRAME_MAXLEN FRAME_DATALEN+20 +#define BL_DATA_LEN 200 + +#define DATALEN_SEND_FAST 4 +#define DATALEN_SEND_LONG 64 +#define HEADERLEN_SEND 4 +#define TELEGRAMLEN_SEND_FAST 12 +#define TELEGRAMLEN_SEND_LONG 70 +#define STARTSIGN_SEND_FAST 0x3F +#define STARTSIGN_SEND_LONG 0x3D + +#define DATALEN_RECEIVE_FAST 8 +#define DATALEN_RECEIVE_LONG 64 +#define HEADERLEN_RECEIVE 2 +#define TELEGRAMLEN_RECEIVE_FAST 12 +#define TELEGRAMLEN_RECEIVE_LONG 68 +#define STARTSIGN_RECEIVE_FAST 0x5F +#define STARTSIGN_RECEIVE_LONG 0x5D + + +class T_prot : public QMainWindow +{ + Q_OBJECT + + // Dateneingang von Datif: + uint8_t SendDataValid; // bit1: WR OK bit 2: RD OK + uint16_t slaveAddr; + + uint16_t WriteCommand; + uint16_t WriteAddr; + uint8_t WrDataLength; + uint8_t ui8OutputData[FRAME_DATALEN]; + char chOut_Data[FRAME_DATALEN]; + uint8_t kindOfData; // 0: binaries, 1:text + + uint16_t ReadCommand; + //uint16_t ReadAddr; + uint16_t reserve; + + // Ausgangs-Daten, werden vom Datif geholt: + // nur wenn CommandState und readState OK + uint8_t RecSlaveAddr; + bool INdataValid; // nur true wenn CommandState OK und readState OK + uint16_t readSource; // diese (Eingangs-)Daten stehen im Puffer + uint16_t readAddress; // von dieser Adr wurden die Daten gelesen + //uint8_t lastWakeSrc; // falls der Slave den Master geweckt hat + uint8_t RdDataLength; + uint8_t InputData[FRAME_DATALEN]; + + // 11.11.2020: + uint8_t BLsendDataLength; + uint8_t ui8BLsendData[BL_DATA_LEN]; + uint8_t prot_storeResult; + + T_com *mySerialPort; + + void startPacking(void); + void startFastPacking(void); + uint8_t FramecheckInData(uint8_t *Inbuf, uint16_t LL); + uint8_t FastCheckInData(uint8_t *Inbuf, uint16_t LL); + + uint8_t CheckInResult(uint8_t *Inbuf); + + uint8_t ShowFastInData(uint8_t *recBuffer); + uint8_t ShowInData(uint8_t *recBuffer); // was CheckInData + void setRecLen(uint16_t WriteCmd); + +private slots: + void analyseRecData(void); + +public: + T_prot(); + bool isPortOpen(void); + bool isSerialFree(void); + void setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, uint8_t *data); + void setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr); + void setUserWriteData(uint16_t WriteCmd); + void setUserWriteText(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, char *data); + + void setUserWrite1DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val); + void setUserWrite2DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1); + + void setUserReadData( uint16_t ReadCmd); + + void setBLsendData( uint8_t len, uint8_t *buf); + + void receiveFixLen(int64_t nrOfbytesToReceive); + + void sendUserData(uint16_t slaveAdr); + + uint8_t ifDataReceived(); + // return: 0xFF: result unknown 0=OK + // 1= wrong length 2=wrong start sign 5= wrong crc + // 6= slave: master cmd was wrong 7: slave: could not write/read data + + bool getReceivedInData(uint8_t *SlavAddr, uint16_t *readSrc, uint16_t *readAddr, + uint8_t *RdDlen, uint8_t *receivedData); + // retval: data valid, only one time true + + +signals: + void framerecieved(); //bool gotINdata); + void rawDataRecieved(); + +}; + + + +#endif // T_prot_H diff --git a/include/runProc.h b/include/runProc.h new file mode 100755 index 0000000..09a8457 --- /dev/null +++ b/include/runProc.h @@ -0,0 +1,86 @@ + +#ifndef RUN_PROCESS_H +#define RUN_PROCESS_H + +#include +#include +#include +#include "tslib.h" +#include "com.h" +#include "interfaces.h" + +#include +#include +#include +#include "datIf.h" +#include +#include "sendWRcmd.h" +#include "controlBus.h" +#include "storeINdata.h" +#include "dcBL.h" +#include "shared_mem_buffer.h" + + + +class T_runProc : public QObject +{ + Q_OBJECT + QTimer *hwapi_TimerPayment, *hwapi_triggerBL; + + void sub_emp_getAllParameters(struct T_emp *emp); + void changer_getAllParameters(struct T_changer *mw); + + void sub_getDynMachineConditions(struct T_dynamicCondition *dynMachCond); + + void restoreDeviceParameter(struct T_devices *deviceSettings); + +private slots: + void runProc_slotProcess(void); + bool bl_performComplStart(void); + +public: + T_runProc(); + + bool cash_startPayment(uint32_t amount); + uint8_t cash_paymentProcessing(void); + uint8_t epi_store64BdevParameter(uint8_t length, uint8_t *buf); + uint8_t epi_restore64BdevParameter(uint8_t *length, uint8_t *buf); + bool doors_supervise(void); + uint8_t prn_getHwState(struct Tprn_hw_state *prn_hw_state); + void bl_completeStart(void); + void dc_autoRequest(bool on); + void bl_rebootDC(void); + void bl_startBL(void); + void bl_checkBL(void); + bool bl_isUp(void); + + +signals: + //void runProc_templatePrintFinished_OK(void) const override; + //void runProc_templatePrintFinished_Err(void) const override; + + void runProc_coinCollectionJustStarted(void); + void runProc_coinCollectionAborted(void); + + void runProc_gotNewCoin(void); + void runProc_payStopByMax(void); + void runProc_payStopByPushbutton(void); + + void runProc_payStopByEscrow(void); + void runProc_payStopByError(void); + void runProc_payStopByTimeout(void); + void runProc_payCancelled(void); + void runProc_coinProcessJustStopped(void); + + void runProc_doorServiceDoorOpened(void); + void runProc_doorVaultDoorOpened(void); + void runProc_doorCoinBoxRemoved(void); + void runProc_doorCoinBoxInserted(void); + void runProc_doorCBinAndAllDoorsClosed(void); + void runProc_doorAllDoorsClosed(void); + +}; + + + +#endif diff --git a/include/sendWRcmd.h b/include/sendWRcmd.h new file mode 100644 index 0000000..7e83be6 --- /dev/null +++ b/include/sendWRcmd.h @@ -0,0 +1,262 @@ + +#ifndef SENDWRCMDS_DEFS_H +#define SENDWRCMDS_DEFS_H +#include "tslib.h" +#include + +// asynch. Commands +// store OUTPUT commands until time to send +// problem: OUT commands are set if a button is pressed or a transaction event happens +// so it's never synchron with sending grid +// but sending must apply the 100ms time grid as we have to wait for the response before sending the next command!!! + + +// aug2023: used with setSendCommand0 +//#define SENDDIRCMD_TestSerial 1 +//#define SENDDIRCMD_MakeReset 2 +//#define SENDDIRCMD_setTime 3 +//#define SENDDIRCMD_setWakeFrequ 4 + +//#define SENDDIRCMD_MOVEUP_LOCK 5 +//#define SENDDIRCMD_MOVEDN_LOCK 6 +//#define SENDDIRCMD_OPENUP_DOOR 7 +//#define SENDDIRCMD_OPENDN_DOOR 8 + + +//#define SENDDIRCMD_LEDILLU 9 +//#define SENDDIRCMD_LEDCOIN 10 +//#define SENDDIRCMD_LEDTICKET 11 +//#define SENDDIRCMD_LEDPAD 12 +//#define SENDDIRCMD_LEDSTART 13 +//#define SENDDIRCMD_LEDINSIDE 14 +//#define SENDDIRCMD_LED_ALL 15 +//#define SENDDIRCMD_FAN 16 +//#define SENDDIRCMD_LAERM 17 +//#define SENDDIRCMD_REL1 18 + +//#define SENDDIRCMD_WAKEPTU 20 +//#define SENDDIRCMD_AUXPWR 21 +//#define SENDDIRCMD_AUXDDR 22 +//#define SENDDIRCMD_AUXOUT 23 + + +//#define SENDDIRCMD_UCONTACT_ON 30 +//#define SENDDIRCMD_PRN2_SWONOFF 31 + +//#define SENDDIRCMD_MIF_SWONOFF 32 +//#define SENDDIRCMD_MIF_ATBCREATE 33 + +//#define SENDDIRCMD_MOD_SWONOFF 40 +//#define SENDDIRCMD_MOD_WAKE 41 +//#define SENDDIRCMD_MDB_POWER 42 +//#define SENDDIRCMD_MDB_WAKE 43 +//#define SENDDIRCMD_CRED_ON 44 +//#define SENDDIRCMD_CRED_WAKE 45 + +//#define SENDDIRCMD_SHUT_MOV 50 +//#define SENDDIRCMD_ESCRO_MOV 51 +//#define SENDDIR_OPENVAULT 52 +//#define SENDDIR_REJMOT_ON 53 +//#define SENDDIR_REJMOT_RUN 54 + +// Level 2 (serial from DC to devices) +//#define SEND_REQU_SERCONF 100 +//#define SEND_REQU_HWversion 101 +//#define SEND_REQU_SWversion 102 +//#define SEND_REQU_CONDITION 103 +//#define SEND_REQU_UID 104 +//#define SEND_REQU_TIME 105 + // includes wake frequency +//#define SEND_REQU_ANALOGS 110 +//#define SEND_REQU_DIG_INPUTS 111 +//#define SEND_REQU_DIG_OUTPUTS 112 + +//#define SEND_REQU_PRN_STATE 120 +//#define SEND_REQU_PRN_FONTS 121 +//#define SEND_REQU_PRN_ALL 122 + +//#define SEND_REQU_MIFSTATE 123 + // Type and state of reader + +//#define SEND_REQU_MIFDATA 124 + // Type, UID, Header of card + // read one card sector + // sectors must be addressed by RD_ADD + +//#define SEND_REQU_MIF_ATB_TYPE 125 + +//#define SEND_REQU_MDB_GETSTAT 126 +//#define SEND_REQU_MDB_GETWAK 127 +//#define SEND_REQU_MDB_GETRESP 128 +//#define SEND_REQU_EMP_GETALL 129 +//#define SEND_REQU_EMP_GETCOIN 130 + + +//#define SENDDIRCMD_DEVICE_PARA 131 +//#define SENDDIRCMD_MACHINE_ID 132 +//#define SEND_REQU_DEVICE_PARA 133 +//#define SEND_REQU_MACINE_ID 134 + + + + + +// TODO: +//#define SENDDIRCMD_PRN_SETUP 72 +//#define SENDDIRCMD_MDB_SNDMSG 92 +//#define SENDDIRCMD_EMP_SETT 93 +//#define SENDDIRCMD_PRN_BC 80 + + + +// further: mdb state, coinchecker state, bill state, modem state, credit_state.... +/* +#define SENDDIRCMD_SHUTOPENBYTIME 60 +#define SENDDIRCMD_SHUTOPENBYCOIN 61 +//#define SENDDIRCMD_SHUT_SENDTIME 62 + +#define SENDDIRCMD_ESCRO_TAKE 63 +#define SENDDIRCMD_ESCRO_GIVE 64 + +#define SENDDIRCMD_PRN_SYS_CMD 70 +#define SENDDIRCMD_PRN_ESC_CMD 71 +#define SENDDIRCMD_PRN_MOVE 73 +#define SENDDIRCMD_PRN_SETFONT 74 +#define SENDDIRCMD_PRN_SETLETT 75 +#define SENDDIRCMD_PRN_CUT 76 +//#define SENDDIRCMD_PRN_TXT // not needed +#define SENDDIRCMD_PRN_LF 78 +#define SENDDIRCMD_PRN_FONTTAB 79 +#define SENDDIRCMD_PRN_QR 81 +#define SENDDIRCMD_PRN_STOREDQR 82 +#define SENDDIRCMD_PRN_LOGO_FL 83 +//#define SENDDIRCMD_PRN_LOGO_GRAF 84 +//#define SENDDIRCMD_PRN_LOGODAT 85 +//#define SENDDIRCMD_PRN_STORBC 86 +#define SENDDIRCMD_PRN_STORQR 87 +#define SENDDIRCMD_PRN_DOC 88 +#define SENDDIRCMD_PRN_CLEARDOC 89 + +//#define SENDDIRCMD_MDB_POWER 42 +//#define SENDDIRCMD_MDB_WAKE 43 +#define SENDDIRCMD_MDB_RES 90 +#define SENDDIRCMD_MDB_SENDCMD 91 +#define SENDDIRCMD_EMP_POLL 94 +#define SENDDIRCMD_EMP_STARPPAY 95 +#define SENDDIRCMD_EMP_STOPPAY 96 +*/ + + + +// obsolete: +/* +#define SENDDIRCMD_PRN1_SENDTEXT 54 +#define SENDDIRCMD_PRN1_SENDCMD 55 +#define SENDDIRCMD_PRN1_SERPAR 56 +#define SENDDIRCMD_PRN_LEVEL2_4B 58 +#define SENDDIRCMD_PRN_LEVEL2_64 59 +*/ + +// highest priority +//#define CMDSTACKDEPTH 16 +// means: up to 16 cmd can be stored. They are issued one by one every 100ms +//void sendWRcmd_clrCmdStack(void); +//bool sendWRcmd_setSendCommand0(uint16_t nextCmd); + // GUI or app sends a command to DC transfered by serial + +//uint16_t sendWRcmd_getSendCommand0(void); + +// lower priority +//#define CMD4STACKDEPTH 8 +//void sendWRcmd_clrCmd4Stack(void); +//bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4); +//uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4); + +//#define CMD8STACKDEPTH 4 +//void sendWRcmd_clrCmd8Stack(void); +//bool sendWRcmd_setSendCommand8(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint16_t dat3, uint32_t dat4); +//uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3, uint32_t *dat4); + + + +// lowest priority +// wait for resonse before send next! +bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t *buf); +uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf); + // retval = *leng + +void sendWRcmd_INI(void); + + + +//uint8_t epi_store64ByteSendData(uint8_t length, uint8_t *buf); + // HWapi writes data to be forwarded to DC and further to mdb-device + // not batched! don't use twice within 100ms + +//uint8_t gpi_restore64ByteSendData(uint8_t *length, uint8_t *buf); + // datif reads data to forward to dc + + + +// ONE printer doc consists of 20 x 64 byte +//#define MAXNROF_PRNBYTES 64 +//#define MAXNROF_PRNBLOCKS 20 +/* +void epi_resetPrinterStack(void); + +uint8_t epi_storePrnText(char *buf, uint8_t leng); + // store text and binary data from Gui in next higher free memory 0....9 + +uint8_t gpi_restorePrnText(uint8_t *retbuf); + // read printer text and send to slave, size of retbuf== 64 + +uint8_t gpi_chk4remainingText(void); + // retval: 0: no more textline left (to send) >0: nr of lines +*/ + + +//void epi_storeUserOfSendingTextBuffer(uint8_t user, uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4 ); + // user=1: Text-Print is using this buffer + // 2: QR-code-Printer is using this buffer + +//uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2, uint8_t *para3, uint8_t *para4); + // user=1: Text-Print is using this buffer + // 2: QR-code-Printer is using this buffer + + + + + + +// #define FDCMD_STACKDEPTH 16 / 32 +// short and long commands are queued into the same stack to guaranty right order +void sendFDcmd_clrStack(void); + +bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4); + // write Command to memory, wait for transport +bool sendFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4); + +uint8_t check4usedFDstack(void); + // returns number of waiting command, maxFDCMD_STACKDEPTH + +uint8_t checkNextFDcmd(void); + // return 0: no command waiting +// 1: short cmd +// 2: long cmd + +uint8_t check4freeFDstack(void); + // returns number of free places in FD-command stack + + +bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data); +bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, QByteArray *data); + // write Command to memory, wait for transport + // data buffer size always 64! data[64], padded with 0 + + +bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data); + + +#endif + + diff --git a/include/shared_mem_buffer.h b/include/shared_mem_buffer.h new file mode 100644 index 0000000..16ea62a --- /dev/null +++ b/include/shared_mem_buffer.h @@ -0,0 +1,351 @@ +#ifndef SHARED_MEM_BUFFER_INCLUDED_H +#define SHARED_MEM_BUFFER_INCLUDED_H + +#include +#include + +#include +#include + + +bool shdMem_firstUse(void); + +// Vorsicht: im shared memory ist kein QString erlaubt!!!!!!!!!!!!!!!!!!!!!! +// nur standard C Typen!!!!!! +// also auch kein QByteArray o.ä. + +// Vorsicht: Zugriffe auf Comport NICHT ins shared mem --> Absturz!!!! + +struct SharedMem +{ + // ------------------ Comport Control -------------------------------- + bool rs_portIsOpen; + bool AutoEmissionOn; + bool Sdata_serialTestResult; + uint8_t Sdata_pProtResultOk; + uint16_t Sdata_receivedDataLength; + uint8_t Sdata_receivedDataBlock[64]; + uint8_t ndbs, pari, nsb, br; + + uint8_t Sdata_lastResult; + uint8_t Sdata_OverallResult; + bool Sdata_startSV; + + // ------------------ Data INPUT -------------------------------- + + bool indat_savePrnPwr; + bool indat_saveMifPwr; + bool indat_MdbIsOn; + //QString indat_HWversion; + //QString indat_SWversion; + //QString indat_DCstate; + + #define versionBufferLen 32 + char indat_HWversion[versionBufferLen]; + char indat_SWversion[versionBufferLen]; + char indat_DCstate[versionBufferLen]; + + struct Sdata + { + uint64_t slaveUID; + uint8_t UIDstr[8]; + } Sdata; + + struct T_globTime + { + // Reihenfolge nicht vertauschen!!!!! + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t Year; + uint8_t Month; + uint8_t DayOfMonth; + uint8_t DayOfWeek; // 1=monday...7 + uint8_t reserve1; + + uint16_t MinutesOfToday; + uint16_t reserve2; + + uint32_t SecondsOfToday; + + uint8_t IsLeapyear; + uint8_t nextLeap; + uint8_t lastLeap; + uint8_t hoursOfWeek; + + uint16_t minOfWeek; + uint16_t hoursOfMonth; + uint16_t minOfMonth; + uint16_t dayOfYear; + uint16_t hoursOfYear; + uint16_t reserve3; + + uint32_t minOfYear; + + uint8_t squareOutMode; + uint8_t free1; + uint16_t reserve4; + uint32_t minOfMillenium; + // bis hierher 44byts + uint32_t free2; + uint32_t free3; + uint32_t free4; + + } getGlobalTime; + + #define MAXNROF_AI 4 + uint16_t AI_val[MAXNROF_AI]; + + #define MAXNROF_MEASURE 4 + uint32_t Sdata_measurement[MAXNROF_MEASURE]; + + uint8_t di_doorSwitch; + uint8_t di_vaultSwitch; + uint8_t di_lockSwitch; + uint8_t di_opto; + uint8_t di_aux; + bool di_wakeFromPtu; + bool di_wakeFromMdb; + bool di_PrnReady; + bool di_CoinAttach; + bool di_CoinEscrowOpen; + bool di_mifCardTap; + bool di_wakeFromModem; + bool di_contactPwrOn; + bool di_mifarePwrOn; + bool di_rdbk_mdbTxd; + bool di_AuxPwrOn; + bool di_gsmPwrOn; + bool di_creditPwrOn; + bool di_printerPwrOn; + bool di_mdbPwrOn; + bool di_rejMot_home; + uint8_t di_npe_sensor; + + uint8_t do_mbdRxTst; + uint8_t do_motorBits; + uint8_t do_serialSwitch; + uint8_t do_ledsAndFan; + uint8_t do_laermUndRelay; + uint8_t do_ptuWake; + uint8_t do_auxPower; + uint8_t do_coinShutter; + uint8_t do_coinEscrow; + uint8_t do_printerPower; + + //#define NROFMIFSTATEBYTES 40 + //uint8_t Sdata_MIF_STATE[NROFMIFSTATEBYTES]; + uint8_t Sdata_MIF_DATA[64]; + //uint8_t mif_cardType; + //uint8_t mif_cardHolder[8]; + uint8_t Sdata_MIF_ATB[64]; + + #define pi_prnStateArraySize 20 + uint8_t Sdata_PRN_STATE[pi_prnStateArraySize]; + + #define pi_prnFontArraySize 20 + uint8_t Sdata_PRN_FONTS[pi_prnFontArraySize]; + + bool Sdata_mdb_busRdy; + bool Sdata_mdb_V12on; + bool Sdata_mdb_V5on; + + uint8_t Sdata_mdbNrOfRecData; + uint8_t Sdata_RecBuff[40]; + + uint8_t Sdata_empNrOfsettings; + uint8_t Sdata_emp_settingsBuff[66]; + + struct T_coin + { + uint8_t valid; + uint8_t signal; + uint8_t error; + uint8_t pad; + uint16_t value; + }; + + #define MEMDEPTH_GOTCOINS 16 + struct T_coin gotCoin[MEMDEPTH_GOTCOINS]; + uint8_t ctr_gotCoin; + + uint8_t Sdata_NrOfDeviceSetting; + uint8_t Sdata_DeviceSettingBuff[66]; + + uint8_t SizeMachineIDBuff; + uint8_t MachineIDBuff[66]; + + uint32_t store_insertedAmount; + uint16_t store_lastCoinType[64]; + uint16_t store_lastCoinValue[64]; + uint8_t p_lastCoin; + char store_curPayNewCoin; + + uint64_t stor_wakSrc; + uint8_t stor_reason; + + uint8_t store_rbDevParamLen; + uint8_t store_rbDevParams[66]; + + uint8_t store_deviceCondLen; + uint8_t store_deviceCond[66]; + + uint8_t store_machCondLen; + uint8_t store_machCond[66]; + + uint8_t store_DcBackupNrOfAccNr; + uint16_t store_DcBackupAccNr[16]; // z.Z. nur 8 + + #define PI_SIZOFVAULTRECORD 400 + uint8_t store_gotNrBlocksOfVaultRec; + uint8_t store_vaultrecord[PI_SIZOFVAULTRECORD]; + + uint32_t store_amount; + uint16_t store_nrOfCoins; + + bool store_DcDataAreValid; + + uint8_t storeDCdynPrinterData[64]; + uint8_t DCdynPrinterDataActual; + + uint16_t store_DCNextAccountNumber; + + uint16_t storeMifCardTypDataLen; + uint8_t storeMcardTypData[64]; + + // new from 6.9.23: + #define RAW_BL_DATALEN 150 + uint8_t Sdata_rawData[RAW_BL_DATALEN]; + uint8_t Sdata_LengthRawData; + +#define numberOfJsons 36 +#define versionStringLength 16 + char store_jsonVersion[versionStringLength][numberOfJsons]; + + uint8_t Sdata_changeResult; + uint32_t Sdata_changedAmount; + uint8_t store_tubeLev[64]; + + + // Mitteilung von Hwapi zu Datif: + bool Sdata_coinPaymentNow; + bool Sdata_bootloadingNow; + + + // ------------------ Data OUTPUT -------------------------------- + + // sendWRcmd.cpp + #define CMDSTACKDEPTH 16 + uint16_t nextAsynchsendCmd0[CMDSTACKDEPTH]; + uint8_t nrOfCmdsInQueue; + + #define CMD4STACKDEPTH 8 + uint16_t nextAsynchsendCmd4[CMD4STACKDEPTH]; + uint8_t nextCmd4para1[CMD4STACKDEPTH]; + uint8_t nextCmd4para2[CMD4STACKDEPTH]; + uint8_t nextCmd4para3[CMD4STACKDEPTH]; + uint8_t nextCmd4para4[CMD4STACKDEPTH]; + uint8_t nrOfCmds4InQueue; + + #define CMD8STACKDEPTH 4 + uint16_t nextAsynchsendCmd8[CMD8STACKDEPTH]; + uint8_t nextCmd8para1[CMD8STACKDEPTH]; + uint8_t nextCmd8para2[CMD8STACKDEPTH]; + uint16_t nextCmd8para3[CMD8STACKDEPTH]; + uint32_t nextCmd8para4[CMD8STACKDEPTH]; + uint8_t nrOfCmds8InQueue; + + #define SENDASYDAT_BUFFSIZE 200 + uint8_t sendAsynchDataBuf[SENDASYDAT_BUFFSIZE]; // no stack, only ONE buffer + uint8_t sendAsyDatLen; + + #define MDBSEND_BUFFSIZE 64 + uint8_t Sdata_mdbSendBuffer[MDBSEND_BUFFSIZE]; + uint8_t Sdata_mdbSendLen; + + uint8_t prnDataParameters[4]; + uint8_t prnDataBufferUser; + + + // ONE printer doc consists of 20 x 64 byte + #define MAXNROF_PRNBYTES 64 + #define MAXNROF_PRNBLOCKS 20 + char Sdata_PRN_TEXT[MAXNROF_PRNBLOCKS][MAXNROF_PRNBYTES]; + uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK + + + //#define FDCMD_STACKDEPTH 16 // up to 1024 byte + #define FDCMD_STACKDEPTH 32 // up to 2048 byte + // header + uint8_t nextFDwrCmd[FDCMD_STACKDEPTH]; + uint8_t nextFDrdCmd[FDCMD_STACKDEPTH]; + uint8_t nextFDblkNr[FDCMD_STACKDEPTH]; + uint8_t nextFDshort[FDCMD_STACKDEPTH]; + + // short data + uint8_t nextFDpara1[FDCMD_STACKDEPTH]; + uint8_t nextFDpara2[FDCMD_STACKDEPTH]; + uint8_t nextFDpara3[FDCMD_STACKDEPTH]; + uint8_t nextFDpara4[FDCMD_STACKDEPTH]; + // long data: + uint8_t longFDlength[FDCMD_STACKDEPTH]; + uint8_t longFDpara[FDCMD_STACKDEPTH][64]; + + uint8_t p_nextFDcmdsInQueue; + + + + + + + static QSharedMemory *getShm(std::size_t s = 0); + + static SharedMem *getData() + { + Q_ASSERT_X(getShm()->data() != nullptr, "pointer access", "nullptr"); + return (SharedMem *)getShm()->data(); + } + + static SharedMem const *getDataConst() + { + Q_ASSERT_X(getShm()->data() != nullptr, "pointer access", "nullptr"); + return (SharedMem const *)getShm()->data(); + } + +// static SharedMemBuffer *write() + static SharedMem *write() + { + Q_ASSERT_X(getShm()->data() != nullptr, "pointer access", "nullptr"); + return (SharedMem *)getShm()->data(); + } + +// static SharedMemBuffer const *read() + static SharedMem const *read() + { + Q_ASSERT_X(getShm()->data() != nullptr, "pointer access", "nullptr"); + return (SharedMem const *)getShm()->data(); + } + + bool thisIsTheFirstUse(void); + + #if 0 + static std::atomic __sharedMemLocked; + + static bool sharedMemLocked() { + return __sharedMemLocked; + } + static void setSharedMemLocked() { + __sharedMemLocked = true; + } + static void setSharedMemUnlocked() { + __sharedMemLocked = false; + } + #endif + + + + + +}; + +#endif // SHARED_MEM_BUFFER_INCLUDED_H diff --git a/include/storeINdata.h b/include/storeINdata.h new file mode 100644 index 0000000..93a53c2 --- /dev/null +++ b/include/storeINdata.h @@ -0,0 +1,614 @@ + +#ifndef STOREINDATA_H +#define STOREINDATA_H +#include "tslib.h" +#include + + +#define MAXNROF_AO 3 +#define MAXNROF_GENSTR 16 +#define MAXNROF_CONTR_PORTS 11 +#define MAXNROF_DIports 2 +#define MAXNROF_DOports 2 +#define MAXNROF_CTR 2 +#define MEASCHAN_TEMPERATURE 0 +#define MEASCHAN_VOLTAGE 1 + + +// gpi: DC-driver stores data for graphic peripheral interface +// epi: gui reads values from external peripheral interface + + +// store power on/off condition of the devices to control the data request + +void indat_storePrinterPower(bool isOn); +bool indat_isPrinterOn(); + +void indat_storeMifarePower(bool isOn); +bool indat_isMifareOn(); + +void indat_storeMDBisOn(bool isOn); +bool indat_isMdbOn(); + +void gpi_storeHWver(QString text); +QString epi_loadHWver(void); + +void gpi_storeSWver(QString text); +QString epi_loadSWver(void); + +void gpi_storeDCstate(QString text); +QString epi_loadDCstate(void); + + +void gpi_storeUID(uint8_t const *buf8byteUid); +//void gpi_storeUID(uint8_t *buf8byteUid); +// buffer size: 8 byte + +void epi_getUIDdec(uint8_t *buf8byteUid); +// buffer size: 8 byte + +QString epi_getUIDstr(); + + + + + +// /////////////////////////////////////////////////////////////////////////////////// +// Time and Date +// /////////////////////////////////////////////////////////////////////////////////// + +uint8_t epi_getSquareMode(); +void gpi_backupSquareMode(uint8_t squMode); + +void gpi_backupTime(uint8_t *timeBuffer, uint8_t Leng); // 104, <=8byte +void epi_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss); +void epi_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd); +void epi_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday); +bool epi_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear); +bool epi_isLeapYear(); +void epi_getSpecialWeekTimeDate(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek); +void epi_getSpecialMonthTimeDate(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth); +void epi_getSpecialYearTimeDate(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear); + + +// /////////////////////////////////////////////////////////////////////////////////// +// Analog values +// /////////////////////////////////////////////////////////////////////////////////// + + +void gpi_storeAIs(uint8_t aiNr, uint16_t val); // rs -> Sdata + +uint8_t gpi_getMaxNrAIs(); + +uint16_t epi_loadAIs(uint8_t aiNr); // Sdata -> gui + // return value of one ADC with channel nr: aiNr 0...15 + +uint32_t epi_loadMeasureValue(uint8_t ValueNr); + // ValueNr 0=ADC0, 1=ADC1 aso... + +void gpi_storeMeasureValue(uint8_t ValueNr, uint32_t val); + // in mV, also bis 65,535V + +QString epi_getSlaveTemperatureStr(); + +QString epi_getSlaveVoltageStr(); + // value in "meas_volt" in mV, also bis 65,535V. Value range [6000...16000] (6V...16V) + +// /////////////////////////////////////////////////////////////////////////////////// +// digital inputs +// /////////////////////////////////////////////////////////////////////////////////// + +void gpi_storeDI_doorSwitches(uint8_t upperDoor, uint8_t lowerDoor, uint8_t vaultDoor); + +uint8_t epi_getDI_doorSwitches(void); + // bit0: upper door 1: low door 2:vault door + +void gpi_storeDI_vaultSwitches(uint8_t CashBoxIn, uint8_t BillBoxIn); + +uint8_t epi_getDI_vaultSwitches(void); + // bit0: cash box 1: bill box in + +void gpi_storeDI_lockSwitches(uint8_t indatUL, uint8_t indatLL); + // D5: bit 0: upper lockbar up bit1:down + // D6: bit 0: lower lockbar up bit1:down + +uint8_t epi_getDI_lockSwitches(void); + // retval: bit 0: upper lockbar up bit1: upper lockbar is down + // bit 2: lower lockbar up bit1: lower lockbar is down + + +void gpi_storeDI_optos(uint8_t indatOpto); + // OptoIn bit 0,1: optoin 1,2 + +uint8_t epi_getDI_optos(void); + // bit0: opto in 1 1: opto in 2 + +void gpi_storeDI_auxIn(uint8_t indatAuxIn); + // Aux0...5 + +uint8_t epi_getDI_auxIn(void); + // bit0: auxin 1 ... 5: auxin 6 + +void gpi_storeDI_ptuWake(uint8_t indat); + +bool epi_getDI_ptuWake(void); + +void gpi_storeDI_mbdWake(uint8_t indat); + +bool epi_getDI_mdbWake(void); + +void gpi_storeDI_prnReady(uint8_t indat); + +bool epi_getDI_prnReady(void); + +void gpi_storeDI_CoinAttach(uint8_t indat); + +bool epi_getDI_CoinAttach(void); + +void gpi_storeDI_CoinEscrow(uint8_t indat); + +bool epi_getDI_CoinEscrow(void); + +void gpi_storeDI_mifareCardTapped(uint8_t indat); + +bool epi_getDI_mifareCardTapped(void); + +void gpi_storeDI_modemWake(uint8_t indat); + +bool epi_getDI_modemWake(void); + + +void gpi_storeDI_contactPowerIsOn(bool di_contact_PwrOn); + +bool epi_getDI_contactPwr(void); + +void gpi_storeDI_MifarePowerIsOn(bool di_mifare_PwrOn); + +bool epi_getDI_mifarePwr(void); + +void gpi_storeDI_readbackMdbTxD(bool di_rdbkMdbTxd); + +bool epi_getDI_mdbTxd(void); + +void gpi_storeDI_AuxPowerIsOn(bool di_Aux_PwrOn); + +bool epi_getDI_auxPwr(void); + +void gpi_storeDI_GsmPowerIsOn(bool di_gsm_PwrOn); + +bool epi_getDI_gsmPwr(void); + +void gpi_storeDI_CreditPowerIsOn(bool di_credit_PwrOn); + +bool epi_getDI_creditPwr(void); + +void gpi_storeDI_PrinterPowerIsOn(bool di_printer_PwrOn); + +bool epi_getDI_printerPwr(void); + +void gpi_storeDI_MdbPowerIsOn(bool di_mdb_PwrOn); + +bool epi_getDI_mdbPwr(void); + + +void gpi_storeDI_rejMot_home(bool di); + +bool epi_getDI_rejectMotor_homepos(void); + +void gpi_storeDI_paperLow(uint8_t di); + +uint8_t epi_getDI_npe_sensor(void); + // 0: Sensor sees paper 1: no paper 99: off + + + + + + + + + + + + + + + + +// /////////////////////////////////////////////////////////////////////////////////// +// readback digital outputs +// /////////////////////////////////////////////////////////////////////////////////// + +void gpi_storeDO_mdbRxTst(uint8_t do_mbdRxTst); + +bool epi_getDO_mdbRxTestOut(void); + + +void gpi_storeDO_motorOutputs(uint8_t Pwr); + +uint8_t epi_getDO_motorOuts(void); + // bit0: upper lock forward bit 1 backward + // bit2: lower lock forward bit 3 backward + + +void gpi_storeDO_serialSwitch(uint8_t state); + // serial drv on/off, Serial mux1, Serial mux2 + +uint8_t epi_getDO_serialSwitch(void); + // serial drv on/off, Serial mux1, Serial mux2 + +bool epi_getDO_serialDriverIsOn(void); + +bool epi_getDO_serialMux1isSetToPrinter(void); + // mux1 off: serial is switched to printer + +bool epi_getDO_serialMux1isSetToModem(void); + // mux1 on: serial is switched to modem + +bool epi_getDO_serialMux2isSetToCredit(void); + // mux2 off: serial is switched to credit card terminal + +bool epi_getDO_serialMux2isSetToMifare(void); + // mux2 on: serial is switched to mifare reader + + +void gpi_storeDO_ledsAndFan(uint8_t ledState); + +bool epi_getDO_led_coin(void); + +bool epi_getDO_led_front(void); + +bool epi_getDO_led_ticket(void); + +bool epi_getDO_led_pin(void); + +bool epi_getDO_led_start(void); + +bool epi_getDO_led_inside(void); + +bool epi_getDO_fan(void); + +void gpi_storeDO_sirenAndRelay(uint8_t sirenRelay); + +bool epi_getDO_sirene(void); + +bool epi_getDO_relay(void); + +void gpi_storeDO_ptuWake(uint8_t state); + +bool epi_getDO_ptuWake(void); + +void gpi_storeDO_auxPower(uint8_t pwr); + +bool epi_getDO_auxPower(void); + + +void gpi_storeDO_coinShutter(uint8_t state); + +bool epi_getDO_coinShutterOpen(void); + +bool epi_getDO_coinShutterTest(void); + + +void gpi_storeDO_coinEscrow(uint8_t state); + +uint8_t epi_getDO_coinEscrow(void); + // retval: 1:return flap is open 2:take flap is open 0:closed + + +void gpi_storeDO_printerPwrOn(uint8_t state); + +uint8_t epi_getDO_printerPwr(void); + + + +// --------------------------------------------------------------------------------------------- +// counterchecks, make sure that DC-outputs are correct + +/* +bool epi_cntchk_wakePtu(void); +bool epi_cntchk_enabDrv01(void); // no communication possible if 0 !!!!! +bool epi_cntchk_swRs1toModem(void); +bool epi_cntchk_modemWake(void); +bool epi_cntchk_enabDrv2(void); +bool epi_cntchk_swRs2toMIF(void); + +bool epi_cntchk_shutterIsOpen(void); + // counter check if shutter is really open, PJ4 must be OUT and HIGH, PB5 must be OUT and HIGH + // retval TRUE: shutter is open FALSE: shutter is closed + +bool epi_cntchk_escrowReturnIsOpen(void); +bool epi_cntchk_escrowTakeIsOpen(void); +bool epi_cntchk_aux1DirOut(uint8_t auxNr); +bool epi_cntchk_aux1OutHigh(uint8_t auxNr); + +bool epi_cntchk_ledPaperOn(void); +bool epi_cntchk_ledPinpadOn(void); +bool epi_cntchk_ledStartOn(void); +bool epi_cntchk_ledServiceOn(void); +bool epi_cntchk_ledCoinOn(void); +bool epi_cntchk_ledIllumOn(void); +bool epi_cntchk_FanOn(void); +bool epi_cntchk_RelaisOn(void); +bool epi_cntchk_LaermOn(void); +bool epi_cntchk_Mot1Ron(void); +bool epi_cntchk_Mot1Fon(void); +bool epi_cntchk_Mot2Ron(void); +bool epi_cntchk_Mot2Fon(void); +*/ + + +// ------------------------------------------------------------------------------------ +// MDB Sendind Data are store here for next transport to DC (Device Controller) +// Transport to Slave runs every 100ms, answer from mdb-slave (e.g. coin changer) comes right +// with next slave answer + +// start with: SENDDIRCMD_EXCHGMDB, + // send crude data from here to DC, DC to mdb slaves, mdb answer, return here within 50ms + +uint8_t gpi_storeMdbRecData(uint8_t length, uint8_t *buf); + // datif store received mdb data + +uint8_t epi_getMdbResponse(void); + // 0=no response 1=ACK 2=NAK 3=ACK with data + +uint8_t epi_getMdbRecLength(void); + // 0...31 + +uint8_t epi_restoreMdbRecData(uint8_t *buf); + // hwapi reads received mdb data from PI + + + + + +void gpi_clearMifHwData(void); + +void gpi_storeMifHwData(uint8_t *receivedData); + // blkNr=0...11 receivedData[64] + +uint8_t epi_restoreMifHwData(uint8_t *buf, uint8_t maxBufferSize); + // blkNr=0...11 return buf[64] + // retval: 1=error 0=OK + + +void gpi_clearMifAtbData(void); + +void gpi_storeMifAtbData(uint8_t *receivedData); + +uint8_t epi_restoreMifAtbData( uint8_t *buf, uint8_t maxBufferSize); + + + +void epi_restorePrinterState(uint8_t *buf); + +void gpi_storePrinterState(uint8_t *buf); + +void epi_restorePrinterFonts(uint8_t *buf); + +void gpi_storePrinterFonts(uint8_t *buf); + + + + +void gpi_storeMdbState(uint8_t busReady, uint8_t V12on, uint8_t V5on ); + +bool epi_restoreMdbBusReady(void); + +bool epi_restoreMdbV12Ready(void); + +bool epi_restoreMdbV5Ready(void); + + +void gpi_storeMdbResponse(uint8_t leng, uint8_t *data); + +void epi_restoreMdbResponse(uint8_t *leng, uint8_t *data); + // last received mdb answer (from mdb device) + // only needed if a special command was sent directly + // DB0: mdb Device-Nr + // DB1: last sent mdb command + // DB2: nr of received (payload) data bytes (apart from ACK, can be 0....34) + // DB3...DB38: rec.data (payload) + + +void gpi_storeEmpSettings(uint8_t leng, uint8_t *data); + +void epi_restoreEmpSettings(uint8_t *leng, uint8_t *data); + + +/* +void gpi_storeEmpCoinSignal(uint8_t leng, uint8_t *data); + +void epi_restoreEmpCoinSignal(uint8_t *leng, uint8_t *data); + // return 5 byte: + // data[0]=got coin 0xFF=emp reported an error 0=got nothing + // data[1]=emp-signal of last inserted coin + // data[2,3]=emp-value of last inserted coin + // data[4] = emp-error or warning + +void epi_clearEmpCoinSignal(); +*/ + + + +void gpi_storeEmpCoinSignal(uint8_t leng, uint8_t *data); + +uint8_t epi_isNewCoinLeft(void); + // retval: 0...16 coins left in FIFO + +void epi_restoreEmpCoinSignal(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value); + + + +void gpi_storeRbDeviceSettings(uint8_t leng, uint8_t *data); + +void epi_restoreRbDeviceSettings(uint8_t *leng, uint8_t *data); + + +void gpi_storeMachineIDsettings(uint8_t leng, uint8_t *data); + +void epi_restoreMachineIDsettings(uint8_t *leng, uint8_t *data); + + + + +void epi_clearCurrentPayment(void); + +void gpi_storeCurrentPayment(uint32_t insertedAmount, uint16_t lastCoinType, uint16_t lastCoinValue); + +uint32_t epi_CurrentPaymentGetAmount(void); + +uint16_t epi_CurrentPaymentGetLastCoin(void); + +bool epi_CurrentPaymentGetAllCoins(uint16_t *types, uint16_t *values); + // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert falls die jmd. braucht + + +void gpi_storeWakeSources(uint8_t *receivedData); + +uint64_t epi_getWakeSources(void); + +uint8_t epi_getWakeReason(void); + + + +void gpi_storeExtendedTime(uint8_t leng, uint8_t *data); + +void epi_restoreExtendedTime(uint8_t *leng, uint8_t *data); + + +void epi_clearDeviceConditions(void); + +void gpi_storeDeviceConditions(uint8_t leng, uint8_t *data); + +void epi_restoreDeviceConditions(uint8_t *leng, uint8_t *data); + + +void epi_clearDynMachineConditions(void); // new, 24.6.23 + +void gpi_storeDynMachineConditions(uint8_t leng, uint8_t *data); + +void epi_restoreDynMachineConditions(uint8_t *leng, uint8_t *data); + + +void gpi_storeDCbackupAccNr(uint8_t leng, uint8_t *data); + +void epi_restoreDCbackupAccNr(uint8_t *leng, uint16_t *accNrs); + // return accNrs[0..7] + + +void epi_iniVRstorage(void); + +void gpi_storeVaultRecord(uint8_t blkNr, uint8_t *data ); + +bool epi_checkIfVaultRecordAvailable(void); + +uint8_t epi_getLoadedVaultBlocks(void); + // return 0x0011 1111 if all 6 blocks arer loaded (one bit per block) + +bool epi_restoreVaultRecord(uint16_t *length, uint8_t *buf ); + // true if completly received + +void gpi_storeCBlevel(uint32_t amount, uint16_t nrOfCoins ); + +uint32_t epi_getCashBoxContent(void); + +uint16_t epi_getNrOfCoinsInCashBox(void); + +//void gpi_storeNewMifareCard(uint8_t typ, uint8_t *holder ); + +uint8_t epi_mifGetCardType(uint8_t *holder); + //holder[8] = name of card holder + // retval Type of MifareCard, 1=upper door, 2=lower door 3=test printer 4=test coins + +void gpi_storeDcDataValid(bool isVal); + +bool epi_areDcDataValid(); + + + +void epi_clearDynData(void); + +void gpi_storeDynData(uint8_t *DCdynDat); + // buffer size: 64 byte + +bool epi_getDynPrnData(uint8_t *DCdynDat); + // buffer size: 64 byte + // return true if data are new and valid + + + +void gpi_storeNextDCaccNr(uint16_t nxtDcAccNr); + +uint16_t epi_getNextDCaccNr(void ); + + +void gpi_storeMifCardType(uint16_t length, uint8_t *data); + +void epi_restoreMifCardType(uint16_t *length, uint8_t *data); + + + +// move here from dcBL and use shared mem as ptu-updater uses CAslave Lib 6.9.23TS +//#define RAW_BL_DATALEN 150 +void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t *receivedData); + +uint8_t epi_getRawReceivedData(uint8_t *receivedData); + // retval=length, will be zeroed after first reading + +uint8_t epi_getRawRecLength(void); + // retval=length + +//QString epi_getRawReceivedString(); +// not used + +void epi_clrRawReceivedString(); + + + +// new from 28.9.23 and earliest from DC version 4.45 +// store all versions of the DC-Jsons +//#define numberOfJsons 36 +//#define versionStringLength 16 +//char store_jsonVersion[versionStringLength][numberOfJsons]; + +void gpi_storeJsonVersion(uint8_t jsonNr, uint8_t *versionString); + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + // length of buffer is always 16 byte + +void epi_getJsonVersion(uint8_t jsonNr, char *versionString); + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + // length of buffer is always 16 byte + + + + +void epi_setNowCoinPay(bool on_off); + +bool gpi_getNowCoinPay(void); + + +void epi_setNowIsBootload(bool on_off); + +bool gpi_getNowIsBootload(void); + +void gpi_storeChangerResult(uint8_t result, uint32_t amount); + +uint8_t epi_getChangerResult(uint32_t *returnedAmount); + // get result of coin dispensing + // receivedData[0]: 0: not yet started 1:amount returned + // 2:only partial return 3: no return possible + // receivedData[2,3,4,5]: returned amount + + +void gpi_storeTubeLevel(uint8_t *data); + +void epi_restoreTubeLevel(uint8_t *data); + + +#endif + + + diff --git a/include/tslib.h b/include/tslib.h new file mode 100644 index 0000000..114c9f4 --- /dev/null +++ b/include/tslib.h @@ -0,0 +1,93 @@ +#ifndef TSLIB_H +#define TSLIB_H +#include + + +#define LOWBYTE false +#define HIGHBYTE true + +uint16_t uchar2uint(char Highbyte, char Lowbyte); +uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte); +uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte); + +uint8_t uint2uchar(uint16_t uival, bool getHighB); + +uint8_t ulong2uchar(uint32_t ulval, uint8_t getBytNr); + // getBytNr: 0=LSB 3=MSB + + +void delay(uint16_t MilliSec); + +#define MITSEK 1 +#define OHNESEK 0 +#define HourSys12h 1 +#define HourSys24h 0 + +void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf); + // generate time as ascii string from integers hours/minutes/seconds + // System12h=0: 24h system =1: 12h System + // ShowSec=0: String has 5 digits (hh:mm) =1: String has 8 digits (hh:mm:ss) + // return String in *buf // 12 byte für buf! + +#define DateFormatDeutsch 0 +#define DateFormatAmerica 1 +#define UsePointSeperator 0 +#define UseSlashSeperator 1 + + +void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf); + // generate date as ascii string from integers day/month/year + // yearhigh in europe always 20 (not in arabia) + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11 byte für buf! + + +void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf); + // generate date as ascii string from integers day/month/year + // format= 0: dd.mm.yy (deutsch) + // 1: mm.dd.yy (amerika) + // 2: yy.mm.dd (Iran, Dubai) + // 3: dd.yy.mm + // 4: mm.yy.dd + // 5: yy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + +uint16_t tslib_strlen(char *buf); +uint16_t tslib_strlen(uint8_t *buf); + +void tslib_strclr(char *buf, char clrsign, uint16_t len); +void tslib_strclr(uint8_t *buf, char clrsign, uint16_t len); + +void tslib_strcpy(char *srcbuf, char *destbuf, uint16_t len); +void tslib_strcpy(char *srcbuf, uint8_t *destbuf, uint16_t len); +void tslib_strcpy(uint8_t *srcbuf, uint8_t *destbuf, uint16_t len); + + +uint16_t tslib_calcCrcCcitt(uint16_t BufLength, uint8_t *buf); + +bool tslib_isDecAsciiNumber(char sign); +bool tslib_isHexAsciiNumber(char sign); + + +int tslib_getMinimum(int val1, int val2); + +void tslib_text2array(QByteArray text, char *aray, uint16_t maxArayLen); + // usage: tslib_text2array("my text", ctmp, 50); + +void biox_CopyBlock(uint8_t *src, uint16_t srcPos, uint8_t *dest, uint16_t destPos, uint16_t len); + // both buffers starting from pos 0 + +bool tslib_strComp(uint8_t *buf, char *compStr); + +#endif // TSLIB_H + + +// qDebug << QDateTime::currentDateTime().toString(Qt::ISODateWithMs) << QByteArray((const char*)dataSendBuf,dataBufLen).toHex(':'); diff --git a/lib_ca_master/lib_ca_master.pro b/lib_ca_master/lib_ca_master.pro new file mode 100644 index 0000000..50c433d --- /dev/null +++ b/lib_ca_master/lib_ca_master.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +TARGET = CAmaster +VERSION="1.0.0" + +include(../DCLibraries.pri) + +DEFINES+=THIS_IS_CA_MASTER +DESTDIR=$${_PRO_FILE_PWD_}/../build +system("mkdir -p $${DESTDIR}") +system("cp ../include/interfaces.h $${DESTDIR}") diff --git a/lib_ca_slave/lib_ca_slave.pro b/lib_ca_slave/lib_ca_slave.pro new file mode 100644 index 0000000..f58fcf7 --- /dev/null +++ b/lib_ca_slave/lib_ca_slave.pro @@ -0,0 +1,10 @@ +TEMPLATE = lib +TARGET = CAslave +VERSION="1.0.0" + +include(../DCLibraries.pri) + +DEFINES+=THIS_IS_CA_SLAVE +DESTDIR=$${_PRO_FILE_PWD_}/../build +system("mkdir -p $${DESTDIR}") +system("cp ../include/interfaces.h $${DESTDIR}") diff --git a/src/com.cpp b/src/com.cpp new file mode 100644 index 0000000..b89119d --- /dev/null +++ b/src/com.cpp @@ -0,0 +1,429 @@ +#include "com.h" +#include +//#include "controlBus.h" + +////////////////////////////////////////////////////////////////////////////////// +/// +/// serial hardware layer +/// +////////////////////////////////////////////////////////////////////////////////// + + + + +static int64_t com_want2read; +// ------------------------------------------------------------------------------------------------------------- +// --------- PUBLIC -------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- + +void T_com::writeToSerial(const QByteArray &data, uint16_t sendLength) +{ + sendBuffer=data; + sendLen=sendLength; + if (CatSerial->isOpen()) + { + //qDebug() << "sending..." << sendBuffer; + CatSerial->write(sendBuffer); + } else + qDebug() << "error sending, port is not open"; + +} + + +bool T_com::readFromSerial(QByteArray &data, uint16_t &sendLength) +{ + // return one time true if new data (completly) read. + // return new data in &data and &sendLength to other objects + uint16_t ll=rawInLen; + if (!CatSerial->isOpen()) + return false; + data.clear(); + data.append(rawInput); + sendLength=ll; + rawInLen=0; // beim 2. Aufruf 0 zurück weil nichts neues da + if (ll>0) + return true; + return false; +} + + +// ------------------------------------------------------------------------------------------------------------- +// --------- PRIVATES -------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- + + +T_com::T_com(QObject *parent) : QObject(parent) +{ + // port settings come from tabCom->Sdata->serial + + gpi_serialChanged(); + CatSerial = new QSerialPort(); // PortHW object for Control&Analyse Tool + //CatSerial->clear(); + //CatSerial->clearError(); + + connect(CatSerial, &QSerialPort::readyRead, this, &T_com::readSomeBytes); + // still reading, not sure if complete, undefined number of calls while reading + + connect(CatSerial, &QSerialPort::bytesWritten, this, &T_com::serialSendComplete); + // system confirms sending complete + + //connect(CatSerial, &QSerialPort::dataTerminalReadyChanged, this, &T_com::incomingWake); + //connect(CatSerial, &QSerialPort::requestToSendChanged, this, &T_com::incomingWake); + + // timer detects time gap in input flow + serRecTime = new QTimer(); + connect(serRecTime, SIGNAL(timeout()), this, SLOT(receiveTO())); + serRecTime->setSingleShot(true); // single shot! only one impulse if receive complete + serRecTime->stop(); // on hold + + // check COM-TAB periodic if user wants to connect or disconnect + QTimer *ChkConnectTimer = new QTimer(); + connect(ChkConnectTimer, SIGNAL(timeout()), this, SLOT(ser_ISR100ms())); + ChkConnectTimer->setSingleShot(false); + ChkConnectTimer->start(100); // in ms + com_want2read=0; +} + + + + +T_com::~T_com() +{ + if (CatSerial->isOpen()) + CatSerial->close(); +} + + +void T_com::ser_ISR100ms() +{ + // call every 100ms to check if user(HMI) wants to connect or disconnect + + //qDebug() << "~~>LIB" << "checking connect button... " ; + + uint8_t chkConn = gpi_getSerialConn(); // from global GUI buffer (Sdata) + switch (chkConn) + { + case 0: // 0 button "connect" was just released + closeSerialPort(); + gpi_serialChanged(); // set chkConn to 2, thus getting edge + break; + case 1: // 1 button "connect" was just pressed + open_Serial_Port(); + gpi_serialChanged(); // set chkConn to 2, thus getting edge + break; + } + + + if (CatSerial->isOpen()) + gpi_serialIsOpen(true); + else + gpi_serialIsOpen(false); + +} + +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- + +char T_com::open_Serial_Port() +{ + bool ret; + QString myString=nullptr, myPortName=nullptr, myBaudStr=nullptr; + int myBaudNr; + + if (CatSerial->isOpen()) + return 0; // opening twice is not allowed + + //qDebug() << "connecting..." << myPortName; + myPortName=gpi_getComPortName(); // was selected and stored from GUI + CatSerial->setPortName(myPortName); + myBaudNr=gpi_getBaudNr(); // was selected and stored from GUI + switch (myBaudNr) + { + // 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 + case 0: CatSerial->setBaudRate(QSerialPort::Baud1200); myBaudStr="1200"; break; + case 1: CatSerial->setBaudRate(QSerialPort::Baud9600); myBaudStr="9600"; break; + case 2: CatSerial->setBaudRate(QSerialPort::Baud19200); myBaudStr="19200"; break; + case 3: CatSerial->setBaudRate(QSerialPort::Baud38400); myBaudStr="38400"; break; + case 4: CatSerial->setBaudRate(QSerialPort::Baud57600); myBaudStr="57600"; break; + case 5: CatSerial->setBaudRate(QSerialPort::Baud115200); myBaudStr="115200"; break; + } + + CatSerial->setDataBits(QSerialPort::Data8); + // alt: QSerialPort::Data5,6,7,8 + + CatSerial->setParity(QSerialPort::NoParity); + // alt: EvenParity, OddParity, NoParity + + CatSerial->setStopBits(QSerialPort::OneStop); + // alternative: OneStop, TwoStop, OneAndHalfStop + + CatSerial->setFlowControl(QSerialPort::NoFlowControl); + // alt: HardwareControl, SoftwareControl, NoFlowControl + + ret=CatSerial->open(QIODevice::ReadWrite); + // alt: QIODevice::ReadWrite QIODevice::ReadOnly QIODevice::WriteOnly + if (!ret) + { + myString.clear(); + myString = "error "; + myString.append(CatSerial->errorString()); + qDebug() << myString; + gpi_setTxt4comStateLine(myString); + return 0; + } else + { + myString.clear(); + myString.append(myPortName); + //lang=myString.size(); + myString.append(" opened with "); + myString.append(myBaudStr); + myString.append(" 8N1"); + qDebug() << myString; + gpi_setTxt4comStateLine(myString); + gpi_setTxt4RsDiagWin(myString+"\n"); + + } + + return 0; +} + +void T_com::closeSerialPort() +{ + if (CatSerial->isOpen()) + { + qDebug() << "closing connection"; + CatSerial->close(); + gpi_setTxt4comStateLine("closed"); + gpi_setTxt4RsDiagWin("closed"); + + } +} + + +void T_com::readSomeBytes(void) +{ + // called by serial-read-detection + // restart off-time as input flow is ongoing + + // timer for slow receive + // and serves as timeout for fast receive is msg is shorter as expected + serRecTime->stop(); + serRecTime->start(20); // in ms + + //qDebug()<< "com-rec read some bytes"; + + this->receiveByLength(); // since 14.12.21: fast receive +} + +void T_com::receiveFixLen(int64_t nrOfbytesToReceive) +{ + // call this before sending a request to slave + // then we know exactly when reception is complete -> much faster + com_want2read=nrOfbytesToReceive; + // since 14.12.21: FastDevice Protocol has two lengthen: + // fast: 12byte reception long: 68byte +} + +void T_com::receiveByLength(void) +{ + + if (CatSerial->isOpen()) + { + QString myString=nullptr, tmpStr=nullptr; + int64_t nrOfBytesreceived = CatSerial->bytesAvailable(); // nr of received bytes + + //qDebug()<< "com-rec current Len: "<< nrOfBytesreceived; + + if (nrOfBytesreceived >= com_want2read) + { + QByteArray data = CatSerial->readAll(); // erst auslesen wenn alles da! löscht den Empfangspuffer + serRecTime->stop(); // stop timeout to avoid 2nd emit + rawInLen=uint16_t (nrOfBytesreceived); + rawInput.clear(); + rawInput.append(data); + //qDebug()<< "com-recFinished by Len "<< rawInLen; + gpi_set2ndTxt4RsDiagWin(myString); // 4.10.23 hier neu + emit receivingFinished(); + } + } +} + +void T_com::receiveTO(void) +{ + // no new input data for 20ms, --> assuming frame complete + // save data in private "rawInput"-buffer + + if (CatSerial->isOpen()) + { + + QString myString=nullptr, tmpStr=nullptr; + int64_t nrOfBytesreceived = CatSerial->bytesAvailable(); // nr of received bytes + QByteArray data = CatSerial->readAll(); + + rawInLen=uint16_t (nrOfBytesreceived); + rawInput.clear(); + rawInput.append(data); + //rawInput[rawInLen]=0; // Zwangsterminierung bei QByteArray nicht nötig + + // diag display in serial in/out window and debug window + myString.clear(); + myString.setNum(rawInLen); + myString.append(" in: "); + //myString.append(rawInput); + for (int ii=0; ii0x80 dann wird EIN Byte 16 stellig angezeigt + int ll=tmpStr.length(); + if (ll>2) + { + myString.append(tmpStr[ll-2]); + myString.append(tmpStr[ll-1]); + } else + { + myString.append(tmpStr); + } + myString.append(" "); + } + myString.append("\n"); + #ifdef PRINTALLDEBUGS + qDebug() << "VCP:" << myString; // display all inputs and outputs in output window + #endif + //gpi_setTxt4RsDiagWin(myString); + gpi_set2ndTxt4RsDiagWin(myString); // 4.10.23: diese verwenden weil die gpi_setTxt4RsDiagWin() durch Ausgabe ueberschrieben wird + //qDebug()<< "com-recFinished by TO"; + emit receivingFinished(); + } +} + +void T_com::serialSendComplete(void) +{ + // system confirms sending complete, diag display + QString myString=nullptr, tmpStr=nullptr; + + myString.clear(); + myString.setNum(sendLen); + myString.append(" out: "); + + for (int ii=0; ii0x80 dann 16stellig + int ll=tmpStr.length(); + if (ll>2) + { + //qDebug() << "long_string" << ll << "\n"; + myString.append(tmpStr[ll-2]); + myString.append(tmpStr[ll-1]); + + } else + { + myString.append(tmpStr); + } + myString.append(" "); + } + +#ifdef PRINTALLDEBUGS + myString.append("\n"); + qDebug() << myString; // display all output data in out-window +#endif + + gpi_setTxt4RsDiagWin(myString); + + emit sendingFinished(); // for whom it may interest +} + + +bool T_com::isPortOpen(void) +{ + if (CatSerial->isOpen()) + return true; + return false; +} + + +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- + +/* +uint8_t T_com::getAllPortPins(void) +{ + uint8_t rs232pins=0; + rs232pins= uint8_t(CatSerial->pinoutSignals()); + // rs232pins: all signals bitwise coded in one byte: + // readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output) + // unused inputs: bit1=RxD bit 3=DCD bit 5 = RING + // handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80) + //qDebug()<<"serial port pins: " << rs232pins; + return rs232pins; +} + +bool T_com::getHSin_CTS(void) +{ + // return the used Handshake IN (CTS, alt. DSR): true= high level (+8V) + + uint8_t rs232pins=0; + + rs232pins= uint8_t(CatSerial->pinoutSignals()); + // rs232pins: all signals bitwise coded in one byte: + // readback output: bit 0=TxD(=output) bit2=DTR (=output) bit 6=RTS (=output) + // unused inputs: bit1=RxD bit 3=DCD bit 5 = RING + // handshake inputs: bit 4=DSR (0x10) bit 7=CTS (0x80) + + if (rs232pins & 0x80) // CTS + return true; + + return false; +} + + +bool T_com::getHSin_DSR(void) +{ + uint8_t rs232pins=0; + rs232pins= uint8_t(CatSerial->pinoutSignals()); + if (rs232pins & 0x10) // DSR + return true; + return false; +} + +void T_com::incomingWake(void) //(bool LevelOfTheBit) +{ + emit wasWokenBySerialHandshake(); +} + +bool T_com::setHSout_RTS(bool hsout) +{ + // hsout true=positiv voltage +12V false= -12V + // retval: true=setting OK + + bool cc; + // 10.5.19, am Windows-PC nachgemessen, funktioniert gut + // false ergibt -12V true ergibt +12V + + cc=CatSerial->setRequestToSend(hsout); // RTS out + // retval true means "setting was successful" + + // alternative: use DTR as Handshake: + //cc=CatSerial->setDataTerminalReady(false); // DTR out + // retval true means "setting was successful" + //qDebug()<<"RTS " <setDataTerminalReady(hsout); // DTR out + // retval true means "setting was successful" + //qDebug()<<"DTR " < serial +// /////////////////////////////////////////////////////////////////////////////////// + + + + +static QString rs_comportName; // z.B. "COM48" +static QString rs_baudStr; // z.B. "19200" +static int rs_baudNr; //0...5 oder -1 +static uint8_t rs_connect; // 0,1 + +void epi_setSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) +{ + rs_comportName = ComName; + rs_baudStr = BaudStr; + rs_baudNr = BaudNr; // 0=1200 1=9600 2=19200 3=38400 4=57600 5=115200 oder -1 + rs_connect = connect; // 0/1 + +} + +void epi_closeSerial(void) +{ + rs_connect=0; +} + +void gpi_serialChanged(void) +{ + // serial confirms that port was closed or opened + rs_connect=2; // Flanke, nur 1x öffnen/schließen +} + +uint8_t gpi_getSerialConn(void) +{ + return rs_connect; +} + +int gpi_getBaudNr(void) +{ + return rs_baudNr; +} + +QString gpi_getComPortName(void) +{ + return rs_comportName; +} + +//#endif + +void gpi_serialIsOpen(bool offen) +{ + SharedMem::write()->rs_portIsOpen=offen; + +} + +bool epi_isSerialPortOpen() +{ + // true: port is open false: port is closed + return SharedMem::read()->rs_portIsOpen; +} + +// /////////////////////////////////////////////////////////////////////////////////// +// Control transfer gui <--> serial +// /////////////////////////////////////////////////////////////////////////////////// + + + +void epi_startEmmision(bool start) +{ + SharedMem::write()->AutoEmissionOn=start; +} + +bool gpi_isEmmisionOn(void) +{ + // used in HWapi + return SharedMem::read()->AutoEmissionOn; +} + +// /////////////////////////////////////////////////////////////////////////////////// +// Status Display gui <--> serial +// /////////////////////////////////////////////////////////////////////////////////// + + + +// linke Spalte, über Connect Button +static QString txt4comStateLine; + +QString epi_getTxt4comStateLine(void) +{ + // GUI: get Text for serial Comport-State Line + return txt4comStateLine; +} + +void gpi_setTxt4comStateLine(QString txtline) // gpi +{ + // serial: write Text to be displayed in serial Comport-State line (like "connected") + txt4comStateLine.clear(); + if (txtline=="") + txt4comStateLine.clear(); + else + txt4comStateLine=txtline; +} + +void epi_clrTxt4comStateLine() +{ + txt4comStateLine.clear(); +} + + +//--------------------------------------------------------------------------------------------- + +// rechte Spalte, oberste Statuszeile +// I) "Handshakes" (serial Control) flow.cpp +// geht überhaupt was raus? kommt überhaupt was zurück? +static QString txt4HsStateLine; + +QString epi_getTxt4HsStateLine(void) +{ + return txt4HsStateLine; +} + +void gpi_setTxt4HsStateLine(QString txtline) +{ + txt4HsStateLine.clear(); + if (txtline=="") + txt4HsStateLine.clear(); + else + txt4HsStateLine=txtline; +} + +void epi_clrTxt4HsStateLine() +{ + txt4HsStateLine.clear(); +} + + + +//--------------------------------------------------------------------------------------------- + +// II) Master receive state (empfangenes Telgramm OK? crc? length? ) +// Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp) +static QString txt4masterStateLine; + +QString epi_getTxt4masterStateLine(void) +{ + return txt4masterStateLine; +} + +void gpi_setTxt4masterStateLine(QString txtline) +{ + txt4masterStateLine.clear(); + if (txtline=="") + txt4masterStateLine.clear(); + else + txt4masterStateLine=txtline; +} + +void epi_clrTxt4masterStateLine() +{ + txt4masterStateLine.clear(); +} + + + +//--------------------------------------------------------------------------------------------- + +// III Slave receive (from Master) OK? if then show results, if not then show errors +// entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR +// Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch +// nicht verwenden und nichts ausgeben oder einlesen + +static QString txt4resultStateLine; + +QString epi_getTxt4resultStateLine(void) +{ + return txt4resultStateLine; +} + +void gpi_setTxt4resultStateLine(QString txtline) +{ + txt4resultStateLine.clear(); + if (txtline=="") + txt4resultStateLine.clear(); + else + txt4resultStateLine=txtline; +} + +void epi_clrTxt4resultStateLine() +{ + txt4resultStateLine.clear(); +} + + +//--------------------------------------------------------------------------------------------- + +// IV Statuszeile Empfangsdaten +static QString txt4dataLine; + +QString epi_getTxt4dataStateLine(void) +{ + // GUI: get Text for serial Comport-State Line + return txt4dataLine; + +} + +void gpi_setTxt4dataStateLine(QString txtline) +{ + // serial: write Text to be displayed in serial Comport-State line (like "connected") + txt4dataLine.clear(); + if (txtline=="") + txt4dataLine.clear(); + else + txt4dataLine=txtline; +} + +void epi_clrTxt4dataStateLine() +{ + txt4dataLine.clear(); +} + +//--------------------------------------------------------------------------------------------- + +// 5. Zeile: Datif Ergebnis, Daten brauchbar? + +static QString txt4datifReceive; + +QString epi_getTxt4datifLine(void) +{ + + return txt4datifReceive; + +} + +void gpi_setTxt4datifLine(QString txtline) +{ + + txt4datifReceive.clear(); + if (txtline=="") + txt4datifReceive.clear(); + else + txt4datifReceive=txtline; +} + +void epi_clrTxt4datifLine() +{ + txt4datifReceive.clear(); +} + +//--------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------- + +static QString txt4diagWindow; + +QString epi_getTxt4RsDiagWin(void) +{ + return txt4diagWindow; + +} + +void gpi_setTxt4RsDiagWin(QString txtline) +{ + txt4diagWindow.clear(); + if (txtline=="") + txt4diagWindow.clear(); + else + txt4diagWindow=txtline; +} + +void epi_clrTxt4RsDiagWin() +{ + txt4diagWindow.clear(); +} + +//--------------------------------------------------------------------------------------------- + +static QString sndTxt4diagWindow; + +QString epi_get2ndTxt4RsDiagWin(void) +{ + return sndTxt4diagWindow; + +} + +void gpi_set2ndTxt4RsDiagWin(QString txtline) +{ + sndTxt4diagWindow.clear(); + if (txtline=="") + sndTxt4diagWindow.clear(); + else + sndTxt4diagWindow=txtline; +} + +void epi_clr2ndTxt4RsDiagWin() +{ + sndTxt4diagWindow.clear(); +} + + +// /////////////////////////////////////////////////////////////////////////////////// +// Memory for Slave responses, common data +// /////////////////////////////////////////////////////////////////////////////////// + + +//static bool Sdata_serialTestResult; + +void gpi_storeResult_serialTestOK(bool wasOk) +{ + //Sdata_serialTestResult=wasOk; + SharedMem::write()->Sdata_serialTestResult=wasOk; +} + +bool epi_getResult_serialTestOK() +{ + // retval: true: test was successful, got right response + //return Sdata_serialTestResult; + return SharedMem::read()->Sdata_serialTestResult; +} + + + +// /////////////////////////////////////////////////////////////////////////////////// +// Store received data for hwapi +// /////////////////////////////////////////////////////////////////////////////////// + + + +//static uint8_t Sdata_pProtResultOk; + +void gpi_startNewRequest() +{ + //Sdata_pProtResultOk=0; + SharedMem::write()->Sdata_pProtResultOk=0; + SharedMem::write()->Sdata_lastResult=0; +} + +void gpi_storeResultOfLastRequest(bool answisok) +{ + if (answisok) + //Sdata_pProtResultOk=1; + SharedMem::write()->Sdata_pProtResultOk=1; + else + //Sdata_pProtResultOk=2; + SharedMem::write()->Sdata_pProtResultOk=2; +} + +uint8_t epi_getResultOfLastRequest() +{ + // retval: 0: in progress 1: OK 2: error + //return Sdata_pProtResultOk; + return SharedMem::read()->Sdata_pProtResultOk; +} + + + +//static uint16_t Sdata_receivedDataLength; +//static uint8_t Sdata_receivedDataBlock[64]; + +void gpi_storeRecPayLoad(uint8_t RdDlen, uint8_t *receivedData) +{ + SharedMem::write()->Sdata_receivedDataLength=uint16_t(RdDlen); + if (SharedMem::read()->Sdata_receivedDataLength>64) + SharedMem::write()->Sdata_receivedDataLength=64; + tslib_strclr(SharedMem::write()->Sdata_receivedDataBlock,0,64); + tslib_strcpy(receivedData, SharedMem::write()->Sdata_receivedDataBlock, SharedMem::read()->Sdata_receivedDataLength); + +} + +uint16_t epi_getLastPayLoad(uint16_t plBufSiz, uint8_t *payLoad) +{ + // get data back in *pl, max 64 byte + // retval = nr of bytes received. If host buffer too small then + // only plBufSíz bytes are copied to pl + // plBufSíz=size of host buffer + + uint16_t ml=plBufSiz, nn; + if (ml>64) ml=64; + if (SharedMem::read()->Sdata_receivedDataLengthSdata_receivedDataLength; + + //tslib_strcpy(SharedMem::read()->Sdata_receivedDataBlock, payLoad, ml); + for (nn=0; nnSdata_receivedDataBlock[nn]; + + return SharedMem::read()->Sdata_receivedDataLength; + +} + + + + +//static uint8_t ndbs, pari, nsb, br; + +void gpi_storeSlaveSerParams(uint8_t slaveBaudRate, uint8_t NrDataBits, + uint8_t parity, uint8_t NrStopBits) +{ + // store numbers + SharedMem::write()->ndbs=NrDataBits; + SharedMem::write()->pari=parity; + SharedMem::write()->nsb=NrStopBits; + SharedMem::write()->br=slaveBaudRate; +} + +void epi_getSlaveSerParams(uint8_t *slaveBaudRate, uint8_t *NrDataBits, + uint8_t *parity, uint8_t *NrStopBits) +{ + *NrDataBits=SharedMem::read()->ndbs; + *parity=SharedMem::read()->pari; + *NrStopBits=SharedMem::read()->nsb; + *slaveBaudRate=SharedMem::read()->br; + +} + + +QString epi_getSlaveParamSTR() +{ + QString mySt; + char ctmp; +// uint8_t ndbs; +// uint8_t pari; +// uint8_t nsb; +// uint8_t br; + + mySt.clear(); +// br=SharedMemBuffer::read()->br; +// ndbs=SharedMemBuffer::read()->ndbs; +// pari =SharedMemBuffer::read()->pari; +// nsb=SharedMemBuffer::read()->nsb; + + switch (SharedMem::read()->br) + { + case 1: mySt="1200 ";break; + case 2: mySt="9600 ";break; + case 3: mySt="19200 ";break; + case 4: mySt="38400 ";break; + case 5: mySt="57600 ";break; + case 6: mySt="115200 ";break; + } + + + ctmp=SharedMem::read()->ndbs; + ctmp+=0x30; + mySt.append(ctmp); + ctmp=SharedMem::read()->pari; + mySt.append(ctmp); + ctmp=SharedMem::read()->nsb; + ctmp+=0x30; + mySt.append(ctmp); + //mySt="Hallo"; + return mySt; +} + + + + +//void gpi_startNewRequest(): SharedMem::write()->Sdata_lastResult=0; + +void gpi_storeLastResult(uint8_t letzteAntwort) +{ + SharedMem::write()->Sdata_lastResult=letzteAntwort; +} + +uint8_t epi_getLastResult() +{ + + return SharedMem::read()->Sdata_lastResult; +} + + + +void epi_startSupervision() +{ + SharedMem::write()->Sdata_startSV=true; +} + +bool gpi_wantToResetSupervision() +{ + bool chk=SharedMem::read()->Sdata_startSV; + SharedMem::write()->Sdata_startSV=false; + return chk; +} + + +void gpi_storeOverallResult(uint8_t letzteAntwort) +{ + SharedMem::write()->Sdata_OverallResult=letzteAntwort; +} + +uint8_t epi_getBatchResult() +{ + + return SharedMem::read()->Sdata_OverallResult; +} + + + + + + + + + + + + + + + diff --git a/src/datIf.cpp b/src/datIf.cpp new file mode 100644 index 0000000..194b261 --- /dev/null +++ b/src/datIf.cpp @@ -0,0 +1,1333 @@ +#include "datIf.h" +#include "sendWRcmd.h" +#include "controlBus.h" +#include "storeINdata.h" +#include +#include +#include + + + + + +// called from MainWindow() + + +#define DATIF_MAXCMDS 16 +static uint8_t dif_dataStep; +static uint8_t dif_scanStep; //, RDBLKNR; + + +static uint8_t datif_OutCmdpara1, datif_OutCmdpara2, datif_OutCmdpara3, datif_OutCmdpara4; +static uint16_t datif_OutCmdpara5; +static uint32_t datif_OutCmdpara6; +static uint8_t cycl_running; +static bool doRepeat; + +static uint8_t keepLastWrCmd, keepLastRdCmd; +static uint8_t keepLastblockNum, keepLastdat1, keepLastdat2, keepLastdat3, keepLastdat4; +static uint8_t keepLastlength, keepLastdata64[66]; + + + +// new, 17.7.23: +static uint8_t datif_cmdWasPerformed; +static uint8_t datif_repeatCtr; +static uint8_t datif_kindOfCmd; + +static uint8_t datif_pNextCmd, datif_sendSlowCmd; + +//#define DATIF_MAXTO_WAIT4RESP 80 //20 erhöht am 17.7 geht viel besser + // höchster gemessener Wert (bei 20ms): 6 + + +//#define DATIF_GAP4RESP 1 + // weniger als 1 geht nicht. erzeugt eine Lücke zw. 20..65ms (2 Programmzyklen) + +//#define DATIF_CTR_GOTRESPVAL 100 + + +T_datif::T_datif(QObject *parent) : QObject(parent) +{ + QByteArray myBA; + QDir myDir("../dmd"); + + if (!myDir.exists()) + myDir.mkdir("../dmd"); + + myDCIF = new T_prot(); + + // valid data was received, storing + connect(myDCIF, SIGNAL(framerecieved()), this, SLOT(StoredRecData())); + + // new, 9.11.20 data for DC-bootloader received not matchind Pprot + //connect(myDCIF, SIGNAL(rawDataRecieved()), this, SLOT(BLdataRecData())); + + // cyclic transmission of INPUT-Requests + datif_trigger = new QTimer(); + connect(datif_trigger, SIGNAL(timeout()), this, SLOT(datif_cycleSend())); + datif_trigger->setSingleShot(false); + datif_trigger->start(20); // in ms, + + // passing Signal through + //connect(myDCIF, SIGNAL(framerecieved()), this, SLOT( ResponseRecieved() )); + + datif_OutCmdpara1=0; + datif_OutCmdpara2=0; + datif_OutCmdpara3=0; + datif_OutCmdpara4=0; + dif_dataStep=1; + + dif_scanStep=0; + selectedSlaveAddr=FIX_SLAVE_ADDR; + cycl_running=0; + gpi_storeDcDataValid(0); // data are not yet valid, no response from DC by now + datif_noResponseCtr=0; + + datif_repeatCtr=0; + datif_cmdWasPerformed=0; // 0: no response by now + + datif_kindOfCmd=0; + + gpi_storeOverallResult(0xFF); + + // neu, 24.5.23: Alle Daten zusätzlich in Datei speichern +// if (datei_ifFileExists(FILENAME_SHAREDDATA)) +// { +// myBA.clear(); +// myBA=datei_readFromFile(FILENAME_SHAREDDATA); +// } +/* + // Testfile ereugen: + csv_startCreatingFile(); + csv_addUintToFile(0); + csv_addUintToFile(1); + csv_addUintToFile(2); + csv_addUintToFile(3); + csv_addUintToFile(4); + csv_addUintToFile(5); + myBA=csv_readbackArray(); + datei_clearFile(FILENAME_SHAREDDATA); + datei_writeToFile(FILENAME_SHAREDDATA, myBA); +*/ + doRepeat=true; + datif_pNextCmd=0; + datif_sendSlowCmd=0; + +} + +void T_datif::resetChain(void) +{ + dif_scanStep=0; +} + +char T_datif::datif_cycleSend() +{ + // cyclic transmission of INPUT-Requests + // call cyclic every 20ms to send next request , then wait for response before sending again!!! + //uint16_t nxtAsCmd; + uint8_t dataSendBuf[160], dataBufLen, dbl; + //static uint8_t BlockCounter; + + uint8_t nextWrCmd, nextRdCmd, blockNum, dat1, dat2, dat3, dat4; + uint8_t length, data[66]; + bool b_ret; + + // send next command + if ( !myDCIF->isPortOpen()) + { + //qDebug() << "com port not available"; // wird ununterbrochen ausgegeben + gpi_storeDcDataValid(0); // DC data not valid + return 0; + } + + // supervise if DC data are valid + datif_noResponseCtr++; // inc every 20ms + if (datif_noResponseCtr>250) // no life sign from device controller (DC) for about 3s + gpi_storeDcDataValid(0); // DC data has not updated for >=5s -> no longer valid! + + // Ueberwachung ob ein oder mehrere Commands am Stueck erfolgreich waren + if (gpi_wantToResetSupervision()) + { + gpi_storeOverallResult(0xFF); + } + + + + // wait for response ---------------------------------------------------------------------------- + + // "cycl_running" entscheidet ob ein neues Kommando gesendet werden darf oder ob wir noch auf die Antwort des letzten warten + // bei der Antwort gibt's drei Faelle: + // a) Antwort OK --> nach einer Luecke von 10ms neues Kommando schicken + // b) Antwort meldet Fehler -> 2x wiederholen (nach einer Luecke von 10ms ) + // c) gar keine Antwort, Timeout nach 100ms -> 2x wiederholen (nach einer Luecke von 10ms ) + // cycl_running=0: nichts zu tun 1: Mitteilung: Kommando wurde soeben abgesendet, 2,3,4 = Wiederholung + + if (cycl_running) // 21.9.23 doRepeat hier raus sonst gehts warten auch nicht mehr (BL) + // if (cycl_running && doRepeat) + { + // request is still running, wait for response before next sending + //qDebug()<< "datif wait for response"; + datif_trigger->stop(); + datif_trigger->start(20); // ruft "this" (datif_cycleSend) erneut in 20ms auf + // mit 10 kein Unterscheid weil Zykluszeit grösser + + cycl_running++; // inc every 20...30ms // warte max 100ms auf Antwort + if (cycl_running >80 && cycl_running <95) // neu 13.9.23 mind. 40 damit Templates + // in Folge gedruckt werden koennen + // 95: muss nur kleiner sein als die 100 fuer die Luecke + // 17.10.23: 50--> 80 + { + // 100ms vergangen, bisher keine Antwort, also Kommando wiederholen + qDebug()<< "datif timeout no response for wr/rd cmd "<< keepLastWrCmd << " " << keepLastRdCmd; + cycl_running = 0; // gleich wiederholen weil ja schon ewig nichts mehr reinkam + datif_cmdWasPerformed=2; // NO :(( + gpi_storeLastResult(8); + + } + + if (cycl_running>=101) // 100 + 1 + { + // Antwort ist gekommen, also nach kurzer Luecke naechstes (datif_cmdWasPerformed==1) + // oder nochmal gleiches (datif_cmdWasPerformed==2) Kommando senden + //qDebug()<< "datif got any response"; + cycl_running=0; + } + + // hier stoppen, weil Antwort des letzten Cmds noch nicht da + return 0; + } + + + + + // 17.7.2023: repeat commands if result was !=OK ------------------------------------------------------------------- + if (datif_cmdWasPerformed==2 && doRepeat) // Cmd was not or false performed und Wiederholen erwuenscht + { + //qDebug()<<"datif: repeating..."; + + datif_repeatCtr++; + if (datif_repeatCtr>3) + { + // give in, 3x no or wrong response + datif_cmdWasPerformed=0; + + datif_kindOfCmd=0; + cycl_running=0; + gpi_storeOverallResult(2); + return 0; + } + + // repeat last command as we got no or bad result (error) + if (datif_kindOfCmd==2) + { + //qDebug() << "datif: repeat long FDcmd (wr/rd): " <setUserWriteData(keepLastWrCmd, keepLastblockNum, keepLastlength, keepLastdata64); + myDCIF->setUserReadData(keepLastRdCmd); + myDCIF->sendUserData(selectedSlaveAddr); + cycl_running=1; // 1: start transmission and reset TOcounter + datif_cmdWasPerformed=0; + } else + if (datif_kindOfCmd==1) + { + //qDebug() << "datif: repeat short FDcmd (wr/rd): " <setUserWriteData(keepLastWrCmd, keepLastblockNum, 4, data); + myDCIF->setUserReadData(keepLastRdCmd); + myDCIF->sendUserData(selectedSlaveAddr); + cycl_running=1; // 1: start transmission + datif_cmdWasPerformed=0; + } else + { + qDebug() << "datif: unknown cmd, stop repeating wr/rd:" << keepLastWrCmd << " " << keepLastRdCmd; + datif_cmdWasPerformed=0; + cycl_running=0; + datif_kindOfCmd=0; + } + return 0; + } // end of repeat commands + + // Send new command --------------------------------------------------------------- + // from 11.4.23: direkt access to fastDevice Interface + // send long fast direct command + if (checkNextFDcmd()==2) + { + // return 0: no command waiting + // 1: short cmd + // 2: long cmd + + gpi_storeOverallResult(0); + b_ret=longFDcmd_get(&nextWrCmd, &nextRdCmd, &blockNum, &length, data); + if (b_ret) + { + keepLastWrCmd=nextWrCmd; keepLastRdCmd=nextRdCmd; + keepLastblockNum=blockNum; + keepLastlength=length; + for (int ii=0; ii<66; ii++) + keepLastdata64[ii]=data[ii]; + + myDCIF->setUserWriteData(nextWrCmd, blockNum, length, data); + myDCIF->setUserReadData(nextRdCmd); + myDCIF->sendUserData(selectedSlaveAddr); + + //qDebug()<<"Datif send long FD cmd (wr/rd): "<setUserWriteData(nextWrCmd, blockNum, 4, data); + myDCIF->setUserReadData(nextRdCmd); + myDCIF->sendUserData(selectedSlaveAddr); + + //qDebug()<<"Datif send short FD cmd (wr/rd): "<0) + { + cycl_running=1; // 1: start transmission + //qDebug() << "datif: sending " << dataBufLen << " bytes to BL: " + // << QTime::currentTime().toString(Qt::ISODateWithMs) <<" " + // << QByteArray((const char*)dataSendBuf,dataBufLen).toHex(':'); + + datif_OUT_SendRandomData(dataSendBuf, dataBufLen); + datif_kindOfCmd=0; + datif_repeatCtr=0; + doRepeat=false; + return 0; + } + + // if no direct comands need to be sent then send input requests + if (gpi_isEmmisionOn()) // auto send button is pressed + { + //qDebug() << "auto request is on"; + datif_kindOfCmd=0; + sendINrequestsAutomatic(); // request all cyclic data sequential + } + else + { + dif_scanStep=0; // always start from beginning + gpi_storeDcDataValid(0); + } + + datif_cmdWasPerformed=0; // 0: no response by now + return 0; +} + +// ############################################################################## + +// sende alle Befehle um die Eingangsdaten abzufragen der Reihe nach: +char T_datif::sendINrequestsAutomatic(void) +{ + //qDebug() << "send IN request " << dif_scanStep; +// uint8_t datif_autoRequCommandList[50]={11, 12, 18, 104, 106, 103, 14, 27, 109, 17, 19, 23, 30, 31, 32, 33, 114, 35}; + uint8_t datif_autoRequCommandList[30]={11, 12, 14, 17, 18, 19, 22, 23, 27, 30, 31, 32, 33, 35, 102, 103, 104, 106, 107, 109, 114,0,0,0,0,0,0,0,0,0}; + uint8_t datif_maxNrCommands=21, datif_sendNow; + + // special commands: + // 102: get IOs run constantly!!! + // 108, 112: get inserted amount in cent in sum, quick while purchase + // 113: get wake source, can be requested one time by Master after wake. Not here + // 19: get time and date and Extra values. poll occasionally and if needed + // 107, 22: MDB: poll if needed + + doRepeat=true; // 20.9.23 15uhr (after release) + if (datif_sendSlowCmd>0) + { + // send special command, slowly + datif_sendNow=datif_autoRequCommandList[datif_pNextCmd++]; + if (datif_pNextCmd >= datif_maxNrCommands) + datif_pNextCmd=0; + if (datif_sendNow>0) // never send Command 0 + datif_sendIOrequest(0, datif_sendNow, 0); + else + datif_pNextCmd=0; // falls in der Liste 0 vorkommt dann von vorne beginnen + + //qDebug()<< "datif send request " << datif_sendNow; + + } else + { + if (gpi_getNowCoinPay()) + { + // request coin input, high priority + datif_sendIOrequest(0, 112, 0); + //qDebug()<< "datif send request 112 get coins"; + } else + { + // request inputs, high priority + datif_sendIOrequest(0, 31, 0); // 102 + // while coin collection DIs are polled slowly with datif_autoRequCommandList[] + + //qDebug()<< "datif send request 102 get DIs"; + } + } + + if (++datif_sendSlowCmd>1) datif_sendSlowCmd=0; // 0,1,0,1,0,1,0.... + + return 0; // 25.9.2023, wichtig sonst bleibt die komplette PTU stehen!!!! + +} + + +char T_datif::isPortOpen(void) +{ + return (myDCIF->isPortOpen()); +} + + +// ############################################################################## +// Empfangsdaten einsortieren +// ---------------------------------------------------------------------------------------------- + + + +void T_datif::StoredRecData() +{ + // got response from slave on last request + // call automatically by T_prot + uint8_t res; + + datif_noResponseCtr=0; + loadRecDataFromFrame(); + res=myDCIF->ifDataReceived(); + // return: 0xFF: result unknown 0=OK + // 1= wrong length 2=wrong start sign 5= wrong crc + // 6= slave: master cmd was wrong 7: slave: could not write/read data + gpi_storeLastResult(res); +} + +char T_datif::loadRecDataFromFrame() +{ + // is called even with wrong received data in order to speed up the process (stop waiting for response) + // necessary data in T_prot: + uint16_t readSource, uitmp,uit2; + uint16_t readAddress; + //uint8_t pp; + uint8_t SlaveAdr, RdDleng; + uint8_t receivedData[FRAME_DATALEN]; + QString localStr; + uint32_t ultmp; + //int portNr; + bool ret; + uint8_t uctmp; //, res; // maxai + char ctmp; + //static uint8_t lastResult; + //uint8_t prnResult; + static uint32_t lastInsertedAmount; + uint32_t newInsertedAmount; + +// uint32_t mifatb_cunu, mifatb_cardnu, mifatb_creditAmount, mifatb_creditTime; +// QString mifatb_cardTyp, mifatb_lpr, mifatb_group, mifatb_zone; +// uint8_t nn; char cc; +// uint8_t mifatb_times[10]; + + + if (gpi_getNowIsBootload()) + { + datif_cmdWasPerformed=1; + cycl_running=100; // stop waiting for response and wait 1cycle till next sending + return 0; + } + + ret=myDCIF->getReceivedInData(&SlaveAdr, &readSource, &readAddress, &RdDleng, receivedData); + // nur true wenn CommandState OK und readState OK + + // retval: data valid, only one time true, true if CommandState OK and readState OK + gpi_storeResultOfLastRequest(ret); + if (ret==false) + { + // Details anzeigen: + //res= + myDCIF->ifDataReceived(); + // return: 0xFF: result unknown 0=OK + // 1= wrong length 2=wrong start sign 5= wrong crc + // 6= slave: master cmd was wrong 7: slave: could not write/read data + /* + qDebug() << "datif: bad response, error: " << res << " " << " lastWR: " << keepLastWrCmd << " lastRd: " << keepLastRdCmd; + qDebug("datif_recData: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ", + receivedData[0], receivedData[1], receivedData[2], receivedData[3], + receivedData[4], receivedData[5], receivedData[6], receivedData[7], + receivedData[8], receivedData[9], receivedData[10], receivedData[11], + receivedData[12], receivedData[13], receivedData[14], receivedData[15]); + */ + datif_cmdWasPerformed=2; // NO :(( + cycl_running=100; // stop waiting for response and wait 1cycle till next sending + return 0; + } + datif_cmdWasPerformed=1; // YES :), stop repeating + cycl_running=100; // stop waiting for response + + //qDebug() << "datif: got valid response "; + + gpi_storeRecPayLoad(RdDleng, receivedData); // save for host (user of hwapi) + + // uint8_t nn; + //qDebug() << "\n datif: got valid data, rdsrc:" << readSource << " rdadd:" << readAddress + // << " rdlen:" << RdDleng; +// qDebug("datif_recData: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ", +// receivedData[0], receivedData[1], receivedData[2], receivedData[3], +// receivedData[4], receivedData[5], receivedData[6], receivedData[7], +// receivedData[8], receivedData[9], receivedData[10], receivedData[11], +// receivedData[12], receivedData[13], receivedData[14], receivedData[15]); + + // readSource: reflects the READ Command if possible + // readAddress: reflects the requested read/write address if slave could perform + // lastWakeSrc: if Slave wakes master, this ist the reason for it (e.g. button pressed) + // RdDataLength: number of bytes in receivedData + + //firstDB=receivedData[0]; // just shorter, is used very often + //scndDB=receivedData[1]; + //thrdDB=receivedData[2]; + + localStr.clear(); + +// receivedData[0]='a'; +// receivedData[1]='B'; +// receivedData[2]='1'; +// receivedData[3]='-'; + + + for (int ii=0; ii>2)&3)); + uctmp=receivedData[1]; + gpi_storeDI_contactPowerIsOn(uctmp&0x10); + gpi_storeDI_optos((uctmp>>5)&3); + uctmp=receivedData[2]; + gpi_storeDI_auxIn(uctmp); + + uctmp=receivedData[3]; + gpi_storeDI_ptuWake(uctmp&1); + gpi_storeDI_readbackMdbTxD(uctmp&2); + gpi_storeDI_prnReady(uctmp&4); + gpi_storeDI_CoinAttach(uctmp&8); + gpi_storeDI_CoinEscrow(uctmp&16); + gpi_storeDI_mifareCardTapped(uctmp&32); + gpi_storeDI_rejMot_home(uctmp&64); + + uctmp=receivedData[4]; + //gpi_storeDI_modemWake(0); // gibt's gar nicht! + gpi_storeDI_mbdWake(uctmp&1); + gpi_storeDI_MifarePowerIsOn(uctmp&2); + gpi_storeDI_AuxPowerIsOn(uctmp&8); + gpi_storeDI_GsmPowerIsOn(uctmp&16); + gpi_storeDI_CreditPowerIsOn(uctmp&32); + gpi_storeDI_PrinterPowerIsOn(uctmp&64); + gpi_storeDI_MdbPowerIsOn(uctmp&128); + + gpi_storeDI_paperLow(receivedData[5]); + break; + + case CMD2DC_RdBkAllOutputs: //103 + + /* +// alle DO's in einen 8byte Puffer zusammenstellen, werden in einen Rutsch zum Master gesendet + + outBuf[0]: bit 0: TestMdbInput + 1: RS1 drv enabled + 2: RS1switch: 1=GSM 0=printer + 3: RS2switch: H: mifare L: credit + 4: Vbarcode=Vaux is on + + outBuf[1]: bit 0: coin led + 1: 0 + 2: paper led + 3: pinpad led + 4: start led + 5: service led + + outBuf[2]: bit 0: siren + 1: relay + 2: ptu wake + 3: shutter + 4: shutter test + 5: escrowGive + 6: escrowTake + 7: prn power + + outBuf[3]: Motor 1: 0:off 1=vorwärts / öffnen 2=rückw./zu 3: beide ein + outBuf[4]: Motor 2: 0:off 1=vorwärts / öffnen 2=rückw./zu 3: beide ein + */ + + uctmp=receivedData[0]; + gpi_storeDO_mdbRxTst(uctmp&1); + gpi_storeDO_auxPower(uctmp&0x10); + gpi_storeDO_serialSwitch((uctmp>>1)&7); // serial drv 0:on/off, 1:Serial mux1, 2:Serial mux2 + + uctmp=receivedData[1]; + gpi_storeDO_ledsAndFan(uctmp); + // bit0: coinled 1:front_illu 2: paper-led 3:pinpad-led 4:start-led 5:service-led 6:fan + + uctmp=receivedData[2]; + gpi_storeDO_sirenAndRelay(uctmp&3); // bit0: siren 1:relay + gpi_storeDO_ptuWake(uctmp&4); + + + gpi_storeDO_coinShutter(uctmp>>3); // bit0: Coin shutter output, bit1: input-test-output + gpi_storeDO_coinEscrow(uctmp>>5); // retval: 1:return flap is open 2:take flap is open 0:closed + gpi_storeDO_printerPwrOn(uctmp&0x80); + + uctmp=(receivedData[4] & 3); + uctmp<<=2; + if (receivedData[3] & 1) uctmp |=1; + if (receivedData[3] & 2) uctmp |=2; + gpi_storeDO_motorOutputs(uctmp); + // bit0: upper lock forw bit 1 backw bit2: lowLock forw bit3: LL backw + break; + + + case 109: + // get reader status and card type + + //gpi_storeMifReaderStateAndCardType(receivedData); + //gpi_storeNewMifareCard(receivedData[0], &receivedData[1]); + + break; + + case 24: + gpi_storeMifHwData(receivedData); +/* + struct T_Mifare + { + UCHAR ReaderState; // 1: OK 0: not OK + UCHAR res1; + UCHAR ReaderVersion[10]; + UCHAR CardPresent; + UCHAR CardSelected; + UCHAR Cardtype; + UCHAR CardAllowed; // 0,1 nur Mifare Classic 1k und 4k zugelassen + UCHAR CardSize; // 1 or 4 (kB) + UCHAR LengOfUid; // 4 or 7 (byte) + UCHAR UID[8]; // 4 byte oder 7 byte, Format binär + // 26 byte bis hier + UCHAR res2; + UCHAR res3; + ULONG UidH; // bei 4byte Uid alles 0 + ULONG UidL; + UCHAR SectorLogged; // result of loggin: 2=success 3=failed 1=no_tag 8=addr overflow F0=wrongCmd + UCHAR CurrentSector; + UCHAR RD_WR_Result; + UCHAR res4; + // 40byte lang + }; +*/ + break; + + case CMD2DC_RdBk_AtbCardType: //25 + // DC reports the type of mif-card (valid ATB card?) + + gpi_storeMifAtbData(receivedData); +/* + mifatb_cunu=uchar2ulong(receivedData[3], receivedData[2],receivedData[1],receivedData[0]); + mifatb_cardnu=uchar2ulong(receivedData[7], receivedData[6],receivedData[5],receivedData[4]); + + mifatb_cardTyp.clear(); + for (nn=0; nn<4; nn++) + mifatb_cardTyp.append(char(receivedData[8+nn])); + + mifatb_lpr.clear(); + for (nn=0; nn<16; nn++) + mifatb_lpr.append(char(receivedData[12+nn])); + + mifatb_group.clear(); + for (nn=0; nn<8; nn++) + mifatb_group.append(char(receivedData[28+nn])); + + mifatb_zone.clear(); + for (nn=0; nn<8; nn++) + mifatb_zone.append(char(receivedData[36+nn])); + + for (nn=0; nn<10; nn++) + mifatb_times[nn]=receivedData[44+nn]; + // 0..9: (Start) day, month, year, hh, min (Stop) day, month, year, hh, min, + + mifatb_creditAmount= uchar2ulong(receivedData[57], receivedData[56],receivedData[55],receivedData[54]); + mifatb_creditTime = uchar2ulong(receivedData[61], receivedData[60],receivedData[59],receivedData[58]); + + // for the 2020 cards the field "mifatb_creditAmount" is used as expire date/time: + //for (nn=0; nn<5; nn++) + // mifatb_times[nn]=receivedData[54+nn]; falsch + ultmp=mifatb_creditAmount; + mifatb_times[4]=ultmp%100; + ultmp/=100; + mifatb_times[3]=ultmp%100; + ultmp/=100; + mifatb_times[2]=ultmp%100; + ultmp/=100; + mifatb_times[1]=ultmp%100; + ultmp/=100; + mifatb_times[0]=ultmp%100; + + + qDebug()<<"got MifAtbData: "<0: error + // bit0: paper low 1: no paper 2: temperature error + // 3: head open 4: paper jam in cutter + // 6: no response 7: bad response from printer + + gpi_storePrinterState(receivedData); // derzeit 10bytes ( 0x2A02) + break; + + case CMD2DC_RdBk_PrnFonts: // 26 + //D0: font table/type + //D1: size + //D2: height + //D3: width + //D4: bold + //D5: invers + //D6: underlined + //D7: density + //D8: speed + //D9: Alignment + gpi_storePrinterFonts(receivedData); // derzeit 10bytes + break; + + case CMD2DC_RdBk_AllPrnData: // 27 + gpi_storePrinterState(receivedData); // derzeit 10bytes ( 0x2A02) + gpi_storePrinterFonts(&receivedData[10]); // derzeit 10bytes + /* + qDebug()<<"printer fonts stored " <0) // nur 1x bei neuer Münze 6.10.23 aendern: beim Wechsler hat die kleinste Muenze immer coin type 0! + if (uit2>0) + { + gpi_storeCurrentPayment(newInsertedAmount, uitmp, uit2); + //void gpi_storeCurrentPayment(uint32_t insertedAmount, uint16_t lastCoinType, uint16_t lastCoinValue) + if (newInsertedAmount != lastInsertedAmount) + { + emit datif_gotNewCoin(); + //qDebug()<<"emit new coin"; + + lastInsertedAmount=newInsertedAmount; + } + // qDebug()<<"datif store new coin"<28) + { + gpi_storeDeviceConditions(RdDleng, receivedData); + } + break; + + case 31: // Get dynamic machine conditions (doors, voltage, alarm….) + if (RdDleng>50) + { + gpi_storeDcDataValid(1); // DC-Data are valid as DC responded. + // Could be set to every response but this (31) + // is a very common and very important request + gpi_storeDynMachineConditions(RdDleng, receivedData); + } + /* funktioniert, ist aber nicht nötig. Signal wird nach dem shared memory erzeugt + prnResult=receivedData[52]; + if (prnResult != lastResult) + { + // new result + if (prnResult==1) + { + emit datif_templatePrintFinished_OK(); + } else + if (prnResult==2) + { + emit datif_templatePrintFinished_Err(); + } + + lastResult=prnResult; + }*/ + + break; + + case 32: // Get current cash level (in vault) + // bytes 0..3: amount bytes 4,5=Nr.ofCoins in vault + ultmp=uchar2ulong(receivedData[3],receivedData[2],receivedData[1],receivedData[0]); + uitmp=uchar2uint(receivedData[5],receivedData[4]); + gpi_storeCBlevel(ultmp, uitmp); + break; + + case 33: // Get all backuped acc. Numbers + // 8 UINTs with acc-nr + gpi_storeDCbackupAccNr(RdDleng, receivedData); + break; + + case 35: + gpi_storeMifCardType(RdDleng, receivedData); + break; + case 38: // Get stored account record backup + // readAddress, &RdDleng, receivedData + //if (RdDleng>50) // 1.8.23 nach Verlängerung des Datensatzes um 20byte falsch!!! + //{ + gpi_storeVaultRecord(readAddress, receivedData ); // always/max 64byte + /* + qDebug()<<"datif cmd38 got vault data. blockNr: "<60) + { + gpi_storeDynData(receivedData); + } + break; + + case 40: + //qDebug()<<"datif got response 40 bytes: " << RdDleng; + if (RdDleng>60) + { + gpi_storeTubeLevel(receivedData); + } + break; + + + + + + + + case 21: // readback version strings of all Json-File in DC + // + gpi_storeJsonVersion(readAddress, receivedData); + break; + + + } + readSource=0; // 17.05.2023: to avoid multiple recording + + return 0; +} + +// subs: + +// ---------------------------------------------------------------------------------------------- +// erstelle WRITE Datensätze +// ---------------------------------------------------------------------------------------------- + +// always use this three functions to send data: +//void myDCIF->setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, uint8_t *data); +//void myDCIF->setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr); +//void myDCIF->setUserWriteData(uint16_t WriteCmd); +//void myDCIF->setUserWrite1DB (uint16_t WriteCmd, uint16_t WrAddr, uint8_t val); +//void myDCIF->setUserWrite2DB (uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1); + +//void myDCIF->setUserReadData( uint16_t ReadCmd); + +//void myDCIF->sendUserData(uint16_t slaveAdr); + +void T_datif::datif_startSending(void) +{ + // egal ob WR und RD Daten gesetzt wurden + myDCIF->sendUserData(selectedSlaveAddr); // starte Sendung + gpi_startNewRequest(); + cycl_running=1; + +} + +// allgemeine Schreib/Lese-Funktion +void T_datif::datif_sendIOrequest(uint16_t WRcmd, uint16_t RDcmd, uint8_t nrOfWrData) +{ + uint8_t data[6]; //, who; + + if (nrOfWrData>4) nrOfWrData=0; + tslib_strclr(data,0,6); + + if (nrOfWrData>0) + data[0]=datif_OutCmdpara1; + if (nrOfWrData>1) + data[1]=datif_OutCmdpara2; + if (nrOfWrData>2) + data[2]=datif_OutCmdpara3; + if (nrOfWrData>3) + data[3]=datif_OutCmdpara4; + data[4]=0; data[5]=0; + + keepLastWrCmd=WRcmd; keepLastRdCmd=RDcmd; + + //if (RDcmd==101) + //{ + // who=0; + //} + + myDCIF->setUserWriteData(WRcmd, 0, nrOfWrData, data); + myDCIF->setUserReadData(RDcmd); + myDCIF->sendUserData(selectedSlaveAddr); + cycl_running=1; + +} + +void T_datif::datif_send8byteOutCmd(uint16_t WRcmd, uint16_t RDcmd) +{ + uint8_t data[10]; + uint16_t uitmp; + uint32_t ultmp; + + tslib_strclr(data,0,10); // 8 used + + data[0]=datif_OutCmdpara1; + data[1]=datif_OutCmdpara2; + uitmp=datif_OutCmdpara5; + ultmp=datif_OutCmdpara6; + + data[2]=uint8_t(uitmp); + uitmp>>=8; + data[3]=uint8_t(uitmp); + + data[4]=uint8_t(ultmp); + ultmp>>=8; + data[5]=uint8_t(ultmp); + ultmp>>=8; + data[6]=uint8_t(ultmp); + ultmp>>=8; + data[7]=uint8_t(ultmp); + + data[8]=0; data[9]=0; + + myDCIF->setUserWriteData(WRcmd, 0, 8, data); + myDCIF->setUserReadData(RDcmd); + myDCIF->sendUserData(selectedSlaveAddr); + cycl_running=1; + +} + + +bool T_datif::verifyLineTestresponse(uint8_t RdDlen, uint8_t *receivedData) +{ + if (RdDlen < 16) + return false; + QString myStr; + char ctmp; + + myStr.clear(); + myStr.append("< Slave Response"); + + for (int nn=0; nn<16; nn++) + { + ctmp=receivedData[nn]; + if (myStr[nn] != ctmp) + { + //qDebug() << " datif cmd 10: got wrong string "; + //qDebug() << myStr; + //qDebug() << receivedData; + //qDebug() << nn; + return false; + } + } + return true; +} + + +// RTC ---------------------------------------------------------------------- +/* +void T_datif::datif_OUT_setTime(void) +{ + // send PC time/date to slave + //uint8_t hour,min, sec, year, month, day, dayOfWeek, + //uint8_t dayOfYear, isLeap, weekOfYear; + uint8_t buff[15]; + uint16_t uitmp; + + QTime *systTime = new QTime(); + // qDebug() << systTime->currentTime().hour() <<":" + // << systTime->currentTime().minute() <<":" + // << systTime->currentTime().second(); + + buff[0]=uint8_t(systTime->currentTime().hour()); + buff[1]=uint8_t(systTime->currentTime().minute()); + buff[2]=uint8_t(systTime->currentTime().second()); + + + QDate *systDate = new QDate(); + systDate->currentDate(); + + uitmp= uint16_t(systDate->currentDate().year()); + buff[3]=uint8_t(uitmp); + buff[4]=uint8_t(uitmp>>8); + + buff[5]=uint8_t(systDate->currentDate().month()); + buff[6]=uint8_t(systDate->currentDate().day()); + buff[7]=uint8_t(systDate->currentDate().dayOfWeek()); + +// uitmp=systDate->currentDate().dayOfYear(); +// buff[8]=uint8_t(uitmp); +// buff[9]=uint8_t(uitmp>>8); + +// buff[10]=uint8_t(systDate->currentDate().isLeapYear(systDate->currentDate().year())); +// buff[11]=uint8_t(systDate->currentDate().weekNumber()); //weekOfYear +// buff[12]=0; + + //myDCIF->setUserWriteData(0x1310,0,8, buff); + myDCIF->setUserWriteData(CMD2DC_sendTime,0,8, buff); + myDCIF->setUserReadData(0); + myDCIF->sendUserData(selectedSlaveAddr); // jetzt wegsckicken + cycl_running=1; + +} +*/ +// 0x2311: set time to RTC +// 0x2312: set date to RTC + +uint8_t T_datif::datif_OUT_SendRandomData(uint8_t *buf, uint8_t Length) +{ + uint8_t len=Length; + + myDCIF->setBLsendData(len, buf ); + myDCIF->setUserReadData(0); + myDCIF->sendUserData(selectedSlaveAddr); + cycl_running=1; + + return 0; + +} + + + +/* +void T_datif::datif_send64byteOutCmd(uint16_t WRcmd, uint16_t addr, uint16_t RDcmd) +{ + // sending length is already defined by stored data + // not batched! don't use twice within 100ms + uint8_t LL; + uint8_t data[66]; + + tslib_strclr(data,0,66); // up to 64 used + gpi_restore64ByteSendData(&LL, data); // LL bytes was stored to be sent + myDCIF->setUserWriteData(WRcmd, addr, LL, data); + myDCIF->setUserReadData(RDcmd); + myDCIF->sendUserData(selectedSlaveAddr); + cycl_running=1; + +}*/ + +void T_datif::datif_sendToMemory(uint16_t WRcmd, uint16_t docNr, uint16_t blockNr, uint8_t *data64) +{ + // send printer documents to DC2 memory + // docNr: 0...15(31) with 1280 byte each (20 blocks a 64byte) + // blockNr=0...19 with 64byte each + // docNr =transmitted in WRITEADDRESS high byte + // blockNr=transmitted in WRITEADDRESS low byte + + uint16_t aa=0; + + aa=docNr; + aa<<=8; + aa |=blockNr; + myDCIF->setUserWriteData(WRcmd, aa, 64, data64); + myDCIF->setUserReadData(0); + myDCIF->sendUserData(selectedSlaveAddr); + cycl_running=1; + +} + + +void T_datif::startSupervision(void) +{ + + gpi_storeOverallResult(0xFF); +} + diff --git a/src/datei.cpp b/src/datei.cpp new file mode 100644 index 0000000..e995dc5 --- /dev/null +++ b/src/datei.cpp @@ -0,0 +1,943 @@ +// written by Thomas Sax, Jan.2022 +#include "datei.h" + + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create csv file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +QByteArray datei_writeArray, datei_tempArray; + +void csv_startCreatingFile(void) +{ + datei_writeArray.clear(); + datei_tempArray.clear(); +} + +void csv_addTextToFile(QString myText) +{ + datei_writeArray.append(myText.toLatin1()); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addIntToFile(int myValue) +{ + //qulonglong ullt=12345678901234567890; // max 1,844 x10^19 + datei_tempArray.setNum(myValue,10); // accepted types: short, ushort, int, uint, + // qlonglong, qulonglong, float, double + // numerbase can be 2...36(!),10=dec + + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addUintToFile(uint myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + + +void csv_addLongvalToFile(qlonglong myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +void csv_addUlongvalToFile(qulonglong myValue) +{ + datei_tempArray.setNum(myValue,10); + datei_writeArray.append(datei_tempArray); + datei_writeArray.append(FILESEPERATOR); +} + +/* +void csv_addCurrentTimeToFile(void) +{ + uint8_t hour, minute, sec, ui8buf[20]; + char buf[20]; + + config_getSysTime(&hour, &minute, &sec); + GetTimeString(hour, minute, sec, 0, 1, ui8buf); + for (uint8_t nn=0; nn<20; nn++) + buf[nn]=char(ui8buf[nn]); + datei_writeArray.append(buf,8); // time string + datei_writeArray.append(FILESEPERATOR); + +} + +void csv_addCurrentDateToFile(void) +{ + uint16_t year; + uint8_t month, day, ui8buf[20]; + char buf[20]; + + config_getSystemDate(&year, &month, &day); + //qDebug()<<"date year: "<1) + filSize=uint32_t(filLen); + else + return 0; + + // 1) find position of seperators + for (uint32_t ii=0; iiMAXNUMBEROFSEQUENCES) + return ""; + + // 1) find position of seperators + for (ii=0; ii0) + { + start=sepPos[sequNr-1]+1; + ende=sepPos[sequNr]; + } + + //qDebug()<<"datei getOneFileSequence start/ende: "<=ende) + return ""; + //return "-err3-"; + sequence.clear(); + //batmp.clear(); + pp=0; + for (ii=start; ii=int(filSize)) + mm=0; + oneByt=sourceFile.at(mm); + sequence.append(oneByt); + } + return sequence; +} + +int csv_getEntryAsInt(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA, myVA; + int entry=0; + bool ok; + + myVA.clear(); + myBA = csv_getOneFileSequence(sourceFile, sequNr); + //qDebug()<<"datei getEntryAsInt, sequence: " << myBA; + + entry=myBA.toInt(&ok,16); + if (ok) + { + //qDebug()<<"datei getEntryAsInt, number: " << entry; + return entry; + } + //qDebug()<<"datei getEntryAsInt, error " << myBA; + return 0; +} + +int32_t csv_getEntryAsLong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + long entry=0; + bool ok; + + entry=myBA.toLong(&ok,10); + if (ok) + return entry; + return 0; +} + +uint8_t csv_getEntryAsUshort(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint8_t entry=0; + bool ok; + + entry=uint8_t(myBA.toUShort(&ok,10)); + if (ok) + return entry; + return 0; +} + +uint16_t csv_getEntryAsUint(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint16_t entry=0; + bool ok; + + entry=uint16_t(myBA.toUInt(&ok,10)); + if (ok) + return entry; + return 0; +} + +uint32_t csv_getEntryAsUlong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint32_t entry=0; + bool ok; + + entry=myBA.toULong(&ok,10); + if (ok) + return entry; + return 0; +} + +uint64_t csv_getEntryAs2Ulong(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + uint64_t entry=0; + bool ok; + + entry=myBA.toULongLong(&ok,10); + if (ok) + return entry; + return 0; +} + + + +QString csv_getEntryAsString(QByteArray sourceFile, uint32_t sequNr) +{ + QByteArray myBA = csv_getOneFileSequence(sourceFile, sequNr); + QString entry; + + //qDebug()<<"datei getEntryAsString, sequence: " << myBA; + entry=myBA.toStdString().c_str(); + return entry; +} + +// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------ create Json file ------------------------------- +// ------------------------------------------------------------------------------------------------- + +/* + example +QString str = "{" + " \"Herausgeber\": \"Xema\"," + " \"Nummer\": \"1234-5678-9012-3456\"," + " \"Deckung\": 2e+6," + " \"Währung\": \"EURO\"," + " \"Inhaber\": {" + " \"Name\": \"Mustermann\"," + " \"Vorname\": \"Max\"," + " \"männlich\": true," + " \"Hobbys\": [ \"Reiten\", \"Golfen\", \"Lesen\" ]," + " \"Alter\": 42," + " \"Kinder\": []," + " \"Partner\": null" + " }" + "}"; + +*/ + +QString myJsonCon; +QString tmpStr; + +void json_startRecord(void) +{ + myJsonCon.clear(); + tmpStr.clear(); + myJsonCon.append('{'); +} + +void json_enterIntToRecord(QString attribute, ulong i_value) +{ + tmpStr.clear(); + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + tmpStr.setNum(i_value); + myJsonCon.append(tmpStr); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); +} + +void json_enterTextToRecord(QString attribute, QString txt_value) +{ + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + myJsonCon.append(txt_value); + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); +} +/* +void json_addCurrentTimeToRecord(QString attribute) +{ + uint8_t hour, minute, sec, ui8buf[20]; + //char buf[20]; + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + + datei_getSysTime(&hour, &minute, &sec); + GetTimeString(hour, minute, sec, 0, 1, ui8buf); + for (uint8_t nn=0; nn<8; nn++) + myJsonCon.append(ui8buf[nn]); + + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); + +} + +void json_addCurrentDateToRecord(QString attribute) +{ + uint16_t year; + uint8_t month, day, ui8buf[20]; + //char buf[20]; + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('"'); + + datei_getSystemDate(&year, &month, &day); + GetDateString(day, month, 0x20, uint8_t(year%100), 0, 0, ui8buf); + for (uint8_t nn=0; nn<10; nn++) + myJsonCon.append(ui8buf[nn]); + + myJsonCon.append('"'); + myJsonCon.append(','); + myJsonCon.append(NEWLINEINFILE); + +} +*/ + +void json_enterArrayToRecord(QString attribute, uint8_t *buf, ulong nrofVals) +{ + // add array of numbers with "nrofVals" elements + + myJsonCon.append('"'); + myJsonCon.append(attribute); + myJsonCon.append('"'); + myJsonCon.append(':'); + myJsonCon.append('['); // eckig!!! + for (ulong ul=0; ulMAXNROFARRAYVALUES) + nrOfPairs=MAXNROFARRAYVALUES; + + for (ii=0; iiMaxBufferSize) + { + ok=false; // got not all + nrOfPairs=MaxBufferSize; + } + for (int ii=0; ii +#include "dcBL.h" +#include +//#include "tabFw.h" +#include "sendWRcmd.h" + + +// File sits "behind" the HWapi and in front of "PI", so all necessary Bootloader functions can be called from HWapi + + + +uint16_t ucharTOuint(uint8_t Highbyte, uint8_t Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +#define GETLOWBYTE 0 +#define GETHIGHBYTE 1 + +uint8_t uintTOuchar(uint16_t uival, uint8_t getHighB) +{ + // getHighB: low=GetLowByte + uint16_t uitmp=uival; + if (getHighB==0) + return uint8_t(uitmp); + uitmp>>=8; + return uint8_t(uitmp); + +} + +//#define GETLOWBYTE 0 +//#define GETHIGHBYTE 1 +#define GETMIDLOWBYTE 2 +#define GETMIDHIGHBYTE 3 + +uint8_t ulongTOuchar(uint32_t ulval, uint8_t whichByte) +{ + + uint32_t ultmp=ulval; + if (whichByte==GETLOWBYTE) + return uint8_t(ultmp); + ultmp>>=8; + if (whichByte==GETMIDLOWBYTE) + return uint8_t(ultmp); + ultmp>>=8; + if (whichByte==GETMIDHIGHBYTE) + return uint8_t(ultmp); + ultmp>>=8; + if (whichByte==GETHIGHBYTE) + return uint8_t(ultmp); + return 0; +} + +void strclr(uint8_t *buf, uint8_t clrsign, uint8_t len) +{ + uint16_t nn; + + for (nn=0; nn> (7 - nn)) & 0x01); + if (B15H) + { + crc ^= 0x1021; + } + } + } + + for (nn = 0; nn < 16; nn++) + { + B15H = 0; + if(crc & 0x8000) + B15H = 1; + crc = (crc << 1) | 0x00; + if (B15H) + { + crc ^= 0x1021; + } + } + return crc; + +} + + +#define SEND_STX 2 +#define SEND_ETX 3 +#define SEND_ESC 0x1B + +static uint8_t dcBL_LastBLcmd; // stored the last sent cmd in order to analys response + // cmd echo'ed: error cmd or'ed with 0x80: OK + +uint8_t dcBL_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) +{ + // make BL protocol, retval = outbuf length (5...133) + // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum + // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 + // Data length = 0...64 + // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 + // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + + // 26.01.2021: noch einen Fehler gefunden: die "special conversion" fehlt bei der angehaengten Checksumme!!! + + uint8_t myBuf[140], pp=0, HB, LB; + uint8_t crcBuf[140], mm=0; + uint8_t nn, uctmp, currLen=0; + uint16_t calcCrc; + + strclr(myBuf, 0, 140); + strclr(crcBuf, 0, 140); // extra Puffer because STX must not be caculated + + myBuf[pp++]=SEND_STX; + myBuf[pp++]=Cmd; + crcBuf[mm++]=Cmd; + dcBL_LastBLcmd=Cmd; + + // append data: + for (nn=0; nn0 && recLen<150) + { + epi_getRawReceivedData(respBuff); + epi_clrRawReceivedString(); + //dcBL_writeText("dcBL gotResponse"); + + } + + return recLen; +} + +#define noReceive 0 +#define ISWRONG 1 +#define ISOK 10 + +uint8_t dcBL_ChkResponse() +{ + // retval: 0: no response (by now) + // 1...5: Error, repeat + // 10: OK, next... + uint8_t buf[152], recLen; + + memset(buf,0,152); + recLen=dcBL_getResponse(buf); + if (recLen==0) + return 0; // no response by now + + if ((buf[0]==2) && (buf[1]==(dcBL_LastBLcmd | 0x80) ) ) + return 10; // OK + + // 27.01.21: Problem aufgetaucht: Fehler nur bei CRC melden + // -> block wiederholen. In den anderen Fällen NICHT wiederholen + // sonst ist der block doppelt im Flash!!!!!!!! + if (recLen>0 && recLen<5) + { + //dcBL_writeText("error wrong length"); + //exactError=1; +qDebug()<<" DCBL_chkResp wrong length "; + return 10; // OK + } + if (buf[0] !=2) + { + //dcBL_writeText("error wrong start"); + //exactError=2; +qDebug()<<" DCBL_chkResp wrong start "; + return 10; // OK + } + if (buf[0]==2 && buf[1]=='e' && buf[2]=='0' ) + { + //dcBL_writeText("error wrong crc"); + //exactError=3; // DC reports wrong crc +qDebug()<<" DCBL_chkResp wrong crc"; + return 1; // error + } + if (buf[0]==2 && buf[1]==dcBL_LastBLcmd ) + { + //dcBL_writeText("error wrong cmd"); + //exactError=4; // wrong cmd +qDebug()<<" DCBL_chkResp wrong cmd"; + return 10; // OK + } + return 1; // error +} + + + +uint8_t dcBL_sendSuccess(uint8_t lastCommand) +{ + // return val: 0: no response by now 1:error 10: OK + + uint8_t Indata[152], recLen; + + memset(Indata,0,152); + recLen=dcBL_getResponse(Indata); + if (recLen==0) + return 0; // no response by now + +// qDebug()<<"dcBL_sendSuccess: got BL data"<< recLen << +// Indata[0]<< Indata[1]<< Indata[2]<< Indata[3] << Indata[4]<< Indata[5]<< Indata[6]<< Indata[7]; + + if (Indata[0]==2 && Indata[1]==(lastCommand | 0x80) ) + return 10; // OK + return 1; +} + +// ----------------------------------------------------------------------------------------------- +// --- ATB Bin-File Handling --------------------------------------------------------------------- +// ----------------------------------------------------------------------------------------------- + +/* example read file from HDD: + uint8_t uit8tmp; + QString stemp=" "; + + QFile file("/own/H2B/dc2.bin"); + //QFile file("/own/H2B/dc2.hex"); // laesst sich genauso oeffnen + + // TODO: use File-Open-Dialog-Box + + if (!file.exists()) + { + qDebug()<<"file not exists"; + } else + { + if (!file.open(QIODevice::ReadOnly) ) + { + qDebug()<<"cannot open"; + } else + { + qDebug()<<"loading...."; + qDebug()<<"size: " << file.size() <<"\n"; + QByteArray myBin = file.readAll(); + + // Kontrolle: + int ii=0; + do + { + uit8tmp=(uint8_t)myBin[ii++]; + //qDebug() << uit8tmp << " "; // Anzeige in dez + stemp.setNum(uit8tmp,16); + qDebug() << stemp << " "; // Anzeige in hex + + } while (ii<100); + } + } + + */ + + +// ------------------------------------------------------------------------- + +static QByteArray dcBL_AtbBinFile; +static uint32_t dcBL_fileSize; +static uint16_t dcBL_nrOfBlocks; // incl. last block +static uint16_t dcBL_fileCrc; +static uint8_t dcBL_myBuf[265000]; // same content like "dcBL_AtbBinFile" but bytewise +static uint8_t dcBL_sizeLastBlk; + + +bool dcBL_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) +{ + // copy file from QByteArray into local buffer for sending to DC + // calculate size, nr_of_blocks and crc + uint16_t uitmp; + uint32_t ultmp; + uint32_t LL; + + dcBL_AtbBinFile=readBinFile; + dcBL_fileSize=fileSize; + + if (dcBL_fileSize>=265000) // max bin file size for atmega + return false; // keep last file + ultmp=dcBL_fileSize; + ultmp %=64; + uitmp=uint16_t(ultmp); + ultmp=dcBL_fileSize; + ultmp /=64; + dcBL_nrOfBlocks=uint16_t(ultmp); + if (uitmp>0) + dcBL_nrOfBlocks++; // letzter Block hat !=64 byte + + // type conversion for crc calc + for (LL=0; LLalso sicherstellen dass das Laden des Binfiles 100%ig in Ordnung ist. + QByteArray BINFILECOPY1, BINFILECOPY2; + uint32_t BinFileCpyLen1, BinFileCpyLen2, LL; + uint8_t repeat=0, nn=0, stopp=0; + + do + { + //dcBL_writeText("loading 1st time:"); + //qDebug() <<"loading 1st time:"; + dcBL_loadBinary(fileName); + // file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize" + BINFILECOPY1=dcBL_AtbBinFile; + BinFileCpyLen1=dcBL_fileSize; + + //dcBL_writeText("loading 2nd time:"); + //qDebug() <<"loading 2. time:"; + dcBL_loadBinary(fileName); + // file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize" + BINFILECOPY2=dcBL_AtbBinFile; + BinFileCpyLen2=dcBL_fileSize; + + //dcBL_writeText("loading 3rd time:"); + //qDebug() <<"loading 3. time:"; + dcBL_loadBinary(fileName); + // file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize" + + repeat=0; + if (dcBL_fileSize !=BinFileCpyLen1 || dcBL_fileSize !=BinFileCpyLen2) + { + //dcBL_writeText("file length wrong"); + qDebug() <<"length error"; + + repeat=1; // load both again.... + } + if (repeat==0) + { + LL=0; stopp=0; + do + { + if (dcBL_AtbBinFile.at(LL) != BINFILECOPY1.at(LL)) + stopp=1; + } while((++LL < dcBL_fileSize) && !stopp); + + if (stopp) + { + repeat=1; // load both again.... + } + } + + if (repeat==0) + { + LL=0; stopp=0; + //qDebug() <<"2. loop"; + do + { + if (dcBL_AtbBinFile[LL] != BINFILECOPY2[LL]) + stopp=1; + } while((++LL < dcBL_fileSize) && !stopp); + + if (stopp) + { + repeat=1; // load both again.... + } + } + + } while (++nn<3 && repeat); // 3 trials + + + if (repeat==0) + { + qDebug() << "read file successful after " << nn << " loops"; + return true; // file OK + } + qDebug() << "read file with errors after " << nn << " loops"; + return false; // error, could not load correctly + +} + +// ----------------------------------------------------------------------------------------------- +// --- Send Bin-File to DC --------------------------------------------------------------------- +// ----------------------------------------------------------------------------------------------- +//static uint32_t dcBL_fileSize; +//static uint16_t dcBL_nrOfBlocks; +//static uint16_t dcBL_fileCrc; + +uint16_t dcBL_getNrOfBlocks(void) +{ + // size of the loaded bin file in 64byte blocks + return dcBL_nrOfBlocks; +} + +uint16_t dcBL_getFileCrc(void) +{ + // checksum of the loaded bin file + return dcBL_fileCrc; +} + +uint32_t dcBL_getFileSize(void) +{ + // length of the loaded bin file in byte + return dcBL_fileSize; +} + +uint8_t dcBL_getSizeOfLastBlock(void) +{ + uint32_t ultmp; + ultmp=dcBL_fileSize % 64; + return uint8_t(ultmp); +} + +void dcBL_sendAddress(uint16_t blockNumber) +{ + // send start address, nr of 64byte-block, start with 0 + // will be sent only for folling block-numbers: + // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte + uint32_t dcBL_BlkCtr=(uint32_t)blockNumber; + uint8_t len, buf[20]; + + tslib_strclr(buf, 0, 20); + if (blockNumber==0 || blockNumber==1024 || blockNumber==2048 || blockNumber==3072 || blockNumber==4096) + { + dcBL_BlkCtr*=64; + len=dcBL_sendFlashStartAddr2BL(dcBL_BlkCtr, buf); // make command string + +//qDebug()<<"dcBL_bl_sendAddress "<4095) + return false; + block2beSentNow=blockNumber; + blChainStep=1; + blChainResult=0; + blTimeOutCounter=0; + blRepeatCounter=0; + return true; +} + +int8_t dcBL_getBlockResult(void) +{ + // after every "dcBL_sendOneBlock()" call this until response + // retval 0: wait 1: OK, blk was sent 2: OK, transfer complete + // 3: error despite repeating, cancel. probably bin file corrupted + // Max duration: 3x no response (BL not OK) = 900ms + return blChainResult; + +} + + +char dcBL_cycle(void) +{ + // to be called cyclic every 100ms + uint8_t buf[70], sendBuf[160], ret, sendLen; + + if (blChainStep==1) + { + // start, check if addr necessary + if (block2beSentNow==0 || block2beSentNow==1024 || block2beSentNow==2048 + || block2beSentNow==3072 || block2beSentNow==4096 ) + { + + dcBL_sendAddress(block2beSentNow); + blChainStep++; + //qDebug()<<"dcBL_cycle sending address and wait for response"; + return 0; // continue in 100ms + } else + blChainStep=10; // continue immed. with sending data + } + + if (blChainStep==2) + { + // address was send, wait for response + ret= dcBL_sendSuccess(0x21); + // return val: 0: no response by now 1:error 10: OK + if (ret==10) + { + //qDebug()<<"dcBL_cycle got resp OK"; + + blChainStep=10; // OK, continue with data + blTimeOutCounter=0; + return 0; // continue in 100ms + } + if (ret==1) + { + //qDebug()<<"dcBL_cycle got resp error"; + + // we got response but BL reports an error + blTimeOutCounter=0; + blRepeatCounter++; + if (blRepeatCounter<3) + blChainStep=1; // repeat + else + { + blChainResult=3; // error timeout, no response from DC-BL + blChainStep=99; + return 0; + } + return 0; // continue in 100ms + } + blTimeOutCounter++; + if (blTimeOutCounter>=3) // wait 3 cycles (3x100ms) for response + { + //qDebug()<<"dcBL_cycle TO"; + + blChainResult=3; // error timeout, no response from DC-BL + blChainStep=99; + return 0; + } else + { + // ein oder zweimal keine Antwort + blChainStep=1; // repeat + + //qDebug()<<"dcBL_cycle no response"; + + return 0; // continue in 100ms + } + } + + // kein else! + if (blChainStep==10) + { + // send data block or conclusion + if (block2beSentNow == dcBL_nrOfBlocks) + { + // very last blocknumber, send conclusion + sendLen=dcBL_writeLastPage(sendBuf); + sendWRcmd_setSendBlock160(sendLen, sendBuf); + } else + { + // send data... + dcBL_getFileBlock(block2beSentNow, buf); + + //qDebug()<<"dcBL sending data block"<=3) // wait 3 cycles (3x100ms) for response + { + blChainResult=3; // error timeout, no response from DC-BL + blChainStep=99; + return 0; + } else + { + // ein oder zweimal keine Antwort + blChainStep=10; // repeat + return 0; // continue in 100ms + } + } + + return 0; +} + + + + + + + + + + + +// ----------------------------------------------------------------------------------------------- +// -- fully automatic programmimg chain ------------------------------------------------------------------ +// ----------------------------------------------------------------------------------------------- + +// use modules above and this functions from PI: +// sendWRcmd_setSendBlock160(len, buf); +// epi_getRawRecLength(); +// epi_getRawReceivedData(receivedData); + + +/* +// this lines shall be displayed in tabFW / FW_responseWindow +// they are read every 100ms. Make batch for 10 lines +#define SIZEBLRESP 50 +static QString BlResp[SIZEBLRESP]; +static int pBlResp; + +bool dcBL_isTextMemFree(void) +{ + if (pBlResp<0) pBlResp=0; // just for security + if (pBlResp<(SIZEBLRESP-1)) + return true; + return false; +} + +void dcBL_writeText(QString newTxt) +{ + // write text here in this file from memory 1....9, mem 0 is always free + if (dcBL_isTextMemFree()) + BlResp[++pBlResp]=newTxt; +} + +bool dcBL_checkForText(void) +{ + // if pointer at 0 then no more content + if (pBlResp>0) + return true; + return false; +} + +QString dcBL_readText(void) +{ + // read from 0...9 (oldest first) + if (pBlResp<=0) // should never be <0 + return ""; + QString locStr=BlResp[1]; // store memory[1] + + // move memories down by one: 2->1 3->2 4>3....9->8. Place 1 is free now + // example: if pBlResp==3 then we have still text 2 and 3 to display. 1 will be transfered now with this call + int nn; + for (nn=1; nn0) pBlResp--; + return locStr; +} + +*/ + +// ------------------------------------------------------------------------- + +/* +static uint8_t dcBL_step, dcBL_state; +static uint16_t dcBL_BlkCtr, dcBL_cyclCtr, repeatCtr; + +void dcBL_iniChain(void) +{ + int nn; + dcBL_step=0; + dcBL_cyclCtr=0; + dcBL_state=0; + dcBL_BlkCtr=0; + repeatCtr=0; + + // delete output window: + pBlResp=0; + for (nn=0;nn17) + { + dcBL_iniChain(); + dcBL_step=1; + //epi_clrRawReceivedString(); + qDebug()<<"starting chain..."; + //qDebug()<10) + { + dcBL_writeText("cancel"); + dcBL_step=0; // stop chain + } + break; + + case 8: // send start address + if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096) + { + ultmp=uint32_t(dcBL_BlkCtr); + ultmp*=64; + len=dcBL_sendFlashStartAddr2BL(ultmp, buf); + sendWRcmd_setSendBlock160(len, buf); + dcBL_writeText("sending start address"); + dcBL_cyclCtr=0; + dcBL_step++; + return 0; + } else + dcBL_step=12; + break; + + case 9: // wait for answer 2 161 68 59 3 + if (gotResp==ISOK) + { + dcBL_step=12; // Header nicht senden, unnötig + dcBL_BlkCtr=0; // 0 + repeatCtr=0; + return 0; + } else + if (gotResp==ISWRONG) + { + if (++repeatCtr<3) + { + dcBL_step--; + } else + { + dcBL_step=0; // stop chain + } + } + if (++dcBL_cyclCtr>10) + { + dcBL_writeText("cancel"); + dcBL_step=0; // stop chain + } + break; + + + case 12: // send binary 64 byte wise + + len=dcBL_getFileBlock(dcBL_BlkCtr, buf); // read from file, len = 0...64 + //lastBlkLength=len; // recognize last block or end + sendLen=dcBL_prepareDC_BLcmd(0x22, len, buf, sendBuf); // pack into protocol frame + + + // Kontrolle: + qDebug()<<"dcBL sending: "; + ii=0; + do + { + uit8tmp=(uint8_t)sendBuf[ii++]; + //qDebug() << uit8tmp << " "; // Anzeige in dez + stemp.setNum(uit8tmp,16); + qDebug() << stemp << " "; // Anzeige in hex + + } while (ii<100); + + + sendWRcmd_setSendBlock160(sendLen, sendBuf); // send 140 bytes + delay(100); + //dcBL_writeText("blk nr: "); + tmpStr.setNum(dcBL_BlkCtr); + dcBL_writeText(tmpStr); + delay(100); + //qDebug()<<"sending: " << buf; + dcBL_cyclCtr=0; + dcBL_BlkCtr++; + dcBL_step++; + break; + + case 13: // wait for answer 2 162 116 88 3 + + if (gotResp==ISOK) + { + // check if next address is needed (every 1024Blocks = 65536bytes) + if (dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096) + { + dcBL_step=8; + return 0; + } + + // check for EOF: + if (dcBL_BlkCtr >= dcBL_nrOfBlocks) + { + dcBL_writeText("last block successful sent..."); + dcBL_step++; // stop chain + dcBL_state=3; // transmission SUCCESSFUL + return 0; + } + dcBL_state=2; // transmission started + dcBL_step--; // send next data block + repeatCtr=0; + return 0; + } + if (gotResp==ISWRONG) + { + if (++repeatCtr<3) + { + dcBL_writeText("error"); + dcBL_BlkCtr--; + dcBL_step--; // send same block again + } else + { + dcBL_step=0; // stop chain + } + } + if (++dcBL_cyclCtr>30) // longer TO due to flashing + { + dcBL_writeText("cancel"); + dcBL_step=0; // stop chain + } + break; + + case 14: // + dcBL_writeText("finish writing flash"); + len=dcBL_writeLastPage(buf); // nur zur Sicherheit + sendWRcmd_setSendBlock160(len, buf); + dcBL_step++; + break; + + case 15: // wait for answer + if (gotResp==ISOK) + { + dcBL_step++; + repeatCtr=0; + return 0; + } else + if (gotResp==ISWRONG) + { + if (++repeatCtr>3) + { + dcBL_step--; + } + } + if (++dcBL_cyclCtr>10) + { + dcBL_writeText("cancel"); + dcBL_step=0; // stop chain + } + break; + + + case 16: // + dcBL_writeText("exit BL, bye"); + len=dcBL_exitBL(buf); + sendWRcmd_setSendBlock160(len, buf); + dcBL_step++; + + break; + + case 17: // wait for answer, not sure if it comes! + if (gotResp==ISOK) + { + dcBL_step++; + repeatCtr=0; + return 0; + } else + if (gotResp==ISWRONG) + { + if (++repeatCtr>10) + { + dcBL_step--; + } + } + if (++dcBL_cyclCtr>30) + { + dcBL_writeText("cancel"); + dcBL_step=0; // stop chain + } + break; + + case 18: + dcBL_step=0; + break; + } + + return 0; +} + + + +void dcBL_iniLoading(void) +{ + dcBL_iniChain(); +} + + +// nicht verwendet +void dcBL_startLoading(void) +{ + if (dcBL_step==0 || dcBL_step>17) + { + //dcBL_iniChain(); + dcBL_step=1; + //epi_clrRawReceivedString(); + qDebug()<<"DCBL start sending hexfile..."; + dcBL_writeText("DCBL start sending hexfile..."); + dcBL_BlkCtr=0; + dcBL_cyclCtr=0; + } + +} +*/ + +/* +// nicht verwendet +uint8_t dcBL_sendHexfile(void) +{ + QString tmpStr=""; + uint8_t buf[70], sendBuf[160], len, sendLen, gotResp; //, recLen; recBuff[160], ii, + QString stemp=" "; + uint32_t ultmp; + //uint8_t uit8tmp, ii; + + + gotResp=dcBL_ChkResponse(); + + switch (dcBL_step) + { + case 1: // send start address + if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096) + { + ultmp=uint32_t(dcBL_BlkCtr); + ultmp*=64; + len=dcBL_sendFlashStartAddr2BL(ultmp, buf); + sendWRcmd_setSendBlock160(len, buf); + qDebug()<<" DCBL_CYCL_sending HexFile address "; + dcBL_writeText("sending addr"); + dcBL_step++; + return 0; + } else + dcBL_step=12; + break; + + case 2: // wait for answer 2 161 68 59 3 + if (gotResp==ISOK) + { + dcBL_step=12; // Header nicht senden, unnötig + dcBL_BlkCtr=0; // 0 + repeatCtr=0; + return 0; + } else + if (gotResp==ISWRONG) + { + if (++repeatCtr<3) + { + dcBL_step--; + } else + { + dcBL_step=0; // stop chain + qDebug()<<" DCBL_CYCL_got wrong resp to addr"; + dcBL_writeText("wrong resp"); + } + } + if (++dcBL_cyclCtr>100) + { + dcBL_writeText("cancel"); + qDebug()<<" DCBL_CYCL_step 2 got NO resp to addr"; + dcBL_step=0; // stop chain + } + break; + + case 12: // send binary 64 byte wise + + len=dcBL_getFileBlock(dcBL_BlkCtr, buf); // read from file, len = 0...64 + //lastBlkLength=len; // recognize last block or end + sendLen=dcBL_prepareDC_BLcmd(0x22, len, buf, sendBuf); // pack into protocol frame + + sendWRcmd_setSendBlock160(sendLen, sendBuf); // send 140 bytes + delay(100); + dcBL_writeText("blk nr: "); + tmpStr.setNum(dcBL_BlkCtr); + dcBL_writeText(tmpStr); + delay(100); + qDebug()<<"DCBL sending blk nr: " << dcBL_BlkCtr; + dcBL_cyclCtr=0; + dcBL_BlkCtr++; + dcBL_step++; + break; + + case 13: // wait for answer 2 162 116 88 3 + + if (gotResp==ISOK) + { + // check if next address is needed (every 1024Blocks = 65536bytes) + if (dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096) + { + dcBL_step=8; + return 0; + } + + // check for EOF: + if (dcBL_BlkCtr >= dcBL_nrOfBlocks) + { + dcBL_writeText("last block successful sent..."); + dcBL_step++; // stop chain + dcBL_state=3; // transmission SUCCESSFUL + return 0; + } + dcBL_state=2; // transmission started + dcBL_step--; // send next data block + repeatCtr=0; + return 0; + } + if (gotResp==ISWRONG) + { + if (++repeatCtr<3) + { + dcBL_writeText("error"); + dcBL_BlkCtr--; + dcBL_step--; // send same block again + } else + { + dcBL_step=0; // stop chain + } + } + if (++dcBL_cyclCtr>30) // longer TO due to flashing + { + dcBL_writeText("cancel"); + dcBL_step=0; // stop chain + } + break; + + case 14: // + dcBL_writeText("finish writing flash"); + len=dcBL_writeLastPage(buf); // nur zur Sicherheit + sendWRcmd_setSendBlock160(len, buf); + dcBL_step++; + break; + + case 15: // wait for answer + if (gotResp==ISOK) + { + dcBL_step++; + repeatCtr=0; + return 0; + } else + if (gotResp==ISWRONG) + { + if (++repeatCtr>3) + { + dcBL_step--; + } + } + if (++dcBL_cyclCtr>10) + { + dcBL_writeText("cancel"); + dcBL_step=0; // stop chain + } + break; + + } + return 0; +} + +*/ + + +/* +uint8_t dcBL_getResult(void) +{ + // call after every step to what's going on.... + // 1: connected to BL + // 2: transmission started + // 3: transmission successful + + return dcBL_state; +} +*/ +// ------------------------------------------------------------------------- +// ------------------------------------------------------------------------- +// ------------------------------------------------------------------------- + +// move to storeINdata and use shared mem as ptu-updater uses CAslave Lib 6.9.23TS +/* +static uint8_t Sdata_rawData[RAW_BL_DATALEN]; + +static uint8_t Sdata_LengthRawData; + +void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t *receivedData) +{ + uint8_t nn; + Sdata_LengthRawData=RdDlen; + if (Sdata_LengthRawData>RAW_BL_DATALEN) + Sdata_LengthRawData=RAW_BL_DATALEN; + for (nn=0; nn0x80 dann wird EIN Byte 16 stellig angezeigt + int ll=tmpStr.length(); + if (ll>2) + { + myString.append(tmpStr[ll-2]); + myString.append(tmpStr[ll-1]); + } else + { + myString.append(tmpStr); + } + myString.append(" "); + + } + //ret=Sdata_LengthRawData; + //Sdata_LengthRawData=0; + return myString; +}*/ +/* +void epi_clrRawReceivedString() +{ + Sdata_LengthRawData=0; +} +*/ + + + + + + + + diff --git a/src/dc_plugin_error.cpp b/src/dc_plugin_error.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/dc_result.cpp b/src/dc_result.cpp new file mode 100644 index 0000000..7329a76 --- /dev/null +++ b/src/dc_result.cpp @@ -0,0 +1,91 @@ +#include "dc_result.h" +#include + +struct DCResultInit { + DCResultInit() { + qRegisterMetaType(); + } +}; + +static DCResultInit initMetaTypeDCResult; + +DCResult::DCResult() + : m_pluginState(PLUGIN_STATE::NOT_INITIALIZED) + , m_errorCode("NOT-INITIALIZED") + , m_errorDescription("NOT-INITIALIZED") { +} + +DCResult::DCResult(PLUGIN_STATE pState, RESULT_STATE rState, + QString errorCode, QString errorDescription, + QString cashValue) + : m_pluginState(pState) + , m_resultState(rState) + , m_errorCode(errorCode) + , m_errorDescription(errorDescription) + , m_newCashValue(cashValue) { +} + +DCResult::DCResult(PLUGIN_STATE pState, RESULT_STATE rState, + CASH_STATE cState, QString errorCode, + QString errorDescription, QString cashValue) + : m_pluginState(pState) + , m_resultState(rState) + , m_cashState(cState) + , m_errorCode(errorCode) + , m_errorDescription(errorDescription) + , m_newCashValue(cashValue) { +} + +QDebug operator<<(QDebug d, DCResult const &result) { + + d << "\n"; + + switch(result.m_pluginState) { + case DCResult::PLUGIN_STATE::INITIALIZED: + d << "DC-PLUGIN-STATE ... INITIALIZED\n"; + break; + case DCResult::PLUGIN_STATE::NOT_INITIALIZED: + d << "DC-PLUGIN-STATE ... NOT-INITIALIZED\n"; + break; + } + + switch(result.m_resultState) { + case DCResult::RESULT_STATE::SUCCESS: + d << "DC-RESULT-STATE ... SUCCESS\n"; + break; + case DCResult::RESULT_STATE::ERROR_BACKEND: + d << "DC-RESULT-STATE ... ERROR_BACKEND\n"; + break; + case DCResult::RESULT_STATE::ERROR_TIMEOUT: + d << "DC-RESULT-STATE ... ERROR_TIMEOUT\n"; + break; + case DCResult::RESULT_STATE::ERROR_PROCESS: + d << "DC-RESULT-STATE ... ERROR_PROCESS\n"; + break; + case DCResult::RESULT_STATE::ERROR_RETRY: + d << "DC-RESULT-STATE ... ERROR_RETRY\n"; + break; + case DCResult::RESULT_STATE::INFO: + d << "DC-RESULT-STATE ... INFO\n"; + break; + } + + switch(result.m_cashState) { + case DCResult::CASH_STATE::CACHE_EMPTY: + d << "DC-CASH-STATE ... CASH-EMPTY\n"; + break; + case DCResult::CASH_STATE::CACHE_INPUT: + d << "DC-CASH-STATE ... CASH-INPUT\n"; + break; + case DCResult::CASH_STATE::OVERPAYED: + d << "DC-CASH-STATE ... OVERPAYED\n"; + break; + case DCResult::CASH_STATE::NOT_AVAILABLE: + break; + } + + d << "DC-ERROR-CODE ..." << result.m_errorCode << "\n"; + d << "DC-ERROR-DESC ..." << result.m_errorDescription << "\n"; + + return d; +} diff --git a/src/hwapi.cpp b/src/hwapi.cpp new file mode 100644 index 0000000..3d5862d --- /dev/null +++ b/src/hwapi.cpp @@ -0,0 +1,4236 @@ +/* + * API to the PSA2020 Hardware + * All data come in from device controller via serial interface and will be stored + * PI is updated every 100ms + * This api uses stored data and returns them in the following functions + * created: Q1/2020 TS until Q2/21 + +14.7.23TS: patch for correct printer state in line 3364 in sys_getDeviceConditions(struct T_moduleCondition *devCond) const + +8.9.2023 two new functions (end of file) for mifare test. Interface version 4.4 DC4.40...4.43 + +14.09.2023: Verriegelung eingebaut, nur noch gültige Abr.Daten zurückgeben, Suchbegriff: + alle Mifare-Funktionen ueberprueft und ggf verbessert + 18.09.2023: Signal "Kasse entnommen" und Signale "Tuer auf/zu" ueberprueft + +20.9.2023: in datif die Abfrage der DynMachineData massiv beschleunigt + und hier in hwapi die entprellten Werte fuer Tueren und Kasse verwenden. + Problem war: Signal "Kasse entnommen" war zu langsam -> manchmal abr nicht gesendet + +*/ + +#include "hwapi.h" + +static uint32_t hwapi_lastStartAmount; +static uint32_t hwapi_lastTotalAmount; +static uint8_t hwapi_cash_lastCollectionState; +static uint8_t hwapi_paymentStarted; +static uint8_t hwapi_lastDoorState; +static uint8_t bl_startupStep; + + + +hwapi::hwapi(QWidget *parent) : QObject(parent) +{ + // constructor + + // create or attach shared memory segment + m_sharedMem = SharedMem::getShm(sizeof(SharedMem)); + if (m_sharedMem) { + if (m_sharedMem->isAttached()) { + qInfo() << "Shared memory (" + << sizeof(SharedMem) << "bytes) created and attached"; + } + } else { + qCritical() << "Creating/attaching shared memory failed"; + } + + //if (shdMem_firstUse()) // für Master raus +// { + +#ifdef THIS_IS_CA_MASTER + myDatif = new T_datif(); // für die CAslave-Lib auskommentieren! +#else + qCritical()<<"hwapi: error CAslave cannot include T_datif"; +#endif + +// } + + runProcess = new T_runProc(); + + sendWRcmd_INI(); + + hwapi_TimerPayment = new QTimer(); + hwapi_TimerPayment->setSingleShot(true); + + QTimer *hwapi_callPayProc = new QTimer(); + connect(hwapi_callPayProc, SIGNAL(timeout()), this, SLOT(hwapi_slotPayProc())); + hwapi_callPayProc->setSingleShot(false); + hwapi_callPayProc->start(100); // in ms + +// hwapi_triggerBL = new QTimer(); +// connect(hwapi_triggerBL, SIGNAL(timeout()), this, SLOT(bl_performComplStart())); +// hwapi_triggerBL->setSingleShot(false); +// hwapi_triggerBL->stop(); + + hwapi_lastStartAmount=0; + hwapi_lastTotalAmount=0; + hwapi_cash_lastCollectionState=0; + hwapi_paymentStarted=0; + + //csv_startCreatingFile(FILENAME_SHAREDDATA); + hwapi_lastDoorState=0; // default: all doors (should be) closed, coin box inserted + // bit0: upper door 1:middle 2:lower 3=cash-box out + bl_startupStep=0; + + + + // connect(runProcess, SIGNAL(runProc_coinCollectionJustStarted()), this, SLOT(hwapi_coinCollectionJustStarted())); // geht nicht zuverlaessig! + connect(runProcess, SIGNAL(runProc_coinCollectionJustStarted()), this, SLOT(sub_slotCoin01())); + connect(runProcess, SIGNAL(runProc_coinCollectionAborted()), this, SLOT(sub_slotCoin02())); // hwapi_coinCollectionAborted())); + connect(runProcess, SIGNAL(runProc_gotNewCoin()), this, SLOT(sub_slotCoin03())); // hwapi_gotNewCoin())); + connect(runProcess, SIGNAL(runProc_payStopByMax()), this, SLOT(sub_slotCoin04())); // hwapi_payStopByMax())); + connect(runProcess, SIGNAL(runProc_payStopByPushbutton()), this, SLOT(sub_slotCoin05())); // hwapi_payStopByPushbutton())); + connect(runProcess, SIGNAL(runProc_payStopByEscrow()), this, SLOT(sub_slotCoin06())); // hwapi_payStopByEscrow())); + connect(runProcess, SIGNAL(runProc_payStopByError()), this, SLOT(sub_slotCoin07())); // hwapi_payStopByError())); + connect(runProcess, SIGNAL(runProc_payStopByTimeout()), this, SLOT(sub_slotCoin08())); // hwapi_payStopByTimeout())); + connect(runProcess, SIGNAL(runProc_payCancelled()), this, SLOT(sub_slotCoin09())); // hwapi_payCancelled())); + connect(runProcess, SIGNAL(runProc_coinProcessJustStopped()), this, SLOT(sub_slotCoin10())); // hwapi_coinProcessJustStopped())); + + connect(runProcess, SIGNAL(runProc_doorServiceDoorOpened()), this, SLOT(sub_slotCoin11())); // hwapi_doorServiceDoorOpened())); + connect(runProcess, SIGNAL(runProc_doorVaultDoorOpened()), this, SLOT(sub_slotCoin12())); // hwapi_doorVaultDoorOpened())); + connect(runProcess, SIGNAL(runProc_doorCoinBoxRemoved()), this, SLOT(sub_slotCoin13())); // hwapi_doorCoinBoxRemoved())); + connect(runProcess, SIGNAL(runProc_doorCoinBoxInserted()), this, SLOT(sub_slotCoin14())); // hwapi_doorCoinBoxInserted())); + connect(runProcess, SIGNAL(runProc_doorCBinAndAllDoorsClosed()), this, SLOT(sub_slotCoin15())); // hwapi_doorCBinAndAllDoorsClosed())); + connect(runProcess, SIGNAL(runProc_doorAllDoorsClosed()), this, SLOT(sub_slotCoin16())); // hwapi_doorAllDoorsClosed())); + + +} + +void hwapi::hwapi_slotPayProc(void) +{ + //cash_paymentProcessing(); + //doors_supervise(); + //dcBL_cycle(); + + +} + + +void hwapi::sub_slotCoin01(void) +{ + emit hwapi_coinCollectionJustStarted(); + //qDebug()<<"hwapi::sub_slotCoin01()"; +} + +void hwapi::sub_slotCoin02(void) +{ + emit hwapi_coinCollectionAborted(); + //qDebug()<<"hwapi::sub_slotCoin02()"; +} + +void hwapi::sub_slotCoin03(void) +{ + emit hwapi_gotNewCoin(); + //qDebug()<<"hwapi::sub_slotCoin03()"; +} + +void hwapi::sub_slotCoin04(void) +{ + emit hwapi_payStopByMax(); + //qDebug()<<"hwapi::sub_slotCoin04()"; +} + +void hwapi::sub_slotCoin05(void) +{ + emit hwapi_payStopByPushbutton(); + //qDebug()<<"hwapi::sub_slotCoin05()"; +} + +void hwapi::sub_slotCoin06(void) +{ + emit hwapi_payStopByEscrow(); + qDebug()<<"hwapi::sub_slotCoin06()"; +} +void hwapi::sub_slotCoin07(void) +{ + emit hwapi_payStopByError(); + //qDebug()<<"hwapi::sub_slotCoin07()"; +} + +void hwapi::sub_slotCoin08(void) +{ + emit hwapi_payStopByTimeout(); + //qDebug()<<"hwapi::sub_slotCoin08()"; +} + +void hwapi::sub_slotCoin09(void) +{ + emit hwapi_payCancelled(); + //qDebug()<<"hwapi::sub_slotCoin09()"; +} + +void hwapi::sub_slotCoin10(void) +{ + emit hwapi_coinProcessJustStopped(); + //qDebug()<<"hwapi::sub_slotCoin10()"; +} + +void hwapi::sub_slotCoin11(void) +{ + emit hwapi_doorServiceDoorOpened(); +} + +void hwapi::sub_slotCoin12(void) +{ + emit hwapi_doorVaultDoorOpened(); +} + +void hwapi::sub_slotCoin13(void) +{ + emit hwapi_doorCoinBoxRemoved(); +} + +void hwapi::sub_slotCoin14(void) +{ + emit hwapi_doorCoinBoxInserted(); +} + +void hwapi::sub_slotCoin15(void) +{ + emit hwapi_doorCBinAndAllDoorsClosed(); +} + +void hwapi::sub_slotCoin16(void) +{ + emit hwapi_doorAllDoorsClosed(); +} + + + +/* +void hwapi::sub_storeSendingText(QByteArray *buf) const +{ + + char local[70], copie[1350]; // 64byte more then max buffer size! + int LL, nn, len, maxruns=20; + + epi_resetPrinterStack(); + // make a copy of the incoming byteArray as the byteArray can not be moved (crash!) + tslib_strclr(copie, 0, 1350); + LL=buf->length(); + for (nn=0; nnat(nn); + } + + tslib_strclr(local, 0, 66); + LL=buf->length(); + if (LL>1280) + { + qDebug()<<"reducing text size from " << LL << " to 1280 bytes"; + LL=1280; // Limit size + } else + qDebug()<<"\n printing text with " << LL << " bytes: "; + + do + { + len=tslib_getMinimum(LL, 64); + tslib_strclr(local, 0, 66); + for (nn=0; nn0 && LL>0); + +} +*/ + +bool hwapi::dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const +{ + // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 + // BaudStr: for exapmle "19200" + // ComName: for example "COM48" + // connect: 0, 1 +#ifdef THIS_IS_CA_MASTER +//qDebug() << "~~>LIB" << "dc_openSerial called... " ; + epi_setSerial(BaudNr, BaudStr, ComName, connect); + // Actions: open serial port with parameters +#else + BaudStr=ComName=""; BaudNr=0; connect=0; // to avoid compiler warning + qCritical()<<"hwapi: error CAslave cannot open serial"; + return false; + return BaudNr; // to avoid compiler warning + return connect; // to avoid compiler warning +#endif + epi_setNowIsBootload(false); + return true; +} + +void hwapi::dc_closeSerial(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_closeSerial(); +#else + qCritical()<<"hwapi: error CAslave cannot close serial"; +#endif + +} + + +bool hwapi::dc_isPortOpen(void) const +{ + return epi_isSerialPortOpen(); +} + +void hwapi::dc_autoRequest(bool on) const +{ + // automatically request ALL digital and analog sensors, get time/date, get status information + epi_startEmmision(on); +} + + +void hwapi::dc_requTestResponse() const +{ + //sendWRcmd_ setSendCommand0(SENDDIRCMD_TestSerial); + // CMD2DC_TestSerial + // replace by new command form: + sendFDcmd_set(0, CMD2DC_TestSerial, 0,0,0,0,0); +} + +bool hwapi::dc_readAnswTestResponse() const +{ + return epi_getResult_serialTestOK(); +} + +uint8_t hwapi::dc_isRequestDone(void) const +{ + // retval: 0: request is still in progress + // 1: answer from DC2 was OK + // 2: wrong answer from DC2 + return epi_getResultOfLastRequest(); +} + +uint16_t hwapi::dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const +{ + // get data back in *pl, max 64 byte, can be used for diagnosis + // retval = nr of bytes received. If host buffer too small then + // only plBufSíz bytes are copied to pl + // plBufSíz=size of host buffer + + return epi_getLastPayLoad( plBufSiz, payLoad); + +} + +void hwapi::dc_setWakeFrequency(uint8_t period) const +{ + // RTC wakes DC2 (and PTU) by hardware signal every 32seconds + // change wake signal period to 1...64s + sendFDcmd_set(0, CMD2DC_setWakeFrequ,0, period,0,0,0); + + +} + +void hwapi::dc_OrderToReset(void) const +{ + uint8_t len, buf[160]; + + len=dcBL_restartDC(buf); + sendWRcmd_setSendBlock160(len, buf); + +} + + +QString hwapi::dc_getSerialState(void) const +{ +#ifdef THIS_IS_CA_MASTER + return epi_getTxt4comStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif +} + + +void hwapi::dc_clrSerialStateText(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_clrTxt4comStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; +#endif +} + + +void hwapi::bl_sendDataDirectly(uint8_t length, uint8_t *buf) const +{ + // send without protocol frame, needed for the DC bootloader + sendWRcmd_setSendBlock160(length, buf); + +} + +uint8_t hwapi::getRawRecLength(void) const +{ + return epi_getRawRecLength(); +} + +uint8_t hwapi::getRawReceivedData(uint8_t *receivedData) const +{ + return epi_getRawReceivedData(receivedData); +} + + + + +QString hwapi::dc_getSerialParams(void) const +{ + return epi_getSlaveParamSTR(); +} + +QString hwapi::dc_getHWversion(void) const +{ + return epi_loadHWver(); +} + +QString hwapi::dc_getSWversion(void) const +{ + return epi_loadSWver(); +} + +QString hwapi::dc_getState(void) const +{ + return epi_loadDCstate(); +} + + +// ---------------------------------------------------------------------------------------------------------- +// Date and Time +// ---------------------------------------------------------------------------------------------------------- + +uint8_t hwapi::rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const +{ +// void epi_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss); +// void epi_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd); +// void epi_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday); + uint8_t H, M, S; + uint16_t unused16; + uint32_t unused32; + + epi_getTime(&H, &M, &S); + rtc_DateTime->rtc_hour=H; + rtc_DateTime->rtc_min=M; + rtc_DateTime->rtc_sec=S; + + epi_getDate(&H, &M, &S); + rtc_DateTime->rtc_year=H; + rtc_DateTime->rtc_month=M; + rtc_DateTime->rtc_dayOfMonth=S; + + epi_getToday(&H, &unused16, &unused32); + rtc_DateTime->rtc_dayOfWeek=H; + return 0; +} + +uint8_t hwapi::rtc_setDateTime(void) const +{ + //vorher nur: sendWRcmd_setSendCommand0(SENDDIRCMD_setTime); + // send PC time/date to slave + //uint8_t hour,min, sec, year, month, day, dayOfWeek, + //uint8_t dayOfYear, isLeap, weekOfYear; + uint8_t buff[15]; + uint16_t uitmp; + + QTime *systTime = new QTime(); + // qDebug() << systTime->currentTime().hour() <<":" + // << systTime->currentTime().minute() <<":" + // << systTime->currentTime().second(); + + buff[0]=uint8_t(systTime->currentTime().hour()); + buff[1]=uint8_t(systTime->currentTime().minute()); + buff[2]=uint8_t(systTime->currentTime().second()); + + QDate *systDate = new QDate(); + systDate->currentDate(); + + uitmp= uint16_t(systDate->currentDate().year()); + buff[3]=uint8_t(uitmp); + buff[4]=uint8_t(uitmp>>8); + + buff[5]=uint8_t(systDate->currentDate().month()); + buff[6]=uint8_t(systDate->currentDate().day()); + buff[7]=uint8_t(systDate->currentDate().dayOfWeek()); + + // uitmp=systDate->currentDate().dayOfYear(); + // buff[8]=uint8_t(uitmp); + // buff[9]=uint8_t(uitmp>>8); + + // buff[10]=uint8_t(systDate->currentDate().isLeapYear(systDate->currentDate().year())); + // buff[11]=uint8_t(systDate->currentDate().weekNumber()); //weekOfYear + // buff[12]=0; + + longFDcmd_set(CMD2DC_sendTime,0,0,8,buff); + + return 0; +} + + +void hwapi::rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const +{ + epi_getTime(hh, mm, ss); +} + +void hwapi::rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const +{ + epi_getDate(yy, mm, dd); +} + +uint8_t hwapi::rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const +{ + // dow=day of week, 1=monday...7 + // minOfToday: 0=midnight...1439= 23:59 + // secOfToday: 0=midnight...86399= 23:59:59 + + epi_getToday(dow, minOfToday, secOfToday); + return 0; +} + +bool hwapi::rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const +{ + return epi_isLeapYear(lastLeapYear, NextLeapYear); +} + + +bool hwapi::rtc_isLeapYear(void) const +{ + return epi_isLeapYear(); +} + +void hwapi::rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const +{ + epi_getSpecialWeekTimeDate(DayOfWeek, HoursOfWeek, MinutesOfWeek); +} + +void hwapi::rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const +{ + epi_getSpecialMonthTimeDate(DayOfMonth, HoursOfMonth, MinutesOfMonth); +} + +void hwapi::rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const +{ + epi_getSpecialYearTimeDate(DayOfYear, HoursOfYear, MinutesOfYear); +} + + +QString hwapi::rtc_getTimStr() const +{ + uint8_t hh, mm, ss, buf[20], nn; + QString qbuf; + char ctmp; + qbuf.clear(); + for (nn=0; nn<20; nn++) buf[nn]=0; + epi_getTime(&hh, &mm, &ss); + GetTimeString(hh, mm, ss, HourSys24h, MITSEK, buf); // about 12byte long + for (nn=0; nn<20; nn++) + { + ctmp=buf[nn]; + qbuf[nn]=ctmp; + } + return qbuf; +} + +QString hwapi::rtc_getDatStr() const +{ + uint8_t day, month, year, buf[20], nn; + QString qbuf; + char ctmp; + + qbuf.clear(); + for (nn=0; nn<20; nn++) buf[nn]=0; + epi_getDate(&year, &month, &day); + GetDateString(day, month, 0x20, year, DateFormatDeutsch, 0, buf); + for (nn=0; nn<20; nn++) + { + ctmp= buf[nn]; + qbuf[nn]=ctmp; + } + return qbuf; +} + +QString hwapi::rtc_getTimDatStr() const +{ + // style: 0: hh:mm 1: hh:mm:ss + QString qbuf; + + qbuf.clear(); + qbuf.append(rtc_getTimStr()); + qbuf.append(" "); + qbuf.append(rtc_getDatStr()); + return qbuf; +} + + +// UID +void hwapi::dc_getUID8byte(uint8_t *buf8byteUid) const +{ + epi_getUIDdec(buf8byteUid); +} + +QString hwapi::dc_getUIDstr() const +{ + return epi_getUIDstr(); +} + +uint64_t hwapi::dc_getUIDnumber(void) const +{ + uint64_t retval=0; + uint8_t buf8byteUid[12], nn; + + epi_getUIDdec(buf8byteUid); + for (nn=8; nn>0; nn--) + { + retval+=buf8byteUid[nn-1]; + retval<<=8; // *256 + } + return retval; +} + +// ---------------------------------------------------------------------------------------------------------- +// analogs +// ---------------------------------------------------------------------------------------------------------- + + +uint32_t hwapi::dc_getTemperature(void) const +{ + // + return epi_loadMeasureValue(MEASCHAN_TEMPERATURE); +} + +QString hwapi::dc_getTemperaturStr(void) const +{ + return epi_getSlaveTemperatureStr(); +} + + +uint32_t hwapi::dc_getVoltage(void) const +{ + // in mV, e.g. 12300 = 12,3V + return epi_loadMeasureValue(MEASCHAN_VOLTAGE); +} + +QString hwapi::dc_getVoltagStr(void) const +{ + return epi_getSlaveVoltageStr(); +} + +bool hwapi::dc_mainFuseIsOk(void) const +{ + uint32_t ulong=epi_loadMeasureValue(MEASCHAN_VOLTAGE); // in mV, e.g. 12300 = 12,3V + if (ulong>3000) + return true; + return false; +} + +// ------------------------------------------------------------------------------ +// digital outputs +// ------------------------------------------------------------------------------ + +// Locks: +uint8_t hwapi::lock_switchUpperLock(uint8_t dir) const +{ + // dir 0=off 1=up 2=down + sendFDcmd_set(CMD2DC_MOV_UPLOCK,0,0, dir,0,0,0); + return 0; +} + +uint8_t hwapi::lock_switchLowerLock(uint8_t dir) const +{ + // dir 0=off 1=up 2=down + sendFDcmd_set(CMD2DC_MOV_DNLOCK,0,0, dir,0,0,0); + return 0; +} + +void hwapi::lock_switchVaultDoor(void) const +{ + sendFDcmd_set(CMD2DC_VAULT_DOOR,0,0, 0,0,0,0); + +} + +void hwapi::coin_switchRejectMotor(uint8_t dir) const +{ + sendFDcmd_set(CMD2DC_REJMOT_ON,0,0, dir,0,0,0); +} + +void hwapi::coin_rejectCoins(void) const +{ + sendFDcmd_set(CMD2DC_REJMOT_RUN,0,0, 0,0,0,0); +} + + +void hwapi::led_switchLedService(uint8_t on) const +{ + sendFDcmd_set(CMD2DC_LED_IN, CMD2DC_RdBkAllOutputs, 0, on, 0, 0, 0); +} + +void hwapi::led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendFDcmd_set(CMD2DC_LED_TICKET, CMD2DC_RdBkAllOutputs,0, on, ton, tof, 0); +} + +void hwapi::led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendFDcmd_set(CMD2DC_LED_PIN, CMD2DC_RdBkAllOutputs, 0, on, ton, tof, 0); +} + +void hwapi::led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendFDcmd_set(CMD2DC_LED_START, CMD2DC_RdBkAllOutputs,0, on, ton, tof, 0); +} + +void hwapi::led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendFDcmd_set(CMD2DC_LED_COIN, CMD2DC_RdBkAllOutputs, 0, on, ton, tof, 0); +} + +void hwapi::fan_switchFan(bool on) const +{ + sendFDcmd_set(CMD2DC_FAN, CMD2DC_RdBkAllOutputs,0, on, 0, 0, 0); +} + +void hwapi::alarm_switchSiren(bool on) const +{ + sendFDcmd_set(CMD2DC_SIREN, CMD2DC_RdBkAllOutputs,0, on, 0, 0, 0); +} + +void hwapi::bar_OpenBarrier(bool open) const +{ + sendFDcmd_set(CMD2DC_BARRIER, CMD2DC_RdBkAllOutputs,0, open, 0, 0, 0); +} + +void hwapi::ptu_switchWake(bool WAKEACTIVE) const +{ + sendFDcmd_set(CMD2DC_WAKEPTU,0,0, WAKEACTIVE,0,0,0); +} + +// AUX-IO's or barcode reader +void hwapi::aux_power(bool on) const +{ + sendFDcmd_set(CMD2DC_SWITCHAUXPWR, CMD2DC_RdBkAllOutputs, 0, on,0,0,0); +} + +void hwapi::aux_setUsage(uint8_t PinDirection) const +{ + // bit 0= Aux1 bit5=Aux6 1=output 0=input with pullup + sendFDcmd_set(CMD2DC_SWITCHAUXDDR, CMD2DC_RdBkAllOutputs,0, PinDirection,0,0,0); +} + +void hwapi::aux_setOutputs(uint8_t PinIsHigh) const +{ + // PinIsHigh bit 0..5 =Aux1...6 1=output high 0=set output low + sendFDcmd_set(CMD2DC_SWITCHAUXOUT, CMD2DC_RdBkAllOutputs,0, PinIsHigh,0,0,0); +} + +void hwapi::lock_switchContactPower(bool on) const +{ + sendFDcmd_set(CMD2DC_UCONTACTON, 0,0, on, 0,0,0); +} + +void hwapi::prn_switchPower(bool on) const +{ + // also switches and enables serial driver + //sendWRcmd_ setSendCommand4(SENDDIRCMD_PRN2_SWONOFF, on,0,0,0); + indat_storePrinterPower(on); + // PRINTER-ON/OFF zusätzlich statisch abspeichern + // Status-request soll nur gesendet werden wenn der Drucker ein ist + // Status-Abfrage (hier in HWapi) gibt 0 zurück wenn power-off + // dito mit allen anderen Geräten! + + // pi ---> storeINdata.cpp speichert diese statische Info (printer on/off) UND + // auch alles rückgelesene + sendFDcmd_set(CMD2DC_PRINTERON,0,0, on,0,0,0); +} + + +void hwapi::mif_readerOn(bool on) const +{ + // DC2 also switches and enables serial driver + //sendWRcmd_ setSendCommand4(SENDDIRCMD_MIF_SWONOFF, on,0,0,0); + sendFDcmd_set(CMD2DC_MIFREADERON,0,0, on,0,0,0); + indat_storeMifarePower(on); + if (on==false) + { + gpi_clearMifAtbData(); // neu 14.9.23 + gpi_clearMifHwData(); // neu 8.9.23 + } +} + +void hwapi::mif_creatAtbCard(uint8_t cardType) const +{ + sendFDcmd_set(CMD2DC_MIFREADERON,0,0, cardType,0,0,0); + indat_storeMifarePower(cardType); +} + + +void hwapi::mod_switchPower(bool on) const +{ + sendFDcmd_set(CMD2DC_MOD_ON,0,0, on,0,0,0); +} + +void hwapi::mod_switchWake(bool WAKEACTIVE) const +{ + sendFDcmd_set(CMD2DC_MOD_WAK,0,0, WAKEACTIVE,0,0,0); +} + +void hwapi::mdb_switchPower(bool on) const +{ + sendFDcmd_set(CMD2DC_MDB_ON,0,0, on,0,0,0); + indat_storeMDBisOn(CMD2DC_MDB_ON); +} + +void hwapi::mdb_switchWake(bool WAKEACTIVE) const +{ + sendFDcmd_set(CMD2DC_MDB_SETWAK,0,0, WAKEACTIVE,0,0,0); +} + +void hwapi::credit_switchPower(bool on) const +{ + sendFDcmd_set(CMD2DC_CRED_ON,0,0, on,0,0,0); +} + +void hwapi::credit_switchWake(bool WAKEACTIVE) const +{ + sendFDcmd_set(CMD2DC_CRED_WAK,0,0, WAKEACTIVE,0,0,0); +} + +void hwapi::shut_move(bool open) const +{ + // true:open false:close + sendFDcmd_set(CMD2DC_SHUTTER_OPEN, 0,0, open, 0,0,0); +} + +void hwapi::esc_moveFlaps(uint8_t flap ) const +{ + // 0: close both 1: open take-flap 2: open return + sendFDcmd_set(CMD2DC_ESCR_OPEN,0,0, flap, 0,0,0); +} + + +// ------------------------------------------------------------------------------ +// door, cashbox and lock switches +// ------------------------------------------------------------------------------ + + + +uint8_t hwapi::door_getSwitches(void) const +{ + // retval // bit0: upper door 1: low door 2:vault door + uint8_t ret; + + ret= epi_getDI_doorSwitches(); + // bit0: upper door 1: low door 2:vault door + ret &= 0x08; + return ret; +} + +bool hwapi::door_isUpperDoorOpen(void) const +{ +// uint8_t ret; +// ret= epi_getDI_doorSwitches(); +// // bit0: upper door 1: low door 2:vault door +// if (ret & 1) +// return true; +// return false; + + // new, since 20.9.23: use debounced values: + struct T_dynamicCondition myDynMachCond; + sys_getDynMachineConditions(&myDynMachCond); + if (myDynMachCond.upperDoor==0) // 0=zu + return false; + return true; // report "open" even if undefined because "closed" is more important +} + +bool hwapi::door_isLowerDoorOpen(void) const +{ +// uint8_t ret; +// ret= epi_getDI_doorSwitches(); +// if (ret & 2) +// return false; +// return true; + + // new, since 20.9.23: use debounced values: + struct T_dynamicCondition myDynMachCond; + sys_getDynMachineConditions(&myDynMachCond); + if (myDynMachCond.lowerDoor==0) // 0=zu + return false; + return true; // report "open" even if undefined because "closed" is more important + +} + +bool hwapi::vault_isVaultDoorOpen(void) const +{ +// uint8_t ret; +// ret= epi_getDI_doorSwitches(); +// // bit0: upper door 1: low door 2:vault door +// if (ret & 4) +// return true; +// return false; + + // new, since 20.9.23: use debounced values: + struct T_dynamicCondition myDynMachCond; + sys_getDynMachineConditions(&myDynMachCond); + if (myDynMachCond.middleDoor==0) // 0=zu + return false; + return true; // report "open" even if undefined because "closed" is more important + +} + + +uint8_t hwapi::vault_getSwitches(void) const +{ + // retval bit0: cash box, bit 1: bill box + uint8_t ret; + + ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in + ret&=0x03; + return ret; +} + +bool hwapi::vault_isCoinVaultIn(void) const +{ +// uint8_t ret; +// ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in +// if (ret & 1) +// return true; +// return false; + + // new, since 20.9.23: use debounced values: + struct T_dynamicCondition myDynMachCond; + sys_getDynMachineConditions(&myDynMachCond); + if (myDynMachCond.CBinDebounced==0) // 0:fehlt 1:drin + return false; + return true; + +} + +bool hwapi::vault_isBillVaultIn(void) const +{ + uint8_t ret; + + ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in + if (ret & 2) + return true; + return false; +} + + + +uint8_t hwapi::door_getLocks(void) const +{ + // retval bit0: upper lever is up + // bit1: upper lever is down + // bit2: lower lever is up + // bit3: lower lever is down + + uint8_t ret; + + ret= epi_getDI_lockSwitches(); + // retval: bit 0: upper lockbar up bit1: upper lockbar is down + // bit 2: lower lockbar up bit1: lower lockbar is down + ret&=0x0F; + return ret; +} + +bool hwapi::door_upperDoorIsLocked(void) const +{ + uint8_t ret; + + ret= epi_getDI_lockSwitches(); + if (ret & 2) + return true; + return false; +} + +bool hwapi::door_upperDoorIsUnlocked(void) const +{ + uint8_t ret; + + ret= epi_getDI_lockSwitches(); + if (ret & 1) + return true; + return false; +} + +bool hwapi::door_lowerDoorIsLocked(void) const +{ + uint8_t ret; + + ret= epi_getDI_lockSwitches(); + if (ret & 8) + return true; + return false; +} + +bool hwapi::door_lowerDoorIsUnlocked(void) const +{ + uint8_t ret; + + ret= epi_getDI_lockSwitches(); + if (ret & 4) + return true; + return false; +} + + + +bool hwapi::bar_optoIn1isOn(void) const +{ + uint8_t ret=epi_getDI_optos(); + // bit0: opto in 1 1: opto in 2 + if (ret & 1) + return true; + return false; +} + +bool hwapi::bar_optoIn2isOn(void) const +{ + uint8_t ret=epi_getDI_optos(); + // bit0: opto in 1 1: opto in 2 + if (ret & 2) + return true; + return false; +} + + +uint8_t hwapi::aux_getAuxInputs(void) const +{ + // retval: bit0=Aux1....Bit5=Aux6 + // 0: input low 1:input high + + uint8_t ret=epi_getDI_auxIn(); + // bit0: auxin 1 ... 5: auxin 6 + ret &=0x3F; + return ret; +} + +bool hwapi::ptu_WakeINisActive(void) const +{ + return epi_getDI_ptuWake(); +} + +bool hwapi::mdb_WakeINisActive(void) const +{ + return epi_getDI_mdbWake(); +} + +bool hwapi::prn_readyINisActive(void) const +{ + return epi_getDI_prnReady(); +} + +bool hwapi::coid_isAttached(void) const +{ + return epi_getDI_CoinAttach(); +} + +bool hwapi::coin_escrowIsOpen(void) const +{ + return epi_getDI_CoinEscrow(); +} + +bool hwapi::mif_cardIsAttached(void) const +{ + return epi_getDI_mifareCardTapped(); +} + +//bool hwapi::mod_WakeINisActive(void) +//{ +// return epi_getDI_modemWake(); +//} + + + +bool hwapi::door_isContactPowerOn(void) const +{ + return epi_getDI_contactPwr(); +} + +bool hwapi::mif_isMifarePowerOn(void) const +{ + bool mo=indat_isMifareOn(); + bool mi=epi_getDI_mifarePwr(); + if (mo && mi) + return true; + return false; +} + +bool hwapi::mdb_testIsmdbTxDon(void) const +{ + return epi_getDI_mdbTxd(); + //return mdb_busVoltageOk(); gleich? +} + +bool hwapi::aux_isAuxPowerOn(void) const +{ + return epi_getDI_auxPwr(); +} + +bool hwapi::mod_isGsmPowerOn(void) const +{ + return epi_getDI_gsmPwr(); +} + +bool hwapi::cred_isCreditPowerOn(void) const +{ + return epi_getDI_creditPwr(); +} + +bool hwapi::prn_isPrinterPowerOn(void) const +{ + return epi_getDI_printerPwr(); +} + +uint8_t hwapi::prn_PrnFuseIsOk(void) const +{ + //retval: 0: fuse blown 1: fuse OK 2:unknown as printer power is off + if (!epi_getDO_printerPwr()) + return 2; // unknown as printer power is off + if (epi_getDI_printerPwr()) + return 1; // printer voltage is OK + return 0; // fuse blown +} + +bool hwapi::mdb_isMdbPowerOn(void) const +{ + //return epi_getDI_mdbPwr(); // all DIs byte 4 bit 7 da ist was verschoben + return mdb_deviceVoltageOK(); // gleich? aus MDB_GET_STATE=107 Byte[1] +} + + +bool hwapi::cash_getRejectMotorHomePos(void) const +{ + // DI=low in Homepos + if (epi_getDI_rejectMotor_homepos()) + return 0; + return 1; +} + +uint8_t hwapi::cash_getLowPaperSensor(void) const +{ + // 0: Sensor sees paper 1: no paper 99: off + return epi_getDI_npe_sensor(); + +} + +// ------------------------------------------------------------------------------ +// request commands +// ------------------------------------------------------------------------------ + + // all read-requests can be sent manually by the following functions + // or automatically in background by: void hwapi::dc_autoRequest(bool on) + +void hwapi::request_DC2serialConfig() const +{ + sendFDcmd_set(0,CMD2DC_GetSerialConfig,0,0,0,0,0); +} + +void hwapi::request_DC2_HWversion() const +{ + sendFDcmd_set(0,CMD2DC_RdBkHWversion,0,0,0,0,0); +} + +void hwapi::request_DC2_SWversion() const +{ + sendFDcmd_set(0,CMD2DC_RdBkSWversion,0,0,0,0,0); +} + +void hwapi::request_DC2_condition() const +{ + sendFDcmd_set(0,CMD2DC_RdBkDCstate,0,0,0,0,0); +} + +void hwapi::request_DC2_UID() const +{ + sendFDcmd_set(0,CMD2DC_RdBkUID,0,0,0,0,0); +} + +void hwapi::request_DC2_TimeAndDate() const +{ + sendFDcmd_set(0,CMD2DC_RdBkTime,0,0,0,0,0); +} + +void hwapi::request_DC2_analogues() const +{ + sendFDcmd_set(0,CMD2DC_RdBkAnalog,0,0,0,0,0); +} + +void hwapi::request_DC2_digitalInputs() const +{ + sendFDcmd_set(0,CMD2DC_GetAllInputs,0,0,0,0,0); +} + +void hwapi::request_DC2_digitalOutputs() const +{ + sendFDcmd_set(0,CMD2DC_RdBkAllOutputs,0,0,0,0,0); +} + +// ------------------------------------------------------------------------------ +// the folowing device state requests are deployed only if device is powered up: + +void hwapi::request_PrinterHwState() const +{ + sendFDcmd_set(0,CMD2DC_RdBk_PrnState,0,0,0,0,0); +} + +void hwapi::request_PrinterCurrentFonts() const +{ + sendFDcmd_set(0,CMD2DC_RdBk_PrnFonts,0,0,0,0,0); + +} + +void hwapi::request_PrinterStateComplete() const +{ + sendFDcmd_set(0,CMD2DC_RdBk_AllPrnData,0,0,0,0,0); +} + + +void hwapi::request_MifareReaderState() const +{ + sendFDcmd_set(0, 24, 0, 0,0,0,0); // return reader type, card state and type and card UID +} + +void hwapi::request_MifareCardType() const +{ + sendFDcmd_set(0, 109, 0, 0,0,0,0); // ATB Card Type: upper/lower door, test card and card holder +} + +void hwapi::request_MifareAtbType() const +{ + sendFDcmd_set(0,25,0,0,0,0,0); + +} + +void hwapi::request_MifareID() const +{ + this->request_MifareReaderState(); +} + +void hwapi::request_MifareData(uint8_t dataBlockNumber) const +{ + if (dataBlockNumber<12) // 1k cards return 12 data blocks, 4k cards would return 54 data blocks (not implemented) + sendFDcmd_set(0,28,0, dataBlockNumber,0,0,0); // 1st data = card sequence =blk nr (0...15) + +} + + + +void hwapi::request_MDB_Status() const +{ + sendFDcmd_set(0,CMD2DC_MDB_GET_STATE,0,0,0,0,0); + +} + +//void hwapi::request_MDB_wakeInLine() const +//{ +// sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETWAK); +//} + +void hwapi::request_MDB_lastResponse() const +{ + sendFDcmd_set(0,CMD2DC_MDB_GETRESP,0,0,0,0,0); + +} + +void hwapi::request_EMP_allParameters() const +{ + sendFDcmd_set(0,CMD2DC_EMP_GET_ALL,0,0,0,0,0); + +} + +void hwapi::request_EMP_lastCoin() const +{ + sendFDcmd_set(0,CMD2DC_EMP_GOTCOIN,0,0,0,0,0); +} + + + +// ------------------------------------------------------------------------------ +// readback digital outputs of connected devices +// these functions are not needed for normal operation +// but can be used to test and verify conditions +// ------------------------------------------------------------------------------ + +bool hwapi::test_getDO_mdbRXtst(void) const +{ + return epi_getDO_mdbRxTestOut(); +} + +uint8_t hwapi::lock_getDO_motors(void) const +{ + // bit0: upper lock forward bit 1 backward + // bit2: lower lock forward bit 3 backward + + return epi_getDO_motorOuts(); +} + +uint8_t hwapi::test_serialState(void) const +{ + // test on-board signals for the serials + // serial drv on/off, Serial mux1, Serial mux2 + + uint8_t ret=epi_getDO_serialSwitch(); + // serial drv on/off, Serial mux1, Serial mux2 + ret &=0x07; + return ret; +} + +bool hwapi::test_serialIsOn(void) const +{ + return epi_getDO_serialDriverIsOn(); +} + +bool hwapi::test_serialMux1isSetToPrinter(void) const +{ + return epi_getDO_serialMux1isSetToPrinter(); + // mux1 off: serial is switched to printer +} + +bool hwapi::test_serialMux1isSetToModem(void) const +{ + return epi_getDO_serialMux1isSetToModem(); + // mux1 on: serial is switched to modem +} + +bool hwapi::test_serialMux2isSetToCredit(void) const +{ + return epi_getDO_serialMux2isSetToCredit(); + // mux2 off: serial is switched to credit card terminal +} + +bool hwapi::test_serialMux2isSetToMifare(void) const +{ + return epi_getDO_serialMux2isSetToMifare(); + // mux2 on: serial is switched to mifare reader +} + +bool hwapi::led_coinIsOn(void) const +{ + return epi_getDO_led_coin(); +} + +bool hwapi::led_frontIsOn(void) const +{ + return epi_getDO_led_front(); +} + +bool hwapi::led_ticketIsOn(void) const +{ + return epi_getDO_led_ticket(); +} + +bool hwapi::led_pinIsOn(void) const +{ + return epi_getDO_led_pin(); +} + +bool hwapi::led_StartIsOn(void) const +{ + return epi_getDO_led_start(); +} + +bool hwapi::led_insideIsOn(void) const +{ + return epi_getDO_led_inside(); +} + +bool hwapi::fan_isOn(void) const +{ + return epi_getDO_fan(); +} + +bool hwapi::siren_isOn(void) const +{ + return epi_getDO_sirene(); +} + +bool hwapi::bar_relayIsOn(void) const +{ + return epi_getDO_relay(); +} + +bool hwapi::ptu_WakeOutIsOn(void) const +{ + return epi_getDO_ptuWake(); +} + +bool hwapi::aux_powerIsOn(void) const +{ + return epi_getDO_auxPower(); +} + + +bool hwapi::coin_shutterIsOpen(void) const +{ + return epi_getDO_coinShutterOpen(); +} + +bool hwapi::coin_shutterTestOutput(void) const +{ + return epi_getDO_coinShutterTest(); +} + +uint8_t hwapi::coin_escrowFlapOpened(void) const +{ + // retval: 1:return flap is open 2:take flap is open 0:closed + + return epi_getDO_coinEscrow(); +} + + + +// ------------------------------------------------------------------------------ +// devices are operated by DC +// processes with more then one devices +// timer controlled or long term processes +// ------------------------------------------------------------------------------ + +void hwapi::sendDeviceSettings(uint8_t kindOfPrinter, uint8_t kindOfCoinChecker, + uint8_t kindOfMifareReader, uint8_t suppressSleep, + uint8_t kindOfModem, uint8_t kindOfCredit) const +{ + uint8_t buf[64]; + + tslib_strclr(buf,0,64); + buf[0]=kindOfPrinter; + buf[1]=kindOfCoinChecker; + buf[2]=kindOfMifareReader; + buf[3]=suppressSleep; + buf[4]=kindOfModem; + buf[5]=kindOfCredit; + + longFDcmd_set(CMD2DC_DEVICE_PARAM, 0, 0, 6, buf); +} + +void hwapi::request_ReadbackDeviceSettings() const +{ + sendFDcmd_set(0,CMD2DC_RDBK_DEV_PARA,0,0,0,0,0); +} + + +void hwapi::readback_DeviceSettings(uint8_t *length, uint8_t *data) const +{ + + epi_restoreRbDeviceSettings(length, data); +/* + buf66[0]=devPara.kindOfPrinter; + buf66[1]=devPara.kindOfCoinChecker; + buf66[2]=devPara.kindOfMifareReader; + buf66[3]=devPara.suppressSleepMode; + buf66[4]=devPara.kindOfModem; + buf66[5]=devPara.kindOfCreditcard; + buf66[6]=devPara.CoinEscrow; + buf66[7]=devPara.CoinRejectUnit; + buf66[8]=devPara.CoinShutter; + buf66[9]=devPara.BillAcceptor; + buf66[10]=devPara.usevaultLock; + buf66[11]=devPara.autoAlarm; + buf66[12]=devPara.autoOpen; + buf66[13]=devPara.printAccReceipt; + buf66[14]=devPara.printDoorReceipt; + buf66[15]=devPara.printTokenTicket; + uitmp=devPara.VaultFullWarnLevel; + buf66[16]=swl_getOneByteFromUint(uitmp, GETLOWBYT); + buf66[17]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); + uitmp=devPara.VaultFullErrorLevel; + buf66[18]=swl_getOneByteFromUint(uitmp, GETLOWBYT); + buf66[19]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); + +*/ +} + +// .................................................................................... + +void hwapi::sendMachineID(uint16_t customerNr, uint16_t machineNr, + uint16_t borough, uint16_t zone, + uint16_t alias, char *location) const +{ + uint8_t buf[64]; + + tslib_strclr(buf,0,64); + buf[0]=uint2uchar(customerNr, LOWBYTE); + buf[1]=uint2uchar(customerNr, HIGHBYTE); + buf[2]=uint2uchar(machineNr, LOWBYTE); + buf[3]=uint2uchar(machineNr, HIGHBYTE); + buf[4]=uint2uchar(borough, LOWBYTE); + buf[5]=uint2uchar(borough, HIGHBYTE); + buf[6]=uint2uchar(zone, LOWBYTE); + buf[7]=uint2uchar(zone, HIGHBYTE); + buf[8]=uint2uchar(alias, LOWBYTE); + buf[9]=uint2uchar(alias, HIGHBYTE); + tslib_strcpy(location, &buf[10], 32); + + longFDcmd_set(CMD2DC_SEND_MACH_ID,0,0,42,buf); + +} + +void hwapi::request_ReadbackMachineID() const +{ + sendFDcmd_set(0,CMD2DC_RDBK_MACH_ID,0,0,0,0,0); +} + + +void hwapi::readback_machineIDdata(uint8_t *length, uint8_t *data) const +{ + epi_restoreMachineIDsettings(length, data); +} + + +// .................................................................................... + + + + + +static uint16_t hwapi_shutterTime; + +// locks, 2.Level: (Motor stops automatical on end switch or by 5s timeout) +uint8_t hwapi::lock_openUpperDoor(void) const +{ + // paras: dat2: 1=upper door lock 2=lower + // dat1: 1=open 2=close + sendFDcmd_set(CMD2DC_UPPER_DOOR,0,0,1,0,0,0); + return 0; +} + + +uint8_t hwapi::lock_closeUpperDoor(void) const +{ + sendFDcmd_set(CMD2DC_UPPER_DOOR,0,0,2,0,0,0); + return 0; +} + +uint8_t hwapi::lock_openLowerDoor(void) const +{ + sendFDcmd_set(CMD2DC_LOWER_DOOR,0,0,1,0,0,0); + return 0; +} + +uint8_t hwapi::lock_closeLowerDoor(void) const +{ + sendFDcmd_set(CMD2DC_LOWER_DOOR,0,0,2,0,0,0); + return 0; +} + +void hwapi::shut_openOnce(void) const +{ + // and close automatic after shutter time + uint16_t zeit=hwapi_shutterTime; + zeit/=100; + sendFDcmd_set(CMD2DC_SHUTTER_OPEN3S, 0,0,uint8_t(zeit) ,0,0,0); +} + +void hwapi::shut_openForCoin(bool start) const +{ + // start=true: start opening flap if coin is attached + // start=false: stop process + + uint16_t zeit=hwapi_shutterTime; + zeit/=100; + sendFDcmd_set(CMD2DC_SHUTTER_COIN, 0,0,uint8_t(start), uint8_t(zeit),0,0); +} + +void hwapi::shut_sendOpeningTime(uint16_t timeIn_ms ) const +{ + // after this time without retrigger the flap is closed + hwapi_shutterTime=timeIn_ms; + +} + + +void hwapi::esc_takeMoney(void) const +{ + // and close automatically after escrow time (1s) + sendFDcmd_set(CMD2DC_ESCR_TAKE,0,0,0,0,0,0); +} + +void hwapi::esc_returnMoney(void) const +{ + // and close automatically after time + sendFDcmd_set(CMD2DC_ESCR_RETURN,0,0,0,0,0,0); +} + + + + + + + +// ---------------------------------------------------------------------------------------------------------- +// --------------------------------------------- MIFARE ----------------------------------------------------- +// ---------------------------------------------------------------------------------------------------------- + +// fixed, 8.9.23 +uint8_t hwapi::mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const +{ + // retval 0=OK 1=error + if (maxBufferSize<64) + return 0; + epi_restoreMifHwData(buf, 64); + return 0; +} + +bool hwapi::mif_readerIsOK(void) const +{ + // return true if mifare reader is power, serial connected and is the correct one + uint8_t mifData[66]; + + epi_restoreMifHwData(mifData, 66); + /* stand 8.9.23 + struct T_Mifare + { + UCHAR ReaderState; // 1: OK 0: not OK + UCHAR res1; + 2: UCHAR ReaderVersion[10]; + 12: UCHAR CardPresent; + UCHAR CardSelected; + UCHAR Cardtype; + UCHAR CardAllowed; // 0,1 nur Mifare Classic 1k und 4k zugelassen + UCHAR CardSize; // 1 or 4 (kB) + UCHAR LengOfUid; // 4 or 7 (byte) + 18: UCHAR UID[8]; // 4 byte oder 7 byte, Format binär + // 26 byte bis hier + UCHAR res2; + UCHAR res3; + 28: ULONG UidH; // bei 4byte Uid alles 0 + ULONG UidL; + 36: UCHAR SectorLogged; // result of loggin: 2=success 3=failed 1=no_tag 8=addr overflow F0=wrongCmd + UCHAR CurrentSector; + UCHAR RD_WR_Result; + UCHAR res4; + // 40byte lang + }; + */ + + if (mifData[0]==0) + return false; + + // Type=currently "SL025-1.8" + if (mifData[2]=='S' && mifData[3]=='L' && mifData[4]=='0' && mifData[5]=='2' && mifData[6]=='5' ) + return true; + + return false; +} + +bool hwapi::mif_cardAttached(void) const // gefixt am 8.9.23 +{ + return mif_cardIsAttached(); +} + +uint8_t hwapi::mif_readResult(void) const // geht nicht +{ + // 1: read card successful 0: not + uint8_t mifData[66]; + + epi_restoreMifHwData(mifData, 66); + /* stand 8.9.23 + struct T_Mifare + { + UCHAR ReaderState; // 1: OK 0: not OK + UCHAR res1; + 2: UCHAR ReaderVersion[10]; + 12: UCHAR CardPresent; + UCHAR CardSelected; + UCHAR Cardtype; + UCHAR CardAllowed; // 0,1 nur Mifare Classic 1k und 4k zugelassen + UCHAR CardSize; // 1 or 4 (kB) + UCHAR LengOfUid; // 4 or 7 (byte) + 18: UCHAR UID[8]; // 4 byte oder 7 byte, Format binär + // 26 byte bis hier + UCHAR res2; + UCHAR res3; + 28: ULONG UidH; // bei 4byte Uid alles 0 + ULONG UidL; + 36: UCHAR SectorLogged; // result of loggin: 2=success 3=failed 1=no_tag 8=addr overflow F0=wrongCmd + UCHAR CurrentSector; + UCHAR RD_WR_Result; + UCHAR res4; + // 40byte lang + }; + */ + + if (mifData[12]>0 && mifData[15]>0 && (mifData[16]==1 || mifData[16]==4) && (mifData[17]==4 || mifData[17]==7)) + return 1; + return 0; // error +} + + +QString hwapi::mif_cardUID(void) const // OK +{ + // new, 8.9.23, works + QString myStr; + uint8_t mifData[66]; + + epi_restoreMifHwData(mifData, 66); + + myStr.clear(); + // UID in buf[18...25] + for (int ii=0;ii<8; ii++) + { + + myStr+=QString::number(mifData[ii+18],16); + myStr+=" "; // make a gap between numbers + } + return myStr; +} + + +uint8_t hwapi::mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const +{ + // come in with cmd 28 + return blkNr+buf[0]+maxBufferSize; // just to get rid of warning +} + +QString hwapi::mif_getCardDataStr(uint8_t blockNumber) const +{ + // come in with cmd 28 + // with blockNumber=0...11 + QString myStr; + myStr.clear(); + if (blockNumber>11) + return myStr; + else + return myStr; +} + + +// ---------------------------------------------------------------------------------------------------------- +// --------------------------------------------- PRINTER ---------------------------------------------------- +// ---------------------------------------------------------------------------------------------------------- + +// already above: +// void hwapi::prn_switchPower(bool on) 0x2A01 +// bool hwapi::prn_readyINisActive(void) +// bool hwapi::prn_isPrinterPowerOn(void) +// void hwapi::request_PrinterHwState() 0x2A02 +// void hwapi::request_PrinterCurrentFonts() 0x2A12 +// void hwapi::request_PrinterStateComplete() // =request_PrinterHwState + request_PrinterCurrentFonts + +uint8_t hwapi::prn_getHwState(struct Tprn_hw_state *prn_hw_state) const +{ + // return printer hardware state: power is on? rs-driver on? rs_switch ok? hw-ready-line ok? + // printer on error or ok? + + return runProcess->prn_getHwState(prn_hw_state); + +} + +bool hwapi::prn_isUpAndReady(void) const +{ + // 25.5.2023: geht nicht richtig :( bringt immer false obwohl Drucker OK + struct Tprn_hw_state prnHwNow; + + prn_getHwState(&prnHwNow); + if (prnHwNow.inIdle && prnHwNow.rsSwOk && prnHwNow.rsDrvOk && prnHwNow.powerRdBk ) + return true; + return false; +} + +void hwapi::prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const +{ + uint8_t prnFonts[22]; + + epi_restorePrinterFonts(&prnFonts[0]); + prn_fonts->currFont = prnFonts[0]; + prn_fonts->currSize = prnFonts[1]; + prn_fonts->currHeigth= prnFonts[2]; + prn_fonts->currWidth = prnFonts[3]; + prn_fonts->nowBold = prnFonts[4]; + prn_fonts->nowInvers = prnFonts[5]; + prn_fonts->nowUnderlined= prnFonts[6]; + prn_fonts->currDensity = prnFonts[7]; + prn_fonts->currSpeed = prnFonts[8]; + prn_fonts->nowAligned = prnFonts[9]; + +} + + +void hwapi::prn_sendText(QByteArray *buf) const +{ + uint16_t nn, pp, mm, leng_byt, leng_blk, llb, freeStak; + uint8_t tmp66[66]; + + epi_clearDynMachineConditions(); // 24.6.23 + gpi_storeDcDataValid(0); + + // komplett aendern 11.9.23 + memset(tmp66,0,66); + leng_byt=buf->size(); + freeStak=check4freeFDstack(); + freeStak<<=6; + if ( leng_byt > freeStak) + { + leng_byt=freeStak; // shorten the buffer as we cannot return an error (void function) + } + llb=leng_byt % 64; // length of last block, >0 if not dividable by 64 + leng_blk=leng_byt / 64; + + pp=0; + for (nn=0; nnat(pp++); + longFDcmd_set(CMD2DC_PRI_PRINT_TXT, 0,0,64, tmp66); + } + + if (llb>0) + { + + //leng_blk++; // z.B. 200 = 3 volle blocks und ein block mit nur 8byte + memset(tmp66,0,66); + for (mm=0; mmat(pp++); + for (mm=llb; mm<64; mm++) + tmp66[mm]=0; + longFDcmd_set(CMD2DC_PRI_PRINT_TXT, 0,0,64, tmp66); + } + +} + + +void hwapi::prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const +{ + // send three byte through to printer, see printers manual + //sendWRcmd _setSendCommand8(SENDDIRCMD_PRN_SYS_CMD, para1, para2, 0, para3); hat gar nicht funktioniert + + uint8_t data[64]; + uint32_t ultmp=para3; + memset(data, 0,64); + data[0]=para1; + data[1]=para2; + data[2]=0; + data[3]=0; + data[4]=uint8_t(ultmp); ultmp>>=8; + data[5]=uint8_t(ultmp); ultmp>>=8; + data[6]=uint8_t(ultmp); ultmp>>=8; + data[7]=uint8_t(ultmp); + + longFDcmd_set(CMD2DC_PRI_SYS_CMD, 0, 0, 8, data); +// getestet auf richtige uebertragung am 11.9.23TS + +} + +void hwapi::prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const +{ + // send four byte through to printer, see printers manual + sendFDcmd_set(CMD2DC_PRI_ESC_CMD, 0,0, para1, para2, para3, para4); +} + +void hwapi::prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density, uint8_t alignment, uint8_t orientation) const +{ + // send 5 byte: byte 0,1: speed 5...250 mm/s + // byte2: density 0....(25)....50 + // byte3: alignment 'l', 'c', 'r' = left, center, right + // byte4: orientation 0, 90, 180 = 0°, 90°, 180° rotation (by now not supported!) + // not batched! don't use twice within 100ms + + uint8_t buf[10]; + uint16_t uitmp; + + uitmp=paperSpeed; + buf[0]=uint8_t(uitmp); + uitmp>>=8; + buf[1]=uint8_t(uitmp); + buf[2]=density; + buf[3]=alignment; + buf[4]=orientation; + buf[5]=0; + longFDcmd_set(CMD2DC_PRI_SETUP,0,0,5, buf); + +} + +void hwapi::prn_movePaper(uint8_t wayInMm, uint8_t direction) const +{ + //direction: 1=forward 2=backward + sendFDcmd_set(CMD2DC_PRI_MOVE, 0,0, wayInMm, direction, 0,0); +} + + +void hwapi::prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const +{ + // font = kind of font 0...8 + // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge + // width: 0...4 0=1x 1=2x 2=4x (huge!) 3=8x 4=16x (3,4 make no sense) + // heigth: 0...7 = 1x...8x only 0,1,2,(3) make sense + sendFDcmd_set(CMD2DC_PRI_SETFONT, 0,0, font, size, width, height); +} + + +void hwapi::prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const +{ + sendFDcmd_set(CMD2DC_PRI_SETLETTER, 0, 0, bold, invers, underlined, 0); +} + +void hwapi::prn_cut(uint8_t kindof) const +{ + // kindof = 1: full cut 2: partial cut 3=eject (5xLF + full cut) + sendFDcmd_set(CMD2DC_PRI_CUT, 0,0, kindof,0,0,0); +} + +void hwapi::prn_newLine(uint8_t nrOfLines) const +{ + sendFDcmd_set(CMD2DC_PRI_LF, 0,0, nrOfLines, 0, 0, 0); +} + +void hwapi::prn_printCompleteFontTable(void) const +{ + sendFDcmd_set(CMD2DC_PRI_PRIFONTTABLE,0,0,0,0,0,0); +} + + +void hwapi::prn_printBarcode(uint8_t kindOf, uint8_t withText, uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const +{ + uint8_t buf[66], nn; + //uint16_t uitmp; + + if (dataLeng>58) + dataLeng=58; + + buf[0]=kindOf; + buf[1]=withText; + buf[2]=offset; + buf[3]=rotation; + buf[4]=dataLeng; + // rest: Barcode-data: + for (nn=0; nnclear(); +} + +void hwapi::prn_printQRcode(void) const +{ + // which was sent before + sendFDcmd_set(CMD2DC_PRI_QR_CODE,0,0,0,0,0,0); +} + +void hwapi::prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const +{ + sendFDcmd_set(CMD2DC_PRI_LOGOFROMFLASH, 0,0, nrOfLogo, offset, 0, 0); +} + + +// ......................................................... +// Parking Ticket (print out) designer - obsolete +// ......................................................... +/* +static QByteArray ticketTemplate; + +void hwapi::pri_startTicketDesign(void) const +{ + ticketTemplate.clear(); + +} + +int hwapi::pri_TD_getCurrentSize(void) const +{ + return ticketTemplate.size(); +} + +bool hwapi::pri_TD_addText(QByteArray text) const +{ + if ((ticketTemplate.length() + text.length())>1278) + return false; + ticketTemplate.append(text); + qDebug()<<"\nText added "<1266) + return false; + ticketTemplate.append(tmpStr); + return true; +} +*/ + +//bool hwapi::pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const +//{ + // always add 8 byte to the ticket layout: ESC & group & attribute & parameter1...5 + +/* + char tmpStr[10]; + + // command has always fixed length of 8 byte + if (ticketTemplate.length()>1270) + return false; + if (group<50 || group>59) + return false; + if (attribute<10 || attribute>30) + return false; + + tmpStr[0]=0x1B; // ESC + tmpStr[1]=group; + tmpStr[2]=attribute; + tmpStr[3]=p1; + tmpStr[4]=p2; + tmpStr[5]=p3; + tmpStr[6]=p4; + tmpStr[7]=p5; + + ticketTemplate.append(tmpStr, 8); + + + qDebug()<<"\ncmd added "<1277) + return false; + ticketTemplate.append("\n"); + return true; +} + +bool hwapi::pri_TD_addSign(char sign) const +{ + if (ticketTemplate.length()>1277) + return false; + ticketTemplate.append(sign); + return true; +} + + +char hwapi::prn_clearDocument(uint8_t documentNumber) const +{ + if (documentNumber>15) + return false; + sendWRcmd_ setSendCommand4(SENDDIRCMD_PRN_CLEARDOC, documentNumber, 0, 0, 0); + CMD2DC_PRI_CLEAR_DOC + return true; +} + + +bool hwapi::prn_store_Document(uint8_t documentNumber ) const +{ + // send to DC + // documentNumber=0...15, stored in Eeprom + // maximal 1280 bytes each + // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc) + // 0x1B=start of embedded command (next 7bytes = command) + + if (documentNumber>15) + return false; + sub_storeSendingText(&ticketTemplate); + epi_storeUserOfSendingTextBuffer(3,documentNumber,0,0,0); // 3=store document + + + return true; +} + + +bool hwapi::prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const +{ + if (documentNumber>15) + return false; + epi_store64ByteSendData(64, &(dynTicketData->licensePlate[0])); + sendWRcmd_ setSendCommand4(SENDDIRCMD_PRN_DOC, documentNumber, 0, 0, 0); + return true; +} + +*/ + + + + +// ---------------------------------------------------------------------------------------------------------- +// ------------------------------------------- MDB Bus ------------------------------------------------------ +// ---------------------------------------------------------------------------------------------------------- + + + +void hwapi::mdb_sendBusReset(void) const +{ + //sendWRcmd_ setSendCommand4(SENDDIRCMD_MDB_RES, 0,0,0,0); + sendFDcmd_set(CMD2DC_MDB_DORESET, 0,0, 0,0,0,0); + +} + +#define mdb_device_coinChk 0 +#define mdb_device_changer 1 +#define mdb_device_bill 2 +//#define mdb_device_credit 3 // obsolete + + +void hwapi::mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const +{ + //sendWRcmd _setSendCommand4(SENDDIRCMD_MDB_SENDCMD, toMdbDevice, mdbCommand, 0,0); + sendFDcmd_set(CMD2DC_MDB_SENDCMD, 0,0, toMdbDevice, mdbCommand, 0,0); +} + +void hwapi::mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const +{ + // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs + uint8_t myBuf[64], ii; + + tslib_strclr(myBuf, 0, 64); + myBuf[0]=toMdbDevice; + myBuf[1]=mdbCommand; + if (nrOfData>34) nrOfData=34; + myBuf[2]=nrOfData; + for (ii=0; ii>=8; + myBuf[1]=uint8_t (uitmp); + myBuf[2]=tokenChannel; + pp=3; + for (ii=0; ii<16; ii++) + { + uitmp=coinDenomination[ii]; + myBuf[pp]=uint8_t(uitmp); + uitmp>>=8; + myBuf[pp+1]=uint8_t(uitmp); + pp+=2; + } + longFDcmd_set(CMD2DC_EMP_SET,0,0,35, myBuf); + +} + +void hwapi::emp_pollingOnOff(uint8_t on) const +{ + // on: 1=start polling the coin accepter 0=stop + sendFDcmd_set(CMD2DC_EMP_STARTPOLL, 0,0, on,0,0,0); +} + +void hwapi::emp_startCoinAcceptance(void) const +{ + sendFDcmd_set(CMD2DC_EMP_STARTPAY, 0,0, 0,0,0,0); +} + +void hwapi::emp_stopCoinAcceptance(void) const +{ + sendFDcmd_set(CMD2DC_EMP_STOPPAY, 0,0, 0,0,0,0); +} + + + +void hwapi::emp_getAllParameters(struct T_emp *emp) const +{ + uint8_t leng, data[66], ii, pp; + epi_restoreEmpSettings(&leng, data); // expected length = 64 byte + + // get 64 bytes about EMP: see h-file + + emp->gotSetup = data[0]; + emp->state = data[1]; + emp->shaft = data[2]; + emp->countryCode= uchar2uint(data[4], data[3]); + emp->scale = data[5]; + emp->decimals = data[6]; + for (ii=0; ii<16; ii++) + emp->coinValues[ii] = data[7+ii]; + emp->coinAccept = uchar2uint(data[24], data[23]); + emp->tokenChannel = data[25]; + emp->pollingRunning = data[26]; + emp->paymentRunning = data[27]; + + pp=28; + for (ii=0; ii<16; ii++) + { + emp->denomination[ii] = uchar2uint(data[pp+1], data[pp]); + pp+=2; + } + emp->routing= uchar2uint(data[61], data[60]); + +} + +uint8_t hwapi::emp_chkIfCoinInserted(void) const +{ + // retval: 0...16 coins left in FIFO + return epi_isNewCoinLeft(); +} + + +void hwapi::emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const +{ + + epi_restoreEmpCoinSignal(valid, signal, error, value); + +} + + +uint8_t hwapi::emp_giveLastCoin(uint16_t *value, uint8_t *signal) const +{ + // retval: 0: NO coin stored 1: valid coin 2: got wrong coin or coin denied + // value: if retval1: value of the coin if reval=2: error number + // signal: channel nr reported from checker + + uint8_t valid, chan, error; + uint16_t wert; + + epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert); + + if (valid && error==0xFF ) + { + *value=wert; + *signal=chan; + return 1; + } + + if (valid && error<0xFF ) + { + *value=error; + *signal=chan; // normally 0, but sometimes we get both + return 2; + } + return 0; +} + + +uint8_t hwapi::emp_returnLastCoin(uint16_t *value, uint8_t *signal) const +{ + // use this for coin changer + + uint8_t valid, chan, error; + uint16_t wert; + + epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert); + + if (error) + { + *value=0; + *signal=error; + return 0; + } + *value=wert; + *signal=chan; + return valid; +} + + + +QString hwapi::dc_getTxt4RsDiagWin(void) const +{ +#ifdef THIS_IS_CA_MASTER + return epi_getTxt4RsDiagWin(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif + +} + +void hwapi::dc_clrTxt4RsDiagWin(void) const +{ +#ifdef THIS_IS_CA_MASTER + + epi_clrTxt4RsDiagWin(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + +#endif +} + +QString hwapi::dc_get2ndTxt4RsDiagWin(void) const +{ +#ifdef THIS_IS_CA_MASTER + return epi_get2ndTxt4RsDiagWin(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif +} + +void hwapi::dc_clr2ndTxt4RsDiagWin(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_clr2ndTxt4RsDiagWin(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + +#endif +} + +QString hwapi::dc_getTxt4HsStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + // Crash! + return epi_getTxt4HsStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif +} + +void hwapi::dc_clrTxt4HsStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_clrTxt4HsStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + +#endif +} + + +QString hwapi::dc_getTxt4masterStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + return epi_getTxt4masterStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif +} + +void hwapi::dc_clrTxt4masterStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_clrTxt4masterStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + +#endif +} + +QString hwapi::dc_getTxt4resultStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + return epi_getTxt4resultStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif +} + +void hwapi::dc_clrTxt4resultStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_clrTxt4resultStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + +#endif +} + +QString hwapi::dc_getdataStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + return epi_getTxt4dataStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif +} + +void hwapi::dc_clrTxt4dataStateLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_clrTxt4dataStateLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + +#endif +} + + +QString hwapi::dc_getdatifLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + return epi_getTxt4datifLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; + return ""; +#endif +} + +void hwapi::dc_clrTxt4datifLine(void) const +{ +#ifdef THIS_IS_CA_MASTER + epi_clrTxt4datifLine(); +#else + qCritical()<<"hwapi: error CAslave cannot use serial"; +#endif +} + + + + +// ---------------------------------------------------------------------------------------------------------- +// -------- DC Bootloader 1.Version // obsolete +// ---------------------------------------------------------------------------------------------------------- + +// obsolete +void hwapi::bl_iniChain(void) const +{ +} + +// obsolete +bool hwapi::bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const +{ + // copy file from QByteArray into local buffer for sending to DC + // calculate size, nr_of_blocks and crc + // just for special usage + return dcBL_importBinFile(readBinFile, fileSize, withDispl); +} + +// obsolete +uint8_t hwapi::bl_activatBootloader(uint8_t *sendData) const +{ + //return dcBL_activatBootloader(sendData); + // just for special usage + return sendData[0]; +} + +// obsolete +uint8_t hwapi::bl_startChain(void) const +{ + // obsolete + //return dcBL_startChain(); + return 0; +} + +// obsolete +uint8_t hwapi::bl_readBLversion(uint8_t *sendData) const +{ + // minimum size of sendData-buffer: 5byte retval: length + // just for special usage + return dcBL_readBLversion(sendData); + +} + +// obsolete +uint8_t hwapi::bl_readFWversion(uint8_t *sendData) const +{ + // minimum size of sendData-buffer: 5byte retval: length + return dcBL_readFWversion(sendData); +} + +// obsolete +uint8_t hwapi::bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const +{ + // just for very special usage + // make BL protocol, retval = outbuf length (5...133) + // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum + // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 + // Data length = 0...64 + // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 + // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + + return dcBL_prepareDC_BLcmd(Cmd, SendDataLength, sendData, outBuf); +} + +// obsolete +uint8_t hwapi::bl_exitBL(uint8_t *sendData) const +{ + // returns command to be sent to DC-BL in order to stop the BL + // just for very special usage + // minimum size of sendData-buffer: 5byte retval: length + return dcBL_exitBL(sendData); +} + +// obsolete +void hwapi::led_switchLedIllumination(uint8_t on) const +{ + sendFDcmd_set(CMD2DC_LED_IN, CMD2DC_RdBkAllOutputs, 0, on, 0, 0, 0); +} + + + +// ------------------------------------------------------------------------------------ +// 27.3.2023: Use Device-Controller's Bootloader to send hex-file +// ------------------------------------------------------------------------------------ + +void hwapi::bl_rebootDC(void) const // tested 26.09.2023 +{ + // send command to normal DC-Program requesting a restart + // BL is working for 5s after power-on-reset. + runProcess->bl_rebootDC(); + +} + +void hwapi::bl_startBL(void) const // tested 26.09.2023 +{ + // use this function within the first 5s after reboot to startup the BL, + // otherwise the BL jumps to normal DC application + runProcess->bl_startBL(); + +} + +void hwapi::bl_checkBL(void) const // tested 26.09.2023 +{ + // call this function in order to get information, afterwards use "bl_isUp()" + runProcess->bl_checkBL(); + +} + +bool hwapi::bl_isUp(void) const // tested 26.09.2023 +{ + return runProcess->bl_isUp(); +} + +// obsolete, better use auto function listed further down +void hwapi::bl_sendAddress(uint16_t blockNumber) const +{ + // send start address, nr of 64byte-block, start with 0 + // will be sent only for folling block-numbers: + // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte + uint32_t dcBL_BlkCtr=(uint32_t)blockNumber; + uint8_t len, buf[20]; + + tslib_strclr(buf, 0, 20); + if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096) + { + dcBL_BlkCtr*=64; + len=dcBL_sendFlashStartAddr2BL(dcBL_BlkCtr, buf); // make command string + // minimum size of sendData-buffer: 13byte retval: length (9...13) + sendWRcmd_setSendBlock160(len, buf); // send command to BL + } +} + +// obsolete, better use auto function listed further down + +uint8_t hwapi::bl_wasSendingAddOK(void) const +{ + // return val: 0: no response by now 1:error 10: OK + + return dcBL_sendSuccess(0x21); +} + + +void hwapi::bl_openBinary(void) const +{ + +} + +// obsolete, better use auto function listed further down +void hwapi::bl_sendDataBlock(uint8_t length, uint8_t *buffer) const +{ + // send 64 byte from bin file + uint8_t LL=length, sendBuf[80], sendLen; + if (LL>64) LL=64; + + tslib_strclr(sendBuf,0,80); + sendLen=dcBL_prepareDC_BLcmd(0x22, LL, buffer, sendBuf); // pack into protocol frame + sendWRcmd_setSendBlock160(sendLen, sendBuf); // send 140 bytes + delay(100); +} + +// obsolete, better use auto function listed further down +void hwapi::bl_sendLastBlock(void) const +{ + uint8_t len, buf[20]; + + len=dcBL_writeLastPage(buf); + sendWRcmd_setSendBlock160(len, buf); +} + +// obsolete, better use auto function listed further down +uint8_t hwapi::bl_wasSendingDataOK(void) const +{ + // return val: 0: no response by now 1:error 10: OK + + return dcBL_sendSuccess(0x22); + +} + + +void hwapi::bl_stopBL(void) const // tested 26.09.2023 +{ + uint8_t len, buf[20]; + + len=dcBL_exitBL(buf); + sendWRcmd_setSendBlock160(len, buf); + epi_setNowIsBootload(false); +} + + +// ------------------------------------------------------------------------------------ +// 6.4.2023: new functions for coin collection and printing +// some new system functions +// ------------------------------------------------------------------------------------ + +// use: +// bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4); + // write Command to memory, wait for transport + +// bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data); + // write Command to memory, wait for transport + // data buffer size always 64! data[64], padded with 0 + +bool hwapi::rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const +{ + // return true if successful. could fail if more the 8 commands are waiting + + uint8_t temp[66]; + bool b_ret; + /* in interfaces.h: + struct Trtc_DateTime + { + uint8_t rtc_hour; + uint8_t rtc_min; + uint8_t rtc_sec; + uint8_t rtc_dayOfMonth; + uint8_t rtc_month; + uint8_t rtc_year; + uint8_t rtc_dayOfWeek; + }; + */ + tslib_strclr(temp,0,66); + temp[0]= DateTime->rtc_hour; + temp[1]= DateTime->rtc_min; + temp[2]= DateTime->rtc_sec; + temp[3]= 20; + temp[4]= DateTime->rtc_year; + temp[5]= DateTime->rtc_month; + temp[6]= DateTime->rtc_dayOfMonth; + temp[7]= DateTime->rtc_dayOfWeek; + b_ret=longFDcmd_set(20,0,0,8,temp); + return b_ret; +} + +bool hwapi::rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const +{ + epi_restoreExtendedTime(leng, data); + return true; + +/* + buf[0]=GlobTime.Hours; + buf[1]=GlobTime.Min; + buf[2]=GlobTime.Sec; + buf[3]=GlobTime.Year; + buf[4]=GlobTime.Month; + buf[5]=GlobTime.Day; + buf[6]=GlobTime.DOW; + buf[7]=' '; // immer auf 32bit auffüllen sonst Speicherproblem beim Master! + uitmp=GlobTime.MinOfDay; + buf[8]=swl_getOneByteFromUint(uitmp, 0); + buf[9]=swl_getOneByteFromUint(uitmp, 1); + buf[10]=' '; + buf[11]=' '; + ultmp=GlobTime.SecOfDay; + buf[12]=swl_getOneByteFromUlong(ultmp, 0); + buf[13]=swl_getOneByteFromUlong(ultmp, 1); + buf[14]=swl_getOneByteFromUlong(ultmp, 2); + buf[15]=swl_getOneByteFromUlong(ultmp, 3); + + buf[16]=swl_isLeap(GlobTime.Year); + buf[17]=swl_getNextLeapYear(GlobTime.Year); + buf[18]=swl_getLastLeapYear(GlobTime.Year); + buf[19]=swl_hoursOfThisWeek(GlobTime.DOW, GlobTime.Hours); + + uitmp=swl_minutesOfThisWeek(GlobTime.DOW, GlobTime.Hours, GlobTime.Min); + buf[20]=swl_getOneByteFromUint(uitmp, 0); // 0=low byte 1=high byte + buf[21]=swl_getOneByteFromUint(uitmp, 1); + + uitmp=swl_hoursOfThisMonth(GlobTime.Day, GlobTime.Hours); + buf[22]=swl_getOneByteFromUint(uitmp, 0); + buf[23]=swl_getOneByteFromUint(uitmp, 1); + + uitmp=swl_minutesOfThisMonth(GlobTime.Day, GlobTime.Hours, GlobTime.Min); + buf[24]=swl_getOneByteFromUint(uitmp, 0); + buf[25]=swl_getOneByteFromUint(uitmp, 1); + + uitmp=swl_GetDaysOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day); + buf[26]=swl_getOneByteFromUint(uitmp, 0); + buf[27]=swl_getOneByteFromUint(uitmp, 1); + + uitmp=swl_GetHoursOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day, GlobTime.Hours); + buf[28]=swl_getOneByteFromUint(uitmp, 0); + buf[29]=swl_getOneByteFromUint(uitmp, 1); + buf[30]=0; + buf[31]=0; + ultmp= swl_GetMinutesOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day, + GlobTime.Hours, GlobTime.Min); + buf[32]=swl_getOneByteFromUlong(ultmp, 0); + buf[33]=swl_getOneByteFromUlong(ultmp, 1); + buf[34]=swl_getOneByteFromUlong(ultmp, 2); + buf[35]=swl_getOneByteFromUlong(ultmp, 3); + + buf[36]=rtc_getSqwaveSettings(); + buf[37]=0; + buf[38]=0; + buf[39]=0; + + ultmp= 0; // Minutes of the Millenium + buf[40]=swl_getOneByteFromUlong(ultmp, 0); + buf[41]=swl_getOneByteFromUlong(ultmp, 1); + buf[42]=swl_getOneByteFromUlong(ultmp, 2); + buf[43]=swl_getOneByteFromUlong(ultmp, 3); + + dc2prot_setReadData(44, buf); + + */ + +} + +bool hwapi::rtc_getExtendedTime(struct T_extTime *exTime) const +{ + uint8_t len; + uint16_t LL, nn; + uint8_t *start; + uint8_t buf[66]; + + epi_restoreExtendedTime(&len, buf); + // Puffer in struct eintragen: + LL=sizeof(struct T_extTime); + start = &(exTime->Hours); + nn=0; + do + { + *start = buf[nn]; + start++; + } while(++nn800) dateiLang=800; + tslib_strcpy(content, inhaltOfJson, dateiLang); // enthaelt genaue Laenge, Rest =0 + nrOfBlocks=dateiLang/64; + if (dateiLang%64>0) + nrOfBlocks++; + dateiLang=nrOfBlocks; + dateiLang<<=6; // auf volle 64byte aufgerundet + + // check free memory + frei=check4freeFDstack(); + // Command-Stack sollte 16 Commands fassen, je 64byte Nutzdaten = 1024byte + // frei gibt also die Anzahl freier 64byte Bloecke zurueck + // das Json-File hat max 800 byte = 13 bloecke + if (frei<16) // Puffer muss ganz leer sein! nicht dass was durcheinander kommt + return false; + + // Start- und Stop auch als langes Kommando schicken + // PROBLEM: wuerden sie in einem anderen Batch gespeichert (short command stack), + // dann kann die Reihenfolge nicht gewaehrleistet werden + // Das Startkommando muss sicher zuerst kommen + // Das Abschlusskommando muss sicher zuletzt kommen + + tslib_strclr(temp,0,65); + temp[0]=dateiArt; + temp[1]=NummDesTempl; + longFDcmd_set(30, 0,0, 2,temp); // sende "Starte-file-DL" + uitmp=0; bn=0; + do + { + biox_CopyBlock(inhaltOfJson, uitmp, temp, 0, 64); + longFDcmd_set(31,0, bn++, 64, temp); + //uitmp<<=6; // falsch + uitmp+=64; + } while(uitmp < dateiLang); + + longFDcmd_set(32, 0,0, 0,temp); // Abschluss + + return true; +} + +static uint8_t lastSentDynData[64]; + +//char prn_dynPrnVal[8][8]; +bool hwapi::prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const +{ + // dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string + // like: char prn_dynPrnVal[8][8]; + // return true if sending, false if cmd-stack is full + + //uint8_t temp[66]; + //tslib_strcpy(dynPrnVal, temp, 64); // Vorsicht, kann \0en enthalten + memcpy(lastSentDynData, dynPrnVal, 64); + return longFDcmd_set(33,39,0, 64, lastSentDynData); + +} + +bool hwapi::prn_printTemplate(uint8_t nrOftemplate) const + // print one of the templates loaded by Json prior + // nr = 1..32 +{ + // return true if sending, false if cmd-stack is full + + epi_clearDynMachineConditions(); // 24.6.23 + gpi_storeDcDataValid(0); + + return sendFDcmd_set(152, 0,0, nrOftemplate,0,0,0); +} + +void hwapi::log_getHoldAccountNumbers(uint8_t *nrOfVals, uint16_t *accNr ) const +{ + // returns all acc nrs of the backuped vault records + // use: uint16_t backupedAccNumbers[8] + + epi_restoreDCbackupAccNr(nrOfVals, accNr); +} + + + +bool hwapi::log_selectVaultRecord(uint16_t accountNr ) const +{ + // return true if sending, false if cmd-stack is full + // and trigger transfer + + uint8_t dat1, dat2; + bool ret; + + uint8_t frei=check4freeFDstack(); + if (frei<8) + return false; + sendFDcmd_clrStack(); + epi_startSupervision(); + epi_iniVRstorage(); + dat1=uint2uchar(accountNr, LOWBYTE); + dat2=uint2uchar(accountNr, HIGHBYTE); + ret=sendFDcmd_set(153, 0,0, dat1,dat2,0,0); // select this record + // true means "will be sent" + sendFDcmd_set(0,38,0, 0,0,0,0); // return VaultRecord block-Nr.0 + sendFDcmd_set(0,38,1, 0,0,0,0); // return VaultRecord block-Nr.1 + sendFDcmd_set(0,38,2, 0,0,0,0); // return VaultRecord block-Nr.2 + sendFDcmd_set(0,38,3, 0,0,0,0); // return VaultRecord block-Nr.3 + sendFDcmd_set(0,38,4, 0,0,0,0); // return VaultRecord block-Nr.4 + sendFDcmd_set(0,38,5, 0,0,0,0); // return VaultRecord block-Nr.5 + // 38: <100 to get long 64byte response + + return ret; +} + +bool hwapi::log_chkIfVaultRecordAvailable(void) const +{ + // return true if completly received + + if ( epi_checkIfVaultRecordAvailable() ) + { + return true; + } + return false; +} + +//uint8_t hwapi::log_getAvailableVaultBlocks(void) const + +bool hwapi::log_getVaultRecord(struct T_vaultRecord *retVR) const + // which was selected by: log_selectVaultRecord() + // to be forwarded to Ismas + // return true if completly received +{ + #define MAXLENOFVAULTREC 400 + uint16_t LL, nn, len; + char *start; + uint8_t buf[MAXLENOFVAULTREC]; + bool ret; + + ret=epi_restoreVaultRecord(&len, buf); // true if completly received + if (ret==false) + return false; + // Puffer in struct eintragen: + LL=sizeof(struct T_vaultRecord); + if (LL>MAXLENOFVAULTREC) LL=MAXLENOFVAULTREC; + start = &retVR->startbuffer[0]; + nn=0; + + // 14.9.23 neu: Datensatz erst pruefen, [0..3] enthaelt "Psa>" und [4,5 =Abr.Nr] + uint16_t ds_acc_nr=uchar2uint(buf[5], buf[4]); + if (buf[0]=='P' && buf[1]=='S' && buf[2]=='A' && buf[3]=='>' && ds_acc_nr<60000) + { + // valid data, copy data to struct + do + { + *start = buf[nn]; + start++; + } while(++nncash_startPayment(amount); +} + + +uint8_t hwapi::cash_paymentProcessing(void) const +{ + // no need to use + // will be called automatically + uint8_t collActiv=0; + collActiv = runProcess->cash_paymentProcessing(); + return collActiv; +} + + +uint32_t hwapi::getInsertedAmount(void) const +{ + + uint32_t ultmp; + ultmp=epi_CurrentPaymentGetAmount(); + if (ultmp>65000) ultmp=0; // 19.6.23 + qDebug() << "current inserted amount: "<< ultmp; + return ultmp; +} + +uint16_t hwapi::getLastInsertedCoin(void) const +{ + uint32_t ultmp; + ultmp=epi_CurrentPaymentGetLastCoin(); + qDebug() << "last inserted coin: "<< ultmp; + return ultmp; + +} + +bool hwapi::getAllInsertedCoins(uint16_t *types, uint16_t *values) const +{ + // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64 + return epi_CurrentPaymentGetAllCoins(types, values); + +} + + +bool hwapi::cash_cancelPayment(void) const + // and return coins +{ + // DB1: 1=encash 2=cancel & return coins + // 3=stop and keep coins in escrow + epi_setNowCoinPay(false); // new since 20.9.23 + //qCritical() << "cash cancel payment and return coins"; + return sendFDcmd_set(156, 0,0, 2,0,0,0); +} + +bool hwapi::cash_stopPayment(void) const + // and keep coins in escrow +{ + // DB1: 1=encash 2=cancel & return coins + // 3=stop and keep coins in escrow + epi_setNowCoinPay(false); // new since 20.9.23 + //qCritical() << "cash stop payment and keep coins in escrow"; + // qCritical() << "emitting signal StopByPushbutton 2"; + emit hwapi_payStopByPushbutton(); + return sendFDcmd_set(156, 0,0, 3,0,0,0); +} + +// after ticket/goods issue: +bool hwapi::vend_success(void) const + // conclude payment process, encash all inserted coins to vault. Printing was successful + // if possible return change +{ + // DB1: 1=encash 2=cancel & return coins + // 3=stop and keep coins in escrow + epi_setNowCoinPay(false); // new since 20.9.23 + //qCritical() << "printing finished, encash coins"; + return sendFDcmd_set(156, 0,0, 1,0,0,0); +} + +bool hwapi::vend_failed(void) const + // conclude payment process and return all inserted coins +{ + // DB1: 1=encash 2=cancel & return coins + // 3=stop and keep coins in escrow + + epi_setNowCoinPay(false); // new since 20.9.23 + //qCritical() << "printing failed, encash coins"; + return sendFDcmd_set(156, 0,0, 2,0,0,0); +} + + + + + +// obsolete +uint8_t hwapi::mif_getCardType(QString *cardholder) const +{ + // return 1,2,3,4 = upper, lower access card, printer test, coin test + // cardholder: 7byte Name-String + + uint8_t type=0, nn; // buf[8], + char ctmp=0; + + for (nn=0;nn<8; nn++) + { + cardholder[nn]=ctmp; + } + return type; +} + +uint64_t hwapi::sys_getWakeSource(void) const +{ + // retval: 6 bytes, bit coded, 1=event keeps DC awake + return epi_getWakeSources(); +} + +uint8_t hwapi::sys_getWakeReason(void) const +{ + // Master was woken by following reason: + // 1: MDB Event + // 2: Coin Event + // ( 3: Master Event) - will not set the wake line + // ( 4: 32s pulse) - will not set the wake line + // 5: Door Event + // ( 6: Diag Event) - will not set the wake line + // 7: 30min-Pulse for HB + + return epi_getWakeReason(); +} + +void hwapi::sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const +{ + //uint8_t leng, data[66]; + epi_restoreDeviceConditions(leng, data); + +} + +void hwapi::sys_getDeviceConditions(struct T_moduleCondition *devCond) const +{ + uint16_t LL, nn; + uint8_t *start; + uint8_t buf[70], leng; + + epi_restoreDeviceConditions(&leng, buf); + + // Puffer in struct eintragen: + LL=sizeof(struct T_moduleCondition); + start = &devCond->ram; + nn=0; + do + { + *start = buf[nn]; + start++; + } while(++nnprinter=200; // not connected + else + if (zustand & 0x1C) + devCond->printer=201; // on error + else + if (zustand & 0x02) + devCond->printer=202; // no paper + else + if (zustand & 0x01) + devCond->printer=100; // low paper + // ------------------ end of patch ------------------------------------------------- + +} + + + + +void hwapi::sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const +{ + epi_restoreDynMachineConditions(leng, data); +} + +void hwapi::sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const +{ + + uint16_t LL, nn; + char *start; + uint8_t buf[70], leng; + + epi_restoreDynMachineConditions(&leng, buf); + // Puffer in struct eintragen: + LL=sizeof(struct T_dynamicCondition); + start = &dynMachCond->allDoorsDebounced; + nn=0; + do + { + *start = buf[nn]; + start++; + } while(++nnkindOfPrinter; + nn=0; + do + { + buf[nn] = *start; + start++; + } while(++nnepi_restore64BdevParameter(&LL, buf); // wozu die??? + epi_restoreRbDeviceSettings(&LL, buf); // viel besser, stimmt immer + + // Puffer in struct eintragen: + start = &deviceSettings->kindOfPrinter; + nn=0; + do + { + *start = buf[nn]; + start++; + } while(++nn8)) + return false; + + epi_clearDynMachineConditions(); // 24.6.23 + gpi_storeDcDataValid(0); + + return sendFDcmd_set(158, 0,0, nrOfKombi,0,0,0); +} + +void hwapi::lock_triggerUpperSolenoid(void) const +{ + sendFDcmd_set(159, 0,0, 0,0,0,0); +} + +void hwapi::lock_triggerLowerSolenoid(void) const +{ + sendFDcmd_set(160, 0,0, 0,0,0,0); +} + +bool hwapi::doors_supervise(void) const +{ + // no need to use + // will be called automatically + + // new from 2023.06.12, generate some signals: + //virtual void hwapi_ doorServiceDoorOpened(void) const=0; + //virtual void hwapi_ doorVaultDoorOpened(void) const=0; + //virtual void hwapi_ doorCBinAndAllDoorsClosed(void) const=0; + //virtual void hwapi_ doorAllDoorsClosed(void) const=0; + //virtual void hwapi_ doorCoinBoxRemoved(void) const=0; + return runProcess->doors_supervise(); +} + +bool hwapi::dc_isAutoRequestOn(void) const +{ + return gpi_isEmmisionOn(); +} + +uint16_t hwapi::log_getLatestAccountNumber(void) const +{ +// new function 27.6.2023 +// latest = highest, by now 8 records are stored in DC, prepare for 32 +#define maxNrElements 8 + uint8_t anz, nn; + uint16_t nummern[maxNrElements], highest=0; + + memset(nummern, 0, sizeof(uint16_t)*maxNrElements); + log_getHoldAccountNumbers(&anz, nummern); + if (anz>maxNrElements) anz=maxNrElements; + + for (nn=0; nnhighest) + highest=nummern[nn]; + return highest; +} + +uint8_t hwapi::log_getAvailableVaultBlocks(void) const +{ + // return 0x0011 1111 if all 6 blocks arer loaded (one bit per block) + return epi_getLoadedVaultBlocks(); + +} + +uint8_t hwapi::log_getAnswerToLastSlaveRequest(void) const +{ + // use only for ONE request/command + + // return: 0xFF: result unknown + // 0=OK + // 1= wrong length 2=wrong start sign 5= wrong crc + // 6= slave: master cmd was wrong 7: slave: could not write/read data + // 8=timeout, got no response from slave + + return epi_getLastResult(); + +} + + +// use for important and extended commands (print more templates, print ticket...) +void hwapi::log_startSupervision(void) const +{ + epi_startSupervision(); + +} + +uint8_t hwapi::log_getAnswerToLastCmdBatch(void) const +{ + + // 0xFF: no command sent by now + // 0: started, in progress + // 1: done and OK + // 2: done and error + return epi_getBatchResult(); + +} + + +bool hwapi::log_getVaultData(uint8_t *data) const +{ + // get vault record in linear 8bit buffer with 384 byte + + uint16_t len=384; + uint8_t buf[400]; + bool ret; + int nn; + + ret=epi_restoreVaultRecord(&len, buf); + if (ret==false) + return false; + + // 14.9.23 neu: Datensatz erst pruefen, [0..3] enthaelt "Psa>" und [4,5 =Abr.Nr] + uint16_t ds_acc_nr=uchar2uint(buf[5], buf[4]); + if (buf[0]=='P' && buf[1]=='S' && buf[2]=='A' && buf[3]=='>' && ds_acc_nr<60000) + { + // valid data, return data + for (nn=0; nn<384; nn++) + data[nn]= buf[nn]; + return true; + } else + { + // wrong data, clear array + for (nn=0; nn<384; nn++) + data[nn]=0; + return false; + } + return false; +} + + + +// new from 1.8.23 +bool hwapi::prn_printOneAccountReceipt(uint16_t accountNr) const +{ + // print one out of eight stored last accounting receipts + // function log_getHoldAccountNumbers() gives a list of acc-Nr. of the stored receipts + epi_clearDynMachineConditions(); // 24.6.23 + gpi_storeDcDataValid(0); + + uint8_t frei=check4freeFDstack(); + if (frei<2) + return false; + + uint8_t dat1, dat2; + dat1=uint2uchar(accountNr, LOWBYTE); + dat2=uint2uchar(accountNr, HIGHBYTE); + sendFDcmd_set(153, 0,0, dat1,dat2,0,0); // select this record + sendFDcmd_set(161, 0,0, 0,0,0,0); // print this + return true; +} + +bool hwapi::prn_printAllAvailAccountReceipts(void) const +{ + // same as: prn_printAccountReceipt() from line 1153 + // return true if sending to DC OK, false if cmd-stack is full + return prn_printAccountReceipt(); +} + + +uint16_t biox_crc_xmodem_update(uint16_t crc, uint8_t data) +{ + // berechne CRC16 XModem nach Polynom x^16 + x^12 + x^5 + 1 + + int i; + + crc = crc ^ ((uint16_t)data << 8); + for (i=0; i<8; i++) + { + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + else + crc <<= 1; + } + return crc; +} + +//bool hwapi::log_verifyVaultRecordByCrc(struct T_vaultRecord *retVR) const +bool hwapi::log_verifyVaultRecordByCrc(void) const +{ + // return true if CRC16 is correct, data are 100% OK. Security level 1:65536 + // verification is strongly recommended before further processing + // in case of "false"-result please reload from DC + + uint16_t myChkSum=0, nn, myOldSum=0, recCheckSum=0; + uint16_t LL=332; //320; // in DC noch falsch, sollte 332 sein + uint8_t val; + uint8_t data[400]; + + memset(data,0,400); + log_getVaultData(data); + for (nn=0; nn=64) + { + epi_restoreMifAtbData(mifData, 66); + for (nn=0; nn<64; nn++) + buf[nn]=mifData[nn]; + return true; + } + return false; +} + +bool hwapi::mif_isValidAtbCard(void) const +{ + uint8_t receivedData[66], nn; + //uint32_t mifatb_cunu, mifatb_cardnu, mifatb_creditAmount, mifatb_creditTime; + //QString mifatb_cardTyp, mifatb_lpr, mifatb_group, mifatb_zone; + //uint8_t mifatb_times[10]; + uint8_t lprbuff[20]; + bool ret; + + epi_restoreMifAtbData(receivedData, 66); + for (nn=0; nn<16; nn++) + { + lprbuff[nn]=char(receivedData[12+nn]); + //mifatb_lpr.append(char(receivedData[12+nn])); // "AtbPsa1256Ptu5_!" = recognition ATB card + } +/* + //mifatb_lpr.clear(); + + mifatb_cunu=uchar2ulong(receivedData[3], receivedData[2],receivedData[1],receivedData[0]); + // 281 + + mifatb_cardnu=uchar2ulong(receivedData[7], receivedData[6],receivedData[5],receivedData[4]); + // always 0, not used + + mifatb_cardTyp.clear(); + for (nn=0; nn<4; nn++) + mifatb_cardTyp.append(char(receivedData[8+nn])); // = "PREP" no idea what that means + + mifatb_group.clear(); + for (nn=0; nn<8; nn++) + mifatb_group.append(char(receivedData[28+nn])); // "7x§0 TPf" used for card type + + mifatb_zone.clear(); + for (nn=0; nn<8; nn++) + mifatb_zone.append(char(receivedData[36+nn])); // "PNsax001" used for personal number and shortcode + + for (nn=0; nn<10; nn++) + mifatb_times[nn]=receivedData[44+nn]; + // 0..9: (Start) day, month, year, hh, min (Stop) day, month, year, hh, min, + + mifatb_creditAmount= uchar2ulong(receivedData[57], receivedData[56],receivedData[55],receivedData[54]); + // is used as expire date/time + + mifatb_creditTime = uchar2ulong(receivedData[61], receivedData[60],receivedData[59],receivedData[58]); + // always 0 +// qDebug()<<"got MifAtbData: "<bl_completeStart(); + //hwapi_triggerBL->start(100); + return true; +} + + + +// select binfile-name in GUI + +// send binfile-name to BL-processor: +bool hwapi::bl_storeFirmware(QString fileName) const +{ + // load binary file 3x and compare + // return true if loaded correctly + // return false: error, could not load correctly + + return dcBL_loadBinSafe(fileName); +} + +// request the number of blocks for this file +uint16_t hwapi::bl_getNrOfFirmwareBlocks(void) const +{ + // size of the loaded bin file in 64byte blocks + // call after bl_storeFirmware() + return dcBL_getNrOfBlocks(); + +} + +// call this function with "blockNumber"=0,1,2,3.....bl_getNrOfFirmwareBlocks +//the last block "bl_getNrOfFirmwareBlocks()" is sent as conclusion command (important!) +bool hwapi::bl_blockAutoLoad(uint16_t blockNumber) const +{ + // call in loop from block number 0 up to <= "dcBL_getNrOfBlocks()" + // but after every call WAIT (!) for response "bl_blockAutoResponse()" !!!! + + // data will be sent to DC, if neccesary addr will be sent additionally + // if neccesary sending will automatically repeat up to 3times + // retval: false if blockNumber>4095, true else + + return dcBL_sendOneBlockCpl(blockNumber); + +} + +// check out this response after every block-sending, wait until >0!!! +int8_t hwapi::bl_blockAutoResponse(void) const +{ + // after every "bl_blockAutoLoad()" call this until response + // retval 0: wait 1: OK, blk was sent 2: OK, transfer complete + // 3: error despite repeating, cancel. probably bin file corrupted + // Max duration: 3x no response from BL = 900ms + + return dcBL_getBlockResult(); + +} + +// finally call: +// void hwapi::bl_stopBL(void) const + +// -------------- end of bootloader --------------------------------------------------- + + + +// new from 28.9.23 and earliest from DC version 4.45 +// get all versions of the DC-Jsons + +void hwapi::sys_requestJsonVersions(uint8_t jsonNr) const +{ + // send one request for every single version + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + sendFDcmd_set(0, 21, jsonNr,0,0,0,0); +} + +void hwapi::sys_getJsonVersions(uint8_t jsonNr, char *versionString) const +{ + + epi_getJsonVersion(jsonNr, versionString); + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + // length of buffer is always 16 byte + +} + +// ------------------------------------------------------------------------------------ +// Coin Changer +// ------------------------------------------------------------------------------------ + +void hwapi::changer_returnCoins(uint32_t amountInCent) const +{ + // command to give change + uint8_t buff[8]; + + buff[0]=ulong2uchar(amountInCent, 0); //LOWBYTE + buff[1]=ulong2uchar(amountInCent, 1); + //buff[2]=ulong2uchar(amountInCent, 2); + //buff[3]=ulong2uchar(amountInCent, 3); // HIGHBYTE + // repeat for security: + buff[2]=ulong2uchar(amountInCent, 0); //LOWBYTE + buff[3]=ulong2uchar(amountInCent, 1); + //buff[6]=ulong2uchar(amountInCent, 2); + //buff[7]=ulong2uchar(amountInCent, 3); // HIGHBYTE + +// longFDcmd_set(169, 0,0, 4,buff); // short cmd max 4 byte! + sendFDcmd_set(169,0,0,buff[0], buff[1], buff[2], buff[3]); + + +} + +void hwapi::changer_requestChangeResult(void) const +{ + + sendFDcmd_set(0, 115,0, 0,0,0,0); +} + +uint8_t hwapi::changer_getChangeResult(uint32_t *returnedAmount) const +{ + return epi_getChangerResult(returnedAmount); + // get result of coin dispensing + // receivedData[0]: 0: not yet started 1:amount returned + // 2:only partial return 3: no return possible + // receivedData[2,3,4,5]: returned amount +} + +void hwapi::changer_getAllParameters(struct T_changer *mw) const +{ + // requested automatically with 23, same like EMP + + uint8_t leng, data[66], pp, nn; + epi_restoreEmpSettings(&leng, data); // expected length = 64 byte + + // get 64 bytes about Changer (mw), see interfaces.h-file + mw->setup = data[0]; + mw->state = data[1]; + mw->level = data[2]; + mw->countryCode = uchar2uint(data[4], data[3]); + mw->scale = data[5]; + mw->decimals= data[6]; + + for (nn=0; nn<16; nn++) + mw->coinSetup[nn]= data[nn+7]; // 7...22 + mw->intendedAcceptance = uchar2uint(data[24], data[23]); + mw->tokenChannel= data[25]; + mw->pollingRunning= data[26]; + mw->paymentRunning= data[27]; + pp=28; + for (nn=0; nn<16; nn++) + { + mw->denomination[nn] = uchar2uint(data[pp+1], data[pp]); + pp+=2; + } + // bis pp=60 + mw->availableTubes = uchar2uint(data[61], data[60]); +} + +void hwapi::changer_requestTubelevel(void) const +{ + sendFDcmd_set(0, 40,0, 0,0,0,0); +} + +void hwapi::changer_getTubelevel(struct T_chg_Tub *tubLevel) const +{ + // don't use tubeDispens[], it's not yet correct! + + uint16_t LL, nn; + uint8_t *start; + uint8_t buf[66]; + + epi_restoreTubeLevel(buf); + // Puffer in struct eintragen: + LL=sizeof(struct T_chg_Tub); + start = &(tubLevel->tubeLevel[0]); + nn=0; + do + { + *start = buf[nn]; + start++; + } while(++nn +#include "tslib.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + return a.exec(); +} diff --git a/src/prot.cpp b/src/prot.cpp new file mode 100644 index 0000000..60b3e09 --- /dev/null +++ b/src/prot.cpp @@ -0,0 +1,623 @@ +#include "prot.h" +#include +#include "controlBus.h" +#include "dcBL.h" +#include "interfaces.h" + + +T_prot::T_prot() +{ + + mySerialPort = new T_com(); + connect(mySerialPort, SIGNAL(receivingFinished()), this, SLOT( analyseRecData() )); + //connect(mySerialPort, SIGNAL(sendingFinished()), this, SLOT(sendeFin())); + + for (int nn=0; nnisPortOpen(); +} + +bool T_prot::isSerialFree(void) +{ + return true; // ohne HS's kann er nicht blockiert sein +} + + +// 14.9.23 Fehler!!!!! +// hier wird vorausgesetzt dasss die Empfangslaenge von Sendetelegramm abh. ist. +// also cmd>=100 ist kurze Antwort. das stimmt aber nicht, ist unabh. Wahr ist: cmd>=100 = kurzes Sendetelegramm + +// Laenge des request-telegramms (PTU-->DC) ist nur abh. vom WRcmd, die Antwort auf WR ist immer kurz (nur result byte) +// WRcmd kurz oder lang: Antwort immer kurz +// RDcmd kurz oder lang: Antwort genauso +// Also Korrektur dieser Funktion: nur der Variablenname "WriteCmd" -> "ReadCmd" + +void T_prot::setRecLen(uint16_t ReadCmd) +{ + if (ReadCmd<100) + { + RdDataLength=DATALEN_RECEIVE_LONG; // 64, store here already because it's no longer returned from slave + mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_LONG); // 68 + } else + { + RdDataLength=DATALEN_RECEIVE_FAST; // 8 + mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_FAST); // 12 + } +} + +/* + * void T_prot::setRecLen(uint16_t WriteCmd) +{ + if (WriteCmd<100) + { + RdDataLength=DATALEN_RECEIVE_LONG; // store here already because it's no longer + // returned from slave + mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_LONG); // 68 + } else + { + RdDataLength=DATALEN_RECEIVE_FAST; + mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_FAST); // 12 + } +} +*/ + +void T_prot::setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, uint8_t *data) +{ + WriteCommand=WriteCmd; + WriteAddr=WrAddr; + WrDataLength=WrDatLen; + if (WrDataLength>FRAME_DATALEN) + WrDataLength=FRAME_DATALEN; + + for (int nn=0; nnsetRecLen(100); // default: short response + +} + +void T_prot::setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr) +{ + WriteCommand=WriteCmd; + WriteAddr=WrAddr; + WrDataLength=0; + for (int nn=0; nnsetRecLen(100); // default: short response + +} + +void T_prot::setUserWriteData(uint16_t WriteCmd) +{ + WriteCommand=WriteCmd; + WriteAddr=0; + WrDataLength=0; + for (int nn=0; nnsetRecLen(100); // default: short response + +} + +void T_prot::setUserWrite1DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val) +{ + // wie oben, jedoch einfachere Datenübergabe + WriteCommand=WriteCmd; + WriteAddr=WrAddr; + WrDataLength=1; + ui8OutputData[0]=val; + SendDataValid=1; // always set WR first + kindOfData=0; // 0: binaries, 1:text + this->setRecLen(100); // default: short response + +} + +void T_prot::setUserWrite2DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1) +{ + WriteCommand=WriteCmd; + WriteAddr=WrAddr; + WrDataLength=2; + ui8OutputData[0]=val0; + ui8OutputData[1]=val1; + SendDataValid=1; // always set WR first + kindOfData=0; // 0: binaries, 1:text + this->setRecLen(100); // default: short response + +} + +void T_prot::setUserWriteText(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, char *data) +{ + WriteCommand=WriteCmd; + WriteAddr=WrAddr; + WrDataLength=WrDatLen; + if (WrDataLength>FRAME_DATALEN) + WrDataLength=FRAME_DATALEN; + + for (int nn=0; nnsetRecLen(100); // default: short response + +} + +void T_prot::setUserReadData( uint16_t ReadCmd) +{ + ReadCommand=ReadCmd; + //ReadAddr=WriteAddr; + reserve=0; + SendDataValid |=2; + readAddress=WriteAddr; // store here already because it's no longer returned from slave + + //qDebug()<<"prot_setUserReadData, read address : " << readAddress; + + this->setRecLen(ReadCmd); // long response (68byte) only for ReadCmd < 100 + readSource=ReadCmd; +} + +void T_prot::setBLsendData( uint8_t len, uint8_t *buf) +{ + for (int nn=0; nnBL_DATA_LEN) BLsendDataLength=BL_DATA_LEN; + for (int nn=0; nnsetRecLen(100); + + + //qDebug()<<"prot: got BL data " << len << "bytes, "; + //for (int i=0; ireceiveFixLen(nrOfbytesToReceive); +} + +void T_prot::sendUserData(uint16_t slaveAdr) +{ + // man könnte hier noch "SendDataValid" abfragen, + // muss immer 3 sein, muss man aber nicht + + //qDebug() << "prot send user data "<writeToSerial(packBuf_2, BLsendDataLength); + + } else + startFastPacking(); // quicker since 15.12.21TS + //startPacking(); +} + +void T_prot::startFastPacking(void) +{ + uint16_t mycrc; + uint16_t sendLen; + uint8_t uctmp, nn, pp, CrcLp; + char sendBuffer[FRAME_MAXLEN], ctmp; + + //qDebug() << "prot start fast packing "<9 && WriteCommand<100) + { + // long command 10...99 + // WriteCommand==0 if only read request, then use short sending + sendBuffer[0]=STARTSIGN_SEND_LONG; + WrDataLength=DATALEN_SEND_LONG; // immer + //qDebug() << "send long cmd, len: " << WrDataLength; + } else + { + // fast command + sendBuffer[0]=STARTSIGN_SEND_FAST; + WrDataLength=DATALEN_SEND_FAST; // immer + //qDebug() << "send fast cmd, len: " << WrDataLength; + } + sendBuffer[1]= uint8_t(WriteCommand); + sendBuffer[2]= uint8_t(ReadCommand); + //if (WriteAddr>0) + sendBuffer[3]= char(WriteAddr); // bei fast nur EINE adresse, wr hat Vorrang + //else + // sendBuffer[3]= char(ReadAddr); + // beim Fast prot. ist das reserve dann ists egal was drin steht + + if (kindOfData) // 0: binaries, 1:text + { + for (nn=0; nn>=8; + sendBuffer[CrcLp+1]=char(mycrc); + sendLen=CrcLp+2; + + // send to VCP: + QByteArray packBuff; + packBuff.clear(); + packBuff.append(sendBuffer, sendLen); // ohne sendLen wird beim ersten \0 abgeschnitten!!! + mySerialPort->writeToSerial(packBuff, sendLen); + +} + + +// --------------------------------------------------------------------------------------------------------- +// receiving..... +// --------------------------------------------------------------------------------------------------------- + + +void T_prot::analyseRecData(void) +{ + // Aufruf per connect aus serialcontrol wenn Daten empfangen wurden + // getRecData(QByteArray &data, uint16_t &sendLength); + + QByteArray Indata; + QString myString, tempStr; +//char recBuffer[FRAME_MAXLEN]; +uint8_t recBuffer[FRAME_MAXLEN]; + + uint16_t recLength; + + INdataValid=false; + + gpi_setTxt4HsStateLine(""); + gpi_setTxt4masterStateLine(""); + gpi_setTxt4resultStateLine(""); + gpi_setTxt4dataStateLine(""); + gpi_setTxt4datifLine(""); + + // read from "VCP": + mySerialPort->readFromSerial(Indata, recLength); +//qDebug()<<"prot: got data " << recLength; + if (recLength>FRAME_MAXLEN) + recLength=FRAME_MAXLEN; + for (int nn=0; nn0) + { + // dann anzeige + switch (result) + { + case 1: gpi_setTxt4masterStateLine("wrong length received"); break; + case 2: gpi_setTxt4masterStateLine("wrong start sign received"); break; + case 3: gpi_setTxt4masterStateLine("received datalen too big"); break; + case 4: gpi_setTxt4masterStateLine("wrong data len received"); break; + case 5: gpi_setTxt4masterStateLine("wrong crc received"); break; + case 6: gpi_setTxt4masterStateLine("slave: master cmd was wrong"); break; + case 7: gpi_setTxt4masterStateLine("slave: could not write/read data"); break; + + } + myString.setNum(result); + +// qDebug()<<"T_prot_analyseRecData: got BL data"<< recLength << +// recBuffer[0]<< recBuffer[1]<< recBuffer[2]<< recBuffer[3] << +// recBuffer[4]<< recBuffer[5]<< recBuffer[6]<< recBuffer[7]; + + // Daten abspeichern, könnten vom BL sein: + gpi_storeRawReceivedData(uint8_t(recLength), recBuffer); + INdataValid=false; + emit rawDataRecieved(); + } else + { + gpi_setTxt4masterStateLine("slave response OK"); + INdataValid=true; + ShowFastInData(recBuffer); // Eingangs-Daten des Slaves anzeigen + } + prot_storeResult=result; + emit framerecieved(); // always emit, no matter if data valid or not + +} + + +uint8_t T_prot::FastCheckInData(uint8_t *Inbuf, uint16_t LL) +{ + + uint16_t rawInLen=LL, crcL_Addr, recCrc, myCrc, nn, datalen, nxt; + + + if (Inbuf[0]!=STARTSIGN_RECEIVE_FAST && Inbuf[0]!=STARTSIGN_RECEIVE_LONG) + { + //qDebug() << "prot: got wrong start sign: " << Inbuf[0]; + return 2; // wrong start sign + } + if ( (rawInLen0) schmarrn, kann nie kommen + // qDebug() << "prot, got DC-result: "<< result; + + return 0; +} + +/* +uint8_t T_prot::CheckInResult(uint8_t *Inbuf) +{ + char slaveresult; + QString myString=nullptr, tempStr=nullptr; + + // slave results anzeigen + + slaveresult=Inbuf[2]; // hier steht das "Command Result" des slaves, + // d.h das Ergebnis der Protokol-Prüfung (Master->Slave) + switch (slaveresult) + { +// received message (from master) analysis: +// 0: got valid request +// this errors can only come back from a single device (not bus) +// or from a bus slave in local mode +// 1: wrong start 2: wrong length +// 3: wrong crc 4: wrong addr + + case 1: gpi_setTxt4resultStateLine("slave got wrong start sign"); break; + case 2: gpi_setTxt4resultStateLine("slave got wrong length"); break; + case 3: gpi_setTxt4resultStateLine("slave got wrong crc"); break; + case 4: gpi_setTxt4resultStateLine("slave got wrong addr"); break; + + case 10: gpi_setTxt4resultStateLine("slave is in local mode"); break; + case 13: gpi_setTxt4resultStateLine("local mode with wrong crc"); break; + case 14: gpi_setTxt4resultStateLine("local mode with wrong addr"); break; + // wenn 1..4 dann konnte der Slave das Mastertelegramm gar nicht verwenden, also hier Stoppen + } + if (slaveresult>0 && slaveresult<10) + return 1; + + // Slave hat gültiges Kommando empfangen: + // 2.result auswerten: + // recBuffer[3]; // Write result, d.h. Ergebnis des Schreibvorganges (z.B. DOs) des Slaves + // recBuffer[4]; // Read result, d.h. Ergebnis des Lesevorganges (z.B. DIs) des Slaves + // bisher nicht bekannt welche Fehlercodes es gibt, also den code direkt ausgeben. + // bisher bekannt: 0=OK + + myString.clear(); + myString = "Slave OUT and IN Result: "; + tempStr.setNum(Inbuf[3],16); + myString.append(tempStr); + myString.append(" "); + tempStr.setNum(Inbuf[4],16); + myString.append(tempStr); + gpi_setTxt4resultStateLine(myString); + return 0; +} +*/ + + +uint8_t T_prot::ShowFastInData(uint8_t *recBuffer) +{ + QString myString=nullptr, tempStr=nullptr; + uint8_t result; + + RecSlaveAddr=0; + result=recBuffer[1]; // total result + result &=0x60; // only read result (bit 5,6) + + if (result==0) // read result =OK, + // dann sind die Eingangsdaten gültig + { + myString.append("valid INdata: "); + //INdataValid=true; // 17.7. hier raus! + //readSource already set with sending + //readAddress=0; großer Fehler!!!! raus am 17.7 + // RdDataLength already set with sending + if (RdDataLength>FRAME_DATALEN) + RdDataLength=FRAME_DATALEN; + for (int ii=0; ii +#include "controlBus.h" +#include "dcBL.h" +#include "interfaces.h" + +static uint32_t hwapi_lastStartAmount; +static uint32_t hwapi_lastTotalAmount; +static uint8_t hwapi_cash_lastCollectionState; +static uint8_t hwapi_paymentStarted; +static uint8_t hwapi_lastDoorState; +static uint8_t bl_startupStep; + + + +T_runProc::T_runProc() +{ + + hwapi_TimerPayment = new QTimer(); + hwapi_TimerPayment->setSingleShot(true); + + hwapi_lastStartAmount=0; + hwapi_lastTotalAmount=0; + hwapi_cash_lastCollectionState=0; + hwapi_paymentStarted=0; + hwapi_lastDoorState=0; + bl_startupStep=0; + + QTimer *runProc_callProcesses = new QTimer(); + connect(runProc_callProcesses, SIGNAL(timeout()), this, SLOT(runProc_slotProcess())); + runProc_callProcesses->setSingleShot(false); + runProc_callProcesses->start(100); // in ms + + hwapi_lastDoorState=0; // default: all doors (should be) closed, coin box inserted + // bit0: upper door 1:middle 2:lower 3=cash-box out + + hwapi_triggerBL = new QTimer(); + connect(hwapi_triggerBL, SIGNAL(timeout()), this, SLOT(bl_performComplStart())); + hwapi_triggerBL->setSingleShot(false); + hwapi_triggerBL->stop(); + +} + + +void T_runProc::runProc_slotProcess(void) +{ + cash_paymentProcessing(); + doors_supervise(); + dcBL_cycle(); + +} + +bool T_runProc::cash_startPayment(uint32_t amount) +{ + uint8_t dat1, dat2, dat3, dat4; + + hwapi_lastStartAmount=amount; + epi_clearCurrentPayment(); + dat1=ulong2uchar(amount, 0); + dat2=ulong2uchar(amount, 1); + dat3=ulong2uchar(amount, 2); + dat4=ulong2uchar(amount, 3); + hwapi_cash_lastCollectionState=0; + sendFDcmd_set(155, 0,0, dat1,dat2,dat3,dat4); + // wird im DC auf 65500 gesetzt wenn 0 (Maximalwert 0 macht keinen Sinn!) + + hwapi_paymentStarted=1; + + hwapi_TimerPayment->start(5000); // in ms + hwapi_lastTotalAmount=0; + epi_setNowCoinPay(true); // new since 20.9.23 + qDebug() << "payment started with " << amount ; + return true; + +} + +uint8_t T_runProc::cash_paymentProcessing(void) +{ + // run this function periodically while coin payment process to generate necessary signals: + + // am 5.10.23 umgebaut, geht jetzt auch fuer MW. Für EMP und MW getestet + + // 12.10.23: epi_store64BdevParameter() MUSS vorher aufgerufen werden zur Unterscheidung EMP / MW !!!!! + + // return value: + // 0: stopped 1: starting up 2: coin collection + // 3: finished by User (Push button) 4: finished, Max-Value collected + // 5: finished by escrow + // 6: money encashed + // 7: cancelled + // 10,11: error cannot start + // 12: timeout while payment, coins returned + // 13: stopped by unexpected error + + struct T_emp empStat; + struct T_changer chgrStat; + + struct T_dynamicCondition myDynMachCond; + struct T_devices devParameter; + + uint8_t collActiv=0, payInProg, empState, kcc; + uint32_t newSum; + + if (hwapi_paymentStarted<1) + return 0; // off + + collActiv=1; // starting up payment + devParameter.kindOfCoinChecker=0; + restoreDeviceParameter(&devParameter); + kcc=devParameter.kindOfCoinChecker; + /* + buf66[0]=devPara.kindOfPrinter; + buf66[1]=devPara.kindOfCoinChecker; + buf66[2]=devPara.kindOfMifareReader; + buf66[3]=devPara.suppressSleepMode; + buf66[4]=devPara.kindOfModem; + buf66[5]=devPara.kindOfCreditcard; + buf66[6]=devPara.CoinEscrow; + buf66[7]=devPara.CoinRejectUnit; + buf66[8]=devPara.CoinShutter; + buf66[9]=devPara.BillAcceptor; + buf66[10]=devPara.usevaultLock; + buf66[11]=devPara.autoAlarm; + buf66[12]=devPara.autoOpen; + buf66[13]=devPara.printAccReceipt; + buf66[14]=devPara.printDoorReceipt; + buf66[15]=devPara.printTokenTicket; + uitmp=devPara.VaultFullWarnLevel; + buf66[16]=swl_getOneByteFromUint(uitmp, GETLOWBYT); + buf66[17]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); + uitmp=devPara.VaultFullErrorLevel; + buf66[18]=swl_getOneByteFromUint(uitmp, GETLOWBYT); + buf66[19]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); + +*/ + if (kcc<3) + { + sub_emp_getAllParameters(&empStat); + empState=empStat.state; + } else + { + changer_getAllParameters(&chgrStat); + empState=chgrStat.state; + } + + // 0=start command + // 1=powered, do emp ini, send reset + // 2=delay + // 3=wait for response, requesting status after response + // 4,5 through, startup + // 6: wait for status + // 7: through, startup + // 8: IDLE state. EMP is up and ready, polling is running + // 9: polling on, payment not yet on + // 10: payment, check coins + // 11: through + // 12: wait 1s for last coin + // 90: stop all, 1s delay + // 99: off, all stopped + + sub_getDynMachineConditions(&myDynMachCond); + payInProg= myDynMachCond.paymentInProgress; + // 0: stopped by timeout + // 1: running 2: wait4lastCoin + // 3: payment stopped manually, coins in Escrow + // 4: payment stopped autom, amount collected, coins in Escrow + // 5: payment stopped, escrow full, coins in Escrow + // 6: coins encashed + // 7: coins returned 2 cases: due to cancel-button or printer-error + // 8: CoinChecker or MDB on Error + +// qCritical() << "emitting signal payCancelled"; +// emit runProc_payCancelled(); + + if (payInProg==8) + { + // coin checker faulty, cannot start + if (hwapi_paymentStarted==1) + { + hwapi_paymentStarted=90; // stop due to error + qCritical() << "emitting signal coinCollectionAborted 1"; + emit runProc_coinCollectionAborted(); + //sendFDcmd_set(156, 0,0, 2,0,0,0); // cancel payment + } + + return 10; // error cannot start + } + + if (empState>=10 && empState<=12 && (payInProg==1 || payInProg==2) ) + { + // coin acceptance is active now: + if (hwapi_paymentStarted==1) // && (( payInProg==0) || ( payInProg>5))) //16.6.23 + { // 1=wait for coin checker being ready + hwapi_paymentStarted=2; // coins can be inserted now + qCritical() << "emitting signal coinCollectionJustStarted"; + emit runProc_coinCollectionJustStarted(); + } + } + + if (hwapi_paymentStarted==2) + { + // coins can be inserted now, wait for end + collActiv=2; // coin collection active + + newSum=epi_CurrentPaymentGetAmount(); + if (newSum>hwapi_lastTotalAmount) + { + hwapi_lastTotalAmount=newSum; + qCritical() << "emitting signal gotNewCoin"; + emit runProc_gotNewCoin(); + } + + if (payInProg==0) // timeout, coins returned by DC + { + hwapi_paymentStarted=90; + collActiv=12; // stop by timeout + qCritical() << "emitting signal payStopByTimeout"; + emit runProc_payStopByTimeout(); + + } else + + if (payInProg==3) // user pressed "Next/Continue", keep coin + { + hwapi_paymentStarted++; + collActiv=3; + qCritical() << "emitting signal payStopByPushbutton 1"; + emit runProc_payStopByPushbutton(); + } else + + if (payInProg==4) // max achieved, keep coins + { + hwapi_paymentStarted++; + collActiv=4; + qCritical() << "emitting signal payStopByMax"; + emit runProc_payStopByMax(); + } else + + if (payInProg==5) // escrow full, keep coins + { + hwapi_paymentStarted++; + collActiv=5; + qCritical() << "emitting signal payStopByEscrow"; + emit runProc_payStopByEscrow(); + } + + /* 5.10.23 raus, geht auf 99 wenn Betrag erreicht, ist aber kein fehler + if ( (empState<10) || (empState>12)) // error + { + collActiv=13; + hwapi_paymentStarted=90; + qCritical() << "emitting signal payStopByError" << empState; + emit runProc_payStopByError(); + } */ + + } + + if (hwapi_paymentStarted==3) + { + // coin collection finished, but coins kept until printing done + collActiv=2; + if (payInProg==6) // coins encashed + { + collActiv=6; + hwapi_paymentStarted++; + qCritical() << "emitting signal coinProcessJustStopped"; + emit runProc_coinProcessJustStopped(); + } else + + if (payInProg==7) // coins returned, printing failed + { + collActiv=7; + hwapi_paymentStarted++; + qCritical() << "emitting signal payCancelled"; + emit runProc_payCancelled(); + } + } + + if (hwapi_paymentStarted==4) + { + // transaction finished + hwapi_paymentStarted=0; + } + + //if ( (empState<8) || (empState>12)) + // epi_clearCurrentPayment(); // to avoid wrong "got-coin" messages + + if (hwapi_paymentStarted==90 ) + { + // EMP error, wait till process finished + // everything stopped, no more coins in escrow + hwapi_paymentStarted=0; + } + + return collActiv; +} + + + + + +void T_runProc::sub_emp_getAllParameters(struct T_emp *emp) +{ + uint8_t leng, data[66], ii, pp; + epi_restoreEmpSettings(&leng, data); // expected length = 64 byte + + // get 64 bytes about EMP: see h-file + + emp->gotSetup = data[0]; + emp->state = data[1]; + emp->shaft = data[2]; + emp->countryCode= uchar2uint(data[4], data[3]); + emp->scale = data[5]; + emp->decimals = data[6]; + for (ii=0; ii<16; ii++) + emp->coinValues[ii] = data[7+ii]; + emp->coinAccept = uchar2uint(data[24], data[23]); + emp->tokenChannel = data[25]; + emp->pollingRunning = data[26]; + emp->paymentRunning = data[27]; + + pp=28; + for (ii=0; ii<16; ii++) + { + emp->denomination[ii] = uchar2uint(data[pp+1], data[pp]); + pp+=2; + } + emp->routing= uchar2uint(data[61], data[60]); + +} + +void T_runProc::changer_getAllParameters(struct T_changer *mw) +{ + // requested automatically with 23, same like EMP + + uint8_t leng, data[66], pp, nn; + epi_restoreEmpSettings(&leng, data); // expected length = 64 byte + + // get 64 bytes about Changer (mw), see interfaces.h-file + mw->setup = data[0]; + mw->state = data[1]; + mw->level = data[2]; + mw->countryCode = uchar2uint(data[4], data[3]); + mw->scale = data[5]; + mw->decimals= data[6]; + + for (nn=0; nn<16; nn++) + mw->coinSetup[nn]= data[nn+7]; // 7...22 + mw->intendedAcceptance = uchar2uint(data[24], data[23]); + mw->tokenChannel= data[25]; + mw->pollingRunning= data[26]; + mw->paymentRunning= data[27]; + pp=28; + for (nn=0; nn<16; nn++) + { + mw->denomination[nn] = uchar2uint(data[pp+1], data[pp]); + pp+=2; + } + // bis pp=60 + mw->availableTubes = uchar2uint(data[61], data[60]); +} + + +void T_runProc::sub_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) +{ + + uint16_t LL, nn; + char *start; + uint8_t buf[70], leng; + + epi_restoreDynMachineConditions(&leng, buf); + // Puffer in struct eintragen: + LL=sizeof(struct T_dynamicCondition); + start = &dynMachCond->allDoorsDebounced; + nn=0; + do + { + *start = buf[nn]; + start++; + } while(++nnkindOfPrinter; + nn=0; + do + { + *start = buf[nn]; + start++; + } while(++nn16000)) // 8...16V erlaubt + return false; // Fehler + + if ((myDynMachCond.Temperatur<40) || (myDynMachCond.Temperatur>260)) // -30°C...80°C erleubt + return false; // Fehler + + uctmp=(hwapi_lastDoorState & 1); // 0: upper door is closed + if (uctmp==0 && myDynMachCond.upperDoor>0) + { + hwapi_lastDoorState |= 1; + qCritical()<<"hwapi emitting signal ServiceDoorOpened"; + emit runProc_doorServiceDoorOpened(); + } + + uctmp=(hwapi_lastDoorState & 2); + if (uctmp==0 && myDynMachCond.middleDoor>0) + { + hwapi_lastDoorState |= 2; + qCritical()<<"hwapi emitting signal VaultDoorOpened "; + emit runProc_doorVaultDoorOpened(); + } + + uctmp=(hwapi_lastDoorState & 4); + if (uctmp==0 && myDynMachCond.lowerDoor>0) + { + hwapi_lastDoorState |= 4; + qCritical()<<"hwapi emitting signal ServiceDoorOpened (Batt)"; + emit runProc_doorServiceDoorOpened(); + } + + uctmp=(hwapi_lastDoorState & 8); // 0: cash box was in + if (uctmp==0 && myDynMachCond.CBinDebounced==0) // 0:fehlt 1:drin + { + // wurde gerade entnommen + hwapi_lastDoorState |= 8; + qCritical()<<"hwapi emitting signal CoinBoxRemoved "; + emit runProc_doorCoinBoxRemoved(); + } + + uctmp=(hwapi_lastDoorState & 8); + if (uctmp>0 && myDynMachCond.CBinDebounced>0) // 0:fehlt 1:drin + { + // war draussen, ist wieder drin + hwapi_lastDoorState &= ~0x08; + qCritical()<<"hwapi emitting signal CoinBoxInserted"; + emit runProc_doorCoinBoxInserted(); + } + + uctmp=(hwapi_lastDoorState & 0x07); + doorTemp=0; + if (myDynMachCond.upperDoor>0) doorTemp |=1; + if (myDynMachCond.middleDoor>0) doorTemp |=2; + if (myDynMachCond.lowerDoor>0) doorTemp |=4; + + if (uctmp>0 && doorTemp==0) // vorher war mind. EINE Tuer offen UND jetzt sind alle zu + { + hwapi_lastDoorState &= ~0x07; + + // soeben wurde die letzte Tür geschlossen, prüfe ob Kasse eingesetzt wurde: + if (myDynMachCond.CBinDebounced) + { + qCritical()<<"hwapi emitting signal CBinAndAllDoorsClosed"; + emit runProc_doorCBinAndAllDoorsClosed(); + hwapi_lastDoorState &=~0x08; // keine Wirkung + } else + { + qCritical()<<"hwapi emitting signal AllDoorsClosed"; + emit runProc_doorAllDoorsClosed(); + } + } + + return true; + +} + + +uint8_t T_runProc::prn_getHwState(struct Tprn_hw_state *prn_hw_state) +{ + // return printer hardware state: power is on? rs-driver on? rs_switch ok? hw-ready-line ok? + // printer on error or ok? + uint8_t prnHWstate[20]; + + epi_restorePrinterState(prnHWstate); + // byte 1...6 come right from printer, see printer manual + // byte 0 = all important infos: + // byte 0 = 0: prnter OK, >0: error + // bit0: paper low 1: no paper 2: temperature error + // 3: head open 4: paper jam in cutter + // 6: no response 7: bad response from printer + + prn_hw_state->powerRdBk = epi_getDI_printerPwr(); + prn_hw_state->rsSwOk = epi_getDO_serialMux1isSetToPrinter(); // mux1 off: serial is switched to printer + prn_hw_state->rsDrvOk = epi_getDO_serialDriverIsOn(); + prn_hw_state->ReadyLine = epi_getDI_prnReady(); + + if (prnHWstate[0]==0) + prn_hw_state->inIdle = true; // no errors + else + prn_hw_state->inIdle = false; // off or errors + + if (prnHWstate[0] & 1) + prn_hw_state->paperNearEnd=true; + else + prn_hw_state->paperNearEnd = false; + + if (prnHWstate[0] & 2) + prn_hw_state->noPaper=true; + else + prn_hw_state->noPaper = false; + + if (prnHWstate[0] & 4) + prn_hw_state->ErrorTemp=true; + else + prn_hw_state->ErrorTemp = false; + + if (prnHWstate[0] & 8) + prn_hw_state->HeadOpen=true; + else + prn_hw_state->HeadOpen = false; + + if (prnHWstate[0] & 16) + prn_hw_state->cutterJam=true; + else + prn_hw_state->cutterJam = false; + + + if (prnHWstate[0] & 64) + prn_hw_state->noResponse=true; + else + prn_hw_state->noResponse = false; + + if (prnHWstate[0] & 128) + prn_hw_state->badResponse=true; + else + prn_hw_state->badResponse = false; + return prnHWstate[0]; + +} + + + + +void T_runProc::dc_autoRequest(bool on) +{ + // automatically request ALL digital and analog sensors, get time/date, get status information + epi_startEmmision(on); +} + +void T_runProc::bl_rebootDC(void) +{ + // send command to normal DC-Program requesting a restart + // BL is working for 5s after power-on-reset. + + uint8_t len, buf[20]; + + len=dcBL_restartDC(buf); + sendWRcmd_setSendBlock160(len, buf); +} + +void T_runProc::bl_startBL(void) +{ + // use this function within the first 5s after reboot to startup the BL, + // otherwise the BL jumps to normal DC application + uint8_t len, buf[20]; + + len=dcBL_activatBootloader(buf); + sendWRcmd_setSendBlock160(len, buf); + epi_setNowIsBootload(true); +} + +void T_runProc::bl_checkBL(void) +{ + // call this function in order to get information, afterwards use "bl_isUp()" + uint8_t len, buf[20]; + + len=dcBL_readFWversion(buf); + sendWRcmd_setSendBlock160(len, buf); +} + +bool T_runProc::bl_isUp(void) +{ + uint8_t receivedData[160]; + uint8_t LL, nn; + + for (nn=0; nn<160; nn++) receivedData[nn]=0; + LL=epi_getRawRecLength(); + if (LL>0) + { + epi_getRawReceivedData(receivedData); + + // response to "readFWversion" + if (receivedData[0]==2 && receivedData[1]==146 && receivedData[2]==45 && + receivedData[3]==45 && receivedData[4] ==95 && receivedData[5]==176) + { + qDebug() << "got BL response to readFWversion"; + epi_clrRawReceivedString(); + return true; + } + // response to "start BL" + if (receivedData[0]==2 && receivedData[1]==101 && receivedData[2]==48 && + receivedData[3]==223 && receivedData[4] ==131 ) + { + qDebug() << "hwapi_bl_isUp: got BL response to start"; + epi_clrRawReceivedString(); + return true; + } + } + return false; +} + + +void T_runProc::bl_completeStart(void) +{ + bl_startupStep=1; +} + +bool T_runProc::bl_performComplStart(void) +{ + // must be called cyclic by timer + static uint8_t retryCtr; + + if ((bl_startupStep<1) || (bl_startupStep>10)) + return false; + + if (bl_startupStep==1) + { + dc_autoRequest(false); + bl_startupStep++; + } else + + if (bl_startupStep==2) + { + bl_rebootDC(); + hwapi_triggerBL->stop(); + hwapi_triggerBL->start(1000); // call next step in 1s + retryCtr=0; + bl_startupStep++; + } else + + if (bl_startupStep==3) + { + //qDebug()<<"starting BL"; + bl_startBL(); + hwapi_triggerBL->stop(); + hwapi_triggerBL->start(100); + bl_startupStep++; + + } else + + if (bl_startupStep==4) + { + //if (!myTO->isActive()) + //{ + bl_checkBL(); + hwapi_triggerBL->stop(); + hwapi_triggerBL->start(100); + bl_startupStep++; + + //} + + } else + + if (bl_startupStep==5) + { + hwapi_triggerBL->stop(); + if (bl_isUp()) + { + bl_startupStep=99; + // BL is up and running + } else + { + retryCtr++; // start again + if (retryCtr>=15) + { + bl_startupStep=99; + //qDebug()<<"BL error!!!"; + } else + { + bl_startupStep=3; + //qDebug()<<"BL retry..."; + } + } + + } + return true; +} + diff --git a/src/sendWRcmd sm.cpp b/src/sendWRcmd sm.cpp new file mode 100755 index 0000000..4f226cc --- /dev/null +++ b/src/sendWRcmd sm.cpp @@ -0,0 +1,811 @@ +#include +#include +#include +#include +#include "tslib.h" +#include "sendWRcmd.h" +#include "shared_mem_buffer.h" + + +void indat_PrnPwr(void); + + +void sendWRcmd_INI(void) +{ + + sendWRcmd_clrCmdStack(); + sendWRcmd_clrCmd4Stack(); + sendFDcmd_clrStack(); + +} + +// Command Stack for commands without parameters + + +//static uint16_t nextAsynchsendCmd0[CMDSTACKDEPTH]; +//static uint8_t nrOfCmdsInQueue; + +/* convention: use simple (not rotating) FIFO Stack: +Example: nrOfCmdsInQueue=4 then + nextAsynchsendCmd0[0]=cmd1 // was stored as first + nextAsynchsendCmd0[1]=cmd2 + nextAsynchsendCmd0[2]=cmd3 + nextAsynchsendCmd0[3]=cmd4 // came in as last + + Send: [0] first, then move buffer 1 down: + nextAsynchsendCmd0[0]=cmd2 + nextAsynchsendCmd0[1]=cmd3 + nextAsynchsendCmd0[2]=cmd4 + nextAsynchsendCmd0[3]=0; + nrOfCmdsInQueue=3 now +*/ + +void sendWRcmd_clrCmdStack(void) +{ + uint8_t nn; + for (nn=0; nnnextAsynchsendCmd0[nn]=0; + SharedMem::write()->nrOfCmdsInQueue=0; +} + +bool sendWRcmd_setSendCommand0(uint16_t nextCmd) +{ + // write Command to memory, wait for transport + uint8_t ciq=SharedMem::read()->nrOfCmdsInQueue; + if (ciq>=CMDSTACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + + SharedMem::write()->nextAsynchsendCmd0[ciq++]=nextCmd; + SharedMem::write()->nrOfCmdsInQueue=ciq; + + //qDebug() << "PI cmd queued:"<< nextCmd << ", saved, pp=" << nrOfCmdsInQueue; + return true; // ok, will be sent +} + +uint16_t sendWRcmd_getSendCommand0(void) +{ + uint16_t nxtAsynchCmd, data; + uint8_t nn, ll; + uint8_t ciq=SharedMem::read()->nrOfCmdsInQueue; + + if (ciq==0 || ciq>CMDSTACKDEPTH) + return 0; // error + nxtAsynchCmd=SharedMem::read()->nextAsynchsendCmd0[0]; + + // move Puffer down by one element + if (ciq>0) + ll=ciq-1; + else + ll=0; + for (nn=0; nnnextAsynchsendCmd0[nn+1]; + SharedMem::write()->nextAsynchsendCmd0[nn]=data; + } + SharedMem::write()->nrOfCmdsInQueue=ciq; + //qDebug() << "PI cmd queued:"<< nxtAsynchCmd << ", restored, pp now =" << nrOfCmdsInQueue; + return nxtAsynchCmd; +} + +//--------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- +// Command Stack for commands with 4 parameters + + +/* +static uint16_t nextAsynchsendCmd4[CMD4STACKDEPTH]; +static uint8_t nextCmd4para1[CMD4STACKDEPTH]; +static uint8_t nextCmd4para2[CMD4STACKDEPTH]; +static uint8_t nextCmd4para3[CMD4STACKDEPTH]; +static uint8_t nextCmd4para4[CMD4STACKDEPTH]; +static uint8_t nrOfCmds4InQueue; +*/ + + +void sendWRcmd_clrCmd4Stack(void) +{ + uint8_t nn; + for (nn=0; nnnextAsynchsendCmd4[nn]=0; + SharedMem::write()->nextCmd4para1[nn]=0; + SharedMem::write()->nextCmd4para2[nn]=0; + SharedMem::write()->nextCmd4para3[nn]=0; + SharedMem::write()->nextCmd4para4[nn]=0; + } + SharedMem::write()->nrOfCmds4InQueue=0; +} + + +bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4) +{ + // write Command to memory, wait for transport + uint8_t ciq; + ciq=SharedMem::read()->nrOfCmds4InQueue; + + if (ciq>=CMD4STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + + SharedMem::write()->nextAsynchsendCmd4[ciq]=nextCmd; + SharedMem::write()->nextCmd4para1[ciq]=dat1; + SharedMem::write()->nextCmd4para2[ciq]=dat2; + SharedMem::write()->nextCmd4para3[ciq]=dat3; + SharedMem::write()->nextCmd4para4[ciq]=dat4; + ciq++; + SharedMem::write()->nrOfCmds4InQueue=ciq; + + //qDebug() << QDateTime::currentDateTime().time() + // << "sendWRcmd 4 byte saved, pp=" << nextCmd + // << " para: " << SharedMem::getDataConst()->nextCmd4para1[pp]; + + return true; // ok, will be sent +} + +/* +uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4) +{ + uint16_t nxtAsynchCmd; + uint8_t nn, ll; + + if (nrOfCmds4InQueue==0 || nrOfCmds4InQueue>CMD4STACKDEPTH) + return 0; // error + nxtAsynchCmd=nextAsynchsendCmd4[0]; + *dat1=nextCmd4para1[0]; + *dat2=nextCmd4para2[0]; + *dat3=nextCmd4para3[0]; + *dat4=nextCmd4para4[0]; + //qDebug() << "cmd4 restored to send from [0]; pp=" << nrOfCmds4InQueue; + //qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] << + // " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0]; + + // move Puffer down by one element + if (CMD4STACKDEPTH>0) + ll=CMD4STACKDEPTH-1; + else + ll=0; + for (nn=0; nn0) + nrOfCmds4InQueue--; + //qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue; + return nxtAsynchCmd; +} + + +*/ + +uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4) +{ + uint16_t nxtAsynchCmd, data; + uint8_t nn; + uint8_t ciq=SharedMem::read()->nrOfCmds4InQueue; + + if (ciq==0 || ciq > CMD4STACKDEPTH) + return 0; // error + + nxtAsynchCmd=SharedMem::read()->nextAsynchsendCmd4[0]; + *dat1=SharedMem::read()->nextCmd4para1[0]; + *dat2=SharedMem::read()->nextCmd4para2[0]; + *dat3=SharedMem::read()->nextCmd4para3[0]; + *dat4=SharedMem::read()->nextCmd4para4[0]; + //qDebug() << "cmd4 restored to send from [0]; pp=" << nrOfCmds4InQueue; + //qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] << + // " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0]; + + // move Puffer down by one element + if (ciq>0) ciq--; + + for (nn=0; nnnextAsynchsendCmd4[nn+1]; + SharedMem::write()->nextAsynchsendCmd4[nn]=data; + data=SharedMem::read()->nextCmd4para1[nn+1]; + SharedMem::write()->nextCmd4para1[nn]=data; + data=SharedMem::read()->nextCmd4para2[nn+1]; + SharedMem::write()->nextCmd4para2[nn]=data; + data=SharedMem::read()->nextCmd4para3[nn+1]; + SharedMem::write()->nextCmd4para3[nn]=data; + data=SharedMem::read()->nextCmd4para4[nn+1]; + SharedMem::write()->nextCmd4para4[nn]=data; + } + + SharedMem::write()->nrOfCmds4InQueue=ciq; + return nxtAsynchCmd; +} + + + +void sendWRcmd_clrCmd8Stack(void) +{ + uint8_t nn; + for (nn=0; nnnextAsynchsendCmd8[nn]=0; + SharedMem::write()->nextCmd8para1[nn]=0; + SharedMem::write()->nextCmd8para2[nn]=0; + SharedMem::write()->nextCmd8para3[nn]=0; + SharedMem::write()->nextCmd8para4[nn]=0; + } + SharedMem::write()->nrOfCmds8InQueue=0; +} + +bool sendWRcmd_setSendCommand8(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint16_t dat3, uint32_t dat4) +{ + // write Command to memory, wait for transport + uint8_t ciq; + ciq=SharedMem::read()->nrOfCmds8InQueue; + + if (ciq>=CMD8STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + SharedMem::write()->nextAsynchsendCmd8[ciq]=nextCmd; + SharedMem::write()->nextCmd8para1[ciq]=dat1; + SharedMem::write()->nextCmd8para2[ciq]=dat2; + SharedMem::write()->nextCmd8para3[ciq]=dat3; + SharedMem::write()->nextCmd8para4[ciq]=dat4; + ciq++; + SharedMem::write()->nrOfCmds8InQueue=ciq; + return true; // ok, will be sent +} + +uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3, uint32_t *dat4) +{ + uint16_t nxtAsynchCmd, data; + uint8_t nn; + + uint8_t ciq=SharedMem::read()->nrOfCmds8InQueue; + + if (ciq==0 || ciq > CMD8STACKDEPTH) + return 0; // error + + nxtAsynchCmd=SharedMem::read()->nextAsynchsendCmd8[0]; + *dat1=SharedMem::read()->nextCmd8para1[0]; + *dat2=SharedMem::read()->nextCmd8para2[0]; + *dat3=SharedMem::read()->nextCmd8para3[0]; + *dat4=SharedMem::read()->nextCmd8para4[0]; + + // move buffer down by one element + if (ciq>0) ciq--; + + for (nn=0; nnnextAsynchsendCmd8[nn+1]; + SharedMem::write()->nextAsynchsendCmd8[nn]=data; + data=SharedMem::read()->nextCmd8para1[nn+1]; + SharedMem::write()->nextCmd8para1[nn]=data; + data=SharedMem::read()->nextCmd8para2[nn+1]; + SharedMem::write()->nextCmd8para2[nn]=data; + data=SharedMem::read()->nextCmd8para3[nn+1]; + SharedMem::write()->nextCmd8para3[nn]=data; + data=SharedMem::read()->nextCmd8para4[nn+1]; + SharedMem::write()->nextCmd8para4[nn]=data; + } + SharedMem::write()->nrOfCmds8InQueue=ciq; + return nxtAsynchCmd; +} + + + +//static uint8_t sendAsynchDataBuf[160]; // no stack, only ONE buffer +//static uint8_t sendAsyDatLen; + +bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t *buf) +{ + if (leng>SENDASYDAT_BUFFSIZE) leng=SENDASYDAT_BUFFSIZE; + SharedMem::write()->sendAsyDatLen=leng; + tslib_strclr(SharedMem::write()->sendAsynchDataBuf, 0, SENDASYDAT_BUFFSIZE); + for (uint8_t nn=0; nnsendAsynchDataBuf[nn]=buf[nn]; + return true; // ok, will be sent +} + +uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf) +{ + + uint8_t dl=SharedMem::read()->sendAsyDatLen; + *leng=dl; + for (uint8_t nn=0; nnsendAsynchDataBuf[nn]; + SharedMem::write()->sendAsyDatLen=0; + //tslib_strclr(SharedMem::write()->sendAsynchDataBuf, 0, SENDASYDAT_BUFFSIZE); + return *leng; +} + + +// ------------------------------------------------------------------------------------ +// MDB Sendind Data are store here for next transport to DC (Device Controller) +// Transport to Slave runs every 100ms, answer from mdb-slave (e.g. coin changer) comes rigth +// with next slave answer + +// start with: SENDDIRCMD_EXCHGMDB, + // send crude data from here to DC, DC to mdb slaves, mdb answer, return here within 50ms + + +//static uint8_t Sdata_mdbSendBuffer[MDBSEND_BUFFSIZE]; +//static uint8_t Sdata_mdbSendLen; + +uint8_t epi_store64ByteSendData(uint8_t length, uint8_t *buf) +{ + if (length>MDBSEND_BUFFSIZE) length=MDBSEND_BUFFSIZE; + + // HWapi writes data to be forwarded to DC and further to mdb-device + for (uint8_t nn=0; nnSdata_mdbSendBuffer[nn]=buf[nn]; + SharedMem::write()->Sdata_mdbSendLen=length; + return 0; +} + +uint8_t gpi_restore64ByteSendData(uint8_t *length, uint8_t *buf) +{ + // datif reads data to forward to dc + uint8_t dl=SharedMem::read()->Sdata_mdbSendLen; + + for (uint8_t nn=0; nnSdata_mdbSendBuffer[nn]; + *length=dl; + SharedMem::write()->Sdata_mdbSendLen=0; + return 0; +} + + + + +//------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ +//---------------------------------------- Printer Text Fifo ------------------------- +//static uint8_t prnDataParameters[]; +//static uint8_t prnDataBufferUser; + +void epi_storeUserOfSendingTextBuffer(uint8_t user, uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4 ) +{ + // user=1: Text-Print is using this buffer + // 2: QR-code-Printer is using this buffer + SharedMem::write()->prnDataBufferUser=user; + SharedMem::write()->prnDataParameters[0]=para1; + SharedMem::write()->prnDataParameters[1]=para2; + SharedMem::write()->prnDataParameters[2]=para3; + SharedMem::write()->prnDataParameters[3]=para4; + +// qDebug() << "new user stored: " << user; + +} + +uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2, uint8_t *para3, uint8_t *para4) +{ + // user=1: Text-Print is using this buffer + // 2: QR-code-Printer is using this buffer + //qDebug() << "returning user "<< prnDataBufferUser; + + *para1=SharedMem::read()->prnDataParameters[0]; + *para2=SharedMem::read()->prnDataParameters[1]; + *para3=SharedMem::read()->prnDataParameters[2]; + *para4=SharedMem::read()->prnDataParameters[3]; + return SharedMem::read()->prnDataBufferUser; + +} + + + + + + + + // Sending Text Fifo +// ONE printer doc consists of 20 x 64 byte +// #define MAXNROF_PRNBYTES 64 +// #define MAXNROF_PRNBLOCKS 20 +//static char Sdata_PRN_TEXT[MAXNROF_PRNBLOCKS][MAXNROF_PRNBYTES]; +//static uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK +//static uint8_t pPrnDataBuff; // points to next waiting printer text +// defined above, needed if more then one text is stored (before sent) +// every block will be sent after 100ms, if 8 blocks are stored within this 100ms +// then pointer goes up to 8. Important: FIFO!!!!!!!! + +void epi_resetPrinterStack(void) +{ + SharedMem::write()->pPrnDataBuff=0; +} + +uint8_t epi_storePrnText(char *buf, uint8_t leng) +{ + // store text from Gui in next higher free memory 0....9 + + uint16_t len; + uint8_t pp, nn; + + pp=SharedMem::read()->pPrnDataBuff; // next free memory block with 64byte each + if (pp>=MAXNROF_PRNBLOCKS) + return 1; // not possible, no free mem + + //len=tslib_strlen(buf); // kennt keine Binärzeichen!!!!!! + len=leng; + if (len>MAXNROF_PRNBYTES) + len=MAXNROF_PRNBYTES; + + tslib_strclr(SharedMem::write()->Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES); + + for (nn=0; nnSdata_PRN_TEXT[pp][nn]=buf[nn]; // copy new text into buffer + + if (SharedMem::read()->pPrnDataBuffpPrnDataBuff++; // inc pointer if end not yet reached + return 0; // OK +} + + + +uint8_t gpi_restorePrnText(uint8_t *retbuf) +{ + // read printer text and send to slave, size of retbuf == 64 + + // always read from [0] because this is the oldest (Fifo) + // then move all text lines down by one and dec pointer + + uint8_t nn, mm, pp=SharedMem::read()->pPrnDataBuff; + char buf[MAXNROF_PRNBYTES]; + + if (pp==0) // next free memory block with 64byte each + return 1; // no text in buffer + + // example: pp=5: then buffers [0...4] are occupied + + for (nn=0; nnSdata_PRN_TEXT[0][nn]); // restore oldest text + + // now copy textline [1] to [0], then + // copy textline [2] to [1], then + // copy textline [3] to [2] .... upto [pp-1] to [pp-2] + // hint: copying from 9....0 would delete all strings!!!!!! + for (nn=0; nn<(pp-1); nn++) + { + for (mm=0; mmSdata_PRN_TEXT[nn+1][mm]; + for (mm=0; mmSdata_PRN_TEXT[nn][mm]=buf[mm]; + } + if (pp>0) pp--; + SharedMem::write()->pPrnDataBuff=pp; + + // example: pp=4: then buffers [0...3] are still occupied, pp=0: all buffers empty + + // now clear highest copyed line (which became free now) + tslib_strclr(SharedMem::write()->Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES); + + // optionally: clear all remaining higher lines: + for (nn=(pp+1); nnSdata_PRN_TEXT[nn], 0, MAXNROF_PRNBYTES); + + return 0; +} + +uint8_t gpi_chk4remainingText(void) +{ + // retval: 0: no more textline left (to send) >0: nr of 64byte-blocks + return (SharedMem::read()->pPrnDataBuff); +} + + + + + + + + + + +// --------------------------------------------------------------------------------- +// 11.4.23 neu, Kommando direkt an "FastDevice"-protokoll senden, nicht mehr umsetzen +// --------------------------------------------------------------------------------- +/* +// header +static uint8_t nextFDwrCmd[FDCMD_STACKDEPTH]; +static uint8_t nextFDrdCmd[FDCMD_STACKDEPTH]; +static uint8_t nextFDblkNr[FDCMD_STACKDEPTH]; +static uint8_t nextFDshort[FDCMD_STACKDEPTH]; + +// short data +static uint8_t nextFDpara1[FDCMD_STACKDEPTH]; +static uint8_t nextFDpara2[FDCMD_STACKDEPTH]; +static uint8_t nextFDpara3[FDCMD_STACKDEPTH]; +static uint8_t nextFDpara4[FDCMD_STACKDEPTH]; +// long data: +static uint8_t longFDlength[FDCMD_STACKDEPTH]; +static uint8_t longFDpara[FDCMD_STACKDEPTH][64]; + +static uint8_t p_nextFDcmdsInQueue; +*/ + +/* convention: use simple (not rotating) FIFO Stack: +Example: nrOfCmdsInQueue=4 then + nextAsynchsendCmd0[0]=cmd1 // was stored as first + nextAsynchsendCmd0[1]=cmd2 + nextAsynchsendCmd0[2]=cmd3 + nextAsynchsendCmd0[3]=cmd4 // came in as last + + Send: [0] first, then move buffer 1 down: + nextAsynchsendCmd0[0]=cmd2 + nextAsynchsendCmd0[1]=cmd3 + nextAsynchsendCmd0[2]=cmd4 + nextAsynchsendCmd0[3]=0; + nrOfCmdsInQueue=3 now +*/ + + +void sendFDcmd_clrStack(void) +{ + uint8_t nn; + for (nn=0; nnnextFDwrCmd[nn]=0; + SharedMem::write()->nextFDrdCmd[nn]=0; + SharedMem::write()->nextFDblkNr[nn]=0; + SharedMem::write()->nextFDshort[nn]=0; + SharedMem::write()->nextFDpara1[nn]=0; + SharedMem::write()->nextFDpara2[nn]=0; + SharedMem::write()->nextFDpara3[nn]=0; + SharedMem::write()->nextFDpara4[nn]=0; + SharedMem::write()->longFDlength[nn]=0; + memset(&SharedMem::write()->longFDpara[nn][0],0,64); + } + + SharedMem::write()->p_nextFDcmdsInQueue=0; +} + +bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4) +{ + + // write Command to memory, wait for transport + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd >=FDCMD_STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + SharedMem::write()->nextFDwrCmd[pFDcmd]=nextWrCmd; + SharedMem::write()->nextFDrdCmd[pFDcmd]=nextRdCmd; + SharedMem::write()->nextFDblkNr[pFDcmd]=blockNum; + SharedMem::write()->nextFDpara1[pFDcmd]=dat1; + SharedMem::write()->nextFDpara2[pFDcmd]=dat2; + SharedMem::write()->nextFDpara3[pFDcmd]=dat3; + SharedMem::write()->nextFDpara4[pFDcmd]=dat4; + //qDebug() << "data with 4 data byte saved, pp=" << pFDcmd; + //qDebug() << " dat1=" << nextCmd4para1[pFDcmd] << " dat2=" << nextCmd4para2[pFDcmd] + // << " dat3=" << nextCmd4para3[pFDcmd] << " dat4=" << nextCmd4para4[pFDcmd]; + SharedMem::write()->nextFDshort[pFDcmd]=1; // 1=short + pFDcmd++; + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + + return true; // ok, will be sent +} + + +bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data) +{ + // write Command to memory, wait for transport + // data buffer size always 64! data[64], padded with 0 + uint8_t nn; + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd>=FDCMD_STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + SharedMem::write()->nextFDwrCmd[pFDcmd]=nextWrCmd; + SharedMem::write()->nextFDrdCmd[pFDcmd]=nextRdCmd; + SharedMem::write()->nextFDblkNr[pFDcmd]=blockNum; + + SharedMem::write()->longFDlength[pFDcmd]=length; + + for (nn=0; nn<64; nn++) + SharedMem::write()->longFDpara[pFDcmd][nn]=data[nn]; + + SharedMem::write()->nextFDshort[pFDcmd]=2; + pFDcmd++; + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + return true; // ok, will be sent +} + + +bool sendFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4) +{ + uint8_t nn, mm, data; // ll + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd==0 || pFDcmd>FDCMD_STACKDEPTH) + return false; // not possible + + *nextWrCmd=SharedMem::read()->nextFDwrCmd[0]; + *nextRdCmd=SharedMem::read()->nextFDrdCmd[0]; + *blockNum=SharedMem::read()->nextFDblkNr[0]; + *dat1=SharedMem::read()->nextFDpara1[0]; + *dat2=SharedMem::read()->nextFDpara2[0]; + *dat3=SharedMem::read()->nextFDpara3[0]; + *dat4=SharedMem::read()->nextFDpara4[0]; + //qDebug() << "sendFDcmd_get [0]; pp=" << SharedMem::read()->p_nextFDcmdsInQueue; + //qDebug() << " data1: " << SharedMem::read()->nextCmd4para1[0] << " data2: " << SharedMem::read()->nextCmd4para2[0] << + // " data3: " << SharedMem::read()->nextCmd4para3[0] << " data4: " << SharedMem::read()->nextCmd4para4[0]; + + // move Puffer down by one element + //if (FDCMD_STACKDEPTH>0) + // ll=FDCMD_STACKDEPTH-1; + //else + // ll=0; + + if (pFDcmd>0) pFDcmd--; else pFDcmd=0; + + //for (nn=0; nnnextFDwrCmd[nn+1]; + SharedMem::write()->nextFDwrCmd[nn]=data; + data=SharedMem::read()->nextFDrdCmd[nn+1]; + SharedMem::write()->nextFDrdCmd[nn]=data; + data=SharedMem::read()->nextFDblkNr[nn+1]; + SharedMem::write()->nextFDblkNr[nn]=data; + data=SharedMem::read()->nextFDpara1[nn+1]; + SharedMem::write()->nextFDpara1[nn]=data; + data=SharedMem::read()->nextFDpara2[nn+1]; + SharedMem::write()->nextFDpara2[nn]=data; + data=SharedMem::read()->nextFDpara3[nn+1]; + SharedMem::write()->nextFDpara3[nn]=data; + data=SharedMem::read()->nextFDpara4[nn+1]; + SharedMem::write()->nextFDpara4[nn]=data; + + data=SharedMem::read()->nextFDshort[nn+1]; + SharedMem::write()->nextFDshort[nn] = data; + + data=SharedMem::read()->longFDlength[nn+1]; + SharedMem::write()->longFDlength[nn] = data; + + for (mm=0; mm<64; mm++) + { + SharedMem::write()->longFDpara[nn][mm] = SharedMem::read()->longFDpara[nn+1][mm]; + } + + } + + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + //qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue; + + // clear released buffer: + //for (nn=p_nextFDcmdsInQueue; nnnextFDwrCmd[pFDcmd]=0; + SharedMem::write()->nextFDrdCmd[pFDcmd]=0; + SharedMem::write()->nextFDblkNr[pFDcmd]=0; + + SharedMem::write()->nextFDpara1[pFDcmd]=0; + SharedMem::write()->nextFDpara2[pFDcmd]=0; + SharedMem::write()->nextFDpara3[pFDcmd]=0; + SharedMem::write()->nextFDpara4[pFDcmd]=0; + SharedMem::write()->nextFDshort[pFDcmd]=0; + SharedMem::write()->longFDlength[pFDcmd]=0; + for (mm=0; mm<64; mm++) + SharedMem::write()->longFDpara[pFDcmd][mm] = 0; + //} + +/* + qDebug() << "sendFDcmd_set, stack now: " << p_nextFDcmdsInQueue; + for (nn=0; nn<16; nn++) + { + qDebug() << "header: " << nextFDwrCmd[nn] << " / " << nextFDrdCmd[nn] << " / "<< nextFDblkNr[nn] << " / " << nextFDshort[nn]; + + qDebug() << " short data: " << nextFDpara1[nn] << " / "<< nextFDpara2[nn] << " / "<< nextFDpara3[nn]<< " / "<< nextFDpara4[nn]; + + qDebug() << " long data: " << longFDlength[nn] << " / "<< longFDpara[nn][0] << " / "<< longFDpara[nn][1] + << " / "<< longFDpara[nn][2] << " / "<< longFDpara[nn][3] << " / "<< longFDpara[nn][4]; + } +*/ + return true; // ok, will be sent +} + +uint8_t checkNextFDcmd(void) +{ + // return 0: no command waiting +// 1: short cmd +// 2: long cmd + //qDebug() << "chk nxt fd cmd: "<p_nextFDcmdsInQueue==0) + return 0; + if (SharedMem::read()->nextFDshort[0]==1) + return 1; + return 2; +} + +uint8_t check4FDshortCmd(void) +{ + // returns number of waiting command, max FDCMD_STACKDEPTH + return SharedMem::read()->p_nextFDcmdsInQueue; +} + + +uint8_t check4freeFDshortCmd(void) +{ + // returns number of free places in short-command stack + return FDCMD_STACKDEPTH - SharedMem::read()->p_nextFDcmdsInQueue; +} + +bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data) +{ + uint8_t nn, mm, uctmp; + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd==0 || pFDcmd>FDCMD_STACKDEPTH) + return false; // not possible + + *nextWrCmd=SharedMem::read()->nextFDwrCmd[0]; + *nextRdCmd=SharedMem::read()->nextFDrdCmd[0]; + *blockNum=SharedMem::read()->nextFDblkNr[0]; + *length = SharedMem::read()->longFDlength[0]; + for (mm=0; mm<64; mm++) + data[mm] = SharedMem::read()->longFDpara[0][mm]; + + if (pFDcmd>0) pFDcmd--; else pFDcmd=0; + + //for (nn=0; nnnextFDwrCmd[nn+1]; + SharedMem::write()->nextFDwrCmd[nn]=uctmp; + uctmp=SharedMem::read()->nextFDrdCmd[nn+1]; + SharedMem::write()->nextFDrdCmd[nn]=uctmp; + uctmp=SharedMem::read()->nextFDblkNr[nn+1]; + SharedMem::write()->nextFDblkNr[nn]=uctmp; + + uctmp=SharedMem::read()->nextFDpara1[nn+1]; + SharedMem::write()->nextFDpara1[nn]=uctmp; + uctmp=SharedMem::read()->nextFDpara2[nn+1]; + SharedMem::write()->nextFDpara2[nn]=uctmp; + uctmp=SharedMem::read()->nextFDpara3[nn+1]; + SharedMem::write()->nextFDpara3[nn]=uctmp; + uctmp=SharedMem::read()->nextFDpara4[nn+1]; + SharedMem::write()->nextFDpara4[nn]=uctmp; + + uctmp=SharedMem::read()->nextFDshort[nn+1]; + SharedMem::write()->nextFDshort[nn]=uctmp; + uctmp=SharedMem::read()->longFDlength[nn+1]; + SharedMem::write()->longFDlength[nn]=uctmp; + + for (mm=0; mm<64; mm++) + { + SharedMem::write()->longFDpara[nn][mm] = SharedMem::read()->longFDpara[nn+1][mm]; + } + + } + + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + // clear released buffer: + SharedMem::write()->nextFDwrCmd[pFDcmd]=0; + SharedMem::write()->nextFDrdCmd[pFDcmd]=0; + SharedMem::write()->nextFDblkNr[pFDcmd]=0; + + SharedMem::write()->nextFDpara1[pFDcmd]=0; + SharedMem::write()->nextFDpara2[pFDcmd]=0; + SharedMem::write()->nextFDpara3[pFDcmd]=0; + SharedMem::write()->nextFDpara4[pFDcmd]=0; + SharedMem::write()->nextFDshort[pFDcmd]=0; + SharedMem::write()->longFDlength[pFDcmd]=0; + for (mm=0; mm<64; mm++) + SharedMem::write()->longFDpara[pFDcmd][mm] = 0; + + return true; // ok, will be sent +} + + + diff --git a/src/sendWRcmd.cpp b/src/sendWRcmd.cpp new file mode 100644 index 0000000..0f3cec1 --- /dev/null +++ b/src/sendWRcmd.cpp @@ -0,0 +1,842 @@ +#include +#include +#include +#include +#include "tslib.h" +#include "sendWRcmd.h" +#include "shared_mem_buffer.h" + + +void indat_PrnPwr(void); + + +void sendWRcmd_INI(void) +{ + + //sendWRcmd_clrCmdStack(); + //sendWRcmd_clrCmd4Stack(); + sendFDcmd_clrStack(); + +} + +// Command Stack for commands without parameters + + +//static uint16_t nextAsynchsendCmd0[CMDSTACKDEPTH]; +//static uint8_t nrOfCmdsInQueue; + +/* convention: use simple (not rotating) FIFO Stack: +Example: nrOfCmdsInQueue=4 then + nextAsynchsendCmd0[0]=cmd1 // was stored as first + nextAsynchsendCmd0[1]=cmd2 + nextAsynchsendCmd0[2]=cmd3 + nextAsynchsendCmd0[3]=cmd4 // came in as last + + Send: [0] first, then move buffer 1 down: + nextAsynchsendCmd0[0]=cmd2 + nextAsynchsendCmd0[1]=cmd3 + nextAsynchsendCmd0[2]=cmd4 + nextAsynchsendCmd0[3]=0; + nrOfCmdsInQueue=3 now +*/ + +void sendWRcmd_clrCmdStack(void) +{ + uint8_t nn; + for (nn=0; nnnextAsynchsendCmd0[nn]=0; + SharedMem::write()->nrOfCmdsInQueue=0; +} + +bool sendWRcmd_setSendCommand0(uint16_t nextCmd) +{ + // write Command to memory, wait for transport + uint8_t ciq=SharedMem::read()->nrOfCmdsInQueue; + if (ciq>=CMDSTACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + + SharedMem::write()->nextAsynchsendCmd0[ciq++]=nextCmd; + SharedMem::write()->nrOfCmdsInQueue=ciq; + + //qDebug() << "PI cmd queued:"<< nextCmd << ", saved, pp=" << nrOfCmdsInQueue; + return true; // ok, will be sent +} + +uint16_t sendWRcmd_getSendCommand0(void) +{ + uint16_t nxtAsynchCmd, data; + uint8_t nn; + uint8_t ciq=SharedMem::read()->nrOfCmdsInQueue; + + if (ciq==0 || ciq>CMDSTACKDEPTH) + return 0; // error + nxtAsynchCmd=SharedMem::read()->nextAsynchsendCmd0[0]; + + // move Puffer down by one element + if (ciq>0) ciq--; + for (nn=0; nnnextAsynchsendCmd0[nn+1]; + SharedMem::write()->nextAsynchsendCmd0[nn]=data; + } + SharedMem::write()->nrOfCmdsInQueue=ciq; + //qDebug() << "PI cmd queued:"<< nxtAsynchCmd << ", restored, pp now =" << nrOfCmdsInQueue; + return nxtAsynchCmd; +} + +//--------------------------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------------------------- +// Command Stack for commands with 4 parameters + + +/* +static uint16_t nextAsynchsendCmd4[CMD4STACKDEPTH]; +static uint8_t nextCmd4para1[CMD4STACKDEPTH]; +static uint8_t nextCmd4para2[CMD4STACKDEPTH]; +static uint8_t nextCmd4para3[CMD4STACKDEPTH]; +static uint8_t nextCmd4para4[CMD4STACKDEPTH]; +static uint8_t nrOfCmds4InQueue; +*/ + +/* +void sendWRcmd_clrCmd4Stack(void) +{ + uint8_t nn; + for (nn=0; nnnextAsynchsendCmd4[nn]=0; + SharedMem::write()->nextCmd4para1[nn]=0; + SharedMem::write()->nextCmd4para2[nn]=0; + SharedMem::write()->nextCmd4para3[nn]=0; + SharedMem::write()->nextCmd4para4[nn]=0; + } + SharedMem::write()->nrOfCmds4InQueue=0; +} + + +bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4) +{ + // write Command to memory, wait for transport + uint8_t ciq; + ciq=SharedMem::read()->nrOfCmds4InQueue; + + if (ciq>=CMD4STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + + SharedMem::write()->nextAsynchsendCmd4[ciq]=nextCmd; + SharedMem::write()->nextCmd4para1[ciq]=dat1; + SharedMem::write()->nextCmd4para2[ciq]=dat2; + SharedMem::write()->nextCmd4para3[ciq]=dat3; + SharedMem::write()->nextCmd4para4[ciq]=dat4; + ciq++; + SharedMem::write()->nrOfCmds4InQueue=ciq; + + //qDebug() << QDateTime::currentDateTime().time() + // << "sendWRcmd 4 byte saved, pp=" << nextCmd + // << " para: " << SharedMem::getDataConst()->nextCmd4para1[pp]; + + return true; // ok, will be sent +} +*/ +/* +uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4) +{ + uint16_t nxtAsynchCmd; + uint8_t nn, ll; + + if (nrOfCmds4InQueue==0 || nrOfCmds4InQueue>CMD4STACKDEPTH) + return 0; // error + nxtAsynchCmd=nextAsynchsendCmd4[0]; + *dat1=nextCmd4para1[0]; + *dat2=nextCmd4para2[0]; + *dat3=nextCmd4para3[0]; + *dat4=nextCmd4para4[0]; + //qDebug() << "cmd4 restored to send from [0]; pp=" << nrOfCmds4InQueue; + //qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] << + // " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0]; + + // move Puffer down by one element + if (CMD4STACKDEPTH>0) + ll=CMD4STACKDEPTH-1; + else + ll=0; + for (nn=0; nn0) + nrOfCmds4InQueue--; + //qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue; + return nxtAsynchCmd; +} + + +*/ +/* +uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4) +{ + uint16_t nxtAsynchCmd, data; + uint8_t nn; + uint8_t ciq=SharedMem::read()->nrOfCmds4InQueue; + + if (ciq==0 || ciq > CMD4STACKDEPTH) + return 0; // error + + nxtAsynchCmd=SharedMem::read()->nextAsynchsendCmd4[0]; + *dat1=SharedMem::read()->nextCmd4para1[0]; + *dat2=SharedMem::read()->nextCmd4para2[0]; + *dat3=SharedMem::read()->nextCmd4para3[0]; + *dat4=SharedMem::read()->nextCmd4para4[0]; + //qDebug() << "cmd4 restored to send from [0]; pp=" << nrOfCmds4InQueue; + //qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] << + // " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0]; + + // move Puffer down by one element + if (ciq>0) ciq--; + + for (nn=0; nnnextAsynchsendCmd4[nn+1]; + SharedMem::write()->nextAsynchsendCmd4[nn]=data; + data=SharedMem::read()->nextCmd4para1[nn+1]; + SharedMem::write()->nextCmd4para1[nn]=data; + data=SharedMem::read()->nextCmd4para2[nn+1]; + SharedMem::write()->nextCmd4para2[nn]=data; + data=SharedMem::read()->nextCmd4para3[nn+1]; + SharedMem::write()->nextCmd4para3[nn]=data; + data=SharedMem::read()->nextCmd4para4[nn+1]; + SharedMem::write()->nextCmd4para4[nn]=data; + } + + SharedMem::write()->nrOfCmds4InQueue=ciq; + return nxtAsynchCmd; +} +*/ + + +/* +void sendWRcmd_clrCmd8Stack(void) +{ + uint8_t nn; + for (nn=0; nnnextAsynchsendCmd8[nn]=0; + SharedMem::write()->nextCmd8para1[nn]=0; + SharedMem::write()->nextCmd8para2[nn]=0; + SharedMem::write()->nextCmd8para3[nn]=0; + SharedMem::write()->nextCmd8para4[nn]=0; + } + SharedMem::write()->nrOfCmds8InQueue=0; +} + +bool sendWRcmd_setSendCommand8(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint16_t dat3, uint32_t dat4) +{ + // write Command to memory, wait for transport + uint8_t ciq; + ciq=SharedMem::read()->nrOfCmds8InQueue; + + if (ciq>=CMD8STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + SharedMem::write()->nextAsynchsendCmd8[ciq]=nextCmd; + SharedMem::write()->nextCmd8para1[ciq]=dat1; + SharedMem::write()->nextCmd8para2[ciq]=dat2; + SharedMem::write()->nextCmd8para3[ciq]=dat3; + SharedMem::write()->nextCmd8para4[ciq]=dat4; + ciq++; + SharedMem::write()->nrOfCmds8InQueue=ciq; + return true; // ok, will be sent +} + +uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3, uint32_t *dat4) +{ + uint16_t nxtAsynchCmd, data; + uint8_t nn; + + uint8_t ciq=SharedMem::read()->nrOfCmds8InQueue; + + if (ciq==0 || ciq > CMD8STACKDEPTH) + return 0; // error + + nxtAsynchCmd=SharedMem::read()->nextAsynchsendCmd8[0]; + *dat1=SharedMem::read()->nextCmd8para1[0]; + *dat2=SharedMem::read()->nextCmd8para2[0]; + *dat3=SharedMem::read()->nextCmd8para3[0]; + *dat4=SharedMem::read()->nextCmd8para4[0]; + + // move buffer down by one element + if (ciq>0) ciq--; + + for (nn=0; nnnextAsynchsendCmd8[nn+1]; + SharedMem::write()->nextAsynchsendCmd8[nn]=data; + data=SharedMem::read()->nextCmd8para1[nn+1]; + SharedMem::write()->nextCmd8para1[nn]=data; + data=SharedMem::read()->nextCmd8para2[nn+1]; + SharedMem::write()->nextCmd8para2[nn]=data; + data=SharedMem::read()->nextCmd8para3[nn+1]; + SharedMem::write()->nextCmd8para3[nn]=data; + data=SharedMem::read()->nextCmd8para4[nn+1]; + SharedMem::write()->nextCmd8para4[nn]=data; + } + SharedMem::write()->nrOfCmds8InQueue=ciq; + return nxtAsynchCmd; +} +*/ + + +//static uint8_t sendAsynchDataBuf[160]; // no stack, only ONE buffer +//static uint8_t sendAsyDatLen; + +bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t *buf) +{ + if (leng>SENDASYDAT_BUFFSIZE) leng=SENDASYDAT_BUFFSIZE; + SharedMem::write()->sendAsyDatLen=leng; + tslib_strclr(SharedMem::write()->sendAsynchDataBuf, 0, SENDASYDAT_BUFFSIZE); + for (uint8_t nn=0; nnsendAsynchDataBuf[nn]=buf[nn]; + return true; // ok, will be sent +} + +uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf) +{ + + uint8_t dl=SharedMem::read()->sendAsyDatLen; + *leng=dl; + for (uint8_t nn=0; nnsendAsynchDataBuf[nn]; + SharedMem::write()->sendAsyDatLen=0; + //tslib_strclr(SharedMem::write()->sendAsynchDataBuf, 0, SENDASYDAT_BUFFSIZE); + return *leng; +} + + +// ------------------------------------------------------------------------------------ +// MDB Sendind Data are store here for next transport to DC (Device Controller) +// Transport to Slave runs every 100ms, answer from mdb-slave (e.g. coin changer) comes rigth +// with next slave answer + +// start with: SENDDIRCMD_EXCHGMDB, + // send crude data from here to DC, DC to mdb slaves, mdb answer, return here within 50ms + + +//static uint8_t Sdata_mdbSendBuffer[MDBSEND_BUFFSIZE]; +//static uint8_t Sdata_mdbSendLen; +/* +uint8_t epi_store64ByteSendData(uint8_t length, uint8_t *buf) +{ + if (length>MDBSEND_BUFFSIZE) length=MDBSEND_BUFFSIZE; + + // HWapi writes data to be forwarded to DC and further to mdb-device + for (uint8_t nn=0; nnSdata_mdbSendBuffer[nn]=buf[nn]; + SharedMem::write()->Sdata_mdbSendLen=length; + return 0; +} + +uint8_t gpi_restore64ByteSendData(uint8_t *length, uint8_t *buf) +{ + // datif reads data to forward to dc + uint8_t dl=SharedMem::read()->Sdata_mdbSendLen; + + for (uint8_t nn=0; nnSdata_mdbSendBuffer[nn]; + *length=dl; + SharedMem::write()->Sdata_mdbSendLen=0; + return 0; +} +*/ + + + +//------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ +//---------------------------------------- Printer Text Fifo ------------------------- +//static uint8_t prnDataParameters[]; +//static uint8_t prnDataBufferUser; + +/* +void epi_storeUserOfSendingTextBuffer(uint8_t user, uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4 ) +{ + // user=1: Text-Print is using this buffer + // 2: QR-code-Printer is using this buffer + SharedMem::write()->prnDataBufferUser=user; + SharedMem::write()->prnDataParameters[0]=para1; + SharedMem::write()->prnDataParameters[1]=para2; + SharedMem::write()->prnDataParameters[2]=para3; + SharedMem::write()->prnDataParameters[3]=para4; + +// qDebug() << "new user stored: " << user; + +} + +uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2, uint8_t *para3, uint8_t *para4) +{ + // user=1: Text-Print is using this buffer + // 2: QR-code-Printer is using this buffer + //qDebug() << "returning user "<< prnDataBufferUser; + + *para1=SharedMem::read()->prnDataParameters[0]; + *para2=SharedMem::read()->prnDataParameters[1]; + *para3=SharedMem::read()->prnDataParameters[2]; + *para4=SharedMem::read()->prnDataParameters[3]; + return SharedMem::read()->prnDataBufferUser; + +} +*/ + + + + + + + // Sending Text Fifo +// ONE printer doc consists of 20 x 64 byte +// #define MAXNROF_PRNBYTES 64 +// #define MAXNROF_PRNBLOCKS 20 +//static char Sdata_PRN_TEXT[MAXNROF_PRNBLOCKS][MAXNROF_PRNBYTES]; +//static uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK +//static uint8_t pPrnDataBuff; // points to next waiting printer text +// defined above, needed if more then one text is stored (before sent) +// every block will be sent after 100ms, if 8 blocks are stored within this 100ms +// then pointer goes up to 8. Important: FIFO!!!!!!!! +/* +void epi_resetPrinterStack(void) +{ + SharedMem::write()->pPrnDataBuff=0; +} + +uint8_t epi_storePrnText(char *buf, uint8_t leng) +{ + // store text from Gui in next higher free memory 0....9 + + uint16_t len; + uint8_t pp, nn; + + pp=SharedMem::read()->pPrnDataBuff; // next free memory block with 64byte each + if (pp>=MAXNROF_PRNBLOCKS) + return 1; // not possible, no free mem + + //len=tslib_strlen(buf); // kennt keine Binärzeichen!!!!!! + len=leng; + if (len>MAXNROF_PRNBYTES) + len=MAXNROF_PRNBYTES; + + tslib_strclr(SharedMem::write()->Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES); + + for (nn=0; nnSdata_PRN_TEXT[pp][nn]=buf[nn]; // copy new text into buffer + + if (SharedMem::read()->pPrnDataBuffpPrnDataBuff++; // inc pointer if end not yet reached + return 0; // OK +} + + + +uint8_t gpi_restorePrnText(uint8_t *retbuf) +{ + // read printer text and send to slave, size of retbuf == 64 + + // always read from [0] because this is the oldest (Fifo) + // then move all text lines down by one and dec pointer + + uint8_t nn, mm, pp=SharedMem::read()->pPrnDataBuff; + char buf[MAXNROF_PRNBYTES]; + + if (pp==0) // next free memory block with 64byte each + return 1; // no text in buffer + + // example: pp=5: then buffers [0...4] are occupied + + for (nn=0; nnSdata_PRN_TEXT[0][nn]); // restore oldest text + + // now copy textline [1] to [0], then + // copy textline [2] to [1], then + // copy textline [3] to [2] .... upto [pp-1] to [pp-2] + // hint: copying from 9....0 would delete all strings!!!!!! + for (nn=0; nn<(pp-1); nn++) + { + for (mm=0; mmSdata_PRN_TEXT[nn+1][mm]; + for (mm=0; mmSdata_PRN_TEXT[nn][mm]=buf[mm]; + } + if (pp>0) pp--; + SharedMem::write()->pPrnDataBuff=pp; + + // example: pp=4: then buffers [0...3] are still occupied, pp=0: all buffers empty + + // now clear highest copyed line (which became free now) + tslib_strclr(SharedMem::write()->Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES); + + // optionally: clear all remaining higher lines: + for (nn=(pp+1); nnSdata_PRN_TEXT[nn], 0, MAXNROF_PRNBYTES); + + return 0; +} + +uint8_t gpi_chk4remainingText(void) +{ + // retval: 0: no more textline left (to send) >0: nr of 64byte-blocks + return (SharedMem::read()->pPrnDataBuff); +} +*/ + + + + + + + + + +// --------------------------------------------------------------------------------- +// 11.4.23 neu, Kommando direkt an "FastDevice"-protokoll senden, nicht mehr umsetzen +// --------------------------------------------------------------------------------- +/* +// header +static uint8_t nextFDwrCmd[FDCMD_STACKDEPTH]; +static uint8_t nextFDrdCmd[FDCMD_STACKDEPTH]; +static uint8_t nextFDblkNr[FDCMD_STACKDEPTH]; +static uint8_t nextFDshort[FDCMD_STACKDEPTH]; + +// short data +static uint8_t nextFDpara1[FDCMD_STACKDEPTH]; +static uint8_t nextFDpara2[FDCMD_STACKDEPTH]; +static uint8_t nextFDpara3[FDCMD_STACKDEPTH]; +static uint8_t nextFDpara4[FDCMD_STACKDEPTH]; +// long data: +static uint8_t longFDlength[FDCMD_STACKDEPTH]; +static uint8_t longFDpara[FDCMD_STACKDEPTH][64]; + +static uint8_t p_nextFDcmdsInQueue; +*/ + +/* convention: use simple (not rotating) FIFO Stack: +Example: nrOfCmdsInQueue=4 then + nextAsynchsendCmd0[0]=cmd1 // was stored as first + nextAsynchsendCmd0[1]=cmd2 + nextAsynchsendCmd0[2]=cmd3 + nextAsynchsendCmd0[3]=cmd4 // came in as last + + Send: [0] first, then move buffer 1 down: + nextAsynchsendCmd0[0]=cmd2 + nextAsynchsendCmd0[1]=cmd3 + nextAsynchsendCmd0[2]=cmd4 + nextAsynchsendCmd0[3]=0; + nrOfCmdsInQueue=3 now +*/ + + +void sendFDcmd_clrStack(void) +{ + uint8_t nn; + for (nn=0; nnnextFDwrCmd[nn]=0; + SharedMem::write()->nextFDrdCmd[nn]=0; + SharedMem::write()->nextFDblkNr[nn]=0; + SharedMem::write()->nextFDshort[nn]=0; + SharedMem::write()->nextFDpara1[nn]=0; + SharedMem::write()->nextFDpara2[nn]=0; + SharedMem::write()->nextFDpara3[nn]=0; + SharedMem::write()->nextFDpara4[nn]=0; + SharedMem::write()->longFDlength[nn]=0; + memset(&SharedMem::write()->longFDpara[nn][0],0,64); + } + + SharedMem::write()->p_nextFDcmdsInQueue=0; +} + +bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4) +{ + + // write Command to memory, wait for transport + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd >=FDCMD_STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + SharedMem::write()->nextFDwrCmd[pFDcmd]=nextWrCmd; + SharedMem::write()->nextFDrdCmd[pFDcmd]=nextRdCmd; + SharedMem::write()->nextFDblkNr[pFDcmd]=blockNum; + SharedMem::write()->nextFDpara1[pFDcmd]=dat1; + SharedMem::write()->nextFDpara2[pFDcmd]=dat2; + SharedMem::write()->nextFDpara3[pFDcmd]=dat3; + SharedMem::write()->nextFDpara4[pFDcmd]=dat4; + //qDebug() << "data with 4 data byte saved, pp=" << pFDcmd; + //qDebug() << " dat1=" << nextCmd4para1[pFDcmd] << " dat2=" << nextCmd4para2[pFDcmd] + // << " dat3=" << nextCmd4para3[pFDcmd] << " dat4=" << nextCmd4para4[pFDcmd]; + SharedMem::write()->nextFDshort[pFDcmd]=1; // 1=short + pFDcmd++; + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + + return true; // ok, will be sent +} + + +bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data) +{ + // write Command to memory, wait for transport + // data buffer size always 64! data[64], padded with 0 + uint8_t nn; + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd>=FDCMD_STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + SharedMem::write()->nextFDwrCmd[pFDcmd]=nextWrCmd; + SharedMem::write()->nextFDrdCmd[pFDcmd]=nextRdCmd; + SharedMem::write()->nextFDblkNr[pFDcmd]=blockNum; + + SharedMem::write()->longFDlength[pFDcmd]=length; + + for (nn=0; nn<64; nn++) + SharedMem::write()->longFDpara[pFDcmd][nn]=data[nn]; + + SharedMem::write()->nextFDshort[pFDcmd]=2; + pFDcmd++; + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + return true; // ok, will be sent +} + + +bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, QByteArray *data) +{ + // write Command to memory, wait for transport + // data buffer size always 64! data[64], padded with 0 + uint8_t nn; + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + char ctmp; + + if (pFDcmd>=FDCMD_STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + SharedMem::write()->nextFDwrCmd[pFDcmd]=nextWrCmd; + SharedMem::write()->nextFDrdCmd[pFDcmd]=nextRdCmd; + SharedMem::write()->nextFDblkNr[pFDcmd]=blockNum; + + SharedMem::write()->longFDlength[pFDcmd]=length; + + for (nn=0; nn<64; nn++) + { + ctmp=data->at(nn); + SharedMem::write()->longFDpara[pFDcmd][nn]=ctmp; + } + + SharedMem::write()->nextFDshort[pFDcmd]=2; + pFDcmd++; + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + return true; // ok, will be sent +} + + +bool sendFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4) +{ + uint8_t nn, mm, data; // ll + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd==0 || pFDcmd>FDCMD_STACKDEPTH) + return false; // not possible + + *nextWrCmd=SharedMem::read()->nextFDwrCmd[0]; + *nextRdCmd=SharedMem::read()->nextFDrdCmd[0]; + *blockNum=SharedMem::read()->nextFDblkNr[0]; + *dat1=SharedMem::read()->nextFDpara1[0]; + *dat2=SharedMem::read()->nextFDpara2[0]; + *dat3=SharedMem::read()->nextFDpara3[0]; + *dat4=SharedMem::read()->nextFDpara4[0]; + //qDebug() << "sendFDcmd_get [0]; pp=" << SharedMem::read()->p_nextFDcmdsInQueue; + //qDebug() << " data1: " << SharedMem::read()->nextCmd4para1[0] << " data2: " << SharedMem::read()->nextCmd4para2[0] << + // " data3: " << SharedMem::read()->nextCmd4para3[0] << " data4: " << SharedMem::read()->nextCmd4para4[0]; + + // move Puffer down by one element + //if (FDCMD_STACKDEPTH>0) + // ll=FDCMD_STACKDEPTH-1; + //else + // ll=0; + + if (pFDcmd>0) pFDcmd--; else pFDcmd=0; + + //for (nn=0; nnnextFDwrCmd[nn+1]; + SharedMem::write()->nextFDwrCmd[nn]=data; + data=SharedMem::read()->nextFDrdCmd[nn+1]; + SharedMem::write()->nextFDrdCmd[nn]=data; + data=SharedMem::read()->nextFDblkNr[nn+1]; + SharedMem::write()->nextFDblkNr[nn]=data; + data=SharedMem::read()->nextFDpara1[nn+1]; + SharedMem::write()->nextFDpara1[nn]=data; + data=SharedMem::read()->nextFDpara2[nn+1]; + SharedMem::write()->nextFDpara2[nn]=data; + data=SharedMem::read()->nextFDpara3[nn+1]; + SharedMem::write()->nextFDpara3[nn]=data; + data=SharedMem::read()->nextFDpara4[nn+1]; + SharedMem::write()->nextFDpara4[nn]=data; + + data=SharedMem::read()->nextFDshort[nn+1]; + SharedMem::write()->nextFDshort[nn] = data; + + data=SharedMem::read()->longFDlength[nn+1]; + SharedMem::write()->longFDlength[nn] = data; + + for (mm=0; mm<64; mm++) + { + SharedMem::write()->longFDpara[nn][mm] = SharedMem::read()->longFDpara[nn+1][mm]; + } + + } + + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + //qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue; + + // clear released buffer: + //for (nn=p_nextFDcmdsInQueue; nnnextFDwrCmd[pFDcmd]=0; + SharedMem::write()->nextFDrdCmd[pFDcmd]=0; + SharedMem::write()->nextFDblkNr[pFDcmd]=0; + + SharedMem::write()->nextFDpara1[pFDcmd]=0; + SharedMem::write()->nextFDpara2[pFDcmd]=0; + SharedMem::write()->nextFDpara3[pFDcmd]=0; + SharedMem::write()->nextFDpara4[pFDcmd]=0; + SharedMem::write()->nextFDshort[pFDcmd]=0; + SharedMem::write()->longFDlength[pFDcmd]=0; + for (mm=0; mm<64; mm++) + SharedMem::write()->longFDpara[pFDcmd][mm] = 0; + //} + +/* + qDebug() << "sendFDcmd_set, stack now: " << p_nextFDcmdsInQueue; + for (nn=0; nn<16; nn++) + { + qDebug() << "header: " << nextFDwrCmd[nn] << " / " << nextFDrdCmd[nn] << " / "<< nextFDblkNr[nn] << " / " << nextFDshort[nn]; + + qDebug() << " short data: " << nextFDpara1[nn] << " / "<< nextFDpara2[nn] << " / "<< nextFDpara3[nn]<< " / "<< nextFDpara4[nn]; + + qDebug() << " long data: " << longFDlength[nn] << " / "<< longFDpara[nn][0] << " / "<< longFDpara[nn][1] + << " / "<< longFDpara[nn][2] << " / "<< longFDpara[nn][3] << " / "<< longFDpara[nn][4]; + } +*/ + return true; // ok, will be sent +} + +uint8_t checkNextFDcmd(void) +{ + // return 0: no command waiting +// 1: short cmd +// 2: long cmd + //qDebug() << "chk nxt fd cmd: "<p_nextFDcmdsInQueue==0) + return 0; + if (SharedMem::read()->nextFDshort[0]==1) + return 1; + return 2; +} + +uint8_t check4usedFDstack(void) +{ + // returns number of waiting command, max FDCMD_STACKDEPTH + return SharedMem::read()->p_nextFDcmdsInQueue; +} + + +uint8_t check4freeFDstack(void) +{ + // returns number of free places in command stack + return FDCMD_STACKDEPTH - SharedMem::read()->p_nextFDcmdsInQueue; +} + +bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data) +{ + uint8_t nn, mm, uctmp; + uint8_t pFDcmd=SharedMem::read()->p_nextFDcmdsInQueue; + + if (pFDcmd==0 || pFDcmd>FDCMD_STACKDEPTH) + return false; // not possible + + *nextWrCmd=SharedMem::read()->nextFDwrCmd[0]; + *nextRdCmd=SharedMem::read()->nextFDrdCmd[0]; + *blockNum=SharedMem::read()->nextFDblkNr[0]; + *length = SharedMem::read()->longFDlength[0]; + for (mm=0; mm<64; mm++) + data[mm] = SharedMem::read()->longFDpara[0][mm]; + + if (pFDcmd>0) pFDcmd--; else pFDcmd=0; + + //for (nn=0; nnnextFDwrCmd[nn+1]; + SharedMem::write()->nextFDwrCmd[nn]=uctmp; + uctmp=SharedMem::read()->nextFDrdCmd[nn+1]; + SharedMem::write()->nextFDrdCmd[nn]=uctmp; + uctmp=SharedMem::read()->nextFDblkNr[nn+1]; + SharedMem::write()->nextFDblkNr[nn]=uctmp; + + uctmp=SharedMem::read()->nextFDpara1[nn+1]; + SharedMem::write()->nextFDpara1[nn]=uctmp; + uctmp=SharedMem::read()->nextFDpara2[nn+1]; + SharedMem::write()->nextFDpara2[nn]=uctmp; + uctmp=SharedMem::read()->nextFDpara3[nn+1]; + SharedMem::write()->nextFDpara3[nn]=uctmp; + uctmp=SharedMem::read()->nextFDpara4[nn+1]; + SharedMem::write()->nextFDpara4[nn]=uctmp; + + uctmp=SharedMem::read()->nextFDshort[nn+1]; + SharedMem::write()->nextFDshort[nn]=uctmp; + uctmp=SharedMem::read()->longFDlength[nn+1]; + SharedMem::write()->longFDlength[nn]=uctmp; + + for (mm=0; mm<64; mm++) + { + SharedMem::write()->longFDpara[nn][mm] = SharedMem::read()->longFDpara[nn+1][mm]; + } + + } + + SharedMem::write()->p_nextFDcmdsInQueue=pFDcmd; + // clear released buffer: + SharedMem::write()->nextFDwrCmd[pFDcmd]=0; + SharedMem::write()->nextFDrdCmd[pFDcmd]=0; + SharedMem::write()->nextFDblkNr[pFDcmd]=0; + + SharedMem::write()->nextFDpara1[pFDcmd]=0; + SharedMem::write()->nextFDpara2[pFDcmd]=0; + SharedMem::write()->nextFDpara3[pFDcmd]=0; + SharedMem::write()->nextFDpara4[pFDcmd]=0; + SharedMem::write()->nextFDshort[pFDcmd]=0; + SharedMem::write()->longFDlength[pFDcmd]=0; + for (mm=0; mm<64; mm++) + SharedMem::write()->longFDpara[pFDcmd][mm] = 0; + + return true; // ok, will be sent +} + + + diff --git a/src/shared_mem_buffer.cpp b/src/shared_mem_buffer.cpp new file mode 100644 index 0000000..c76b0ea --- /dev/null +++ b/src/shared_mem_buffer.cpp @@ -0,0 +1,101 @@ +#include "shared_mem_buffer.h" + +#include +#include + +#ifdef QT_POSIX_IPC + // The POSIX backend can be explicitly selected using the -feature-ipc_posix + // option to the Qt configure script. If it is enabled, the QT_POSIX_IPC + // macro will be defined. -> we use SystemV shared memory +#error "QT_POSIX_IPC defined" +#else +#ifdef __linux__ +#include // ftok +#endif +#endif + +//static bool shdMemFirstUse; + + +//QSharedMemory *SharedMemBuffer::getShm(std::size_t size) { +QSharedMemory *SharedMem::getShm(std::size_t size) { + static QSharedMemory shMem; + if (size > 0) { +#ifdef __linux__ + //static const long nativeKey = ftok("/etc/os-release", 'H'); + //static const QString fkey = std::to_string(nativeKey).c_str(); + static const QString fkey = "0123456?000=7"; +#else + static const QString fkey = "0123456?000=9"; +#endif + + shMem.setKey(fkey); + if (!shMem.isAttached()) { + if (shMem.create(size)) { + return &shMem; + } else { + if (shMem.error() == QSharedMemory::AlreadyExists) { + if (shMem.attach()) { + return &shMem; + } + } + } + qCritical() << shMem.nativeKey() << shMem.key() << shMem.data() + << shMem.error() << shMem.errorString(); + return nullptr; + } + } + return &shMem; +} + + +// std::atomic_bool SharedMemBuffer::__sharedMemLocked{false}; +/* +//QSharedMemory *SharedMemBuffer::getShm(std::size_t size) { +QSharedMemory *SharedMem::getShm(std::size_t size) { + + static QSharedMemory shMem; + if (size > 0) { +#ifdef __linux__ + static const long nativeKey = ftok("/etc/os-release", 'H'); + static const QString fkey = std::to_string(nativeKey).c_str(); +#else + static const QString fkey = "0123456?000=9"; +#endif + shdMemFirstUse=false; + shMem.setKey(fkey); + if (!shMem.isAttached()) + { + if (shMem.create(size)) + { + // sm was created successful, did not exist before + shdMemFirstUse=true; + return &shMem; + } else + { + // create was false because mem already existed + if (shMem.error() == QSharedMemory::AlreadyExists) + { + if (shMem.attach()) + { + return &shMem; + } + } + } + qCritical() << shMem.nativeKey() << shMem.key() << shMem.data() + << shMem.error() << shMem.errorString(); + return nullptr; + } + } + return &shMem; +} + + +bool shdMem_firstUse(void) +{ + return shdMemFirstUse; +} +*/ + + + diff --git a/src/storeINdata sm.cpp b/src/storeINdata sm.cpp new file mode 100755 index 0000000..20ebcca --- /dev/null +++ b/src/storeINdata sm.cpp @@ -0,0 +1,2053 @@ +#include +#include +#include +#include "storeINdata.h" +#include "tslib.h" +#include "shared_mem_buffer.h" +#include "datei.h" + +// gpi: grafical access to PI: access from external devices over device controller FOR GUI +// epi: external access from GUI to PI: FOR external devices (DC) + + + + +// store power on/off condition of the devices to control the data request + +//static bool indat_savePrnPwr; + +void indat_storePrinterPower(bool isOn) +{ + SharedMem::write()->indat_savePrnPwr=isOn; +} + +bool indat_isPrinterOn() +{ + return SharedMem::read()->indat_savePrnPwr; +} + + +//static bool indat_saveMifPwr; + +void indat_storeMifarePower(bool isOn) +{ + SharedMem::write()->indat_saveMifPwr=isOn; +} + +bool indat_isMifareOn() +{ + return SharedMem::read()->indat_saveMifPwr; +} + + +//static bool indat_MdbIsOn; + +void indat_storeMDBisOn(bool isOn) +{ + SharedMem::write()->indat_MdbIsOn=isOn; +} + +bool indat_isMdbOn() +{ + return SharedMem::read()->indat_MdbIsOn; +} + + + +//QString indat_HWversion; +//QString indat_SWversion; +//QString indat_DCstate; + + +void gpi_storeHWver(QString text) +{ + SharedMem::write()->indat_HWversion=text; +} + +QString epi_loadHWver(void) +{ + return SharedMem::read()->indat_HWversion; +} + +void gpi_storeSWver(QString text) +{ + SharedMem::write()->indat_SWversion=text; +} + +QString epi_loadSWver(void) +{ + return SharedMem::read()->indat_SWversion; +} + +void gpi_storeDCstate(QString text) +{ + text.chop(8); // DC2 State is shorter (8byte) + SharedMem::write()->indat_DCstate=text; +} + +QString epi_loadDCstate(void) +{ + return SharedMem::read()->indat_DCstate; +} + + +// ------------------------------- + +/* +static uint64_t Sdata_slaveUID; +static uint8_t Sdata_UIDstr[8]; +static QString Sdata_DcUidStr; + + +void write2file_UID(void) +{ + QByteArray myBA; + csv_startCreatingFile(); + csv_addUintToFile(Sdata_UIDstr[0]); + csv_addUintToFile(Sdata_UIDstr[1]); + csv_addUintToFile(Sdata_UIDstr[2]); + csv_addUintToFile(Sdata_UIDstr[3]); + csv_addUintToFile(Sdata_UIDstr[4]); + csv_addUintToFile(Sdata_UIDstr[5]); + csv_addUintToFile(Sdata_UIDstr[6]); + csv_addUintToFile(Sdata_UIDstr[7]); + csv_addNewlineToFile(); + csv_addUlongvalToFile(Sdata_slaveUID); + csv_addNewlineToFile(); + csv_addTextToFile(Sdata_DcUidStr); + csv_addNewlineToFile(); + myBA=csv_readbackArray(); + datei_clearFile(FILENAME_SHARED_UID); + datei_writeToFile(FILENAME_SHARED_UID, myBA); + +} + +void gpi_storeUID(uint8_t *buf8byteUid) +{ + uint64_t udltmp=0; + QString myStr; + + //qDebug()<< "store UID "; + + for (int ii=0; ii<8; ii++) + { + //qDebug()<< buf8byteUid[ii] << " "; + + Sdata_UIDstr[ii]=buf8byteUid[ii]; + udltmp|=buf8byteUid[ii]; + udltmp<<=8; + } + Sdata_slaveUID=udltmp; + + Sdata_DcUidStr.clear(); + for (int ii=0;ii<8; ii++) + { + + Sdata_DcUidStr+=QString::number(Sdata_UIDstr[ii],16); + Sdata_DcUidStr+=" "; + } + + write2file_UID(); +} + +void epi_getUIDdec(uint8_t *buf8byteUid) +{ +//qDebug()<< "get UID "; + for (int ii=0; ii<8; ii++) + { + //qDebug()< umformen in hexstring + + QString myStr; + for (int ii=0;ii<8; ii++) + { + + myStr+=QString::number(Sdata_UIDstr[ii],16); + myStr+=" "; + } + return myStr; +} +*/ + +/* read from file: +void epi_getUIDfromFile(uint8_t *buf8byteUid) +{ + QByteArray myBA; + int nn; + + myBA=datei_readFromFile(FILENAME_SHARED_UID); + for (nn=0; nn<8; nn++) + buf8byteUid[nn]=csv_getEntryAsUshort(myBA, nn); + +} + +uint64_t epi_getUIDnumberFromFile(void) +{ + QByteArray myBA; + + myBA=datei_readFromFile(FILENAME_SHARED_UID); + return csv_getEntryAs2Ulong(myBA, 8); + +} + +QString epi_getUIDstrFromFile(void) +{ + QByteArray myBA; + + myBA=datei_readFromFile(FILENAME_SHARED_UID); + return csv_getEntryAsString(myBA, 9); + +} +*/ + +// the same with shared memory : +void gpi_storeUID(uint8_t const *buf8byteUid) +{ + uint64_t udltmp=0; + + for (int ii=0; ii<8; ii++) + { +// SharedMem::getData()->Sdata.UIDstr[ii] = buf8byteUid[ii]; + SharedMem::write()->Sdata.UIDstr[ii] = buf8byteUid[ii]; + udltmp |= buf8byteUid[ii]; + udltmp <<= 8; + } +// SharedMem::getData()->Sdata.slaveUID = udltmp; + SharedMem::write()->Sdata.slaveUID = udltmp; +} + +void epi_getUIDdec(uint8_t *buf8byteUid) +{ + for (int ii=0; ii<8; ii++) + { + //buf8byteUid[ii] = SharedMem::getDataConst()->Sdata.UIDstr[ii]; + buf8byteUid[ii] = SharedMem::read()->Sdata.UIDstr[ii]; + } +} + +QString epi_getUIDstr() +{ + // die UID besteht aus 8 bytes (8 dezimalzahlen) + // -> umformen in hexstring + + QString myStr; + for (int ii=0;ii<8; ii++) + { + //myStr += QString::number(SharedMem::getDataConst()->Sdata.UIDstr[ii], 16); + myStr += QString::number(SharedMem::read()->Sdata.UIDstr[ii], 16); + myStr += " "; + } + return myStr; +} + +// /////////////////////////////////////////////////////////////////////////////////// +// Time and Date +// /////////////////////////////////////////////////////////////////////////////////// +/* +struct T_globTime +{ + // Reihenfolge nicht vertauschen!!!!! + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t Year; + uint8_t Month; + uint8_t DayOfMonth; + uint8_t DayOfWeek; // 1=monday...7 + uint8_t reserve1; + + uint16_t MinutesOfToday; + uint16_t reserve2; + + uint32_t SecondsOfToday; + + uint8_t IsLeapyear; + uint8_t nextLeap; + uint8_t lastLeap; + uint8_t hoursOfWeek; + + uint16_t minOfWeek; + uint16_t hoursOfMonth; + uint16_t minOfMonth; + uint16_t dayOfYear; + uint16_t hoursOfYear; + uint16_t reserve3; + + uint32_t minOfYear; + + uint8_t squareOutMode; + uint8_t free1; + uint16_t reserve4; + uint32_t minOfMillenium; + // bis hierher 44byts + uint32_t free2; + uint32_t free3; + uint32_t free4; + +}; +static T_globTime getGlobalTime; +*/ + + +void gpi_backupSquareMode(uint8_t squMode) +{ + SharedMem::write()->getGlobalTime.squareOutMode=squMode; +} + +uint8_t epi_getSquareMode() +{ + return SharedMem::read()->getGlobalTime.squareOutMode; +} + + +void gpi_backupTime(uint8_t *timeBuffer, uint8_t Leng) +{ + /* + // Daten kommen in gleicher Reihenfolge vom Slave + uint8_t *pTime; + pTime=&getGlobalTime.hour; + if (Leng>44) Leng=44; // mehr brauch ma ned + for (int nn=0; nngetGlobalTime.second=Leng; // nur damit CompilerWarnung weg ist + + SharedMem::write()->getGlobalTime.DayOfWeek=timeBuffer[0]; + SharedMem::write()->getGlobalTime.minute=timeBuffer[1]; + SharedMem::write()->getGlobalTime.second=timeBuffer[2]; + SharedMem::write()->getGlobalTime.hour=timeBuffer[3]; + SharedMem::write()->getGlobalTime.Year=timeBuffer[4]; + SharedMem::write()->getGlobalTime.Month=timeBuffer[5]; + SharedMem::write()->getGlobalTime.DayOfMonth=timeBuffer[6]; + +} + +void epi_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) +{ + *hh=SharedMem::read()->getGlobalTime.hour; + *mm=SharedMem::read()->getGlobalTime.minute; + *ss=SharedMem::read()->getGlobalTime.second; +} + +void epi_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) +{ + *yy=SharedMem::read()->getGlobalTime.Year; + *mm=SharedMem::read()->getGlobalTime.Month; + *dd=SharedMem::read()->getGlobalTime.DayOfMonth; +} + +void epi_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) +{ + *dow=SharedMem::read()->getGlobalTime.DayOfWeek; + *minOfToday=SharedMem::read()->getGlobalTime.MinutesOfToday; + *secOfToday=SharedMem::read()->getGlobalTime.SecondsOfToday; +} + +bool epi_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) +{ + *lastLeapYear=SharedMem::read()->getGlobalTime.lastLeap; + *NextLeapYear=SharedMem::read()->getGlobalTime.nextLeap; + if (SharedMem::read()->getGlobalTime.IsLeapyear) + return true; + return false; +} + +bool epi_isLeapYear() +{ + if (SharedMem::read()->getGlobalTime.IsLeapyear) + return true; + return false; +} + +void epi_getSpecialWeekTimeDate(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) +{ + *DayOfWeek=SharedMem::read()->getGlobalTime.DayOfWeek; + *HoursOfWeek=SharedMem::read()->getGlobalTime.hoursOfWeek; + *MinutesOfWeek=SharedMem::read()->getGlobalTime.minOfWeek; +} + +void epi_getSpecialMonthTimeDate(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) +{ + *DayOfMonth=SharedMem::read()->getGlobalTime.DayOfMonth; + *HoursOfMonth=SharedMem::read()->getGlobalTime.hoursOfMonth; + *MinutesOfMonth=SharedMem::read()->getGlobalTime.minOfMonth; +} + +void epi_getSpecialYearTimeDate(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) +{ + *DayOfYear=SharedMem::read()->getGlobalTime.dayOfYear; + *HoursOfYear=SharedMem::read()->getGlobalTime.hoursOfYear; + *MinutesOfYear=SharedMem::read()->getGlobalTime.minOfYear; +} + +QString epi_getRtcTimeStr(uint8_t timeStyle) +{ + // style: 0: hh:mm 1: hh:mm:ss + QString mystr=nullptr, tempStr=nullptr; + + tempStr.setNum(SharedMem::read()->getGlobalTime.hour,10); + mystr=tempStr.rightJustified(2,'0',false); // macht feste Länge, 5->05 + mystr.append(':'); + //tempStr.clear(); + tempStr.setNum(SharedMem::read()->getGlobalTime.minute,10); // mit 16 statt 10 wirds in HEX angezeigt + //mystr.append(tempStr); + mystr+=tempStr.rightJustified(2,'0',false); + //mystr.append(':'); // so + //mystr+=':'; // oder so, =gleich + + if (timeStyle==1) // hh:mm:ss + { + mystr.append(':'); + tempStr.setNum(SharedMem::read()->getGlobalTime.second,10); + mystr.append(tempStr.rightJustified(2,'0',false)); // wie += + } + return mystr; +} + + +QString epi_getRtcDateStr(uint8_t dateStyle) +{ + // 1=german dd.mm.yy 2=american yy/mm/dd 3=mm.dd.yy + QString tmpStr=nullptr, YYstr=nullptr, MMstr=nullptr, DDstr=nullptr, mystr=nullptr; + mystr.clear(); + + tmpStr.setNum(SharedMem::read()->getGlobalTime.Year,10); // itoa decimal + YYstr=tmpStr.rightJustified(4,'0',false); // immer vierstellig + YYstr[0]='2'; // 2000 dazu + + tmpStr.setNum(SharedMem::read()->getGlobalTime.Month,10); + MMstr=tmpStr.rightJustified(2,'0',false); + + tmpStr.setNum(SharedMem::read()->getGlobalTime.DayOfMonth,10); + DDstr=tmpStr.rightJustified(2,'0',false); + + if (dateStyle==1) // Germany dd.mm.yy + { + mystr=DDstr + '.' + MMstr + '.' + YYstr; + } else + if (dateStyle==2) // american yy/mm/dd + { + mystr=YYstr + '/' + MMstr + '/' + DDstr; + } else + // mm.dd.yy + { + mystr=MMstr + '.' + DDstr + '.' + YYstr; + } + return mystr; +} + + +QString epi_getSlaveTimeDateStr() +{ + QString myStr; + myStr=epi_getRtcTimeStr(1) + " " + epi_getRtcDateStr(1); + return myStr; + +} + + +// /////////////////////////////////////////////////////////////////////////////////// +// analog values +// /////////////////////////////////////////////////////////////////////////////////// + + +//static uint16_t AI_val[MAXNROF_AI]; + +uint8_t gpi_getMaxNrAIs() +{ + return MAXNROF_AI; +} + +void gpi_storeAIs(uint8_t aiNr, uint16_t val) +{ + if (aiNrAI_val[aiNr]=val; +} + +uint16_t epi_loadAIs(uint8_t aiNr) +{ + if (aiNrAI_val[aiNr]; + return 0; +} + + +//-------------- +// measurement values +// ADC0: temp +// 1: voltage +// 2: brightness +#define MAXNROF_MEASURE 4 + +//static uint32_t Sdata_measurement[MAXNROF_MEASURE]; + +uint32_t epi_loadMeasureValue(uint8_t ValueNr) +{ + // ValueNr 0=ADC0, 1=ADC1 aso... + if (ValueNrSdata_measurement[ValueNr]; + return 0; +} + +void gpi_storeMeasureValue(uint8_t ValueNr, uint32_t val) +{ + // in mV, also bis 65,535V + if (ValueNrSdata_measurement[ValueNr]=val; + +} + + + +QString epi_getSlaveTemperatureStr() +{ + char myStr[8], halfDegree=0, Minus=0, oneChar; + int16_t val=0, pp, einer, zehner; + QString myqStr; + + //qDebug() << "AIN0: " << epi_loadAIs(0) << "AIN1: " << epi_loadAIs(1); + + uint32_t meas_temper=epi_loadMeasureValue(MEASCHAN_TEMPERATURE); + // im SaxFormat gespeichert, hier umwandeln in String + + //qDebug() << "meas_temper: " << meas_temper; + + + for (pp=0; pp<8; pp++) myStr[pp]=0; + if (meas_temper&1) // ungerade, also ,5°C + { + halfDegree=1; + meas_temper &=0xFFFE; // um 0,5°C abrunden + } + if (meas_temper<100) + { + Minus=1; + val=int16_t(meas_temper)/2; + val-=50; + } else + { + val=int16_t(meas_temper)-100; + val/=2; + } + pp=0; // pointer auf string + if (Minus) + myStr[pp++]='-'; + // val is now 0..150 for pos Temp or 0..49 for negativ temperature + if (val<10) + { + // only one digit, just change to ascii + oneChar = char(val)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + } else + if (val<100) + { + // 10...99 + einer=val%10; + zehner=val/10; + //myStr[pp++]=char(zehner); + //myStr[pp++]=char(einer); + + oneChar = char(zehner)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + + oneChar = char(einer)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + + } else + { + // 100...150 + myStr[pp++]='1'; // hunderter Stelle immer 1 + val-=100; + einer=val%10; + zehner=val/10; + //myStr[pp++]=char(zehner)+0x30; + //myStr[pp++]=char(einer)+0x30; + oneChar = char(zehner)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + + oneChar = char(einer)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + } + myStr[pp++]=','; + if (halfDegree) + myStr[pp++]='5'; + else + myStr[pp++]='0'; + myqStr.clear(); + myqStr.append(myStr); + myqStr.append("°C"); + return myqStr; +} + +QString epi_getSlaveVoltageStr() +{ + // value in "meas_volt" in mV, also bis 65,535V. Value range [6000...16000] (6V...16V) + QString myqStr; + uint32_t vor, nach, tmp32; + uint16_t pp; + char myStr[12], ke; //, kz, kh; + + uint32_t ultmp=epi_loadMeasureValue(MEASCHAN_VOLTAGE); + for (pp=0; pp<12; pp++) myStr[pp]=0; + + //qDebug() << ultmp << "mV"; + + myqStr.clear(); + vor=ultmp/1000; + //qDebug() << "vor: " << vor; + + nach=ultmp%1000; + //qDebug() << "nach: " << nach; + pp=0; + if (vor>9) + { + myStr[pp++]=char(vor/10)+0x30; + } + myStr[pp++]=char(vor%10)+0x30; + myStr[pp++]=','; + + ke=char(nach/100); + //qDebug() << "ke: " << ke; + myStr[pp++]=char(ke)+0x30; + + tmp32=nach%100; + ke=char(tmp32/10); + //qDebug() << "ke: " << ke; + myStr[pp++]=char(ke)+0x30; + + tmp32=nach%10; + ke=char(tmp32); + //qDebug() << "ke: " << ke; + myStr[pp++]=char(ke)+0x30; + + + myStr[pp++]='V'; + myqStr.append(myStr); + return myqStr; +} + + + +// /////////////////////////////////////////////////////////////////////////////////// +// digital inputs +// /////////////////////////////////////////////////////////////////////////////////// + +/* come all in with 0x1201: +D0: upper door D1: low door D2:vault door +D3: cash box D4: bill box in +D5: bit 0: upper lockbar up bit1:down +D6: bit 0: lower lockbar up bit1:down + +D7: 0 +D7: DI_contact Power Is On + +D8: OptoIn 1,2 +D9: Aux0...5 +D10:Wake from ptu +D11: DI Wake From Mdb +D12: Ready from printer +D13: Coin Shutter Input +D14: CoinEscrow switch +D15: Mifare IN +D16: Modem_Wake In + +D18: DI Mif Pwr is on +D19: DI MDB_TxD_rdBack +D20: DI Aux Pwr is on +D21: DI GSM Pwr from PO2 is ON +D22: DI Credit Pwr from PO2 is on + =DI RdBack Credit Wake +D23: DI Printer Pwr from PO2 is on +D24: DI MDB Pwr from PO2 is on + */ + +//static uint8_t di_doorSwitch; +void gpi_storeDI_doorSwitches(uint8_t upperDoor, uint8_t lowerDoor, uint8_t vaultDoor) +{ + SharedMem::write()->di_doorSwitch=0; + if (upperDoor) SharedMem::write()->di_doorSwitch |=1; + if (lowerDoor) SharedMem::write()->di_doorSwitch |=2; + if (vaultDoor) SharedMem::write()->di_doorSwitch |=4; +// qDebug()<<"storeINdata: "<di_doorSwitch; +} + + +//static uint8_t di_vaultSwitch; +void gpi_storeDI_vaultSwitches(uint8_t CashBoxIn, uint8_t BillBoxIn) +{ + SharedMem::write()->di_vaultSwitch=0; + if (CashBoxIn) SharedMem::write()->di_vaultSwitch |=1; + if (BillBoxIn) SharedMem::write()->di_vaultSwitch |=2; +} + +uint8_t epi_getDI_vaultSwitches(void) +{ + // bit0: cash box 1: bill box in + return SharedMem::read()->di_vaultSwitch; +} + + +//static uint8_t di_lockSwitch; +void gpi_storeDI_lockSwitches(uint8_t indatUL, uint8_t indatLL) +{ + // D5: bit 0: upper lockbar up bit1:down + // D6: bit 0: lower lockbar up bit1:down + SharedMem::write()->di_lockSwitch=0; + if (indatUL & 1) SharedMem::write()->di_lockSwitch |=1; + if (indatUL & 2) SharedMem::write()->di_lockSwitch |=2; + if (indatLL & 1) SharedMem::write()->di_lockSwitch |=4; + if (indatLL & 2) SharedMem::write()->di_lockSwitch |=8; +} + +uint8_t epi_getDI_lockSwitches(void) +{ + // retval: bit 0: upper lockbar up bit1: upper lockbar is down + // bit 2: lower lockbar up bit1: lower lockbar is down + + return SharedMem::read()->di_lockSwitch; +} + +//static uint8_t di_opto; +void gpi_storeDI_optos(uint8_t indatOpto) +{ + // OptoIn bit 0,1: optoin 1,2 + SharedMem::write()->di_opto=0; + if (indatOpto & 1) SharedMem::write()->di_opto |=1; + if (indatOpto & 2) SharedMem::write()->di_opto |=2; + +} + +uint8_t epi_getDI_optos(void) +{ + // bit0: opto in 1 1: opto in 2 + return SharedMem::read()->di_opto; +} + + +//static uint8_t di_aux; +void gpi_storeDI_auxIn(uint8_t indatAuxIn) +{ + // Aux0...5 + SharedMem::write()->di_aux=indatAuxIn; +} + +uint8_t epi_getDI_auxIn(void) +{ + // bit0: auxin 1 ... 5: auxin 6 + return SharedMem::read()->di_aux; +} + + +//static bool di_wakeFromPtu; +void gpi_storeDI_ptuWake(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_wakeFromPtu=true; + else + SharedMem::write()->di_wakeFromPtu=false; +} + +bool epi_getDI_ptuWake(void) +{ + return SharedMem::read()->di_wakeFromPtu; +} + + +//static bool di_wakeFromMdb; +void gpi_storeDI_mbdWake(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_wakeFromMdb=true; + else + SharedMem::write()->di_wakeFromMdb=false; +} + +bool epi_getDI_mdbWake(void) +{ + return SharedMem::read()->di_wakeFromMdb; +} + + +//static bool di_PrnReady; +void gpi_storeDI_prnReady(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_PrnReady=true; + else + SharedMem::write()->di_PrnReady=false; +} + +bool epi_getDI_prnReady(void) +{ + return SharedMem::read()->di_PrnReady; +} + + +//static bool di_CoinAttach; +void gpi_storeDI_CoinAttach(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_CoinAttach=true; + else + SharedMem::write()->di_CoinAttach=false; +} + +bool epi_getDI_CoinAttach(void) +{ + return SharedMem::read()->di_CoinAttach; +} + +//static bool di_CoinEscrowOpen; +void gpi_storeDI_CoinEscrow(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_CoinEscrowOpen=true; + else + SharedMem::write()->di_CoinEscrowOpen=false; +} + +bool epi_getDI_CoinEscrow(void) +{ + return SharedMem::read()->di_CoinEscrowOpen; +} + + +//static bool di_mifCardTap; +void gpi_storeDI_mifareCardTapped(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_mifCardTap=true; + else + SharedMem::write()->di_mifCardTap=false; +} + +bool epi_getDI_mifareCardTapped(void) +{ + return SharedMem::read()->di_mifCardTap; +} + + +//static bool di_wakeFromModem; +void gpi_storeDI_modemWake(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_wakeFromModem=true; + else + SharedMem::write()->di_wakeFromModem=false; +} + +bool epi_getDI_modemWake(void) +{ + return SharedMem::read()->di_wakeFromModem; +} + + + +//static bool di_contactPwrOn; + +void gpi_storeDI_contactPowerIsOn(bool di_contact_PwrOn) +{ + SharedMem::write()->di_contactPwrOn=di_contact_PwrOn; +} + +bool epi_getDI_contactPwr(void) +{ + // invertiert! + if (SharedMem::read()->di_contactPwrOn) + return false; + return true; +} + +//static bool di_mifarePwrOn; + +void gpi_storeDI_MifarePowerIsOn(bool di_mifare_PwrOn) +{ + SharedMem::write()->di_mifarePwrOn=di_mifare_PwrOn; +} + +bool epi_getDI_mifarePwr(void) +{ + return SharedMem::read()->di_mifarePwrOn; +} + +//static bool di_rdbk_mdbTxd; + +void gpi_storeDI_readbackMdbTxD(bool di_rdbkMdbTxd) +{ + SharedMem::write()->di_rdbk_mdbTxd=di_rdbkMdbTxd; +} + +bool epi_getDI_mdbTxd(void) +{ + return SharedMem::read()->di_rdbk_mdbTxd; +} + +//static bool di_AuxPwrOn; + +void gpi_storeDI_AuxPowerIsOn(bool di_Aux_PwrOn) +{ + SharedMem::write()->di_AuxPwrOn=di_Aux_PwrOn; +} + +bool epi_getDI_auxPwr(void) +{ + return SharedMem::read()->di_AuxPwrOn; +} + +//static bool di_gsmPwrOn; + +void gpi_storeDI_GsmPowerIsOn(bool di_gsm_PwrOn) +{ + SharedMem::write()->di_gsmPwrOn=di_gsm_PwrOn; +} + +bool epi_getDI_gsmPwr(void) +{ + return SharedMem::read()->di_gsmPwrOn; +} + +//static bool di_creditPwrOn; + +void gpi_storeDI_CreditPowerIsOn(bool di_credit_PwrOn) +{ + // invertieren!!! + if (di_credit_PwrOn) + SharedMem::write()->di_creditPwrOn=0; + else + SharedMem::write()->di_creditPwrOn=1; +} + +bool epi_getDI_creditPwr(void) +{ + return SharedMem::read()->di_creditPwrOn; +} + +//static bool di_printerPwrOn; + +void gpi_storeDI_PrinterPowerIsOn(bool di_printer_PwrOn) +{ + SharedMem::write()->di_printerPwrOn=di_printer_PwrOn; +} + +bool epi_getDI_printerPwr(void) +{ + return SharedMem::read()->di_printerPwrOn; +} + +//static bool di_mdbPwrOn; + +void gpi_storeDI_MdbPowerIsOn(bool di_mdb_PwrOn) +{ + SharedMem::write()->di_mdbPwrOn=di_mdb_PwrOn; +} + +bool epi_getDI_mdbPwr(void) +{ + return SharedMem::read()->di_mdbPwrOn; +} + +//static bool di_rejMot_home; + +void gpi_storeDI_rejMot_home(bool di) +{ + SharedMem::write()->di_rejMot_home=di; +} + +bool epi_getDI_rejectMotor_homepos(void) +{ + return SharedMem::read()->di_rejMot_home; +} + +//static uint8_t di_npe_sensor; + +void gpi_storeDI_paperLow(uint8_t di) +{ + // 0: Sensor sees paper 1: no paper 99: off + SharedMem::write()->di_npe_sensor=di; +} + +uint8_t epi_getDI_npe_sensor(void) +{ + return SharedMem::read()->di_npe_sensor; +} + + + +// /////////////////////////////////////////////////////////////////////////////////// +// readaback digital outputs +// /////////////////////////////////////////////////////////////////////////////////// + + +/* +D0 bit0: MDB devices 0=off 1=on + bit1: MDB bus power + bit2: MDB WakeOut + +D1=Printer +D2=Credit +D3=Modem + +D5: serial drv on/off, Serial mux1, Serial mux2 +D6: Leds, Fan, +D7: Siren and relay +D8: PtuWakeOut +D9: Power Aux/Barcode +D10: AuxDir 1...6 +D11: AuxOut 1...6 +D12: Coin shutter output +D13: CoinEscrow Outputs +*/ + +//static uint8_t do_mbdRxTst; +void gpi_storeDO_mdbRxTst(uint8_t mdbRxTst) +{ + SharedMem::write()->do_mbdRxTst=mdbRxTst; +} + +bool epi_getDO_mdbRxTestOut(void) +{ + if (SharedMem::read()->do_mbdRxTst & 1) + return true; + return false; +} + +//static uint8_t do_motorBits; +void gpi_storeDO_motorOutputs(uint8_t Pwr) +{ + //D1: motor outputs bit0: upper lock forw bit 1 backw + // Bit2: lowLock forw bit3: LL backw + SharedMem::write()->do_motorBits=Pwr; +} + +uint8_t epi_getDO_motorOuts(void) +{ + // bit0: upper lock forward bit 1 backward + // bit2: lower lock forward bit 3 backward + return SharedMem::read()->do_motorBits; +} + + + +//static uint8_t do_serialSwitch; // serial drv on/off, Serial mux1, Serial mux2 +void gpi_storeDO_serialSwitch(uint8_t state) // serial drv on/off, Serial mux1, Serial mux2 +{ + SharedMem::write()->do_serialSwitch=state; +} + +uint8_t epi_getDO_serialSwitch(void) +{ + // serial drv on/off, Serial mux1, Serial mux2 + return SharedMem::read()->do_serialSwitch; +} + +bool epi_getDO_serialDriverIsOn(void) +{ + + if ( SharedMem::read()->do_serialSwitch & 1) + return true; + return false; +} + +bool epi_getDO_serialMux1isSetToPrinter(void) +{ + // mux1 off: serial is switched to printer + if ((SharedMem::read()->do_serialSwitch & 2)==0) + return true; + return false; +} + +bool epi_getDO_serialMux1isSetToModem(void) +{ + // mux1 on: serial is switched to modem + if ((SharedMem::read()->do_serialSwitch & 2)>0) + return true; + return false; +} + +bool epi_getDO_serialMux2isSetToCredit(void) +{ + // mux2 off: serial is switched to credit card terminal + if ((SharedMem::read()->do_serialSwitch & 4)==0) + return true; + return false; +} + +bool epi_getDO_serialMux2isSetToMifare(void) +{ + // mux2 on: serial is switched to mifare reader + if ((SharedMem::read()->do_serialSwitch & 4)>0) + return true; + return false; +} + + + + + + +//static uint8_t do_ledsAndFan; +void gpi_storeDO_ledsAndFan(uint8_t ledState) +{ + // bit0: coinled 1:front_illu 2: paper-led 3:pinpad-led 4:start-led 5:service-led 6:fan + SharedMem::write()->do_ledsAndFan=ledState; +} + +bool epi_getDO_led_coin(void) +{ + if (SharedMem::read()->do_ledsAndFan & 1) + return true; + return false; +} + +bool epi_getDO_led_front(void) +{ + if (SharedMem::read()->do_ledsAndFan & 2) + return true; + return false; +} + +bool epi_getDO_led_ticket(void) +{ + if (SharedMem::read()->do_ledsAndFan & 4) + return true; + return false; +} + +bool epi_getDO_led_pin(void) +{ + if (SharedMem::read()->do_ledsAndFan & 8) + return true; + return false; +} + +bool epi_getDO_led_start(void) +{ + if (SharedMem::read()->do_ledsAndFan & 16) + return true; + return false; +} + +bool epi_getDO_led_inside(void) +{ + if (SharedMem::read()->do_ledsAndFan & 32) + return true; + return false; +} + +bool epi_getDO_fan(void) +{ + if (SharedMem::read()->do_ledsAndFan & 64) + return true; + return false; +} + + + +//static uint8_t do_laermUndRelay; +void gpi_storeDO_sirenAndRelay(uint8_t sirenRelay) +{ + // bit0: siren 1:relay + SharedMem::write()->do_laermUndRelay=sirenRelay; +} + +bool epi_getDO_sirene(void) +{ + if (SharedMem::read()->do_laermUndRelay & 1) + return true; + return false; +} + +bool epi_getDO_relay(void) +{ + if (SharedMem::read()->do_laermUndRelay & 2) + return true; + return false; +} + + + +//static uint8_t do_ptuWake; +void gpi_storeDO_ptuWake(uint8_t state) +{ + SharedMem::write()->do_ptuWake=state; +} + +bool epi_getDO_ptuWake(void) +{ + if (SharedMem::read()->do_ptuWake>0) + return true; + return false; +} + +//static uint8_t do_auxPower; +void gpi_storeDO_auxPower(uint8_t pwr) +{ + SharedMem::write()->do_auxPower=pwr; +} + +bool epi_getDO_auxPower(void) +{ + if (SharedMem::read()->do_auxPower>0) + return true; + return false; +} + + + +//static uint8_t do_coinShutter; +void gpi_storeDO_coinShutter(uint8_t state) +{ + SharedMem::write()->do_coinShutter=state; +} + +bool epi_getDO_coinShutterOpen(void) +{ + // bit0: Coin shutter output, bit1: input-test-output + if (SharedMem::read()->do_coinShutter & 1) + return true; + return false; +} + +bool epi_getDO_coinShutterTest(void) +{ + // bit0: Coin shutter output, bit1: input-test-output + if (SharedMem::read()->do_coinShutter & 2) + return true; + return false; +} + +//static uint8_t do_coinEscrow; + +void gpi_storeDO_coinEscrow(uint8_t state) +{ + SharedMem::write()->do_coinEscrow=state; +} + +uint8_t epi_getDO_coinEscrow(void) +{ + // retval: 1:return flap is open 2:take flap is open 0:closed + if (SharedMem::read()->do_coinEscrow &1) + return 1; // return flap is open + if (SharedMem::read()->do_coinEscrow &2) + return 2; // take flap is open + return 0; +} + +//static uint8_t do_printerPower; + +void gpi_storeDO_printerPwrOn(uint8_t state) +{ + SharedMem::write()->do_printerPower=state; +} + +uint8_t epi_getDO_printerPwr(void) +{ + return SharedMem::read()->do_printerPower; +} + +//------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ +//----------------------------- Mifare Card Reader ----------------------------------- + +//#define NROFMIFSTATEBYTES 40 +//static uint8_t Sdata_MIF_STATE[NROFMIFSTATEBYTES]; + +uint8_t gpi_storeMifReaderStateAndCardType(uint8_t *buf) +{ + // retval 0=OK 1=error host buffer too small + for (uint8_t nn=0; nnSdata_MIF_STATE[nn]=0; + for (uint8_t nn=0; nn<8; nn++) + SharedMem::write()->Sdata_MIF_STATE[nn]=buf[nn]; + return 0; // OK +} + +/* data description: + +new fast version: +byte 0= still the same: current read state: + 0=power off 1=reader-fault 2=ready + 3=just reading 4=read complete + 5=read partial, removed too early + 6=state unknown + +byte 1: reader state 1=ok 0=nok +byte 2: card preent (0,1) +byte 3: card selected (0) +byte 4: card type: 0...5 +byte 5: card allowed (0=no 1=MifareClassic 1k or 4k) +byte 6: CardSize: 1 or 4 (kB) +byte 7: length of UID 4 or 7 (byte) + + +old long version +byte 0: current read state: 0=power off 1=reader-fault 2=ready + 3=just reading 4=read complete + 5=read partial, removed too early + 6=state unknown +byte 1,2: read data length from card +3: 1=reader is OK (reported serial nr is OK) 0=wrong or no reader +4...15: reader version, expected "SL025-1.8" +byte16: 1=card is present 0:not +17: 0 +18: card type reported from reader +19: 1=allowed card type 0=not +20: card size: 1 or 4 (dec) = card size +21: LengthOfUID: 4 or 7 (dec) (byte) +22: UID 8 byte in hex +byte 30: sector logged: 0 +byte 31: current sector: 0 +byte 32: result, always 0 +*/ + +uint8_t epi_restoreMifState(uint8_t *buf, uint8_t maxBufferSize) +{ + // HWapi can read States from DC + if (maxBufferSize<8) + return 1; // error + + for (uint8_t nn=0; nn<8; nn++) + buf[nn]=SharedMem::read()->Sdata_MIF_STATE[nn]; + return 0; // OK + +} + + + +//static uint8_t Sdata_MIF_DATA[12][64]; +// data come in blockwise, so safe them blockwise as well +void gpi_storeMifCardData(uint8_t blkNr, uint8_t *receivedData) +{ + if (blkNr<12) + { + for (uint8_t nn=0; nn<64; nn++) + SharedMem::write()->Sdata_MIF_DATA[blkNr][nn]=receivedData[nn]; + } + +} + +uint8_t epi_restoreMifData(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) +{ + if (blkNr>11 || maxBufferSize<64) + return 1; // error + + for (uint8_t nn=0; nn<64; nn++) + buf[nn]=SharedMem::read()->Sdata_MIF_DATA[blkNr][nn]; + + return 0; // ois OK +} + +//static uint8_t mif_cardType; +//static uint8_t mif_cardHolder[8]; + +void gpi_storeNewMifareCard(uint8_t typ, uint8_t *holder ) +{ + SharedMem::write()->mif_cardType=typ; + uint8_t nn; + + //tslib_strcpy(holder, SharedMem::write()->mif_cardHolder, 7); + for (nn=0; nn<7; nn++) + SharedMem::write()->mif_cardHolder[nn] = holder[nn]; + SharedMem::write()->mif_cardHolder[7]=0; +} + +uint8_t epi_mifGetCardType(uint8_t *holder) +{ + //holder[8] = name of card holder + // retval Type of MifareCard, 1=upper door, 2=lower door 3=test printer 4=test coins + + //tslib_strcpy(SharedMem::read()->mif_cardHolder, holder, 7); + + uint8_t nn; + + for (nn=0; nn<7; nn++) + holder[nn]= SharedMem::read()->mif_cardHolder[nn]; + holder[7]=0; + return SharedMem::read()->mif_cardType; +} + + +//------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ + + +//static uint8_t Sdata_PRN_STATE[pi_prnStateArraySize]; + +void epi_restorePrinterState(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_STATE[nn]; + +} + +void gpi_storePrinterState(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_STATE[nn]=buf[nn]; + +} + +//static uint8_t Sdata_PRN_FONTS[pi_prnFontArraySize]; + +void epi_restorePrinterFonts(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_FONTS[nn]; + +} + +void gpi_storePrinterFonts(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_FONTS[nn]=buf[nn]; +/* + qDebug()<<"printer fonts stored " <Sdata_mdb_busRdy=bool(busReady); + SharedMem::write()->Sdata_mdb_V12on=bool(V12on); + SharedMem::write()->Sdata_mdb_V5on=bool(V5on); +} + +bool epi_restoreMdbBusReady(void) +{ + return SharedMem::read()->Sdata_mdb_busRdy; +} + +bool epi_restoreMdbV12Ready(void) +{ + return SharedMem::read()->Sdata_mdb_V12on; +} + +bool epi_restoreMdbV5Ready(void) +{ + return SharedMem::read()->Sdata_mdb_V5on; +} + + + +//static uint8_t Sdata_mdbNrOfRecData; +//static uint8_t Sdata_RecBuff[40]; + +// last received mdb answer (from mdb device) +// only needed if a special command was sent directly +// DB0: mdb Device-Nr +// DB1: last sent mdb command +// DB2: nr of received (payload) data bytes (apart from ACK, can be 0....34) +// DB3...DB38: rec.data (payload) +void gpi_storeMdbResponse(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>40) leng=40; + tslib_strclr(SharedMem::write()->Sdata_RecBuff,0,40); + SharedMem::write()->Sdata_mdbNrOfRecData=leng; + //tslib_strcpy(data, SharedMem::write()->Sdata_RecBuff, uint16_t(Sdata_mdbNrOfRecData)); + for (nn=0; nnSdata_RecBuff[nn] = data[nn]; + +} + +void epi_restoreMdbResponse(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->Sdata_mdbNrOfRecData; + //tslib_strcpy(SharedMem::read()->Sdata_RecBuff, data, SharedMem::read()->Sdata_mdbNrOfRecData); + for (nn=0; nnSdata_RecBuff[nn]; + + *leng = LL; +} + + +//static uint8_t Sdata_empNrOfsettings; +//static uint8_t Sdata_emp_settingsBuff[66]; + +void gpi_storeEmpSettings(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->Sdata_empNrOfsettings=leng; + //tslib_strcpy(data, SharedMem::write()->Sdata_emp_settingsBuff, leng); + for (nn=0; nnSdata_emp_settingsBuff[nn] = data[nn]; + +} + +void epi_restoreEmpSettings(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->Sdata_empNrOfsettings; + *leng=LL; + //tslib_strcpy(SharedMem::read()->Sdata_emp_settingsBuff, data, SharedMem::read()->Sdata_empNrOfsettings); + for (nn=0; nnSdata_emp_settingsBuff[nn]; + + +} + + + + + +// ...................................................................... +// Münzbuffer[10]: Münze für Münze auslesen (LIFO) +// 4.5.21 + + +/* +struct T_coin +{ + uint8_t valid; + uint8_t signal; + uint8_t error; + uint8_t pad; + uint16_t value; +}; + +static struct T_coin gotCoin[MEMDEPTH_GOTCOINS]; +static uint8_t ctr_gotCoin; +*/ + +void sub_enterData(uint8_t valid, uint8_t signal, uint8_t error, uint16_t value ) +{ + uint8_t pGotCoin; + + pGotCoin=SharedMem::read()->ctr_gotCoin; + if (pGotCoingotCoin[pGotCoin].valid=valid; + SharedMem::write()->gotCoin[pGotCoin].signal=signal; + SharedMem::write()->gotCoin[pGotCoin].error=error; + SharedMem::write()->gotCoin[pGotCoin].value=value; + } + pGotCoin++; + SharedMem::write()->ctr_gotCoin=pGotCoin; + +} + +void gpi_storeEmpCoinSignal(uint8_t leng, uint8_t *data) +{ + // leng is number of coin record with 5 bytes each + uint8_t LL=leng; // nr of coin records + uint16_t vv, pp=0; + + vv=uchar2uint(data[pp+4], data[pp+3]); + sub_enterData(data[pp], data[pp+1], data[pp+2], vv ); + pp+=5; + LL--; + +} + +uint8_t epi_isNewCoinLeft(void) +{ + // retval: 0...16 coins left in FIFO + return SharedMem::read()->ctr_gotCoin; +} + +void epi_restoreEmpCoinSignal(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) +{ + uint8_t pGotCoin; + + pGotCoin=SharedMem::read()->ctr_gotCoin; + + pGotCoin--; + if (pGotCoingotCoin[pGotCoin].valid; + *signal=SharedMem::read()->gotCoin[pGotCoin].signal; + *error=SharedMem::read()->gotCoin[pGotCoin].error; + *value=SharedMem::read()->gotCoin[pGotCoin].value; + } + SharedMem::write()->ctr_gotCoin=pGotCoin; +} + + + +//static uint8_t Sdata_NrOfDeviceSetting; +//static uint8_t Sdata_DeviceSettingBuff[66]; + +void gpi_storeRbDeviceSettings(uint8_t leng, uint8_t *data) // getestet am 12.4.23TS +{ + uint8_t nn; + + if (leng>64) leng=64; + SharedMem::write()->Sdata_NrOfDeviceSetting=leng; + //tslib_strcpy(data, SharedMem::write()->Sdata_DeviceSettingBuff, leng); + for (nn=0; nnSdata_DeviceSettingBuff[nn] = data[nn]; + +} + +void epi_restoreRbDeviceSettings(uint8_t *leng, uint8_t *data) // getestet am 12.4.23TS +{ + uint8_t nn, LL; + LL=SharedMem::read()->Sdata_NrOfDeviceSetting; + + *leng=LL; + //tslib_strcpy(SharedMem::read()->Sdata_DeviceSettingBuff, data, SharedMem::read()->Sdata_NrOfDeviceSetting); + for (nn=0; nnSdata_DeviceSettingBuff[nn]; + +} + + + +/* +Beispiel: + +void gpi_storeUID(uint8_t const *buf8byteUid) +{ + uint64_t udltmp=0; + + for (int ii=0; ii<8; ii++) + { + SharedMem::getData()->Sdata.UIDstr[ii] = buf8byteUid[ii]; + udltmp |= buf8byteUid[ii]; + udltmp <<= 8; + } + SharedMem::getData()->Sdata.slaveUID = udltmp; +} + +void epi_getUIDdec(uint8_t *buf8byteUid) +{ + for (int ii=0; ii<8; ii++) + { + buf8byteUid[ii] = SharedMem::getDataConst()->Sdata.UIDstr[ii]; + } +} + +*/ + +//static uint8_t Sdata_NrOfMachineIDSetting; +//static uint8_t Sdata_NrOfMachineIDBuff[66]; + +void gpi_storeMachineIDsettings(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + //Sdata_NrOfMachineIDSetting=leng; + //tslib_strcpy(data, Sdata_NrOfMachineIDBuff, leng); + SharedMem::write()->SizeMachineIDBuff=leng; + + for (nn=0; nn<64; nn++) + SharedMem::write()->MachineIDBuff[nn]=data[nn]; + +} + +void epi_restoreMachineIDsettings(uint8_t *leng, uint8_t *data) +{ + + //*leng=Sdata_NrOfMachineIDSetting; + //tslib_strcpy(Sdata_NrOfMachineIDBuff, data, Sdata_NrOfMachineIDSetting); + uint8_t uctmp, nn; + + uctmp=SharedMem::read()->SizeMachineIDBuff; + *leng=uctmp; + for (nn=0; nn<64; nn++) + data[nn]=SharedMem::read()->MachineIDBuff[nn]; + +} + + + + +//static uint32_t store_insertedAmount; +//static uint16_t store_lastCoinType[64]; +//static uint16_t store_lastCoinValue[64]; +//static uint8_t p_lastCoin; +//static char store_curPayNewCoin; + +void epi_clearCurrentPayment(void) +{ + // call at beginning of coin collection + int nn; + + SharedMem::write()->store_insertedAmount=0; + SharedMem::write()->p_lastCoin=0; + + // 17.5.23TS: ergänzt: + for (nn=0; nn<64; nn++) + { + SharedMem::write()->store_lastCoinType[nn]=0; + SharedMem::write()->store_lastCoinValue[nn]=0; + } + SharedMem::write()->store_curPayNewCoin=0; +} + +void gpi_storeCurrentPayment(uint32_t insertedAmount, uint16_t lastCoinType, uint16_t lastCoinValue) +{ + uint8_t pLC=SharedMem::read()->p_lastCoin; + SharedMem::write()->store_insertedAmount=insertedAmount; + SharedMem::write()->store_lastCoinType[pLC]=lastCoinType; + SharedMem::write()->store_lastCoinValue[pLC]=lastCoinValue; + pLC++; + SharedMem::write()->p_lastCoin=pLC; + SharedMem::write()->store_curPayNewCoin++; +} + +uint32_t epi_CurrentPaymentGetAmount(void) +{ + return SharedMem::read()->store_insertedAmount; +} + +uint16_t epi_CurrentPaymentGetLastCoin(void) +{ + uint8_t pp; + + pp=SharedMem::read()->p_lastCoin; + if (pp==0) + return 0; // noch keine Münze erhalten + if (pp>0) pp--; + //store_curPayNewCoin=0; // nur 1x melden + return SharedMem::read()->store_lastCoinValue[pp]; +} + +bool epi_CurrentPaymentGetAllCoins(uint16_t *types, uint16_t *values) +{ + // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert falls die jmd. braucht + uint8_t nn; + uint8_t pp; + + pp=SharedMem::read()->p_lastCoin; + if (pp==0) + return false; + for (nn=0; nn<64; nn++) + { + types[nn]= SharedMem::read()->store_lastCoinType[nn]; + values[nn]=SharedMem::read()->store_lastCoinValue[nn]; + } + + return true; +} + + +//uint64_t stor_wakSrc; +//uint8_t stor_reason; + + +void gpi_storeWakeSources(uint8_t *receivedData) +{ + uint8_t uctmp; + int nn; + SharedMem::write()->stor_wakSrc=0; + for (nn=5; nn>=0; nn--) + { + uctmp=receivedData[nn]; + SharedMem::write()->stor_wakSrc |=uctmp; + SharedMem::write()->stor_wakSrc<<=8; + } + SharedMem::write()->stor_reason=receivedData[6]; +} + +uint64_t epi_getWakeSources(void) +{ + return SharedMem::read()->stor_wakSrc; +} + +uint8_t epi_getWakeReason(void) +{ + return SharedMem::read()->stor_reason; +} + + + +//static uint8_t store_rbDevParamLen; +//static uint8_t store_rbDevParams[66]; + +void gpi_storeExtendedTime(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->store_rbDevParamLen=leng; + //tslib_strcpy(data, SharedMem::write()->store_rbDevParams, leng); + for (nn=0; nnstore_rbDevParams[nn] = data[nn]; +} + +void epi_restoreExtendedTime(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->store_rbDevParamLen; + *leng=LL; + //tslib_strcpy(SharedMem::read()->store_rbDevParams, data, SharedMem::read()->store_rbDevParamLen); + for (nn=0; nnstore_rbDevParams[nn]; +} + + +// store device conditions +//static uint8_t store_deviceCondLen; +//static uint8_t store_deviceCond[66]; + +void gpi_storeDeviceConditions(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->store_deviceCondLen=leng; + //tslib_strcpy(data, SharedMem::write()->store_deviceCond, leng); + for (nn=0; nnstore_deviceCond[nn]=data[nn]; +} + +void epi_restoreDeviceConditions(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->store_deviceCondLen; + *leng=LL; + //tslib_strcpy(SharedMem::read()->store_deviceCond, data, SharedMem::read()->store_deviceCondLen); + for (nn=0; nnstore_deviceCond[nn]; +} + + + +// store dynamic machine conditions +//static uint8_t store_machCondLen; +//static uint8_t store_machCond[66]; + +void gpi_storeDynMachineConditions(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->store_machCondLen=leng; +// tslib_strcpy(data, SharedMem::write()->store_machCond, leng); + for (nn=0; nnstore_machCond[nn] = data[nn]; + + } + +void epi_restoreDynMachineConditions(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->store_machCondLen; + *leng=LL; + //tslib_strcpy(SharedMem::read()->store_machCond, data, SharedMem::read()->store_machCondLen); + for (nn=0; nnstore_machCond[nn]; +} + + + +//static uint8_t store_DcBackupNrOfAccNr; +//static uint16_t store_DcBackupAccNr[16]; // z.Z. nur 8 + +void gpi_storeDCbackupAccNr(uint8_t leng, uint8_t *data) +{ + if (leng>32) leng=32; + SharedMem::write()->store_DcBackupAccNr[0]=uchar2uint(data[1], data[0]); + SharedMem::write()->store_DcBackupAccNr[1]=uchar2uint(data[3], data[2]); + SharedMem::write()->store_DcBackupAccNr[2]=uchar2uint(data[5], data[4]); + SharedMem::write()->store_DcBackupAccNr[3]=uchar2uint(data[7], data[6]); + SharedMem::write()->store_DcBackupAccNr[4]=uchar2uint(data[9], data[8]); + SharedMem::write()->store_DcBackupAccNr[5]=uchar2uint(data[11], data[10]); + SharedMem::write()->store_DcBackupAccNr[6]=uchar2uint(data[13], data[12]); + SharedMem::write()->store_DcBackupAccNr[7]=uchar2uint(data[15], data[14]); + SharedMem::write()->store_DcBackupNrOfAccNr=8; +} + +void epi_restoreDCbackupAccNr(uint8_t *leng, uint16_t *accNrs) +{ + // return accNrs[0..7] + uint8_t nn; + + *leng=SharedMem::read()->store_DcBackupNrOfAccNr; + for (nn=0; nn<8; nn++) + accNrs[nn]=SharedMem::read()->store_DcBackupAccNr[nn]; + +} + + +//static uint8_t store_gotNrBlocksOfVaultRec; +//static uint8_t store_vaultrecord[360]; + +void epi_iniVRstorage(void) +{ + tslib_strclr(SharedMem::write()->store_vaultrecord, 0, 360); + SharedMem::write()->store_gotNrBlocksOfVaultRec=0; +} + +void gpi_storeVaultRecord(uint8_t blkNr, uint8_t *data ) +{ + uint16_t start=blkNr, ii; + + SharedMem::write()->store_gotNrBlocksOfVaultRec |= (1<store_vaultrecord[start+ii]=data[ii]; + +} + +bool epi_checkIfVaultRecordAvailable(void) +{ + if (SharedMem::read()->store_gotNrBlocksOfVaultRec==0x1F) + return true; + else + return false; +} + + +bool epi_restoreVaultRecord(uint16_t *length, uint8_t *buf ) +{ + uint16_t nn; + *length=0; + if (SharedMem::read()->store_gotNrBlocksOfVaultRec==0x1F) + { + *length=320; + //tslib_strcpy(store_vaultrecord, buf, 320); + for (nn=0; nn<320; nn++) + buf[nn] = SharedMem::read()->store_vaultrecord[nn]; + } else + return false; + + return true; +} + + +//static uint32_t store_amount; +//static uint16_t store_nrOfCoins; + +void gpi_storeCBlevel(uint32_t amount, uint16_t nrOfCoins ) +{ + SharedMem::write()->store_amount=amount; + SharedMem::write()->store_nrOfCoins=nrOfCoins; +} + +uint32_t epi_getCashBoxContent(void) +{ + return SharedMem::read()->store_amount; +} + +uint16_t epi_getNrOfCoinsInCashBox(void) +{ + return SharedMem::read()->store_nrOfCoins; +} + +//static bool store_DcDataAreValid; + +void gpi_storeDcDataValid(bool isVal) +{ + SharedMem::write()->store_DcDataAreValid = isVal; +} + + +bool epi_areDcDataValid() +{ + return SharedMem::read()->store_DcDataAreValid; +} + +// .................................................................................... +// 24.5.2023 + +//static uint8_t storeDCdynPrinterData[64]; +//static uint8_t DCdynPrinterDataActual; + + +/* +uint8_t nn, LL; + LL=SharedMem::read()->Sdata_mdbNrOfRecData; + //tslib_strcpy(SharedMem::read()->Sdata_RecBuff, data, SharedMem::read()->Sdata_mdbNrOfRecData); + for (nn=0; nnSdata_RecBuff[nn]; +*/ + +void epi_clearDynData(void) +{ + uint8_t nn; + SharedMem::write()->DCdynPrinterDataActual=0; + //memset(SharedMem::write()->storeDCdynPrinterData,0, sizeof(storeDCdynPrinterData)); + for (nn=0; nn<64; nn++) + SharedMem::write()->storeDCdynPrinterData[nn]=0; +} + +void gpi_storeDynData(uint8_t *DCdynDat) +{ + uint8_t nn; + // buffer size: 64 byte + //memcpy(SharedMem::write()->storeDCdynPrinterData, DCdynDat, 64); + SharedMem::write()->DCdynPrinterDataActual=1; + for (nn=0; nn<64; nn++) + SharedMem::write()->storeDCdynPrinterData[nn] = DCdynDat[nn]; +} + +bool epi_getDynPrnData(uint8_t *DCdynDat) +{ + // buffer size: 64 byte + // return true if data are new and valid + uint8_t nn; + if (SharedMem::read()->DCdynPrinterDataActual) + { + //memcpy(DCdynDat, SharedMem::read()->storeDCdynPrinterData, 64); + for (nn=0; nn<64; nn++) + DCdynDat[nn] = SharedMem::read()->storeDCdynPrinterData[nn]; + return true; + } else + { + return false; + } +} + + + + + + diff --git a/src/storeINdata.cpp b/src/storeINdata.cpp new file mode 100644 index 0000000..ba8a72d --- /dev/null +++ b/src/storeINdata.cpp @@ -0,0 +1,2344 @@ +#include +#include +#include +#include "storeINdata.h" +#include "tslib.h" +#include "shared_mem_buffer.h" +#include "datei.h" + +// gpi: grafical access to PI: access from external devices over device controller FOR GUI +// epi: external access from GUI to PI: FOR external devices (DC) + + + + +// store power on/off condition of the devices to control the data request + +//static bool indat_savePrnPwr; + +void indat_storePrinterPower(bool isOn) +{ + SharedMem::write()->indat_savePrnPwr=isOn; +} + +bool indat_isPrinterOn() +{ + return SharedMem::read()->indat_savePrnPwr; +} + + +//static bool indat_saveMifPwr; + +void indat_storeMifarePower(bool isOn) +{ + SharedMem::write()->indat_saveMifPwr=isOn; +} + +bool indat_isMifareOn() +{ + return SharedMem::read()->indat_saveMifPwr; +} + + +//static bool indat_MdbIsOn; + +void indat_storeMDBisOn(bool isOn) +{ + SharedMem::write()->indat_MdbIsOn=isOn; +} + +bool indat_isMdbOn() +{ + return SharedMem::read()->indat_MdbIsOn; +} + + + +//QString indat_HWversion; +//QString indat_SWversion; +//QString indat_DCstate; + +// im shared memory ist kein QString erlaubt!!!!!!!!!!!!!!!!!!!!!! +// nur standard C Typen!!!!!! + +void gpi_storeHWver(QString text) +{ + // change Qstring to array of chars, because shared mem allowes no QString! + int nn, LL = text.length(); + if (LL >= versionBufferLen) + LL=versionBufferLen-1; // leave place for termination + + for (nn=0; nnindat_HWversion[nn] = text.at(nn).toLatin1(); + } + for (nn=LL; nnindat_HWversion[nn] =0; +} + +QString epi_loadHWver(void) +{ + // load array of chars from SM and change to QString + int nn, LL = versionBufferLen; + char cc; + QString myStr; + + myStr.clear(); + + for (nn=0; nnindat_HWversion[nn]; + myStr.append(cc); + } + return myStr; +} + +void gpi_storeSWver(QString text) +{ + int nn, LL = text.length(); + if (LL >= versionBufferLen) + LL=versionBufferLen-1; // leave place for termination + + for (nn=0; nnindat_SWversion[nn] = text.at(nn).toLatin1(); + } + for (nn=LL; nnindat_SWversion[nn] =0; + +} + +QString epi_loadSWver(void) +{ + int nn, LL = versionBufferLen; + char cc; + QString myStr; + + myStr.clear(); + + for (nn=0; nnindat_SWversion[nn]; + myStr.append(cc); + } + return myStr; + +} + +void gpi_storeDCstate(QString text) +{ + //text.chop(8); // DC2 State is shorter (8byte) + //SharedMem::write()->indat_DCstate=text; + int nn, LL = text.length(); + if (LL >= versionBufferLen) + LL=versionBufferLen-1; // leave place for termination + + for (nn=0; nnindat_DCstate[nn] = text.at(nn).toLatin1(); + } + for (nn=LL; nnindat_DCstate[nn] =0; + +} + +QString epi_loadDCstate(void) +{ + + int nn, LL = versionBufferLen; + char cc; + QString myStr; + + myStr.clear(); + + for (nn=0; nnindat_DCstate[nn]; + myStr.append(cc); + } + return myStr; +} + + +// ------------------------------- + +/* +static uint64_t Sdata_slaveUID; +static uint8_t Sdata_UIDstr[8]; +static QString Sdata_DcUidStr; + + +void write2file_UID(void) +{ + QByteArray myBA; + csv_startCreatingFile(); + csv_addUintToFile(Sdata_UIDstr[0]); + csv_addUintToFile(Sdata_UIDstr[1]); + csv_addUintToFile(Sdata_UIDstr[2]); + csv_addUintToFile(Sdata_UIDstr[3]); + csv_addUintToFile(Sdata_UIDstr[4]); + csv_addUintToFile(Sdata_UIDstr[5]); + csv_addUintToFile(Sdata_UIDstr[6]); + csv_addUintToFile(Sdata_UIDstr[7]); + csv_addNewlineToFile(); + csv_addUlongvalToFile(Sdata_slaveUID); + csv_addNewlineToFile(); + csv_addTextToFile(Sdata_DcUidStr); + csv_addNewlineToFile(); + myBA=csv_readbackArray(); + datei_clearFile(FILENAME_SHARED_UID); + datei_writeToFile(FILENAME_SHARED_UID, myBA); + +} + +void gpi_storeUID(uint8_t *buf8byteUid) +{ + uint64_t udltmp=0; + QString myStr; + + //qDebug()<< "store UID "; + + for (int ii=0; ii<8; ii++) + { + //qDebug()<< buf8byteUid[ii] << " "; + + Sdata_UIDstr[ii]=buf8byteUid[ii]; + udltmp|=buf8byteUid[ii]; + udltmp<<=8; + } + Sdata_slaveUID=udltmp; + + Sdata_DcUidStr.clear(); + for (int ii=0;ii<8; ii++) + { + + Sdata_DcUidStr+=QString::number(Sdata_UIDstr[ii],16); + Sdata_DcUidStr+=" "; + } + + write2file_UID(); +} + +void epi_getUIDdec(uint8_t *buf8byteUid) +{ +//qDebug()<< "get UID "; + for (int ii=0; ii<8; ii++) + { + //qDebug()< umformen in hexstring + + QString myStr; + for (int ii=0;ii<8; ii++) + { + + myStr+=QString::number(Sdata_UIDstr[ii],16); + myStr+=" "; + } + return myStr; +} +*/ + +/* read from file: +void epi_getUIDfromFile(uint8_t *buf8byteUid) +{ + QByteArray myBA; + int nn; + + myBA=datei_readFromFile(FILENAME_SHARED_UID); + for (nn=0; nn<8; nn++) + buf8byteUid[nn]=csv_getEntryAsUshort(myBA, nn); + +} + +uint64_t epi_getUIDnumberFromFile(void) +{ + QByteArray myBA; + + myBA=datei_readFromFile(FILENAME_SHARED_UID); + return csv_getEntryAs2Ulong(myBA, 8); + +} + +QString epi_getUIDstrFromFile(void) +{ + QByteArray myBA; + + myBA=datei_readFromFile(FILENAME_SHARED_UID); + return csv_getEntryAsString(myBA, 9); + +} +*/ + +// the same with shared memory : +void gpi_storeUID(uint8_t const *buf8byteUid) +{ + uint64_t udltmp=0; + + for (int ii=0; ii<8; ii++) + { +// SharedMem::getData()->Sdata.UIDstr[ii] = buf8byteUid[ii]; + SharedMem::write()->Sdata.UIDstr[ii] = buf8byteUid[ii]; + udltmp |= buf8byteUid[ii]; + udltmp <<= 8; + } +// SharedMem::getData()->Sdata.slaveUID = udltmp; + SharedMem::write()->Sdata.slaveUID = udltmp; +} + +void epi_getUIDdec(uint8_t *buf8byteUid) +{ + for (int ii=0; ii<8; ii++) + { + //buf8byteUid[ii] = SharedMem::getDataConst()->Sdata.UIDstr[ii]; + buf8byteUid[ii] = SharedMem::read()->Sdata.UIDstr[ii]; + } +} + +QString epi_getUIDstr() +{ + // die UID besteht aus 8 bytes (8 dezimalzahlen) + // -> umformen in hexstring + + QString myStr; + for (int ii=0;ii<8; ii++) + { + //myStr += QString::number(SharedMem::getDataConst()->Sdata.UIDstr[ii], 16); + myStr += QString::number(SharedMem::read()->Sdata.UIDstr[ii], 16); + myStr += " "; + } + return myStr; +} + +// /////////////////////////////////////////////////////////////////////////////////// +// Time and Date +// /////////////////////////////////////////////////////////////////////////////////// +/* +struct T_globTime +{ + // Reihenfolge nicht vertauschen!!!!! + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t Year; + uint8_t Month; + uint8_t DayOfMonth; + uint8_t DayOfWeek; // 1=monday...7 + uint8_t reserve1; + + uint16_t MinutesOfToday; + uint16_t reserve2; + + uint32_t SecondsOfToday; + + uint8_t IsLeapyear; + uint8_t nextLeap; + uint8_t lastLeap; + uint8_t hoursOfWeek; + + uint16_t minOfWeek; + uint16_t hoursOfMonth; + uint16_t minOfMonth; + uint16_t dayOfYear; + uint16_t hoursOfYear; + uint16_t reserve3; + + uint32_t minOfYear; + + uint8_t squareOutMode; + uint8_t free1; + uint16_t reserve4; + uint32_t minOfMillenium; + // bis hierher 44byts + uint32_t free2; + uint32_t free3; + uint32_t free4; + +}; +static T_globTime getGlobalTime; +*/ + + +void gpi_backupSquareMode(uint8_t squMode) +{ + SharedMem::write()->getGlobalTime.squareOutMode=squMode; +} + +uint8_t epi_getSquareMode() +{ + return SharedMem::read()->getGlobalTime.squareOutMode; +} + + +void gpi_backupTime(uint8_t *timeBuffer, uint8_t Leng) +{ + /* + // Daten kommen in gleicher Reihenfolge vom Slave + uint8_t *pTime; + pTime=&getGlobalTime.hour; + if (Leng>44) Leng=44; // mehr brauch ma ned + for (int nn=0; nngetGlobalTime.second=Leng; // nur damit CompilerWarnung weg ist + + SharedMem::write()->getGlobalTime.DayOfWeek=timeBuffer[0]; + SharedMem::write()->getGlobalTime.minute=timeBuffer[1]; + SharedMem::write()->getGlobalTime.second=timeBuffer[2]; + SharedMem::write()->getGlobalTime.hour=timeBuffer[3]; + SharedMem::write()->getGlobalTime.Year=timeBuffer[4]; + SharedMem::write()->getGlobalTime.Month=timeBuffer[5]; + SharedMem::write()->getGlobalTime.DayOfMonth=timeBuffer[6]; + +} + +void epi_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) +{ + *hh=SharedMem::read()->getGlobalTime.hour; + *mm=SharedMem::read()->getGlobalTime.minute; + *ss=SharedMem::read()->getGlobalTime.second; +} + +void epi_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) +{ + *yy=SharedMem::read()->getGlobalTime.Year; + *mm=SharedMem::read()->getGlobalTime.Month; + *dd=SharedMem::read()->getGlobalTime.DayOfMonth; +} + +void epi_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) +{ + *dow=SharedMem::read()->getGlobalTime.DayOfWeek; + *minOfToday=SharedMem::read()->getGlobalTime.MinutesOfToday; + *secOfToday=SharedMem::read()->getGlobalTime.SecondsOfToday; +} + +bool epi_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) +{ + *lastLeapYear=SharedMem::read()->getGlobalTime.lastLeap; + *NextLeapYear=SharedMem::read()->getGlobalTime.nextLeap; + if (SharedMem::read()->getGlobalTime.IsLeapyear) + return true; + return false; +} + +bool epi_isLeapYear() +{ + if (SharedMem::read()->getGlobalTime.IsLeapyear) + return true; + return false; +} + +void epi_getSpecialWeekTimeDate(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) +{ + *DayOfWeek=SharedMem::read()->getGlobalTime.DayOfWeek; + *HoursOfWeek=SharedMem::read()->getGlobalTime.hoursOfWeek; + *MinutesOfWeek=SharedMem::read()->getGlobalTime.minOfWeek; +} + +void epi_getSpecialMonthTimeDate(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) +{ + *DayOfMonth=SharedMem::read()->getGlobalTime.DayOfMonth; + *HoursOfMonth=SharedMem::read()->getGlobalTime.hoursOfMonth; + *MinutesOfMonth=SharedMem::read()->getGlobalTime.minOfMonth; +} + +void epi_getSpecialYearTimeDate(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) +{ + *DayOfYear=SharedMem::read()->getGlobalTime.dayOfYear; + *HoursOfYear=SharedMem::read()->getGlobalTime.hoursOfYear; + *MinutesOfYear=SharedMem::read()->getGlobalTime.minOfYear; +} + +QString epi_getRtcTimeStr(uint8_t timeStyle) +{ + // style: 0: hh:mm 1: hh:mm:ss + QString mystr=nullptr, tempStr=nullptr; + + tempStr.setNum(SharedMem::read()->getGlobalTime.hour,10); + mystr=tempStr.rightJustified(2,'0',false); // macht feste Länge, 5->05 + mystr.append(':'); + //tempStr.clear(); + tempStr.setNum(SharedMem::read()->getGlobalTime.minute,10); // mit 16 statt 10 wirds in HEX angezeigt + //mystr.append(tempStr); + mystr+=tempStr.rightJustified(2,'0',false); + //mystr.append(':'); // so + //mystr+=':'; // oder so, =gleich + + if (timeStyle==1) // hh:mm:ss + { + mystr.append(':'); + tempStr.setNum(SharedMem::read()->getGlobalTime.second,10); + mystr.append(tempStr.rightJustified(2,'0',false)); // wie += + } + return mystr; +} + + +QString epi_getRtcDateStr(uint8_t dateStyle) +{ + // 1=german dd.mm.yy 2=american yy/mm/dd 3=mm.dd.yy + QString tmpStr=nullptr, YYstr=nullptr, MMstr=nullptr, DDstr=nullptr, mystr=nullptr; + mystr.clear(); + + tmpStr.setNum(SharedMem::read()->getGlobalTime.Year,10); // itoa decimal + YYstr=tmpStr.rightJustified(4,'0',false); // immer vierstellig + YYstr[0]='2'; // 2000 dazu + + tmpStr.setNum(SharedMem::read()->getGlobalTime.Month,10); + MMstr=tmpStr.rightJustified(2,'0',false); + + tmpStr.setNum(SharedMem::read()->getGlobalTime.DayOfMonth,10); + DDstr=tmpStr.rightJustified(2,'0',false); + + if (dateStyle==1) // Germany dd.mm.yy + { + mystr=DDstr + '.' + MMstr + '.' + YYstr; + } else + if (dateStyle==2) // american yy/mm/dd + { + mystr=YYstr + '/' + MMstr + '/' + DDstr; + } else + // mm.dd.yy + { + mystr=MMstr + '.' + DDstr + '.' + YYstr; + } + return mystr; +} + + +QString epi_getSlaveTimeDateStr() +{ + QString myStr; + myStr=epi_getRtcTimeStr(1) + " " + epi_getRtcDateStr(1); + return myStr; + +} + + +// /////////////////////////////////////////////////////////////////////////////////// +// analog values +// /////////////////////////////////////////////////////////////////////////////////// + + +//static uint16_t AI_val[MAXNROF_AI]; + +uint8_t gpi_getMaxNrAIs() +{ + return MAXNROF_AI; +} + +void gpi_storeAIs(uint8_t aiNr, uint16_t val) +{ + if (aiNrAI_val[aiNr]=val; +} + +uint16_t epi_loadAIs(uint8_t aiNr) +{ + if (aiNrAI_val[aiNr]; + return 0; +} + + +//-------------- +// measurement values +// ADC0: temp +// 1: voltage +// 2: brightness +#define MAXNROF_MEASURE 4 + +//static uint32_t Sdata_measurement[MAXNROF_MEASURE]; + +uint32_t epi_loadMeasureValue(uint8_t ValueNr) +{ + // ValueNr 0=ADC0, 1=ADC1 aso... + if (ValueNrSdata_measurement[ValueNr]; + return 0; +} + +void gpi_storeMeasureValue(uint8_t ValueNr, uint32_t val) +{ + // in mV, also bis 65,535V + if (ValueNrSdata_measurement[ValueNr]=val; + +} + + + +QString epi_getSlaveTemperatureStr() +{ + char myStr[8], halfDegree=0, Minus=0, oneChar; + int16_t val=0, pp, einer, zehner; + QString myqStr; + + //qDebug() << "AIN0: " << epi_loadAIs(0) << "AIN1: " << epi_loadAIs(1); + + uint32_t meas_temper=epi_loadMeasureValue(MEASCHAN_TEMPERATURE); + // im SaxFormat gespeichert, hier umwandeln in String + + //qDebug() << "meas_temper: " << meas_temper; + + + for (pp=0; pp<8; pp++) myStr[pp]=0; + if (meas_temper&1) // ungerade, also ,5°C + { + halfDegree=1; + meas_temper &=0xFFFE; // um 0,5°C abrunden + } + if (meas_temper<100) + { + Minus=1; + val=int16_t(meas_temper)/2; + val-=50; + } else + { + val=int16_t(meas_temper)-100; + val/=2; + } + pp=0; // pointer auf string + if (Minus) + myStr[pp++]='-'; + // val is now 0..150 for pos Temp or 0..49 for negativ temperature + if (val<10) + { + // only one digit, just change to ascii + oneChar = char(val)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + } else + if (val<100) + { + // 10...99 + einer=val%10; + zehner=val/10; + //myStr[pp++]=char(zehner); + //myStr[pp++]=char(einer); + + oneChar = char(zehner)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + + oneChar = char(einer)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + + } else + { + // 100...150 + myStr[pp++]='1'; // hunderter Stelle immer 1 + val-=100; + einer=val%10; + zehner=val/10; + //myStr[pp++]=char(zehner)+0x30; + //myStr[pp++]=char(einer)+0x30; + oneChar = char(zehner)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + + oneChar = char(einer)+0x30; + if (tslib_isDecAsciiNumber(oneChar)) + myStr[pp++]=oneChar; + else + myStr[pp++]='0'; + } + myStr[pp++]=','; + if (halfDegree) + myStr[pp++]='5'; + else + myStr[pp++]='0'; + myqStr.clear(); + myqStr.append(myStr); + myqStr.append("°C"); + return myqStr; +} + +QString epi_getSlaveVoltageStr() +{ + // value in "meas_volt" in mV, also bis 65,535V. Value range [6000...16000] (6V...16V) + QString myqStr; + uint32_t vor, nach, tmp32; + uint16_t pp; + char myStr[12], ke; //, kz, kh; + + uint32_t ultmp=epi_loadMeasureValue(MEASCHAN_VOLTAGE); + for (pp=0; pp<12; pp++) myStr[pp]=0; + + //qDebug() << ultmp << "mV"; + + myqStr.clear(); + vor=ultmp/1000; + //qDebug() << "vor: " << vor; + + nach=ultmp%1000; + //qDebug() << "nach: " << nach; + pp=0; + if (vor>9) + { + myStr[pp++]=char(vor/10)+0x30; + } + myStr[pp++]=char(vor%10)+0x30; + myStr[pp++]=','; + + ke=char(nach/100); + //qDebug() << "ke: " << ke; + myStr[pp++]=char(ke)+0x30; + + tmp32=nach%100; + ke=char(tmp32/10); + //qDebug() << "ke: " << ke; + myStr[pp++]=char(ke)+0x30; + + tmp32=nach%10; + ke=char(tmp32); + //qDebug() << "ke: " << ke; + myStr[pp++]=char(ke)+0x30; + + + myStr[pp++]='V'; + myqStr.append(myStr); + return myqStr; +} + + + +// /////////////////////////////////////////////////////////////////////////////////// +// digital inputs +// /////////////////////////////////////////////////////////////////////////////////// + +/* come all in with 0x1201: +D0: upper door D1: low door D2:vault door +D3: cash box D4: bill box in +D5: bit 0: upper lockbar up bit1:down +D6: bit 0: lower lockbar up bit1:down + +D7: 0 +D7: DI_contact Power Is On + +D8: OptoIn 1,2 +D9: Aux0...5 +D10:Wake from ptu +D11: DI Wake From Mdb +D12: Ready from printer +D13: Coin Shutter Input +D14: CoinEscrow switch +D15: Mifare IN +D16: Modem_Wake In + +D18: DI Mif Pwr is on +D19: DI MDB_TxD_rdBack +D20: DI Aux Pwr is on +D21: DI GSM Pwr from PO2 is ON +D22: DI Credit Pwr from PO2 is on + =DI RdBack Credit Wake +D23: DI Printer Pwr from PO2 is on +D24: DI MDB Pwr from PO2 is on + */ + +//static uint8_t di_doorSwitch; +void gpi_storeDI_doorSwitches(uint8_t upperDoor, uint8_t lowerDoor, uint8_t vaultDoor) +{ + SharedMem::write()->di_doorSwitch=0; + if (upperDoor) SharedMem::write()->di_doorSwitch |=1; + if (lowerDoor) SharedMem::write()->di_doorSwitch |=2; + if (vaultDoor) SharedMem::write()->di_doorSwitch |=4; +// qDebug()<<"storeINdata: "<di_doorSwitch; +} + + +//static uint8_t di_vaultSwitch; +void gpi_storeDI_vaultSwitches(uint8_t CashBoxIn, uint8_t BillBoxIn) +{ + SharedMem::write()->di_vaultSwitch=0; + if (CashBoxIn) SharedMem::write()->di_vaultSwitch |=1; + if (BillBoxIn) SharedMem::write()->di_vaultSwitch |=2; +} + +uint8_t epi_getDI_vaultSwitches(void) +{ + // bit0: cash box 1: bill box in + return SharedMem::read()->di_vaultSwitch; +} + + +//static uint8_t di_lockSwitch; +void gpi_storeDI_lockSwitches(uint8_t indatUL, uint8_t indatLL) +{ + // D5: bit 0: upper lockbar up bit1:down + // D6: bit 0: lower lockbar up bit1:down + SharedMem::write()->di_lockSwitch=0; + if (indatUL & 1) SharedMem::write()->di_lockSwitch |=1; + if (indatUL & 2) SharedMem::write()->di_lockSwitch |=2; + if (indatLL & 1) SharedMem::write()->di_lockSwitch |=4; + if (indatLL & 2) SharedMem::write()->di_lockSwitch |=8; +} + +uint8_t epi_getDI_lockSwitches(void) +{ + // retval: bit 0: upper lockbar up bit1: upper lockbar is down + // bit 2: lower lockbar up bit1: lower lockbar is down + + return SharedMem::read()->di_lockSwitch; +} + +//static uint8_t di_opto; +void gpi_storeDI_optos(uint8_t indatOpto) +{ + // OptoIn bit 0,1: optoin 1,2 + SharedMem::write()->di_opto=0; + if (indatOpto & 1) SharedMem::write()->di_opto |=1; + if (indatOpto & 2) SharedMem::write()->di_opto |=2; + +} + +uint8_t epi_getDI_optos(void) +{ + // bit0: opto in 1 1: opto in 2 + return SharedMem::read()->di_opto; +} + + +//static uint8_t di_aux; +void gpi_storeDI_auxIn(uint8_t indatAuxIn) +{ + // Aux0...5 + SharedMem::write()->di_aux=indatAuxIn; +} + +uint8_t epi_getDI_auxIn(void) +{ + // bit0: auxin 1 ... 5: auxin 6 + return SharedMem::read()->di_aux; +} + + +//static bool di_wakeFromPtu; +void gpi_storeDI_ptuWake(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_wakeFromPtu=true; + else + SharedMem::write()->di_wakeFromPtu=false; +} + +bool epi_getDI_ptuWake(void) +{ + return SharedMem::read()->di_wakeFromPtu; +} + + +//static bool di_wakeFromMdb; +void gpi_storeDI_mbdWake(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_wakeFromMdb=true; + else + SharedMem::write()->di_wakeFromMdb=false; +} + +bool epi_getDI_mdbWake(void) +{ + return SharedMem::read()->di_wakeFromMdb; +} + + +//static bool di_PrnReady; +void gpi_storeDI_prnReady(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_PrnReady=true; + else + SharedMem::write()->di_PrnReady=false; +} + +bool epi_getDI_prnReady(void) +{ + return SharedMem::read()->di_PrnReady; +} + + +//static bool di_CoinAttach; +void gpi_storeDI_CoinAttach(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_CoinAttach=true; + else + SharedMem::write()->di_CoinAttach=false; +} + +bool epi_getDI_CoinAttach(void) +{ + return SharedMem::read()->di_CoinAttach; +} + +//static bool di_CoinEscrowOpen; +void gpi_storeDI_CoinEscrow(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_CoinEscrowOpen=true; + else + SharedMem::write()->di_CoinEscrowOpen=false; +} + +bool epi_getDI_CoinEscrow(void) +{ + return SharedMem::read()->di_CoinEscrowOpen; +} + + +//static bool di_mifCardTap; +void gpi_storeDI_mifareCardTapped(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_mifCardTap=true; + else + SharedMem::write()->di_mifCardTap=false; +} + +bool epi_getDI_mifareCardTapped(void) +{ + return SharedMem::read()->di_mifCardTap; +} + + +//static bool di_wakeFromModem; +void gpi_storeDI_modemWake(uint8_t indat) +{ + if (indat) + SharedMem::write()->di_wakeFromModem=true; + else + SharedMem::write()->di_wakeFromModem=false; +} + +bool epi_getDI_modemWake(void) +{ + return SharedMem::read()->di_wakeFromModem; +} + + + +//static bool di_contactPwrOn; + +void gpi_storeDI_contactPowerIsOn(bool di_contact_PwrOn) +{ + SharedMem::write()->di_contactPwrOn=di_contact_PwrOn; +} + +bool epi_getDI_contactPwr(void) +{ + // invertiert! + if (SharedMem::read()->di_contactPwrOn) + return false; + return true; +} + +//static bool di_mifarePwrOn; + +void gpi_storeDI_MifarePowerIsOn(bool di_mifare_PwrOn) +{ + SharedMem::write()->di_mifarePwrOn=di_mifare_PwrOn; +} + +bool epi_getDI_mifarePwr(void) +{ + return SharedMem::read()->di_mifarePwrOn; +} + +//static bool di_rdbk_mdbTxd; + +void gpi_storeDI_readbackMdbTxD(bool di_rdbkMdbTxd) +{ + SharedMem::write()->di_rdbk_mdbTxd=di_rdbkMdbTxd; +} + +bool epi_getDI_mdbTxd(void) +{ + return SharedMem::read()->di_rdbk_mdbTxd; +} + +//static bool di_AuxPwrOn; + +void gpi_storeDI_AuxPowerIsOn(bool di_Aux_PwrOn) +{ + SharedMem::write()->di_AuxPwrOn=di_Aux_PwrOn; +} + +bool epi_getDI_auxPwr(void) +{ + return SharedMem::read()->di_AuxPwrOn; +} + +//static bool di_gsmPwrOn; + +void gpi_storeDI_GsmPowerIsOn(bool di_gsm_PwrOn) +{ + SharedMem::write()->di_gsmPwrOn=di_gsm_PwrOn; +} + +bool epi_getDI_gsmPwr(void) +{ + return SharedMem::read()->di_gsmPwrOn; +} + +//static bool di_creditPwrOn; + +void gpi_storeDI_CreditPowerIsOn(bool di_credit_PwrOn) +{ + // invertieren!!! + if (di_credit_PwrOn) + SharedMem::write()->di_creditPwrOn=0; + else + SharedMem::write()->di_creditPwrOn=1; +} + +bool epi_getDI_creditPwr(void) +{ + return SharedMem::read()->di_creditPwrOn; +} + +//static bool di_printerPwrOn; + +void gpi_storeDI_PrinterPowerIsOn(bool di_printer_PwrOn) +{ + SharedMem::write()->di_printerPwrOn=di_printer_PwrOn; +} + +bool epi_getDI_printerPwr(void) +{ + return SharedMem::read()->di_printerPwrOn; +} + +//static bool di_mdbPwrOn; + +void gpi_storeDI_MdbPowerIsOn(bool di_mdb_PwrOn) +{ + SharedMem::write()->di_mdbPwrOn=di_mdb_PwrOn; +} + +bool epi_getDI_mdbPwr(void) +{ + return SharedMem::read()->di_mdbPwrOn; +} + +//static bool di_rejMot_home; + +void gpi_storeDI_rejMot_home(bool di) +{ + SharedMem::write()->di_rejMot_home=di; +} + +bool epi_getDI_rejectMotor_homepos(void) +{ + return SharedMem::read()->di_rejMot_home; +} + +//static uint8_t di_npe_sensor; + +void gpi_storeDI_paperLow(uint8_t di) +{ + // 0: Sensor sees paper 1: no paper 99: off + SharedMem::write()->di_npe_sensor=di; +} + +uint8_t epi_getDI_npe_sensor(void) +{ + return SharedMem::read()->di_npe_sensor; +} + + + +// /////////////////////////////////////////////////////////////////////////////////// +// readaback digital outputs +// /////////////////////////////////////////////////////////////////////////////////// + + +/* +D0 bit0: MDB devices 0=off 1=on + bit1: MDB bus power + bit2: MDB WakeOut + +D1=Printer +D2=Credit +D3=Modem + +D5: serial drv on/off, Serial mux1, Serial mux2 +D6: Leds, Fan, +D7: Siren and relay +D8: PtuWakeOut +D9: Power Aux/Barcode +D10: AuxDir 1...6 +D11: AuxOut 1...6 +D12: Coin shutter output +D13: CoinEscrow Outputs +*/ + +//static uint8_t do_mbdRxTst; +void gpi_storeDO_mdbRxTst(uint8_t mdbRxTst) +{ + SharedMem::write()->do_mbdRxTst=mdbRxTst; +} + +bool epi_getDO_mdbRxTestOut(void) +{ + if (SharedMem::read()->do_mbdRxTst & 1) + return true; + return false; +} + +//static uint8_t do_motorBits; +void gpi_storeDO_motorOutputs(uint8_t Pwr) +{ + //D1: motor outputs bit0: upper lock forw bit 1 backw + // Bit2: lowLock forw bit3: LL backw + SharedMem::write()->do_motorBits=Pwr; +} + +uint8_t epi_getDO_motorOuts(void) +{ + // bit0: upper lock forward bit 1 backward + // bit2: lower lock forward bit 3 backward + return SharedMem::read()->do_motorBits; +} + + + +//static uint8_t do_serialSwitch; // serial drv on/off, Serial mux1, Serial mux2 +void gpi_storeDO_serialSwitch(uint8_t state) // serial drv on/off, Serial mux1, Serial mux2 +{ + SharedMem::write()->do_serialSwitch=state; +} + +uint8_t epi_getDO_serialSwitch(void) +{ + // serial drv on/off, Serial mux1, Serial mux2 + return SharedMem::read()->do_serialSwitch; +} + +bool epi_getDO_serialDriverIsOn(void) +{ + + if ( SharedMem::read()->do_serialSwitch & 1) + return true; + return false; +} + +bool epi_getDO_serialMux1isSetToPrinter(void) +{ + // mux1 off: serial is switched to printer + if ((SharedMem::read()->do_serialSwitch & 2)==0) + return true; + return false; +} + +bool epi_getDO_serialMux1isSetToModem(void) +{ + // mux1 on: serial is switched to modem + if ((SharedMem::read()->do_serialSwitch & 2)>0) + return true; + return false; +} + +bool epi_getDO_serialMux2isSetToCredit(void) +{ + // mux2 off: serial is switched to credit card terminal + if ((SharedMem::read()->do_serialSwitch & 4)==0) + return true; + return false; +} + +bool epi_getDO_serialMux2isSetToMifare(void) +{ + // mux2 on: serial is switched to mifare reader + if ((SharedMem::read()->do_serialSwitch & 4)>0) + return true; + return false; +} + + + + + + +//static uint8_t do_ledsAndFan; +void gpi_storeDO_ledsAndFan(uint8_t ledState) +{ + // bit0: coinled 1:front_illu 2: paper-led 3:pinpad-led 4:start-led 5:service-led 6:fan + SharedMem::write()->do_ledsAndFan=ledState; +} + +bool epi_getDO_led_coin(void) +{ + if (SharedMem::read()->do_ledsAndFan & 1) + return true; + return false; +} + +bool epi_getDO_led_front(void) +{ + if (SharedMem::read()->do_ledsAndFan & 2) + return true; + return false; +} + +bool epi_getDO_led_ticket(void) +{ + if (SharedMem::read()->do_ledsAndFan & 4) + return true; + return false; +} + +bool epi_getDO_led_pin(void) +{ + if (SharedMem::read()->do_ledsAndFan & 8) + return true; + return false; +} + +bool epi_getDO_led_start(void) +{ + if (SharedMem::read()->do_ledsAndFan & 16) + return true; + return false; +} + +bool epi_getDO_led_inside(void) +{ + if (SharedMem::read()->do_ledsAndFan & 32) + return true; + return false; +} + +bool epi_getDO_fan(void) +{ + if (SharedMem::read()->do_ledsAndFan & 64) + return true; + return false; +} + + + +//static uint8_t do_laermUndRelay; +void gpi_storeDO_sirenAndRelay(uint8_t sirenRelay) +{ + // bit0: siren 1:relay + SharedMem::write()->do_laermUndRelay=sirenRelay; +} + +bool epi_getDO_sirene(void) +{ + if (SharedMem::read()->do_laermUndRelay & 1) + return true; + return false; +} + +bool epi_getDO_relay(void) +{ + if (SharedMem::read()->do_laermUndRelay & 2) + return true; + return false; +} + + + +//static uint8_t do_ptuWake; +void gpi_storeDO_ptuWake(uint8_t state) +{ + SharedMem::write()->do_ptuWake=state; +} + +bool epi_getDO_ptuWake(void) +{ + if (SharedMem::read()->do_ptuWake>0) + return true; + return false; +} + +//static uint8_t do_auxPower; +void gpi_storeDO_auxPower(uint8_t pwr) +{ + SharedMem::write()->do_auxPower=pwr; +} + +bool epi_getDO_auxPower(void) +{ + if (SharedMem::read()->do_auxPower>0) + return true; + return false; +} + + + +//static uint8_t do_coinShutter; +void gpi_storeDO_coinShutter(uint8_t state) +{ + SharedMem::write()->do_coinShutter=state; +} + +bool epi_getDO_coinShutterOpen(void) +{ + // bit0: Coin shutter output, bit1: input-test-output + if (SharedMem::read()->do_coinShutter & 1) + return true; + return false; +} + +bool epi_getDO_coinShutterTest(void) +{ + // bit0: Coin shutter output, bit1: input-test-output + if (SharedMem::read()->do_coinShutter & 2) + return true; + return false; +} + +//static uint8_t do_coinEscrow; + +void gpi_storeDO_coinEscrow(uint8_t state) +{ + SharedMem::write()->do_coinEscrow=state; +} + +uint8_t epi_getDO_coinEscrow(void) +{ + // retval: 1:return flap is open 2:take flap is open 0:closed + if (SharedMem::read()->do_coinEscrow &1) + return 1; // return flap is open + if (SharedMem::read()->do_coinEscrow &2) + return 2; // take flap is open + return 0; +} + +//static uint8_t do_printerPower; + +void gpi_storeDO_printerPwrOn(uint8_t state) +{ + SharedMem::write()->do_printerPower=state; +} + +uint8_t epi_getDO_printerPwr(void) +{ + return SharedMem::read()->do_printerPower; +} + +//------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ +//----------------------------- Mifare Card Reader ----------------------------------- + +//#define NROFMIFSTATEBYTES 40 +//static uint8_t Sdata_MIF_STATE[NROFMIFSTATEBYTES]; + + +void gpi_clearMifHwData(void) +{ + for (uint8_t nn=0; nn<64; nn++) + SharedMem::write()->Sdata_MIF_DATA[nn]=0; + +} + +void gpi_storeMifHwData(uint8_t *receivedData) +{ + for (uint8_t nn=0; nn<64; nn++) + SharedMem::write()->Sdata_MIF_DATA[nn]=receivedData[nn]; + +} + +uint8_t epi_restoreMifHwData(uint8_t *buf, uint8_t maxBufferSize) +{ + if (maxBufferSize<64) + return 1; // error + + for (uint8_t nn=0; nn<64; nn++) + buf[nn]=SharedMem::read()->Sdata_MIF_DATA[nn]; + + return 0; // ois OK +} + + + + +void gpi_clearMifAtbData(void) +{ + for (uint8_t nn=0; nn<64; nn++) + SharedMem::write()->Sdata_MIF_ATB[nn]=0; +} + +void gpi_storeMifAtbData(uint8_t *receivedData) +{ + for (uint8_t nn=0; nn<64; nn++) + SharedMem::write()->Sdata_MIF_ATB[nn]=receivedData[nn]; + +} + +uint8_t epi_restoreMifAtbData( uint8_t *buf, uint8_t maxBufferSize) +{ + if ( maxBufferSize<64) + return 1; // error + + for (uint8_t nn=0; nn<64; nn++) + buf[nn]=SharedMem::read()->Sdata_MIF_ATB[nn]; + + return 0; // ois OK +} + +// not used +//void gpi_storeNewMifareCard(uint8_t typ, uint8_t *holder ) +//{ +// SharedMem::write()->mif_cardType=typ; +// uint8_t nn; + +// //tslib_strcpy(holder, SharedMem::write()->mif_cardHolder, 7); +// for (nn=0; nn<7; nn++) +// SharedMem::write()->mif_cardHolder[nn] = holder[nn]; +// SharedMem::write()->mif_cardHolder[7]=0; +//} + +// not used +//uint8_t epi_mifGetCardType(uint8_t *holder) +//{ + //holder[8] = name of card holder + // retval Type of MifareCard, 1=upper door, 2=lower door 3=test printer 4=test coins + + //tslib_strcpy(SharedMem::read()->mif_cardHolder, holder, 7); + +// uint8_t nn; + +// for (nn=0; nn<7; nn++) +// holder[nn]= SharedMem::read()->mif_cardHolder[nn]; +// holder[7]=0; +// return SharedMem::read()->mif_cardType; +// return 0; +//} + + +//------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ + + +//static uint8_t Sdata_PRN_STATE[pi_prnStateArraySize]; + +void epi_restorePrinterState(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_STATE[nn]; + +} + +void gpi_storePrinterState(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_STATE[nn]=buf[nn]; + +} + +//static uint8_t Sdata_PRN_FONTS[pi_prnFontArraySize]; + +void epi_restorePrinterFonts(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_FONTS[nn]; + +} + +void gpi_storePrinterFonts(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nnSdata_PRN_FONTS[nn]=buf[nn]; +/* + qDebug()<<"printer fonts stored " <Sdata_mdb_busRdy=bool(busReady); + SharedMem::write()->Sdata_mdb_V12on=bool(V12on); + SharedMem::write()->Sdata_mdb_V5on=bool(V5on); +} + +bool epi_restoreMdbBusReady(void) +{ + return SharedMem::read()->Sdata_mdb_busRdy; +} + +bool epi_restoreMdbV12Ready(void) +{ + return SharedMem::read()->Sdata_mdb_V12on; +} + +bool epi_restoreMdbV5Ready(void) +{ + return SharedMem::read()->Sdata_mdb_V5on; +} + + + +//static uint8_t Sdata_mdbNrOfRecData; +//static uint8_t Sdata_RecBuff[40]; + +// last received mdb answer (from mdb device) +// only needed if a special command was sent directly +// DB0: mdb Device-Nr +// DB1: last sent mdb command +// DB2: nr of received (payload) data bytes (apart from ACK, can be 0....34) +// DB3...DB38: rec.data (payload) +void gpi_storeMdbResponse(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>40) leng=40; + tslib_strclr(SharedMem::write()->Sdata_RecBuff,0,40); + SharedMem::write()->Sdata_mdbNrOfRecData=leng; + //tslib_strcpy(data, SharedMem::write()->Sdata_RecBuff, uint16_t(Sdata_mdbNrOfRecData)); + for (nn=0; nnSdata_RecBuff[nn] = data[nn]; + +} + +void epi_restoreMdbResponse(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->Sdata_mdbNrOfRecData; + //tslib_strcpy(SharedMem::read()->Sdata_RecBuff, data, SharedMem::read()->Sdata_mdbNrOfRecData); + for (nn=0; nnSdata_RecBuff[nn]; + + *leng = LL; +} + + +//static uint8_t Sdata_empNrOfsettings; +//static uint8_t Sdata_emp_settingsBuff[66]; + +void gpi_storeEmpSettings(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->Sdata_empNrOfsettings=leng; + //tslib_strcpy(data, SharedMem::write()->Sdata_emp_settingsBuff, leng); + for (nn=0; nnSdata_emp_settingsBuff[nn] = data[nn]; + +} + +void epi_restoreEmpSettings(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->Sdata_empNrOfsettings; + *leng=LL; + //tslib_strcpy(SharedMem::read()->Sdata_emp_settingsBuff, data, SharedMem::read()->Sdata_empNrOfsettings); + for (nn=0; nnSdata_emp_settingsBuff[nn]; + + +} + + + + + +// ...................................................................... +// Münzbuffer[10]: Münze für Münze auslesen (LIFO) +// 4.5.21 + + +/* +struct T_coin +{ + uint8_t valid; + uint8_t signal; + uint8_t error; + uint8_t pad; + uint16_t value; +}; + +static struct T_coin gotCoin[MEMDEPTH_GOTCOINS]; +static uint8_t ctr_gotCoin; +*/ + +void sub_enterData(uint8_t valid, uint8_t signal, uint8_t error, uint16_t value ) +{ + uint8_t pGotCoin; + + pGotCoin=SharedMem::read()->ctr_gotCoin; + if (pGotCoingotCoin[pGotCoin].valid=valid; + SharedMem::write()->gotCoin[pGotCoin].signal=signal; + SharedMem::write()->gotCoin[pGotCoin].error=error; + SharedMem::write()->gotCoin[pGotCoin].value=value; + } + pGotCoin++; + SharedMem::write()->ctr_gotCoin=pGotCoin; + +} + +void gpi_storeEmpCoinSignal(uint8_t leng, uint8_t *data) +{ + // leng is number of coin record with 5 bytes each + uint8_t LL=leng; // nr of coin records + uint16_t vv, pp=0; + + vv=uchar2uint(data[pp+4], data[pp+3]); + sub_enterData(data[pp], data[pp+1], data[pp+2], vv ); + pp+=5; + LL--; + +} + +uint8_t epi_isNewCoinLeft(void) +{ + // retval: 0...16 coins left in FIFO + return SharedMem::read()->ctr_gotCoin; +} + +void epi_restoreEmpCoinSignal(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) +{ + uint8_t pGotCoin; + + pGotCoin=SharedMem::read()->ctr_gotCoin; + + pGotCoin--; + if (pGotCoingotCoin[pGotCoin].valid; + *signal=SharedMem::read()->gotCoin[pGotCoin].signal; + *error=SharedMem::read()->gotCoin[pGotCoin].error; + *value=SharedMem::read()->gotCoin[pGotCoin].value; + } + SharedMem::write()->ctr_gotCoin=pGotCoin; +} + + + +//static uint8_t Sdata_NrOfDeviceSetting; +//static uint8_t Sdata_DeviceSettingBuff[66]; + +void gpi_storeRbDeviceSettings(uint8_t leng, uint8_t *data) // getestet am 12.4.23TS +{ + uint8_t nn; + + if (leng>64) leng=64; + SharedMem::write()->Sdata_NrOfDeviceSetting=leng; + //tslib_strcpy(data, SharedMem::write()->Sdata_DeviceSettingBuff, leng); + for (nn=0; nnSdata_DeviceSettingBuff[nn] = data[nn]; + +} + +void epi_restoreRbDeviceSettings(uint8_t *leng, uint8_t *data) // getestet am 12.4.23TS +{ + uint8_t nn, LL; + LL=SharedMem::read()->Sdata_NrOfDeviceSetting; + + *leng=LL; + //tslib_strcpy(SharedMem::read()->Sdata_DeviceSettingBuff, data, SharedMem::read()->Sdata_NrOfDeviceSetting); + for (nn=0; nnSdata_DeviceSettingBuff[nn]; + +} + + + +/* +Beispiel: + +void gpi_storeUID(uint8_t const *buf8byteUid) +{ + uint64_t udltmp=0; + + for (int ii=0; ii<8; ii++) + { + SharedMem::getData()->Sdata.UIDstr[ii] = buf8byteUid[ii]; + udltmp |= buf8byteUid[ii]; + udltmp <<= 8; + } + SharedMem::getData()->Sdata.slaveUID = udltmp; +} + +void epi_getUIDdec(uint8_t *buf8byteUid) +{ + for (int ii=0; ii<8; ii++) + { + buf8byteUid[ii] = SharedMem::getDataConst()->Sdata.UIDstr[ii]; + } +} + +*/ + +//static uint8_t Sdata_NrOfMachineIDSetting; +//static uint8_t Sdata_NrOfMachineIDBuff[66]; + +void gpi_storeMachineIDsettings(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + //Sdata_NrOfMachineIDSetting=leng; + //tslib_strcpy(data, Sdata_NrOfMachineIDBuff, leng); + SharedMem::write()->SizeMachineIDBuff=leng; + + for (nn=0; nn<64; nn++) + SharedMem::write()->MachineIDBuff[nn]=data[nn]; + +} + +void epi_restoreMachineIDsettings(uint8_t *leng, uint8_t *data) +{ + + //*leng=Sdata_NrOfMachineIDSetting; + //tslib_strcpy(Sdata_NrOfMachineIDBuff, data, Sdata_NrOfMachineIDSetting); + uint8_t uctmp, nn; + + uctmp=SharedMem::read()->SizeMachineIDBuff; + *leng=uctmp; + for (nn=0; nn<64; nn++) + data[nn]=SharedMem::read()->MachineIDBuff[nn]; + +} + + + + +//static uint32_t store_insertedAmount; +//static uint16_t store_lastCoinType[64]; +//static uint16_t store_lastCoinValue[64]; +//static uint8_t p_lastCoin; +//static char store_curPayNewCoin; + +void epi_clearCurrentPayment(void) +{ + // call at beginning of coin collection + int nn; + + SharedMem::write()->store_insertedAmount=0; + SharedMem::write()->p_lastCoin=0; + + // 17.5.23TS: ergänzt: + for (nn=0; nn<64; nn++) + { + SharedMem::write()->store_lastCoinType[nn]=0; + SharedMem::write()->store_lastCoinValue[nn]=0; + } + SharedMem::write()->store_curPayNewCoin=0; +} + +void gpi_storeCurrentPayment(uint32_t insertedAmount, uint16_t lastCoinType, uint16_t lastCoinValue) +{ + uint8_t pLC=SharedMem::read()->p_lastCoin; + SharedMem::write()->store_insertedAmount=insertedAmount; + SharedMem::write()->store_lastCoinType[pLC]=lastCoinType; + SharedMem::write()->store_lastCoinValue[pLC]=lastCoinValue; + pLC++; + SharedMem::write()->p_lastCoin=pLC; + SharedMem::write()->store_curPayNewCoin++; + + //qDebug()<<"gpi_storeCurrentPayment "<store_insertedAmount; +} + +uint16_t epi_CurrentPaymentGetLastCoin(void) +{ + uint8_t pp; + + pp=SharedMem::read()->p_lastCoin; + if (pp==0) + return 0; // noch keine Münze erhalten + if (pp>0) pp--; + //store_curPayNewCoin=0; // nur 1x melden + return SharedMem::read()->store_lastCoinValue[pp]; +} + +bool epi_CurrentPaymentGetAllCoins(uint16_t *types, uint16_t *values) +{ + // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert falls die jmd. braucht + uint8_t nn; + uint8_t pp; + + pp=SharedMem::read()->p_lastCoin; + if (pp==0) + return false; + for (nn=0; nn<64; nn++) + { + types[nn]= SharedMem::read()->store_lastCoinType[nn]; + values[nn]=SharedMem::read()->store_lastCoinValue[nn]; + } + + return true; +} + + +//uint64_t stor_wakSrc; +//uint8_t stor_reason; + + +void gpi_storeWakeSources(uint8_t *receivedData) +{ + uint8_t uctmp; + int nn; + SharedMem::write()->stor_wakSrc=0; + for (nn=5; nn>=0; nn--) + { + uctmp=receivedData[nn]; + SharedMem::write()->stor_wakSrc |=uctmp; + SharedMem::write()->stor_wakSrc<<=8; + } + SharedMem::write()->stor_reason=receivedData[6]; +} + +uint64_t epi_getWakeSources(void) +{ + return SharedMem::read()->stor_wakSrc; +} + +uint8_t epi_getWakeReason(void) +{ + return SharedMem::read()->stor_reason; +} + + + +//static uint8_t store_rbDevParamLen; +//static uint8_t store_rbDevParams[66]; + +void gpi_storeExtendedTime(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->store_rbDevParamLen=leng; + //tslib_strcpy(data, SharedMem::write()->store_rbDevParams, leng); + for (nn=0; nnstore_rbDevParams[nn] = data[nn]; +} + +void epi_restoreExtendedTime(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->store_rbDevParamLen; + *leng=LL; + //tslib_strcpy(SharedMem::read()->store_rbDevParams, data, SharedMem::read()->store_rbDevParamLen); + for (nn=0; nnstore_rbDevParams[nn]; +} + + +// store device conditions +//static uint8_t store_deviceCondLen; +//static uint8_t store_deviceCond[66]; + + +void epi_clearDeviceConditions(void) +{ + uint8_t nn; + SharedMem::write()->store_deviceCondLen=0; + for (nn=0; nn<64; nn++) + SharedMem::write()->store_deviceCond[nn]=0; +} + +void gpi_storeDeviceConditions(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->store_deviceCondLen=leng; + //tslib_strcpy(data, SharedMem::write()->store_deviceCond, leng); + for (nn=0; nnstore_deviceCond[nn]=data[nn]; +} + +void epi_restoreDeviceConditions(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->store_deviceCondLen; + *leng=LL; + //tslib_strcpy(SharedMem::read()->store_deviceCond, data, SharedMem::read()->store_deviceCondLen); + for (nn=0; nnstore_deviceCond[nn]; +} + + + +// store dynamic machine conditions +//static uint8_t store_machCondLen; +//static uint8_t store_machCond[66]; + +void epi_clearDynMachineConditions(void) +{ + uint8_t nn; + SharedMem::write()->store_machCondLen=0; + for (nn=0; nn<64; nn++) + SharedMem::write()->store_machCond[nn] = 0; +} + + +void gpi_storeDynMachineConditions(uint8_t leng, uint8_t *data) +{ + uint8_t nn; + if (leng>64) leng=64; + SharedMem::write()->store_machCondLen=leng; +// tslib_strcpy(data, SharedMem::write()->store_machCond, leng); + for (nn=0; nnstore_machCond[nn] = data[nn]; + + } + +void epi_restoreDynMachineConditions(uint8_t *leng, uint8_t *data) +{ + uint8_t nn, LL; + LL=SharedMem::read()->store_machCondLen; + *leng=LL; + //tslib_strcpy(SharedMem::read()->store_machCond, data, SharedMem::read()->store_machCondLen); + for (nn=0; nnstore_machCond[nn]; +} + + + +//static uint8_t store_DcBackupNrOfAccNr; +//static uint16_t store_DcBackupAccNr[16]; // z.Z. nur 8 + +void gpi_storeDCbackupAccNr(uint8_t leng, uint8_t *data) +{ + if (leng>32) leng=32; + SharedMem::write()->store_DcBackupAccNr[0]=uchar2uint(data[1], data[0]); + SharedMem::write()->store_DcBackupAccNr[1]=uchar2uint(data[3], data[2]); + SharedMem::write()->store_DcBackupAccNr[2]=uchar2uint(data[5], data[4]); + SharedMem::write()->store_DcBackupAccNr[3]=uchar2uint(data[7], data[6]); + SharedMem::write()->store_DcBackupAccNr[4]=uchar2uint(data[9], data[8]); + SharedMem::write()->store_DcBackupAccNr[5]=uchar2uint(data[11], data[10]); + SharedMem::write()->store_DcBackupAccNr[6]=uchar2uint(data[13], data[12]); + SharedMem::write()->store_DcBackupAccNr[7]=uchar2uint(data[15], data[14]); + SharedMem::write()->store_DcBackupNrOfAccNr=8; +} + +void epi_restoreDCbackupAccNr(uint8_t *leng, uint16_t *accNrs) +{ + // return accNrs[0..7] + uint8_t nn; + + *leng=SharedMem::read()->store_DcBackupNrOfAccNr; + for (nn=0; nn<8; nn++) + accNrs[nn]=SharedMem::read()->store_DcBackupAccNr[nn]; + +} + + + + +void epi_iniVRstorage(void) +{ + tslib_strclr(SharedMem::write()->store_vaultrecord, 0, PI_SIZOFVAULTRECORD); + SharedMem::write()->store_gotNrBlocksOfVaultRec=0; +} + +void gpi_storeVaultRecord(uint8_t blkNr, uint8_t *data ) +{ + uint16_t start=blkNr, ii; + qDebug()<<"storing vault data "<store_gotNrBlocksOfVaultRec |= (1< PI_SIZOFVAULTRECORD) + start=320; // beginning of 6.block + for (ii=0; ii<64; ii++) + SharedMem::write()->store_vaultrecord[start+ii]=data[ii]; + +} + +bool epi_checkIfVaultRecordAvailable(void) +{ + uint8_t data; + + data=SharedMem::read()->store_gotNrBlocksOfVaultRec; + // qDebug()<<"epi_checkIfVaultRecordAvailable: "<store_gotNrBlocksOfVaultRec; + return data; +} + +bool epi_restoreVaultRecord(uint16_t *length, uint8_t *buf ) +{ + uint16_t nn; + uint8_t dat; + + *length=384; //genau: 340; + for (nn=0; nn<384; nn++) + { + dat = SharedMem::read()->store_vaultrecord[nn]; + buf[nn]=dat; + } + return true; +} + + +//static uint32_t store_amount; +//static uint16_t store_nrOfCoins; + +void gpi_storeCBlevel(uint32_t amount, uint16_t nrOfCoins ) +{ + SharedMem::write()->store_amount=amount; + SharedMem::write()->store_nrOfCoins=nrOfCoins; +} + +uint32_t epi_getCashBoxContent(void) +{ + return SharedMem::read()->store_amount; +} + +uint16_t epi_getNrOfCoinsInCashBox(void) +{ + return SharedMem::read()->store_nrOfCoins; +} + +//static bool store_DcDataAreValid; + +void gpi_storeDcDataValid(bool isVal) +{ + SharedMem::write()->store_DcDataAreValid = isVal; +} + + +bool epi_areDcDataValid() +{ + return SharedMem::read()->store_DcDataAreValid; +} + +// .................................................................................... +// 24.5.2023 + +//static uint8_t storeDCdynPrinterData[64]; +//static uint8_t DCdynPrinterDataActual; + + +/* +uint8_t nn, LL; + LL=SharedMem::read()->Sdata_mdbNrOfRecData; + //tslib_strcpy(SharedMem::read()->Sdata_RecBuff, data, SharedMem::read()->Sdata_mdbNrOfRecData); + for (nn=0; nnSdata_RecBuff[nn]; +*/ + +void epi_clearDynData(void) +{ + uint8_t nn; + SharedMem::write()->DCdynPrinterDataActual=0; + //memset(SharedMem::write()->storeDCdynPrinterData,0, sizeof(storeDCdynPrinterData)); + for (nn=0; nn<64; nn++) + SharedMem::write()->storeDCdynPrinterData[nn]=0; +} + +void gpi_storeDynData(uint8_t *DCdynDat) +{ + uint8_t nn; + // buffer size: 64 byte + //memcpy(SharedMem::write()->storeDCdynPrinterData, DCdynDat, 64); + SharedMem::write()->DCdynPrinterDataActual=1; + for (nn=0; nn<64; nn++) + SharedMem::write()->storeDCdynPrinterData[nn] = DCdynDat[nn]; +} + +bool epi_getDynPrnData(uint8_t *DCdynDat) +{ + // buffer size: 64 byte + // return true if data are new and valid + uint8_t nn; + if (SharedMem::read()->DCdynPrinterDataActual) + { + //memcpy(DCdynDat, SharedMem::read()->storeDCdynPrinterData, 64); + for (nn=0; nn<64; nn++) + DCdynDat[nn] = SharedMem::read()->storeDCdynPrinterData[nn]; + return true; + } else + { + return false; + } +} + + +void gpi_storeNextDCaccNr(uint16_t nxtDcAccNr) +{ + SharedMem::write()->store_DCNextAccountNumber = nxtDcAccNr; + +} + +uint16_t epi_getNextDCaccNr(void ) +{ + return SharedMem::read()->store_DCNextAccountNumber; + +} + + + + + + +void gpi_storeMifCardType(uint16_t length, uint8_t *data) +{ + SharedMem::write()->storeMifCardTypDataLen = length; + + for (uint8_t ii=0; ii<64; ii++) + SharedMem::write()->storeMcardTypData[ii] = data[ii]; + +} + +void epi_restoreMifCardType(uint16_t *length, uint8_t *data) +{ + *length = SharedMem::read()->storeMifCardTypDataLen; + for (uint8_t ii=0; ii<64; ii++) + data[ii] = SharedMem::read()->storeMcardTypData[ii]; + +} + + + +// before with local memory: +//static uint8_t Sdata_rawData[RAW_BL_DATALEN]; +//static uint8_t Sdata_LengthRawData; + +void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t *receivedData) +{ + uint8_t nn, lrd; + + lrd=RdDlen; + if (lrd>RAW_BL_DATALEN) + lrd=RAW_BL_DATALEN; + SharedMem::write()->Sdata_LengthRawData=lrd; + for (nn=0; nnSdata_rawData[nn]=receivedData[nn]; + //qDebug()<<"dcBL got data"<< Sdata_LengthRawData << "bytes :)"; + +} + +uint8_t epi_getRawReceivedData(uint8_t *receivedData) +{ + uint8_t nn, lrd; + + lrd=SharedMem::read()->Sdata_LengthRawData; + for (nn=0; nnSdata_rawData[nn]; + SharedMem::write()->Sdata_LengthRawData=0; // nur 1x gueltig + return lrd; +} + +uint8_t epi_getRawRecLength(void) +{ + // retval=length + return SharedMem::read()->Sdata_LengthRawData; +} +/* +QString epi_getRawReceivedString() +{ + uint8_t nn; //, ret; + QString myString=nullptr, tmpStr=nullptr; + + myString.clear(); + if (Sdata_LengthRawData==0) + return myString; + + for (nn=0; nn0x80 dann wird EIN Byte 16 stellig angezeigt + int ll=tmpStr.length(); + if (ll>2) + { + myString.append(tmpStr[ll-2]); + myString.append(tmpStr[ll-1]); + } else + { + myString.append(tmpStr); + } + myString.append(" "); + + } + //ret=Sdata_LengthRawData; + //Sdata_LengthRawData=0; + return myString; +}*/ + +void epi_clrRawReceivedString() +{ + SharedMem::write()->Sdata_LengthRawData=0; +} + + + +// Mitteilung von Hwapi zu Datif (request coin type) + +void epi_setNowCoinPay(bool on_off) +{ + SharedMem::write()->Sdata_coinPaymentNow=on_off; +} + +bool gpi_getNowCoinPay (void) +{ + return SharedMem::read()->Sdata_coinPaymentNow; +} + +// Mitteilung von Hwapi zu Datif: using BL now + +void epi_setNowIsBootload(bool on_off) +{ + SharedMem::write()->Sdata_bootloadingNow=on_off; +} + +bool gpi_getNowIsBootload(void) +{ + return SharedMem::read()->Sdata_bootloadingNow; +} + + + + +// new from 28.9.23 and earliest from DC version 4.45 +// store all versions of the DC-Jsons +//#define numberOfJsons 36 +//#define versionStringLength 16 +//char store_jsonVersion[versionStringLength][numberOfJsons]; + +void gpi_storeJsonVersion(uint8_t jsonNr, uint8_t *versionString) +{ + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + // length of buffer is always 16 byte + uint8_t nn, lrd; + char einZeichen; + + lrd=jsonNr; + if (lrd>0 && lrd<=numberOfJsons) + { + lrd--; + for (nn=0; nnstore_jsonVersion[nn][lrd]=einZeichen; + } + } +} + +void epi_getJsonVersion(uint8_t jsonNr, char *versionString) +{ + // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. + // 5=printer template 1 ..... 36= template 32 + // length of buffer is always 16 byte + uint8_t nn, lrd; + + lrd=jsonNr; + if (lrd>0 && lrd<=numberOfJsons) + { + lrd--; + for (nn=0; nnstore_jsonVersion[nn][lrd]; + } + +} + + + +void gpi_storeChangerResult(uint8_t result, uint32_t amount) +{ + SharedMem::write()->Sdata_changeResult=result; + SharedMem::write()->Sdata_changedAmount=amount; + +} + +uint8_t epi_getChangerResult(uint32_t *returnedAmount) +{ + *returnedAmount=SharedMem::read()->Sdata_changedAmount; + return SharedMem::read()->Sdata_changeResult; +} + + +void gpi_storeTubeLevel(uint8_t *data) +{ + int nn; + for (nn=0; nn<64; nn++) + { + SharedMem::write()->store_tubeLev[nn]=data[nn]; + } + +} + +void epi_restoreTubeLevel(uint8_t *data) +{ + int nn; + for (nn=0; nn<64; nn++) + { + data[nn]=SharedMem::read()->store_tubeLev[nn]; + } + +} + + + + + + + + + + + + + + diff --git a/src/tslib.cpp b/src/tslib.cpp new file mode 100644 index 0000000..c5a3002 --- /dev/null +++ b/src/tslib.cpp @@ -0,0 +1,612 @@ +#include "tslib.h" +#include + +//tslib::tslib() +//{ + + +//} + + +/* +uint16_t tslib::uchar2uint(uint8_t Highbyte, uint8_t Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint8_t tslib::uint2uchar(uint16_t uival, bool getHighB) +{ + // getHighB: low=GetLowByte + uint16_t uitmp=uival; + if (getHighB==0) + return uint8_t(uitmp); + uitmp>>=8; + return uint8_t(uitmp); + +}*/ + +uint16_t uchar2uint(char Highbyte, char Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint16_t uchar2uint(uint8_t Highbyte, uint8_t Lowbyte) +{ + uint16_t uitmp; + uitmp=0; + uitmp |= uint8_t(Highbyte); + uitmp<<=8; + uitmp |= uint8_t(Lowbyte); + return uitmp; +} + +uint32_t uchar2ulong(uint8_t Highbyte, uint8_t MHbyte, uint8_t MLbyte, uint8_t Lowbyte) +{ + uint32_t ultmp=0; + + ultmp |= uint8_t(Highbyte); + ultmp<<=8; + ultmp |= uint8_t(MHbyte); + ultmp<<=8; + ultmp |= uint8_t(MLbyte); + ultmp<<=8; + ultmp |= uint8_t(Lowbyte); + return ultmp; +} + +uint8_t uint2uchar(uint16_t uival, bool getHighB) +{ + // getHighB: low=GetLowByte + uint16_t uitmp=uival; + if (getHighB==0) + return uint8_t(uitmp); + uitmp>>=8; + return uint8_t(uitmp); + +} + + +uint8_t ulong2uchar(uint32_t ulval, uint8_t getBytNr) +{ + // getBytNr: 0=LSB 3=MSB + uint32_t ultmp=ulval; + if (getBytNr==0) + return uint8_t(ultmp); + ultmp>>=8; + if (getBytNr==1) + return uint8_t(ultmp); + ultmp>>=8; + if (getBytNr==2) + return uint8_t(ultmp); + ultmp>>=8; + return uint8_t(ultmp); + +} + +void delay(uint16_t MilliSec) +{ + QThread::msleep(uint32_t(MilliSec)); +} + + +void GetTimeString(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t System12h, uint8_t ShowSec, uint8_t *buf) +{ + // Zahlenwerte in String wandeln, 12/24h-Format // 12byte für buf! + uint8_t usa; + uint16_t jj; + uint8_t hh, mm, ss, with_sec; + + // buf[0]= ganz linkes Zeichen + hh=hours; + mm=minutes; + ss=seconds; + + // 15.10.12, Plausibilitätsprüfung -------------------------------------------------- + if (hh>23) hh=0; + if (mm>59) mm=0; + if (ss>59) ss=0; + + with_sec=ShowSec; + for (jj=0; jj<12; jj++) buf[jj]=0; + usa = System12h; // 1:12h 0:24h + + // Stunden: + if (usa) + { + // 12h System + if (hh==0 || hh==12) + { + // 12AM (Mitternacht) oder 12PM (Mittag) + buf[0]=0x31; + buf[1]=0x32; + } else + if (hh<12) + { + // 1..11AM + buf[0]=hh/10+0x30; + buf[1]=hh%10+0x30; + } else + { + //13:00 bis 23Uhr + buf[0]=(hh-12)/10+0x30; + buf[1]=(hh-12)%10+0x30; + } + } else + { + // 24h System + buf[0]=hh/10+0x30; + buf[1]=hh%10+0x30; + } + + // Minuten: + buf[2]=':'; + buf[3]=mm/10+0x30; + buf[4]=mm%10+0x30; + + jj=5; + if (with_sec) + { + buf[jj++]=':'; + buf[jj++]=ss/10+0x30; + buf[jj++]=ss%10+0x30; + } + if (usa) + { + buf[jj++]=' '; + if (hh<12) + buf[jj++]='A'; + else + buf[jj++]='P'; + buf[jj++]='M'; + } + +} + +// ------------------- ******************************************************************************** + +void GetDateString(uint8_t day, uint8_t month, uint8_t yearhigh, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf) +{ + // generate date as ascii string from integers day/month/year + // yearhigh: 10..29, in europe always 20 (not in arabia!) comes as hex number, e.g. 0x20 + // format= 0: dd.mm.yyyy (deutsch) + // 1: mm.dd.yyyy (amerika) + // 2: yyyy.mm.dd (Iran, Dubai) + // 3: dd.yyyy.mm + // 4: mm.yyyy.dd + // 5: yyyy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + + uint8_t tag, mon, jahr, d10, d1, m10, m1, y1000, y100, y10, y1; + uint8_t slash; + + + y100= (yearhigh & 0x0F)+0x30; + y1000=((yearhigh & 0xF0)>>4)+0x30; +// if (yearhigh>=20) +// { +// y1000='2'; +// y100=28+yearhigh; // '0' + (yearhigh-20) +// } else +// if (yearhigh<20) +// { +// y1000='1'; +// y100=38-yearhigh; // '9' - (19-yearhigh) +// } + + tag=day; + mon=month; + jahr=yearlow; + + if (mon>12 || mon==0) mon=1; // 23.10.12 + if (tag>31 || tag==0) tag=1; + if (jahr>50 || jahr<11) jahr=1; + + if (sep==0) + slash='.'; // slash==0 + else if (sep==1) + slash='/'; + else + if (sep>=0x20) + slash=sep; + else + slash='.'; + + d10 =tag/10; + d1 =tag%10; + m10 =mon/10; + m1 =mon%10; + y10 =jahr/10; + y1 =jahr%10; + + d10 +=0x30; // in Asccii wandeln + d1 +=0x30; + m10 +=0x30; + m1 +=0x30; + y10 +=0x30; + y1 +=0x30; + + switch (format) + { + // 0: dd.mm.yyyy + case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash; + buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break; + + // 1: mm.dd.yyyy + case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash; + buf[6]=y1000; buf[7]=y100; buf[8]=y10; buf[9]=y1; break; + + // 2: yyyy.mm.dd + case 2: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=m10; + buf[6]=m1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break; + + // 3: dd.yyyy.mm + case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=y1000; buf[4]=y100; + buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break; + + // 4: mm.yyyy.dd + case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=y1000; buf[4]=y100; + buf[5]=y10; buf[6]=y1; buf[7]=slash; buf[8]=d10; buf[9]=d1; break; + + // 5: yyyy.dd.mm + case 5: buf[0]=y1000; buf[1]=y100; buf[2]=y10; buf[3]=y1; buf[4]=slash; buf[5]=d10; + buf[6]=d1; buf[7]=slash; buf[8]=m10; buf[9]=m1; break; + + } + buf[10]=0; + + +} + +// ------------------- ******************************************************************************** + +void GetShortDateString(uint8_t day, uint8_t month, uint8_t yearlow, uint8_t format, uint8_t sep, uint8_t *buf) +{ + // generate date as ascii string from integers day/month/year + // format= 0: dd.mm.yy (deutsch) + // 1: mm.dd.yy (amerika) + // 2: yy.mm.dd (Iran, Dubai) + // 3: dd.yy.mm + // 4: mm.yy.dd + // 5: yy.dd.mm + // sep: 0: use . as seperator 1: use / as seperator + // return String in *buf // 11byte für buf! + + + uint8_t tag, mon, jahr, d10, d1, m10, m1, y10, y1; + uint8_t slash; + + + tag=day; + mon=month; + jahr=yearlow; + + if (mon>12 || mon==0) mon=1; // 23.10.12 + if (tag>31 || tag==0) tag=1; + if (jahr>50 || jahr<11) jahr=1; + + if (sep==0) + slash='.'; // slash==0 + else if (sep==1) + slash='/'; + else if (sep>=0x20) + slash=sep; + else + slash='.'; + + d10 =tag/10; + d1 =tag%10; + m10 =mon/10; + m1 =mon%10; + y10 =jahr/10; + y1 =jahr%10; + + d10 +=0x30; // in Asccii wandeln + d1 +=0x30; + m10 +=0x30; + m1 +=0x30; + y10 +=0x30; + y1 +=0x30; + + switch (format) + { + // 0: dd.mm.yyyy + case 0: buf[0]=d10; buf[1]=d1; buf[2]=slash; buf[3]=m10; buf[4]=m1; buf[5]=slash; + buf[6]=y10; buf[7]=y1; break; + + // 1: mm.dd.yyyy + case 1: buf[0]=m10; buf[1]=m1; buf[2]=slash; buf[3]=d10; buf[4]=d1; buf[5]=slash; + buf[6]=y10; buf[7]=y1; break; + + // 2: yyyy.mm.dd + case 2: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=m10; + buf[4]=m1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break; + + // 3: dd.yyyy.mm + case 3: buf[0]=d10; buf[1]=d1; buf[2]=slash; + buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break; + + // 4: mm.yyyy.dd + case 4: buf[0]=m10; buf[1]=m1; buf[2]=slash; + buf[3]=y10; buf[4]=y1; buf[5]=slash; buf[6]=d10; buf[7]=d1; break; + + // 5: yyyy.dd.mm + case 5: buf[0]=y10; buf[1]=y1; buf[2]=slash; buf[3]=d10; + buf[4]=d1; buf[5]=slash; buf[6]=m10; buf[7]=m1; break; + + } + buf[8]=0; + + +} + +uint16_t tslib_strlen(char *buf) +{ + uint16_t nn; + + for (nn=0; nn<0xFFF0; nn++) + if (buf[nn]==0) + return nn; + return 0; +} + +uint16_t tslib_strlen(uint8_t *buf) +{ + uint16_t nn; + + for (nn=0; nn<0xFFF0; nn++) + if (buf[nn]==0) + return nn; + return 0; +} + +void tslib_strclr(char *buf, char clrsign, uint16_t len) +{ + uint16_t nn; + + for (nn=0; nn=0x30 && sign<=0x39) + return true; + return false; +} + +bool tslib_isHexAsciiNumber(char sign) +{ + if (sign>=0x30 && sign<=0x39) + return true; + if (sign>=0x61 && sign<=0x66) // a...f + return true; + if (sign>=0x41 && sign<=0x46) // A...F + return true; + return false; +} + +int tslib_getMinimum(int val1, int val2) +{ + if (val1maxArayLen) LL=maxArayLen; + for (ii=0; ii> (7 - nn)) & 0x01); + if (B15H) + { + crc ^= 0x1021; + } + } + } + + for (nn = 0; nn < 16; nn++) + { + B15H = 0; + if(crc & 0x8000) + B15H = 1; + crc = (crc << 1) | 0x00; + if (B15H) + { + crc ^= 0x1021; + } + } + return crc; + +} + +static uint8_t LastBLcmd; // stored the last sent cmd in order to analys response + // cmd echo'ed: error cmd or'ed with 0x80: OK + +uint8_t tslib_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) +{ + // make BL protocol, retval = outbuf length (5...133) + // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum + // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 + // Data length = 0...64 + // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 + // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 + + uint8_t myBuf[140], pp=0, nn, uctmp, currLen=0; + uint16_t calcCrc; + + tslib_strclr(myBuf, 0, 140); + + myBuf[pp++]=2; // STX + myBuf[pp++]=Cmd; + LastBLcmd=Cmd; + + // append data: + for (nn=0; nn>8) & 0x00FF); + myBuf[pp++]=3; + currLen=pp; + + return currLen; +} + +// some special commands (right out of bootloader manual) +uint8_t tslib_readBLversion(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData); +} + +uint8_t tslib_readFWversion(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x12, 0, myBuf, sendData); +} + +uint8_t tslib_exitBL(uint8_t *sendData) +{ + // minimum size of sendData-buffer: 5byte retval: length + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x18, 0, myBuf, sendData); +} + +uint8_t tslib_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData) +{ + // minimum size of sendData-buffer: 13byte retval: length (9...13) + uint8_t myBuf[2]; + tslib_strclr(myBuf, 0, 2); + return tslib_prepareDC_BLcmd(0x11, 0, myBuf, sendData); +} +*/ + +// ----------------------------------------------------------------------------------------------- + + +void biox_CopyBlock(uint8_t *src, uint16_t srcPos, uint8_t *dest, uint16_t destPos, uint16_t len) +{ + // both buffers starting from pos 0 + uint16_t xx,yy,zz,ii; + + xx = srcPos; + yy = destPos; + zz = len; + + for (ii = 0; ii < zz; ++ii) + { + dest[yy + ii] = src[xx + ii]; + } +} + + +bool tslib_strComp(uint8_t *buf, char *compStr) +{ + uint16_t strLen=tslib_strlen(compStr), pp; + + for (pp=0; pp