From 3c7aec979af86ff5ba513f8b867f54dc278592df Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Tue, 11 Apr 2023 14:04:38 +0200 Subject: [PATCH] Squashed 'DCPlugin/' content from commit debade9 git-subtree-dir: DCPlugin git-subtree-split: debade99427801efa46a708cd726648c7f83a257 --- .gitignore | 1 + DCPlugin.pri | 23 + DCPlugin.pro | 68 + README.md | 0 include/com.h | 105 ++ include/controlBus.h | 194 +++ include/datIf.h | 335 +++++ include/dcBL.h | 102 ++ include/hwapi.h | 1231 +++++++++++++++++ include/interfaces.h | 1116 +++++++++++++++ include/prot.h | 129 ++ include/sendWRcmd.h | 217 +++ include/storeINdata.h | 489 +++++++ include/tslib.h | 84 ++ plugins/interfaces.h | 1115 +++++++++++++++ src/com.cpp | 449 ++++++ src/controlBus.cpp | 422 ++++++ src/datIf.cpp | 1368 +++++++++++++++++++ src/dcBL.cpp | 1461 ++++++++++++++++++++ src/hwapi.cpp | 3017 +++++++++++++++++++++++++++++++++++++++++ src/prot.cpp | 764 +++++++++++ src/sendWRcmd.cpp | 435 ++++++ src/storeINdata.cpp | 1572 +++++++++++++++++++++ src/tslib.cpp | 557 ++++++++ 24 files changed, 15254 insertions(+) create mode 100644 .gitignore create mode 100644 DCPlugin.pri create mode 100644 DCPlugin.pro create mode 100644 README.md create mode 100644 include/com.h create mode 100644 include/controlBus.h create mode 100644 include/datIf.h create mode 100644 include/dcBL.h create mode 100644 include/hwapi.h create mode 100644 include/interfaces.h create mode 100644 include/prot.h create mode 100644 include/sendWRcmd.h create mode 100644 include/storeINdata.h create mode 100644 include/tslib.h create mode 100644 plugins/interfaces.h create mode 100644 src/com.cpp create mode 100644 src/controlBus.cpp create mode 100644 src/datIf.cpp create mode 100644 src/dcBL.cpp create mode 100644 src/hwapi.cpp create mode 100644 src/prot.cpp create mode 100644 src/sendWRcmd.cpp create mode 100644 src/storeINdata.cpp create mode 100644 src/tslib.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a9d35c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.user diff --git a/DCPlugin.pri b/DCPlugin.pri new file mode 100644 index 0000000..ee140f9 --- /dev/null +++ b/DCPlugin.pri @@ -0,0 +1,23 @@ +INCLUDEPATH += $${PWD}/include +DEPENDPATH += $${PWD} + +HEADERS += $${PWD}/include/com.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 + +SOURCES += $${PWD}/src/com.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 diff --git a/DCPlugin.pro b/DCPlugin.pro new file mode 100644 index 0000000..79dffcc --- /dev/null +++ b/DCPlugin.pro @@ -0,0 +1,68 @@ +TEMPLATE = lib +CONFIG += plugin +#CONFIG += c++11 console +#CONFIG -= app_bundle +#QT += widgets +QT -= gui +QT += widgets serialport + +INCLUDEPATH += $${PWD}/plugins +INCLUDEPATH += $${PWD}/include + +QMAKE_CXXFLAGS += -Wno-deprecated-copy + +# default +ARCH = PTU5 + +contains( CONFIG, DesktopLinux ) { + QMAKE_CC = ccache $$QMAKE_CC + QMAKE_CXX = ccache $$QMAKE_CXX + QMAKE_CXXFLAGS += -std=c++11 + # QMAKE_CXXFLAGS += -Wno-deprecated-ctor + linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments } + ARCH = DesktopLinux + include(DCPlugin.pri) +} + +contains( CONFIG, PTU5 ) { + # QMAKE_CC = ccache $$QMAKE_CC + # QMAKE_CXX = ccache $$QMAKE_CXX + QMAKE_CXXFLAGS += -std=c++11 + linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments } + CONFIG += link_pkgconfig + ARCH = PTU5 + + # NOTE: include contents of DCPlugin.pri. Also used by ATBQT. + # Add new files in DCPlugin.pri. + include(DCPlugin.pri) +} + +contains( CONFIG, PTU5_YOCTO ) { + ARCH = PTU5 + + # add qmqtt lib + #LIBS += -lQt5Qmqtt +} + +TARGET = CashAgentLib +DESTDIR = ../plugins + + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + + +# 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/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/include/com.h b/include/com.h new file mode 100644 index 0000000..69a8ea4 --- /dev/null +++ b/include/com.h @@ -0,0 +1,105 @@ +//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" + +#define MAXTELEGRAMLEN 90 + +// display all inputs and outputs in output window: +//#define PRINTALLDEBUGS 1 + +class T_com : public QMainWindow //, 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(QWidget *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..6619e6e --- /dev/null +++ b/include/controlBus.h @@ -0,0 +1,194 @@ +#ifndef CONTROLBUS_H +#define CONTROLBUS_H + + +#include +#include "tslib.h" +#include + + +// /////////////////////////////////////////////////////////////////////////////////// +// 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 + +// Actions, GUI Buttons -> API, start cyclic transmission +void epi_startEmmision(char start); // 1: start sending activated + +//void epi_setPeriodicSendTimeVal(uint16_t val); + + +// 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); + + +void gpi_serialIsOpen(bool offen); + +bool epi_isSerialPortOpen(); + // true: port is open false: port is closed + + + + + +// Meldung von TabCom an Datif: starte zyklische Sendung: +bool gpi_isEmmisionOn(void); + +//uint16_t gpi_getPeriodicSendTimeVal(); + +//bool gpi_PeriodicSendTimeHasChanged(); + +//void epi_setCurrSlavAddr(int slavAd); + +//int gpi_getCurrSlavAddr(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); + +// /////////////////////////////////////////////////////////////////////////////////// +// 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 +// /////////////////////////////////////////////////////////////////////////////////// + + +uint8_t gpi_startNewRequest(); + // called by Datif + +uint8_t 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 + + + +#endif + + + + + + + + + + diff --git a/include/datIf.h b/include/datIf.h new file mode 100644 index 0000000..9a20cb5 --- /dev/null +++ b/include/datIf.h @@ -0,0 +1,335 @@ +// 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 +#include "tslib.h" +#include "prot.h" +#include "dcBL.h" + + +#include +#include +#include +#include +#include +#include +#include + + + +#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_GETWAK 0x2812 // REQ not nec. +#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 + + +/* +// WRITE Commands (e.g. switch relay) +#define CMD2DC_sendTime 0x1310 +#define CMD2DC_setWakeFrequ 0x1320 + +#define CMD2DC_MOV_UPLOCK 0x1801 +#define CMD2DC_MOV_DNLOCK 0x1802 +#define CMD2DC_UPPER_DOOR 0x1810 +#define CMD2DC_LOWER_DOOR 0x1811 +#define CMD2DC_VAULT_DOOR 0x1812 + +// neu 7.10.21: +#define CMD2DC_REJMOT_ON 0x1813 +#define CMD2DC_REJMOT_RUN 0x1814 + + +#define CMD2DC_LED_COIN 0x1204 +#define CMD2DC_LED_ILLU 0x1205 +#define CMD2DC_LED_TICKET 0x1206 +#define CMD2DC_LED_START 0x1208 +#define CMD2DC_LED_PIN 0x1207 +#define CMD2DC_LED_IN 0x1209 +#define CMD2DC_FAN 0x1210 +#define CMD2DC_SIREN 0x1211 +#define CMD2DC_BARRIER 0x1212 +#define CMD2DC_WAKEPTU 0x1218 +#define CMD2DC_SWITCHAUXPWR 0x1220 +#define CMD2DC_SWITCHAUXDDR 0x1222 +#define CMD2DC_SWITCHAUXOUT 0x1224 +#define CMD2DC_UCONTACTON 0x1226 + +#define CMD2DC_DEVICE_PARAM 0x2000 +#define CMD2DC_SEND_MACH_ID 0x2002 +#define CMD2DC_RDBK_DEV_PARA 0x2001 +#define CMD2DC_RDBK_MACH_ID 0x2003 + + + +// --------------------------- MDB -------------- +#define CMD2DC_MDB_ON 0x2800 +#define CMD2DC_MDB_GET_STATE 0x2801 // REQ +#define CMD2DC_MDB_DORESET 0x2802 +#define CMD2DC_MDB_SETWAK 0x2811 +//#define CMD2DC_MDB_GETWAK 0x2812 // REQ not nec. +#define CMD2DC_MDB_SENDCMD 0x2820 +#define CMD2DC_MDB_SENDMSG 0x2821 +#define CMD2DC_MDB_GETRESP 0x2822 // REQ + +// --------------------------- EMP -------------- +#define CMD2DC_EMP_SET 0x2830 +#define CMD2DC_EMP_GET_ALL 0x2831 // REQ +#define CMD2DC_EMP_STARTPOLL 0x2832 +#define CMD2DC_EMP_STARTPAY 0x2834 +#define CMD2DC_EMP_STOPPAY 0x2836 +#define CMD2DC_EMP_GOTCOIN 0x2837 // REQ + + + + + + + + +#define CMD2DC_SHUTTER_OPEN 0x2911 +#define CMD2DC_ESCR_OPEN 0x2920 +#define CMD2DC_ESCR_TAKE 0x2921 +#define CMD2DC_ESCR_RETURN 0x2922 +#define CMD2DC_MOD_ON 0x2940 +#define CMD2DC_MOD_WAK 0x2941 +#define CMD2DC_CRED_ON 0x2960 +#define CMD2DC_CRED_WAK 0x2961 + + +// READ Commands ((e.g. get input) +#define CMD2DC_TestSerial 0x1101 +#define CMD2DC_GetSerialConfig 0x1107 +#define CMD2DC_RdBkHWversion 0x110A +#define CMD2DC_RdBkSWversion 0x110B +#define CMD2DC_RdBkDCstate 0x110C + +#define CMD2DC_RdBkUID 0x1305 +#define CMD2DC_RdBkTime 0x1313 +#define CMD2DC_RdBkAnalog 0x1550 +#define CMD2DC_GetAllInputs 0x1201 +#define CMD2DC_RdBkAllOutputs 0x1202 + + +#define CMD2DC_MIFREADERON 0x2900 +#define CMD2DC_ATB_CREATE 0x2907 +// Mif read data: +#define CMD2DC_RdBk_MifState 0x2902 +#define CMD2DC_RdBk_MifData 0x2903 +#define CMD2DC_RdBk_AtbCardType 0x2905 +//#define CMD2DC_RdBk_CardData 0x2906 + + + + +// higher Level operation commands +//#define CMD2DC_SHUTTER_ONE 0x2912 +#define CMD2DC_SHUTTER_COIN 0x2913 +#define CMD2DC_SHUTTER_OPEN3S 0x2912 +#define CMD2DC_SEND_SHUT_TIME 0x2915 + +#define CMD2DC_ESCR_TAKE 0x2921 +#define CMD2DC_ESCR_RETURN 0x2922 + + +#define CMD2DC_PRINTERON 0x2A01 +#define CMD2DC_RdBk_PrnState 0x2A02 +#define CMD2DC_RdBk_PrnFonts 0x2A12 +#define CMD2DC_RdBk_AllPrnData 0x2A40 + + // nr of params: +#define CMD2DC_PRI_SYS_CMD 0x2A03 // 3 +#define CMD2DC_PRI_ESC_CMD 0x2A04 // 4 +#define CMD2DC_PRI_SETUP 0x2A05 // 5 +#define CMD2DC_PRI_MOVE 0x2A06 // 2 +#define CMD2DC_PRI_SETFONT 0x2A10 // 4 +#define CMD2DC_PRI_SETLETTER 0x2A11 // 3 +#define CMD2DC_PRI_CUT 0x2A13 // 1 + +#define CMD2DC_PRI_PRINT_TXT 0x2A14 // 64 + +#define CMD2DC_PRI_LF 0x2A15 // 1 +#define CMD2DC_PRI_PRIFONTTABLE 0x2A16 +#define CMD2DC_PRI_BARCODE 0x2A17 // ca 15...25 + +#define CMD2DC_STOR_QR_DATA 0x2A18 // 150 +#define CMD2DC_PRI_QR_CODE 0x2A19 // 0 + +#define CMD2DC_PRI_LOGOFROMFLASH 0x2A1A // 2 + +#define CMD2DC_PRI_STORE_DOC 0x2A41 // 1 +#define CMD2DC_PRI_DOCUMENT_NR 0x2A42 // 1 + 64 +#define CMD2DC_PRI_CLEAR_DOC 0x2A43 // 1 + +*/ + + + + +#define FIX_SLAVE_ADDR 0 +#define SEND_ATONCE 1 +#define SENDCOMBINED 0 + + + + +class T_datif : public QMainWindow +{ + 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 + + + T_prot *myDCIF; + QTimer *datif_trigger; + uint8_t selectedSlaveAddr; + +private slots: + char datif_cycleSend(); + void StoredRecData(); + +public: + T_datif(QWidget *parent = nullptr); + + T_prot *getProt() { return myDCIF; } + T_prot const *getProt() const { return myDCIF; } + + 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); + +signals: + void ResponseRecieved(); + //the requested data are stored in peripheral image + // can be loaded with epi + +}; + +#endif // CI_H diff --git a/include/dcBL.h b/include/dcBL.h new file mode 100644 index 0000000..f605270 --- /dev/null +++ b/include/dcBL.h @@ -0,0 +1,102 @@ +#ifndef DCBL_H +#define DCBL_H +#include +#include "qbytearray.h" +#include "qstring.h" +#include + +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 + +uint8_t dcBL_getResponse(uint8_t *respBuff); + // retval: nr of received bytes + +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); + + + +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) + + + +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 what's going on.... +// 1: connected to BL +// 2: transmission started +// 3: transmission successful + + + +#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(); + +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/hwapi.h b/include/hwapi.h new file mode 100644 index 0000000..f904e5d --- /dev/null +++ b/include/hwapi.h @@ -0,0 +1,1231 @@ +/* + +PSA1259 hardware control using the DeviceController DC2 + +covering enclosure (switches and doors) and money devices, +controls mifare card to access or program +optional it can control printer, modem, bar code reader and credit card + + * API to the PSA1259 Hardware + * All data come in from device controller via serial interface and will be stored + * in "PI" = peripheral image + * PI is updated every 100ms (up to 30ms possible) + * This api uses stored pi data and returns them in the following functions + * created: Q1/2020 TS + * + +The devices, connected to device controller2 (DC2) can be controlled in different access levels. +Level 1: + direct connection to DC2, check versions, state and parameters + control serial interfaces + digital/analog IO's + read and write to connected devices on lowest level, this is a kind of fall-back-level + in case higher levels fail or do not support the needed (new) function + Example: send a specific printer command, several bytes that need to be conform to + printer manual. This command is routed to the printer through the DC2 without + any action of the DC. You can write your own device driver that way. + Level 1 is flexible but complicated + +Level 2: + The DC controls the connected devices containing a device driver. The DC offers + usage of the device by simple commands, + Example: "Printer on", "set Font size 3" "print "hello world"", "cut" + In opposite to level 1 where you had to send a set of numbers and letters. + In other words: you "talk" to the device controller, not to the device itself. + +Level 3: + start/stop complete processes. + Example: 1) print (predefined) document nr 3 with Text, letter size, font set, cut. + Also power up/down the printer, check if paper ok and so on. + */ + +/* +Another access example: control the coin unit + +Level 1): read digital inputs to detect coin, + switch digital output which opens coin slot + communicate with coin checker by certain mdb-commands (manual conform) + poll coin checker for inserted coins + close coin slot after 3seconds by setting DO to 0.... + +Level 2): get message of attached coin from DC + send command "initialize coin checker" to DC + send command "open slot for 3s" + poll DC for inserted coins, DC polls coin checker in right way, no need + to know the data sheet of the coin checker or mdb-bus + command to DC "open coin escrow's return flap for 1s" + +Level 3): send command: "start payment process" + all coin devices are started up + coin blocker opens for 3s if a coin is attached + coin checker summarizes inserted value and reports sum + later send command "stop payment process" (puts coins to vault) or + send command "cancel payment process" (returns coins to user) + +*/ + +#ifndef hwapi_H +#define hwapi_H + +#include +#include +#include +#include +#include <../plugins/interfaces.h> +#include "datIf.h" + + + +//public QWidget, + +/* +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; +}; + +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_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=Emp & Bus power off, 1=powered, poll off 2=polling on + // 3=device responded, requesting status + // 4=waiting for status 5=have status, + // 6: IDLE, have paramters from master, polling running, ready for payment + // Master can stop/start polling and acceptance + // 7: end of transaction, polling on, accept off, reporting coins, (wait for last coin) + // 8: transaction running, polling on, acceptance on, reporting coins, + + uint8_t pollingRunning; + uint8_t paymentRunning; + +}; +*/ + + +class hwapi : public QObject, + public hwinf +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "Atb.Psa2020.software.HWapi/1.0" ) //FILE "HWapi.json") + Q_INTERFACES(hwinf) + + DownloadResult sendNextAddress(int bNum) const; + DownloadResult sendNextDataBlock(QByteArray const &b, int bNum) const; + DownloadResult sendStatus(int ret) const; + DownloadResult dc_downloadBinary(QByteArray const &binary) const; + + bool startBootloader() const; + bool stopBootloader() const; + bool openSerial(int br, QString baudrate, QString comPort) const; + bool closeSerial(QString comport) const; + bool resetDeviceController() const; + QByteArray loadBinaryDCFile(QString filename) const; + bool downloadBinaryToDC(QString const &bFile) const; +public: + explicit hwapi(QWidget *parent = nullptr); + + T_datif *myDatif; + + // ------------------------------------------------------------------------------ + // Level 0 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 + + bool 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 + + bool dc_updateDC(QString binFileName, QString baudrate, + QString comPort) const override; + + // ------------------------------------------------------------------------------ + // Level 1, control device-controller (functions of µC) + // check serial connection to deviceController + // read response from DC2 (input data) + // some test function for serial communication + // also Bootloader is here + // ------------------------------------------------------------------------------ + + 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; + + // neu, 25.8.21 + 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; + + // 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 + + + + + + + + + // ------------------------------------------------------------------------------ + // Level 2 DC2-onboard devices + // WR: set time + // RD. get time, get measure, get test results + // ------------------------------------------------------------------------------ + + // get UID, get time/date test results memory, RTC analog values +/* + 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; + }; +*/ + 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; + + + // 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; + + // ------------------------------------------------------------------------------ + // Level 3: digital outputs and simple switching of connected devices + // simple processes like flashing a led or open flap for 1s + // ------------------------------------------------------------------------------ + + void lock_switchContactPower(bool on) const override; + + // 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_switchLedIllumination(uint8_t on) const override; + 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 prn_switchPower(bool on) const override; + + void mif_readerOn(bool on) 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 + + void mdb_switchPower(bool on) const override; + void mdb_switchWake(bool WAKEACTIVE) const override; + + void mod_switchPower(bool on) const override; + void credit_switchPower(bool on) 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 mod_switchWake(bool WAKEACTIVE) const override; + + void credit_switchWake(bool WAKEACTIVE) const override; + + + + + // ------------------------------------------------------------------------------ + // Level 3: digital inputs of connected devices + // ------------------------------------------------------------------------------ + + bool door_isContactPowerOn(void) const override; + + 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; + + bool ptu_WakeINisActive(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 prn_readyINisActive(void) const override; + + bool mif_cardIsAttached(void) const override; + bool mif_isMifarePowerOn(void) const override; + + bool mdb_WakeINisActive(void) const override; + bool mdb_testIsmdbTxDon(void) const override; + bool mdb_isMdbPowerOn(void) const override; + + bool coid_isAttached(void) const override; + bool coin_escrowIsOpen(void) const override; + + bool aux_isAuxPowerOn(void) const override; + + uint8_t aux_getAuxInputs(void) const override; + + bool mod_isGsmPowerOn(void) const override; + + bool cred_isCreditPowerOn(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 + + + // ------------------------------------------------------------------------------ + // Level1,2,3 RD request commands + // ------------------------------------------------------------------------------ + + // all read-requests can be sent manually by the following functions + // or automatically in background by: void hwapi::dc_autoRequest(bool on) + // in other words: + // if automatic-reading is on, then there's no need to send any of these commands, + // but it's allowed to send them in order to speed up the refreshing of the inputs + + 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; + + + + // ------------------------------------------------------------------------------ + // Level 3: readback digital outputs of connected devices + // these functions are not needed for normal operation + // but can be used to test and verify conditions + + // There are two options: + // 1) the important things like power-outputs and wake lines are + // measured at DC2-terminals (after transistors) and come as input to DC-board + // 2) others like Leds are read from µC-pins by DC-board + // ------------------------------------------------------------------------------ + + 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 + + uint8_t test_serialState(void) const override; + // test on-board signals for the serials + // serial drv on/off, Serial mux1, Serial mux2 + 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 + + + + // ------------------------------------------------------------------------------ + // Level4 ( Timer processes, device supervision by DC, processes with more then one devices + // WRITE + // ------------------------------------------------------------------------------ + + + 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 + + uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const override; + // use for changer + + 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) + + void mif_creatAtbCard(uint8_t cardType) const override; + + + // ------------------------------------------------------------------------------ + // read response from DC2 (input data) + // ------------------------------------------------------------------------------ + + 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 + // ......................................................... + + // 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_switchPower(bool on) const override; defined above + //void mdb_switchWake(bool WAKEACTIVE) const override; defined above +// bool mdb_WakeINisActive(void) const override; +// bool mdb_testIsmdbTxDon(void) const override; +// bool mdb_isMdbPowerOn(void) const override; +// void request_MDB_Status() const override; +// void request_MDB_lastResponse() const override; + + + 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 + + + + + +// neu, 25.3.23 + + void bl_rebootDC(void) const override; + + void bl_startBL(void) const override; + bool 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(u_int16_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, u_int8_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; + + //bool bl_isDiagAvailable(void) const override; + + //QString dc_getDiagText(void) const override; + + + + + // Komplett-schreib Funktion, noch nicht getestet + // Nachteil: keine Rückmeldung wie lang's noch dauert + + //void bl_startSending(void) const override; + + //void bl_sendFile(void) const override; + + + +/* + + // neu, 25.8.21 + 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; + + // 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 +*/ + + /* + uint8_t emp_getInsertedCoinSignal(void) const override; + // can be called one time after each coin + // emp_chkIfCoinInserted() must be called before! + + uint16_t emp_getInsertedCoinValue(void) const override; + // can be called one time after each coin + // emp_chkIfCoinInserted() must be called before! + + uint8_t emp_getCoinError(void) const override; + // can be called one time after each coin + // emp_chkIfCoinInserted() must be called before! + */ + + +private: + void sub_storeSendingText(QByteArray *buf) const; + + + + + +/* + // Modem: + + uint8_t mod_power(bool on) const override; + uint8_t mod_getHwState(struct Tmod_hw_state *mod_hw_state) const override; + uint8_t mod_setCondition(uint16_t chgCmd) const override; // e.g. change to state registered, sleep, open, off.... + uint16_t mod_getCondition(void) const override; // e.g. now socket open + bool mod_sendBufferFree(void) const override; // sending allowed (before writing) and sending finished (after writing) + uint8_t mod_sendDataBlk(uint16_t len, uint8_t *buf) const override; + void mod_wantReadData(uint16_t nrOfData) const override; // start reading + uint16_t mod_gotData(void) const override; // return nr of received bytes + uint8_t mod_loadDataBlk(uint16_t len, uint8_t *buf) const override; + uint8_t mod_setupSerial(struct TserialParams serialParameter) const override; + uint8_t mod_getCurrentSerialSettings(struct TserialParams *serialParameter) const override; + + // Credit Card Terminal: + + uint8_t cc_power(bool on) const override; + uint8_t cc_getHwState(struct Tcc_hw_state *cc_hw_state) const override; + +*/ + +}; + + +#endif + + + + + +/* + // Coin checker and changer mdb4.2 / section 5 + // Level 2 Commands (predefined device msg acc. mdb manual and auto-poll) + uint8_t mdb_coin_startPolling(bool on) const override; // send ether one command (from list below) + // or a poll command in the proper polling grid (e.g. every 100ms) + uint8_t mdb_coin_reset() const override; + uint8_t mdb_coin_setup() const override; + uint8_t mdb_coin_tubestatus() const override; + uint8_t mdb_coin_pollManually(void) const override; + uint8_t mdb_coin_type(uint16_t coinEnable, uint16_t dispenseEnable) const override; + uint8_t mdb_coin_dispense(uint8_t disp) const override; + uint8_t mdb_coin_expansion(uint8_t subCmd, uint8_t send[32]) const override; + uint8_t mdb_coin_getResponse(void) const override; + // 0: no response 1: got ACK 2: got NAK 3 got ACK with additional data + uint8_t mdb_coin_getDataLen(void) const override; + // return nr of byte received from any mdb device + uint8_t mdb_coin_getData(uint8_t *mdb_data, uint8_t maxBufferSize) const override; + + + + // Bill validator // section 6 + uint8_t mdb_bill_startPolling(bool on) const override; + uint8_t mdb_bill_reset() const override; + uint8_t mdb_bill_setup() const override; + uint8_t mdb_bill_security(uint16_t secLevel) const override; + uint8_t mdb_bill_pollManually(void) const override; + uint8_t mdb_bill_billType(uint16_t billEnable, uint16_t escrowEnable) const override; + uint8_t mdb_bill_escrow(uint8_t action) const override; + uint16_t mdb_bill_stacker(void) const override; + uint8_t mdb_bill_expansion(uint8_t subCmd, uint8_t send[32]) const override; + uint8_t mdb_bill_gotPollResponse(void) const override; + // 0: no response 1: got ACK 2: got NAK 3 got ACK with additional data + uint8_t mdb_bill_getDataLen(void) const override; + uint8_t mdb_bill_getPollData(uint8_t *mdb_data, uint8_t maxBufferSize) const override; + + + + // Level 3 Commands - all cash devices are used together and automatically + // -->easiest way to use + + // setting up payment: + uint8_t cash_getAcceptance(struct Tcash_state *cash_state) const override; + // return device specific parameters, (e.g. which tubes are installed) + // to be requested before/after payment + uint8_t cash_setMaxReturn(uint32_t amount) const override; // Security Limit + uint8_t cash_setMaxAcceptance(uint32_t amount) const override; // can pay up to this amount + // example: set to 12€ (=max price step), then the 3rd 5€ bill would be kept in escrow + // or with coins: max. insertable = 13,95€ (11,95€ is still <12€, plus a 2€-coin) + uint8_t cash_setCoinsToBeAccepted(uint16_t coinVal[2][16]) const override; + // up to 16 coins per currency in one or two currencies + // [0]=first currency, e.g. Huf [1]=2nd, like euros + uint8_t cash_setBillsToBeAccepted(uint32_t billVal[2][16]) const override; + uint8_t cash_setOpeningTime(uint16_t opentime_100ms) const override; // coin slot is opening/closing automatically + uint8_t cash_setWaitForLastCoinTime(uint16_t lastCoinTime_100ms) const override; + // while this time coin/bill aceptance is still active after "disable payment" command + uint8_t cash_getAllsettings(struct TcashSettings cashSettings) const override; + // return all above set own parameters + + // starting payment + uint8_t cash_powerUp(bool on) const override; // power up/down devices (bill takes up to 3s) + uint8_t cash_enablePayment(bool start) const override; // start/stop accepting bills and coins + + // running payment + bool gotNewCoinBill(void) const override; // true on every insertion, only once + uint8_t cash_getInserted(struct Tcash_pay *payment_state) const override; + + // finishing payment + uint8_t cash_coinEscrowTake(void) const override; + uint8_t cash_coinEscrowReturn(void) const override; + uint8_t cash_return(uint32_t amount) const override; +*/ + + +/* + uint8_t cc_setCondition(uint16_t chgCmd) const override; // e.g. change to state registered, sleep, open, off.... + uint16_t cc_getCondition(void) const override; // e.g. now socket open + bool cc_sendBufferFree(void) const override; // sending allowed (before writing) and sending finished (after writing) + uint8_t cc_sendDataBlk(uint16_t len, uint8_t *buf) const override; + void cc_wantReadData(uint16_t nrOfData) const override; // start reading + uint16_t cc_gotData(void) const override; // return nr of received bytes + uint8_t cc_loadDataBlk(uint16_t len, uint8_t *buf) const override; + uint8_t cc_getWorkFlow(void) const override; + // off, activated, gotStart_wait4card, wait4pin, gotPin, callingBank, CardAccepted..... + uint8_t cc_setupSerial(struct TserialParams serialParameter) const override; + uint8_t cc_getCurrentSerialSettings(struct TserialParams *serialParameter) const override; +*/ + + +/* + +struct TcashSettings +{ + uint32_t MaxReturnAmount const override; + uint32_t MaxAcceptAmount const override; + uint32_t CoinsAcceptedCur[2][16] const override; + uint32_t BillsAcceptedCur[2][16] const override; + uint32_t availableReturnAmount const override; + +} const override; + + +struct Tcc_hw_state +{ + bool powerRdBk const override; // prn pwr is on + bool rsSwOk const override; // serial switch (printer or modem) is set to CreditCard (iUC) + bool rsDrvOk const override; // RS232 converter for PTU, Printer and Modem in on + uint8_t HwState const override; // idle, off, on, ready + bool gotAnswer const override; // cable OK? + uint8_t moduleType const override; + uint8_t protocolType const override; + +} const override; + + +*/ + + diff --git a/include/interfaces.h b/include/interfaces.h new file mode 100644 index 0000000..50e1ef0 --- /dev/null +++ b/include/interfaces.h @@ -0,0 +1,1116 @@ +#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=Emp & Bus power off, 1=powered, poll off 2=polling on + // 3=device responded, requesting status + // 4=waiting for status 5=have status, + // 6: IDLE, have paramters from master, polling running, ready for payment + // Master can stop/start polling and acceptance + // 7: end of transaction, polling on, accept off, reporting coins, (wait for last coin) + // 8: transaction running, polling on, acceptance on, reporting coins, + + 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; +}; + + 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]; +}; + + + +class hwinf +{ + +public: + enum class DownloadResult {OK, ERROR, TIMEOUT, NOP}; + + 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 bool 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 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 dc_updateDC(QString binFileName, + QString baudrate, + QString comPort) const = 0; + // download binary file down into device controller + + 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 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­z=size of host buffer + + 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 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_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 QString dc_getTxt4HsStateLine(void) const =0; + // return string with status of handshakes + + virtual void dc_clrTxt4HsStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getTxt4masterStateLine(void) const =0; + // returns string telling if the received packet is valid and complies protocol + // if OK: "slave response OK" in case of error: "wrong length received", "wrong start sign received", + // "received datalen to big", "wrong data len received", "wrong crc received" + + virtual void dc_clrTxt4masterStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getTxt4resultStateLine(void) const =0; + // returns string telling response of DC. First question: did DC get a correct request telegram? + // and if: 2nd question did DC perform the contained output and input commands + // if OK: "Slave OUT and IN Result: 0 0" + // in case of error: "slave got wrong start sign" ..length" ...crc" ... address" + // slave does not perform and command! + // 2nd) received telegram was OK, DC tried to perform the master commands. result + // result of writing data (e.g switching leds and motors, sending stuff to printer...) + // OUT = 0: OK 1: unknown command 2: operation not possible + // result of reading data (e.g. switches, voltages, accepted coins, printer status....) + // IN = 0: OK 1: unknown command 2: could not read due to hardware error 3: could not read because device is off + + virtual void dc_clrTxt4resultStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getdataStateLine(void) const =0; + // check if recveied input data are ok/valid + // OK-string : "valid INdata...." with protocol details + // not OK: string empty + + virtual void dc_clrTxt4dataStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getdatifLine(void) const =0; + // returns string with result of function dc_requTestResponse() + // "correct" or "false" + + virtual void dc_clrTxt4datifLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getTxt4RsDiagWin(void) const =0; + // returns string to be displayed in "serial traffic" window + // details about sent and received protocol + + virtual void dc_clrTxt4RsDiagWin(void) const =0; + // clear above text to avoid multiple repetive displaying + + virtual QString dc_get2ndTxt4RsDiagWin(void) const =0; + // returns string to be displayed in "serial traffic" window + // details about sent and received protocol + + virtual void dc_clr2ndTxt4RsDiagWin(void) const =0; + // clear above text to avoid multiple repetive displaying + + +// 28 functions + + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // DC2b internal data + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + 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? ) + + + // 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 + + // Analog values: + virtual uint32_t dc_getTemperature(void) const =0; + // in Sax-Format 0...400 (0=-50,0°C 100=0,0°C 141=20,5°C 400=150,0°C) + + virtual QString dc_getTemperaturStr(void) const =0; + // as string like "-12,5°C" + + 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! + + 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) + + + + // all read-requests can be sent manually by the following functions + // or automatically in background by: void hwapi::dc_autoRequest(bool on) + // in other words: + // if automatic-reading is on, then there's no need to send any of these commands, + // but it's allowed to send them in order to speed up the refreshing of the inputs + + 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_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 + +// 22 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // using DC2 Bootloader + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const =0; + // send without protocol frame, needed for the DC 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 + + + + +// 9 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // get Time and Date from DC2b (contains a buffered real time clock) valid for about three days without power + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + 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; + + + + + virtual void request_DC2_TimeAndDate() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + + + +// 14 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // PTU, Master + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void ptu_switchWake(bool WAKEACTIVE) const =0; + + virtual bool ptu_WakeINisActive(void) const =0; + + virtual bool ptu_WakeOutIsOn(void) const =0; + + 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: 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) + + + 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 + +// 9 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Printer + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + + virtual void prn_switchPower(bool on) 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 prn_readyINisActive(void) const =0; + + virtual uint8_t cash_getLowPaperSensor(void) const=0; + // 0: Sensor sees paper 1: no paper 99: off + + // 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 bool test_serialMux1isSetToPrinter(void) const =0; + + // 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 = 0°, 90°, 180° 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 + // ......................................................... + + // 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!!) + + virtual void pri_startTicketDesign(void) const =0; + // 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 + + virtual int pri_TD_getCurrentSize(void) const =0; + // retval: 0...1278 + + virtual bool pri_TD_addText(QByteArray text) const =0; + // example: pri_TD_addText("Hello") const =0; + // example: pri_TD_addText(tempStr) const =0; + // retval: true=ok false=too long, buffer full + + virtual bool pri_TD_addValue(int val) const =0; + // +/- 0...2^(31) + + virtual bool pri_TD_addNewLine(void) const =0; + + virtual bool pri_TD_addSign(char sign) const =0; + // example: '.' ' ' 0x20 'W' '$' + + virtual bool pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const =0; + // 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 + + */ + + virtual char prn_clearDocument(uint8_t documentNumber) const =0; + // clear memory buffer for ONE document + // function takes a second! don't send right before "store doc" + + virtual bool prn_store_Document(uint8_t documentNumber ) const =0; + // 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 + + virtual bool prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const =0; + + +// 36 + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Mifare Card Reader + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void mif_readerOn(bool on) const =0; + + virtual bool mif_cardIsAttached(void) const =0; + virtual bool mif_isMifarePowerOn(void) 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; + + // dataBlockNumber must be 0....11, returns 64byte of data + + + virtual bool test_serialMux2isSetToMifare(void) const =0; + + virtual void mif_creatAtbCard(uint8_t cardType) const =0; + + /* data description: + 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 "ATB25-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 + */ + virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0; + // retval 0=OK 1=error host buffer too small + + virtual bool mif_readerIsOK(void) const =0; + + virtual bool mif_cardAttached(void) const =0; + + virtual uint8_t mif_readResult(void) const =0; + // result: 0: unknown or still in progress + // 1: card read successful + // 2: reading error + + //virtual void mif_clearDataBuffer(void) const =0; + + virtual QString mif_cardUID(void) const =0; + // returns string with 8 byte + + //virtual bool mif_isBlockAvailable(uint8_t blkNr) const =0; + //blkNr=0...11 + + //virtual uint32_t mif_getAvailableDataBlocks(void) const =0; + // bit0=1 if block 0 = valid ...up to ... bit 11=1 if block 11=read + + 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 + + // read mifare data independant from blocks + //virtual uint16_t mif_getNrOfAvailableDataBytes(void) const =0; + + //virtual bool mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize) const =0; + + //virtual bool mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize) const =0; + + //virtual QString mif_getCardDataStr(bool useHexFormat, char seperator) const =0; + +// 16 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Credit Card Terminal + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void credit_switchPower(bool on) const =0; + // the same as modem power + + virtual bool cred_isCreditPowerOn(void) const =0; + + virtual bool test_serialMux2isSetToCredit(void) const =0; + + virtual void credit_switchWake(bool WAKEACTIVE) const =0; + +// 4 + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Modem + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void mod_switchPower(bool on) const=0; + + virtual bool mod_isGsmPowerOn(void) const =0; + + virtual bool test_serialMux1isSetToModem(void) const =0; + + virtual void mod_switchWake(bool WAKEACTIVE) const=0; + +// 2 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // MDB Bus + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void mdb_switchPower(bool on) const =0; + virtual void mdb_switchWake(bool WAKEACTIVE) const =0; + + virtual bool mdb_WakeINisActive(void) const =0; + virtual bool mdb_testIsmdbTxDon(void) const =0; + virtual bool mdb_isMdbPowerOn(void) const =0; + + virtual void request_MDB_Status() const =0; + virtual void request_MDB_lastResponse() const =0; + + 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 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) + + +// 15 + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Coin Changer, Checker (EMP) + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void request_EMP_allParameters() const =0; + + virtual void request_EMP_lastCoin() const =0; + + virtual uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const =0; + // use for changer + + + // ---------------------------------- 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 =0; + // HWaccess = new hwapi() const =0; + // struct T_emp myEmp const =0; + // HWaccess->emp_getAllParameters(&myEmp) const =0; + // readval=myEmp.pollingRunning const =0; + + 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 + +// 11 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Coin blocker, Coin Escrow, Coin reject + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + 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 + + virtual void coin_switchRejectMotor(uint8_t dir) const =0; + virtual bool coid_isAttached(void) const =0; + virtual bool coin_escrowIsOpen(void) const =0; + virtual bool cash_getRejectMotorHomePos(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 + + 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) + + virtual void coin_rejectCoins(void) const =0; + +// 15 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // MDB Bill evaluator + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // doors, locks, cashboxes + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void lock_switchContactPower(bool on) const =0; + + virtual bool door_isContactPowerOn(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 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_openUpperDoor(void) const =0; + // Locks stops automatically at end switch or by timeout + + virtual uint8_t lock_closeUpperDoor(void) const =0; + // Locks stops automatically at end switch or by timeout + + 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_lowerDoorIsLocked(void) const =0; + + virtual bool door_lowerDoorIsUnlocked(void) const =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 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 lock_openLowerDoor(void) const =0; + // there's no closing function as Lock always makes one complete cycle and can be locked again immed. + + virtual uint8_t lock_closeLowerDoor(void) const =0; + + virtual bool door_isLowerDoorOpen(void) const =0; + + virtual uint8_t vault_getSwitches(void) const =0; + // retval bit0: cash box, bit 1: bill box + + virtual bool vault_isVaultDoorOpen(void) const =0; + + virtual void lock_switchVaultDoor(void) const =0; + + virtual bool vault_isCoinVaultIn(void) const =0; + + virtual bool vault_isBillVaultIn(void) const =0; + +// 21 + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // LEDs, Barrier, Alarm, Relais, Aux + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void led_switchLedIllumination(uint8_t on) const = 0; + + virtual void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const =0; + + virtual bool led_coinIsOn(void) const =0; + // read back digital output from DC-uC-Port + virtual bool led_frontIsOn(void) const =0; + + virtual void led_switchLedService(uint8_t on) const =0; + // on=1 off=0 + virtual bool led_insideIsOn(void) const =0; + + virtual void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual bool led_ticketIsOn(void) const =0; + + virtual void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual bool led_StartIsOn(void) const =0; + + virtual void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual bool led_pinIsOn(void) const =0; + + + virtual void fan_switchFan(bool on) const =0; + virtual void alarm_switchSiren(bool on) const =0; + virtual bool fan_isOn(void) const =0; + + virtual bool siren_isOn(void) const =0; + + virtual void bar_OpenBarrier(bool open) const =0; + virtual bool bar_relayIsOn(void) const =0; + + virtual bool bar_optoIn1isOn(void) const =0; + + virtual bool bar_optoIn2isOn(void) const =0; + + virtual void aux_power(bool on) const =0; + virtual bool aux_powerIsOn(void) const =0; + + virtual void aux_setUsage(uint8_t PinDirection) const =0; + virtual void aux_setOutputs(uint8_t PinIsHigh) const =0; + + virtual bool aux_isAuxPowerOn(void) const =0; + + virtual uint8_t aux_getAuxInputs(void) 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; + // send command within 4s after DC power-on, otherwise bl is left + + virtual bool bl_checkBL(void) const = 0; + // send command to verify if bl is up + + virtual bool bl_isUp(void) const =0; + // return true is bl is up and running + // also initializes "sendFile" + + virtual void bl_sendAddress(u_int16_t blockNumber) const=0; + // send start address, nr of 64byte-block, start with 0 + // will be sent only for following block-numbers: + // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte + // for other addresses nothing happens + + 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; + // to be used within CashAgent, momentary not processed + + virtual void bl_sendDataBlock(uint8_t length, u_int8_t *buffer) const=0; + // send 64 byte from bin file + + virtual void bl_sendLastBlock(void) const=0; + // send this command after all data are transfered + + 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; + // leave BL and start (the new) application + + //virtual bool bl_isDiagAvailable(void) const=0; + + //virtual QString dc_getDiagText(void) const=0; + + + // Komplett-schreib Funktion, noch nicht getestet + // Nachteil: keine Rückmeldung wie lang's noch dauert + //virtual void bl_startSending(void) const=0; + // call once after BL is working and file is loaded + //virtual void bl_sendFile(void) const=0; + // call cyclic while loading bin-file to bootloader + + + +}; + + +// 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) + + +#define HWINF_iid "Atb.Psa2020.software.HWapi/3.1" + +Q_DECLARE_INTERFACE(hwinf, HWINF_iid) + + +#endif + + + diff --git a/include/prot.h b/include/prot.h new file mode 100644 index 0000000..93304c0 --- /dev/null +++ b/include/prot.h @@ -0,0 +1,129 @@ + +#ifndef SERIAL_FRAME_H +#define SERIAL_FRAME_H + +#include +#include +#include +#include +#include "tslib.h" +#include "com.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 150 + +#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]; + + 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_com *getSerialPort() { return mySerialPort; } + T_com const *getSerialPort() const { return mySerialPort; } + + 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, uint16_t RdAddr, uint16_t reserv); + void setUserReadData( uint16_t ReadCmd, uint16_t RdAddr); + void setUserReadData( uint16_t ReadCmd); + + void setBLsendData( uint8_t len, uint8_t *buf); + + void receiveFixLen(int64_t nrOfbytesToReceive); + + void sendUserData(uint16_t slaveAdr); + bool ifDataReceived(); + 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/sendWRcmd.h b/include/sendWRcmd.h new file mode 100644 index 0000000..bb19b72 --- /dev/null +++ b/include/sendWRcmd.h @@ -0,0 +1,217 @@ + +#ifndef SENDWRCMDS_DEFS_H +#define SENDWRCMDS_DEFS_H + +#include +#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!!! + +// Level 0 (DC direct) +#define SENDDIRCMD_TestSerial 1 +#define SENDDIRCMD_MakeReset 2 +#define SENDDIRCMD_setTime 3 +#define SENDDIRCMD_setWakeFrequ 4 + +// Level 1 (DC DO's switching connected parts) +#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 // 0x2900 +#define SENDDIRCMD_MIF_ATBCREATE 33 // 0x2907 + +#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 + + +// 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_SETUP 72 +#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_BC 80 +#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_MDB_SNDMSG 92 +#define SENDDIRCMD_EMP_SETT 93 +#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 + + +#endif + + diff --git a/include/storeINdata.h b/include/storeINdata.h new file mode 100644 index 0000000..3c2919b --- /dev/null +++ b/include/storeINdata.h @@ -0,0 +1,489 @@ + +#ifndef STOREINDATA_H +#define STOREINDATA_H + +#include +#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_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_storeGenerals(uint8_t genNr, QString text); + // 0=HW 1=SW 2=State + +QString epi_loadGenerals(uint8_t genNr); +// genNr=0=HW 1=SW 2=State + + +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); +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 +// /////////////////////////////////////////////////////////////////////////////////// + + +#define MAXNROF_AI 4 + +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 + + + + + +uint8_t gpi_storeMifReaderStateAndCardType(uint8_t *buf); + +/* data description: +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); + // retval 0=OK 1=error host buffer too small + +void gpi_storeMifCardData(uint8_t blkNr, uint8_t *receivedData); + // blkNr=0...11 receivedData[64] + +uint8_t epi_restoreMifData(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize); + // blkNr=0...11 return buf[64] + // retval: 1=error 0=OK + + + +#define pi_prnStateArraySize 20 +#define pi_prnFontArraySize 20 + +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(); +*/ + +#define MEMDEPTH_GOTCOINS 16 + +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_storeDeviceSettings(uint8_t leng, uint8_t *data); + +void epi_restoreDeviceSettings(uint8_t *leng, uint8_t *data); + +void gpi_storeMachineIDsettings(uint8_t leng, uint8_t *data); + +void epi_restoreMachineIDsettings(uint8_t *leng, uint8_t *data); + + +#endif + + + diff --git a/include/tslib.h b/include/tslib.h new file mode 100644 index 0000000..ec24fae --- /dev/null +++ b/include/tslib.h @@ -0,0 +1,84 @@ +#ifndef TSLIB_H +#define TSLIB_H +#include +#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); + + +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); + + + +#endif // TSLIB_H diff --git a/plugins/interfaces.h b/plugins/interfaces.h new file mode 100644 index 0000000..4ae5d46 --- /dev/null +++ b/plugins/interfaces.h @@ -0,0 +1,1115 @@ +#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=Emp & Bus power off, 1=powered, poll off 2=polling on + // 3=device responded, requesting status + // 4=waiting for status 5=have status, + // 6: IDLE, have paramters from master, polling running, ready for payment + // Master can stop/start polling and acceptance + // 7: end of transaction, polling on, accept off, reporting coins, (wait for last coin) + // 8: transaction running, polling on, acceptance on, reporting coins, + + 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; +}; + + 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]; +}; + + + +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 void 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 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 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 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­z=size of host buffer + + 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 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_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 QString dc_getTxt4HsStateLine(void) const =0; + // return string with status of handshakes + + virtual void dc_clrTxt4HsStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getTxt4masterStateLine(void) const =0; + // returns string telling if the received packet is valid and complies protocol + // if OK: "slave response OK" in case of error: "wrong length received", "wrong start sign received", + // "received datalen to big", "wrong data len received", "wrong crc received" + + virtual void dc_clrTxt4masterStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getTxt4resultStateLine(void) const =0; + // returns string telling response of DC. First question: did DC get a correct request telegram? + // and if: 2nd question did DC perform the contained output and input commands + // if OK: "Slave OUT and IN Result: 0 0" + // in case of error: "slave got wrong start sign" ..length" ...crc" ... address" + // slave does not perform and command! + // 2nd) received telegram was OK, DC tried to perform the master commands. result + // result of writing data (e.g switching leds and motors, sending stuff to printer...) + // OUT = 0: OK 1: unknown command 2: operation not possible + // result of reading data (e.g. switches, voltages, accepted coins, printer status....) + // IN = 0: OK 1: unknown command 2: could not read due to hardware error 3: could not read because device is off + + virtual void dc_clrTxt4resultStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getdataStateLine(void) const =0; + // check if recveied input data are ok/valid + // OK-string : "valid INdata...." with protocol details + // not OK: string empty + + virtual void dc_clrTxt4dataStateLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getdatifLine(void) const =0; + // returns string with result of function dc_requTestResponse() + // "correct" or "false" + + virtual void dc_clrTxt4datifLine(void) const =0; + // clear above text to avoid multiple repetive displaying + + + virtual QString dc_getTxt4RsDiagWin(void) const =0; + // returns string to be displayed in "serial traffic" window + // details about sent and received protocol + + virtual void dc_clrTxt4RsDiagWin(void) const =0; + // clear above text to avoid multiple repetive displaying + + virtual QString dc_get2ndTxt4RsDiagWin(void) const =0; + // returns string to be displayed in "serial traffic" window + // details about sent and received protocol + + virtual void dc_clr2ndTxt4RsDiagWin(void) const =0; + // clear above text to avoid multiple repetive displaying + + +// 28 functions + + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // DC2b internal data + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + 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? ) + + + // 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 + + // Analog values: + virtual uint32_t dc_getTemperature(void) const =0; + // in Sax-Format 0...400 (0=-50,0°C 100=0,0°C 141=20,5°C 400=150,0°C) + + virtual QString dc_getTemperaturStr(void) const =0; + // as string like "-12,5°C" + + 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! + + 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) + + + + // all read-requests can be sent manually by the following functions + // or automatically in background by: void hwapi::dc_autoRequest(bool on) + // in other words: + // if automatic-reading is on, then there's no need to send any of these commands, + // but it's allowed to send them in order to speed up the refreshing of the inputs + + 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_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 + +// 22 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // using DC2 Bootloader + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void bl_sendDataDirectly(uint8_t length, uint8_t *buf) const =0; + // send without protocol frame, needed for the DC 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 + + + + +// 9 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // get Time and Date from DC2b (contains a buffered real time clock) valid for about three days without power + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + 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; + + + + + virtual void request_DC2_TimeAndDate() const =0; + // read-request can be sent manually by this function, not needed if auto-request is on + + + +// 14 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // PTU, Master + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void ptu_switchWake(bool WAKEACTIVE) const =0; + + virtual bool ptu_WakeINisActive(void) const =0; + + virtual bool ptu_WakeOutIsOn(void) const =0; + + 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: 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) + + + 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 + +// 9 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Printer + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + + virtual void prn_switchPower(bool on) 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 prn_readyINisActive(void) const =0; + + virtual uint8_t cash_getLowPaperSensor(void) const=0; + // 0: Sensor sees paper 1: no paper 99: off + + // 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 bool test_serialMux1isSetToPrinter(void) const =0; + + // 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 = 0°, 90°, 180° 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 + // ......................................................... + + // 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!!) + + virtual void pri_startTicketDesign(void) const =0; + // 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 + + virtual int pri_TD_getCurrentSize(void) const =0; + // retval: 0...1278 + + virtual bool pri_TD_addText(QByteArray text) const =0; + // example: pri_TD_addText("Hello") const =0; + // example: pri_TD_addText(tempStr) const =0; + // retval: true=ok false=too long, buffer full + + virtual bool pri_TD_addValue(int val) const =0; + // +/- 0...2^(31) + + virtual bool pri_TD_addNewLine(void) const =0; + + virtual bool pri_TD_addSign(char sign) const =0; + // example: '.' ' ' 0x20 'W' '$' + + virtual bool pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const =0; + // 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 + + */ + + virtual char prn_clearDocument(uint8_t documentNumber) const =0; + // clear memory buffer for ONE document + // function takes a second! don't send right before "store doc" + + virtual bool prn_store_Document(uint8_t documentNumber ) const =0; + // 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 + + virtual bool prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const =0; + + +// 36 + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Mifare Card Reader + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void mif_readerOn(bool on) const =0; + + virtual bool mif_cardIsAttached(void) const =0; + virtual bool mif_isMifarePowerOn(void) 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; + + // dataBlockNumber must be 0....11, returns 64byte of data + + + virtual bool test_serialMux2isSetToMifare(void) const =0; + + virtual void mif_creatAtbCard(uint8_t cardType) const =0; + + /* data description: + 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 "ATB25-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 + */ + virtual uint8_t mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const =0; + // retval 0=OK 1=error host buffer too small + + virtual bool mif_readerIsOK(void) const =0; + + virtual bool mif_cardAttached(void) const =0; + + virtual uint8_t mif_readResult(void) const =0; + // result: 0: unknown or still in progress + // 1: card read successful + // 2: reading error + + //virtual void mif_clearDataBuffer(void) const =0; + + virtual QString mif_cardUID(void) const =0; + // returns string with 8 byte + + //virtual bool mif_isBlockAvailable(uint8_t blkNr) const =0; + //blkNr=0...11 + + //virtual uint32_t mif_getAvailableDataBlocks(void) const =0; + // bit0=1 if block 0 = valid ...up to ... bit 11=1 if block 11=read + + 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 + + // read mifare data independant from blocks + //virtual uint16_t mif_getNrOfAvailableDataBytes(void) const =0; + + //virtual bool mif_getCardData768byteDec(uint8_t *buf, uint16_t bufferSize) const =0; + + //virtual bool mif_getCardDataDec(uint16_t fromAddr, uint16_t toAddr, uint8_t *buf, uint16_t bufferSize) const =0; + + //virtual QString mif_getCardDataStr(bool useHexFormat, char seperator) const =0; + +// 16 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Credit Card Terminal + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void credit_switchPower(bool on) const =0; + // the same as modem power + + virtual bool cred_isCreditPowerOn(void) const =0; + + virtual bool test_serialMux2isSetToCredit(void) const =0; + + virtual void credit_switchWake(bool WAKEACTIVE) const =0; + +// 4 + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Modem + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void mod_switchPower(bool on) const=0; + + virtual bool mod_isGsmPowerOn(void) const =0; + + virtual bool test_serialMux1isSetToModem(void) const =0; + + virtual void mod_switchWake(bool WAKEACTIVE) const=0; + +// 2 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // MDB Bus + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void mdb_switchPower(bool on) const =0; + virtual void mdb_switchWake(bool WAKEACTIVE) const =0; + + virtual bool mdb_WakeINisActive(void) const =0; + virtual bool mdb_testIsmdbTxDon(void) const =0; + virtual bool mdb_isMdbPowerOn(void) const =0; + + virtual void request_MDB_Status() const =0; + virtual void request_MDB_lastResponse() const =0; + + 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 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) + + +// 15 + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Coin Changer, Checker (EMP) + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void request_EMP_allParameters() const =0; + + virtual void request_EMP_lastCoin() const =0; + + virtual uint8_t emp_returnLastCoin(uint16_t *value, uint8_t *signal) const =0; + // use for changer + + + // ---------------------------------- 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 =0; + // HWaccess = new hwapi() const =0; + // struct T_emp myEmp const =0; + // HWaccess->emp_getAllParameters(&myEmp) const =0; + // readval=myEmp.pollingRunning const =0; + + 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 + +// 11 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // Coin blocker, Coin Escrow, Coin reject + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + 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 + + virtual void coin_switchRejectMotor(uint8_t dir) const =0; + virtual bool coid_isAttached(void) const =0; + virtual bool coin_escrowIsOpen(void) const =0; + virtual bool cash_getRejectMotorHomePos(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 + + 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) + + virtual void coin_rejectCoins(void) const =0; + +// 15 + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // MDB Bill evaluator + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // doors, locks, cashboxes + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void lock_switchContactPower(bool on) const =0; + + virtual bool door_isContactPowerOn(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 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_openUpperDoor(void) const =0; + // Locks stops automatically at end switch or by timeout + + virtual uint8_t lock_closeUpperDoor(void) const =0; + // Locks stops automatically at end switch or by timeout + + 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_lowerDoorIsLocked(void) const =0; + + virtual bool door_lowerDoorIsUnlocked(void) const =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 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 lock_openLowerDoor(void) const =0; + // there's no closing function as Lock always makes one complete cycle and can be locked again immed. + + virtual uint8_t lock_closeLowerDoor(void) const =0; + + virtual bool door_isLowerDoorOpen(void) const =0; + + virtual uint8_t vault_getSwitches(void) const =0; + // retval bit0: cash box, bit 1: bill box + + virtual bool vault_isVaultDoorOpen(void) const =0; + + virtual void lock_switchVaultDoor(void) const =0; + + virtual bool vault_isCoinVaultIn(void) const =0; + + virtual bool vault_isBillVaultIn(void) const =0; + +// 21 + + + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + // LEDs, Barrier, Alarm, Relais, Aux + // $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + virtual void led_switchLedIllumination(uint8_t on) const = 0; + + virtual void led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const =0; + + virtual bool led_coinIsOn(void) const =0; + // read back digital output from DC-uC-Port + virtual bool led_frontIsOn(void) const =0; + + virtual void led_switchLedService(uint8_t on) const =0; + // on=1 off=0 + virtual bool led_insideIsOn(void) const =0; + + virtual void led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual bool led_ticketIsOn(void) const =0; + + virtual void led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual bool led_StartIsOn(void) const =0; + + virtual void led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const =0; + virtual bool led_pinIsOn(void) const =0; + + + virtual void fan_switchFan(bool on) const =0; + virtual void alarm_switchSiren(bool on) const =0; + virtual bool fan_isOn(void) const =0; + + virtual bool siren_isOn(void) const =0; + + virtual void bar_OpenBarrier(bool open) const =0; + virtual bool bar_relayIsOn(void) const =0; + + virtual bool bar_optoIn1isOn(void) const =0; + + virtual bool bar_optoIn2isOn(void) const =0; + + virtual void aux_power(bool on) const =0; + virtual bool aux_powerIsOn(void) const =0; + + virtual void aux_setUsage(uint8_t PinDirection) const =0; + virtual void aux_setOutputs(uint8_t PinIsHigh) const =0; + + virtual bool aux_isAuxPowerOn(void) const =0; + + virtual uint8_t aux_getAuxInputs(void) 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; + // send command within 4s after DC power-on, otherwise bl is left + + virtual void bl_checkBL(void) const =0; + // send command to verify if bl is up + + virtual bool bl_isUp(void) const =0; + // return true is bl is up and running + // also initializes "sendFile" + + virtual void bl_sendAddress(u_int16_t blockNumber) const=0; + // send start address, nr of 64byte-block, start with 0 + // will be sent only for following block-numbers: + // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte + // for other addresses nothing happens + + 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; + // to be used within CashAgent, momentary not processed + + virtual void bl_sendDataBlock(uint8_t length, u_int8_t *buffer) const=0; + // send 64 byte from bin file + + virtual void bl_sendLastBlock(void) const=0; + // send this command after all data are transfered + + 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; + // leave BL and start (the new) application + + //virtual bool bl_isDiagAvailable(void) const=0; + + //virtual QString dc_getDiagText(void) const=0; + + + // Komplett-schreib Funktion, noch nicht getestet + // Nachteil: keine Rückmeldung wie lang's noch dauert + //virtual void bl_startSending(void) const=0; + // call once after BL is working and file is loaded + //virtual void bl_sendFile(void) const=0; + // call cyclic while loading bin-file to bootloader + + + +}; + + +// 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) + + +#define HWINF_iid "Atb.Psa2020.software.HWapi/3.1" + +Q_DECLARE_INTERFACE(hwinf, HWINF_iid) + + +#endif + + + diff --git a/src/com.cpp b/src/com.cpp new file mode 100644 index 0000000..01f9292 --- /dev/null +++ b/src/com.cpp @@ -0,0 +1,449 @@ +#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(QWidget *parent) : QMainWindow(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() +{ + //qDebug() << "~~>LIB" << "ENTER..."; + // call every 100ms to check if user(HMI) wants to connect or disconnect + uint8_t chkConn = gpi_getSerialConn(); // from global GUI buffer (Sdata) + + //qDebug() << "~~>LIB" << "checking connect button... " << chkConn; + + switch (chkConn) + { + case 0: // 0 button "connect" was just released + //qDebug() << "close serial port" << chkConn; + closeSerialPort(); + gpi_serialChanged(); // set chkConn to 2, thus getting edge + break; + case 1: // 1 button "connect" was just pressed + //qDebug() << "open serial port" << chkConn; + open_Serial_Port(); + gpi_serialChanged(); // set chkConn to 2, thus getting edge + break; + } + + + if (CatSerial->isOpen()) { + gpi_serialIsOpen(true); + } else { + gpi_serialIsOpen(false); + } + + //qDebug() << "LEAVE " << chkConn; +} + +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- + +char T_com::open_Serial_Port() +{ + //qDebug() << "ENTER"; + + bool ret; + QString myString=nullptr, myPortName=nullptr, myBaudStr=nullptr; + int myBaudNr; + + if (CatSerial->isOpen()) { + qDebug() << "!!!IS OPEN!!!"; + 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 + + //qDebug() << "myPortName" << myPortName << ", myBaudNr" << myBaudNr; + + 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); + + //qDebug() << "LEAVE"; + + 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"); + + } + + //qDebug() << "LEAVE"; + return 0; +} + +void T_com::closeSerialPort() +{ + //qDebug() << "ENTER"; + + if (CatSerial->isOpen()) + { + qDebug() << "closing connection"; + CatSerial->close(); + gpi_setTxt4comStateLine("closed"); + gpi_setTxt4RsDiagWin("closed"); + + } + + //qDebug() << "LEAVE"; +} + + +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); + // report "new data received" to other objects + //qDebug()<< "com-recFinished by Len "<< rawInLen; + 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); + + // report "new data received" to other objects + //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 " < +#include +#include +#include "tslib.h" +//#include "controlBus.h" + +// /////////////////////////////////////////////////////////////////////////////////// +// control serial interface gui <--> 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) +{ +// qDebug() << "ENTER" << BaudNr << BaudStr << ComName << 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 + +// qDebug() << "LEAVE" << rs_baudNr << rs_baudStr << rs_comportName << rs_connect; +} + +void epi_closeSerial(void) +{ + rs_connect=0; +// qDebug() << "ENTER/LEAVE rc_connect=0"; +} + + +void gpi_serialChanged(void) +{ + // serial confirms that port was closed or opened + rs_connect=2; // Flanke, nur 1x öffnen/schließen + //qDebug() << "ENTER/LEAVE rc_connect=2"; +} + +uint8_t gpi_getSerialConn(void) +{ + return rs_connect; +} + + +int gpi_getBaudNr(void) +{ + return rs_baudNr; +} + +QString gpi_getComPortName(void) +{ + return rs_comportName; +} + +static bool rs_portIsOpen; + +void gpi_serialIsOpen(bool offen) +{ + //qDebug() << "ENTER/LEAVE offen=" << offen; + rs_portIsOpen=offen; +} + +bool epi_isSerialPortOpen() +{ + // true: port is open false: port is closed + //qDebug() << "ENTER/LEAVE offen=" << rs_portIsOpen; + return rs_portIsOpen; +} + +// /////////////////////////////////////////////////////////////////////////////////// +// Control transfer gui <--> serial +// /////////////////////////////////////////////////////////////////////////////////// + + +static char AutoEmissionOn; // 1: zyklisch Anfragen zum Slave senden + +void epi_startEmmision(char start) +{ + AutoEmissionOn=start; +} + +bool gpi_isEmmisionOn(void) +{ + return AutoEmissionOn; +} + +//----------------------------------------------------- + +static uint16_t datif_sendingPeriod; +static bool datif_sendingPer_changed; + +uint16_t gpi_getPeriodicSendTimeVal() +{ + datif_sendingPer_changed=0; + if (datif_sendingPeriod<3 || datif_sendingPeriod>10000) + return 130; // ms, default + else + return datif_sendingPeriod; +} + +void epi_setPeriodicSendTimeVal(uint16_t val) +{ + if (val>=3 && val<10000) + { + datif_sendingPer_changed=1; + datif_sendingPeriod=val; + } +} + +bool gpi_PeriodicSendTimeHasChanged() +{ + return datif_sendingPer_changed; +} + +//----------------------------------------------------- + + +//----------------------------------------------------- + +// /////////////////////////////////////////////////////////////////////////////////// +// 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; +} + +bool epi_getResult_serialTestOK() +{ + // retval: true: test was successful, got right response + return Sdata_serialTestResult; +} + + + +// /////////////////////////////////////////////////////////////////////////////////// +// Store received data for hwapi +// /////////////////////////////////////////////////////////////////////////////////// + + + +static uint8_t Sdata_pProtResultOk; + +void gpi_startNewRequest() +{ + Sdata_pProtResultOk=0; +} + +void gpi_storeResultOfLastRequest(bool answisok) +{ + if (answisok) + Sdata_pProtResultOk=1; + else + Sdata_pProtResultOk=2; +} + +uint8_t epi_getResultOfLastRequest() +{ + // retval: 0: in progress 1: OK 2: error + return Sdata_pProtResultOk; +} + + + + +static uint16_t Sdata_receivedDataLength; +static uint8_t Sdata_receivedDataBlock[64]; + +void gpi_storeRecPayLoad(uint8_t RdDlen, uint8_t *receivedData) +{ + Sdata_receivedDataLength=uint16_t(RdDlen); + if (Sdata_receivedDataLength>64) + Sdata_receivedDataLength=64; + tslib_strclr(Sdata_receivedDataBlock,0,64); + tslib_strcpy(receivedData, Sdata_receivedDataBlock, 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; + if (ml>64) ml=64; + if (Sdata_receivedDataLength + +// 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; + +T_datif::T_datif(QWidget *parent) : QMainWindow(parent) +{ + + 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(10); // in ms, 80 gut, default 100 50....200 + + // 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; +} + +void T_datif::resetChain(void) +{ + dif_scanStep=0; +} + +char T_datif::datif_cycleSend() +{ + // cyclic transmission of INPUT-Requests + // call cyclic to send next request every 100ms, then wait for response before sending again!!! + uint16_t nxtAsCmd; + uint8_t dataSendBuf[160], dataBufLen, dbl, who; + static uint8_t BlockCounter; + + if (cycl_running) + { + // request is still running, wait for response before next sending + datif_trigger->stop(); + datif_trigger->start(10); + cycl_running++; + if (cycl_running>10) + cycl_running=0; + return 0; + } + if (myDCIF->isPortOpen()) + { + #ifdef USEHANDSHAKES + if (myDCIF->isSerialFree()) + #endif + { + // direct commands have highest prio (setting OUTPUTS) + nxtAsCmd=sendWRcmd_getSendCommand0(); // command was stored by Gui + if (nxtAsCmd>0) + { + cycl_running=1; + // qDebug() << "datif: send next cmd0"; + sendWRcommand(nxtAsCmd); + send_requests(nxtAsCmd); + sendHighLevel(nxtAsCmd); + BlockCounter=0; + return 0; + } + + nxtAsCmd=sendWRcmd_getSendCommand4(&datif_OutCmdpara1, &datif_OutCmdpara2, &datif_OutCmdpara3, &datif_OutCmdpara4); + // command was stored by Gui + if (nxtAsCmd>0) + { + cycl_running=1; + //qDebug() << "datif: send next cmd4"; + sendWRcommand(nxtAsCmd); + send_requests(nxtAsCmd); + sendHighLevel(nxtAsCmd); + BlockCounter=0; + return 0; + } + + nxtAsCmd=sendWRcmd_getSendCommand8(&datif_OutCmdpara1, &datif_OutCmdpara2, &datif_OutCmdpara5, &datif_OutCmdpara6); + // command was stored by Gui + if (nxtAsCmd>0) + { + cycl_running=1; + //qDebug() << "datif: send next cmd8"; + sendWRcommand(nxtAsCmd); + send_requests(nxtAsCmd); + sendHighLevel(nxtAsCmd); + BlockCounter=0; + return 0; + } + + dbl=sendWRcmd_getSendBlock160(&dataBufLen, dataSendBuf); // used for bootloader + if (dbl>0) + { + cycl_running=1; + //qDebug() << "datif: sending 160 byte block, len: " << dataBufLen; + datif_OUT_SendRandomData(dataSendBuf, dataBufLen); + BlockCounter=0; + return 0; + } + + dbl=gpi_chk4remainingText(); + if (dbl>0) + { + cycl_running=1; + //qDebug() << "datif: sending printer text "; + gpi_restorePrnText(&dataSendBuf[0]); + // can hold 1280 byte, get next 64 + //for (uint8_t nn=0; nn<64; nn++) + // qDebug() << dataSendBuf[nn] << " "; + + + who=gpi_getUserOfSendingTextBuffer(&datif_OutCmdpara1, &datif_OutCmdpara2, &datif_OutCmdpara3, &datif_OutCmdpara4); + + if (who==1) + { + epi_store64ByteSendData(64, dataSendBuf); // "dueway", copy this 64 back to pi, used by datif_ send64byteOutCmd + datif_send64byteOutCmd(CMD2DC_PRI_PRINT_TXT, 0, 0); + } else + if (who==2) + { + epi_store64ByteSendData(64, dataSendBuf); // "dueway", copy this 64 back to pi, used by datif_ send64byteOutCmd + datif_send64byteOutCmd(CMD2DC_STOR_QR_DATA, 0, 0); + } else + if (who==3) + { + //qDebug() << "datif: sending printer text, docnr: " <11) + RDBLKNR=0; + datif_OutCmdpara1=RDBLKNR; + + } break; + + case 17: + datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0); + break; + + case 18: + if (indat_isMdbOn()) + datif_sendIOrequest(0, CMD2DC_MDB_GET_STATE, 0); + //else + // dif_scanStep=24; unsinn + break; + + case 19: + datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0); + break; + + case 20: + //if (indat_isMdbOn()) + datif_sendIOrequest(0, CMD2DC_MDB_GETRESP, 0); + + break; + + case 21: + datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0); + break; + + case 22: + //if (indat_isMdbOn()) // kein eigener Schalter für EMP + datif_sendIOrequest(0, CMD2DC_EMP_GET_ALL, 0); + break; + + case 23: + datif_sendIOrequest(0, CMD2DC_GetAllInputs, 0); + break; + + case 24: + //if (indat_isMdbOn()) // kein eigener Schalter für EMP + datif_sendIOrequest(0, CMD2DC_EMP_GOTCOIN, 0); + break; + + } + + dif_scanStep++; + if (dif_scanStep>=25) + dif_scanStep=0; //dif_scanStep=5; + +return 0; + +} + + +char T_datif::isPortOpen(void) +{ + return (myDCIF->isPortOpen()); +} + + +// ############################################################################## +// ############################################################################## +// ############################################################################## +// Empfangsdaten einsortieren +// ---------------------------------------------------------------------------------------------- + + + +void T_datif::StoredRecData() +{ + //qDebug() << "StoreRecData called"; + // call automatically by T_prot + //if (myDCIF->ifDataReceived()) + //if (neu) + { + // just a wrapper as we need a retval + // "neu" is the same as "INdataValid" + loadRecDataFromFrame(); + } + cycl_running=0; +} + +char T_datif::loadRecDataFromFrame() +{ + // necessary data in T_prot: + uint16_t readSource, uitmp; + 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; // maxai + + ret=myDCIF->getReceivedInData(&SlaveAdr, &readSource, &readAddress, &RdDleng, receivedData); + // retval: data valid, only one time true, true if CommandState OK and readState OK + gpi_storeResultOfLastRequest(ret); + if (ret==false) + { + // qDebug() << "datif: rec data not valid"; + return 0; + } + + gpi_storeRecPayLoad(RdDleng, receivedData); // save for host (user of hwapi) + + //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<4; ii++) haut hin :) + + 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_storeMdbState(uctmp&4, uctmp&128, uctmp&4); // hat ein eigenes Cmd weiter unten! + gpi_storeDI_MdbPowerIsOn(uctmp&128); + + gpi_storeDI_paperLow(receivedData[5]); + break; + + case CMD2DC_RdBkAllOutputs: + + /* +// 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 CMD2DC_RdBk_MifState: + // get reader status and card type + + gpi_storeMifReaderStateAndCardType(receivedData); + break; + + case CMD2DC_RdBk_MifData: + // one block of data (64byte) comes in + // blkNr 0...11 in "Addr" + gpi_storeMifCardData(readAddress, receivedData); +//qDebug()<<"datif storing mif data: (adr/data) "<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: // 0x2A12 + //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: // 0x2A40 + gpi_storePrinterState(receivedData); // derzeit 10bytes ( 0x2A02) + gpi_storePrinterFonts(&receivedData[10]); // derzeit 10bytes + /* + qDebug()<<"printer fonts stored " <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, uint16_t RdAddr, uint16_t reserv); +//void myDCIF->setUserReadData( uint16_t ReadCmd, uint16_t RdAddr); +//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]; + + 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; + + 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; + myStr.clear(); + myStr.append("< Slave Response"); + + for (int nn=0; nn<16; nn++) + if (myStr[nn] !=receivedData[nn]) + { + //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; + +} + + + diff --git a/src/dcBL.cpp b/src/dcBL.cpp new file mode 100644 index 0000000..0d114f7 --- /dev/null +++ b/src/dcBL.cpp @@ -0,0 +1,1461 @@ +//#include +#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"); + + if (display) + { +/* + // Antwort ins Fenster schreiben: + QString tmpStr="", myStr="~~> "; + + tmpStr.setNum(recLen); + myStr.append(tmpStr); + myStr.append(" bytes received: "); + for (int nn=0; nn 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 + } + //tmpStr.clear(); + //tmpStr.setNum(exactError); + //dcBL_writeText(tmpStr); + return 1; // error +} + + + +uint8_t dcBL_sendSuccess(uint8_t lastCommand) +{ + // return val: 0: no response by now 1:error 10: OK + + uint8_t buf[152], recLen; + + recLen=dcBL_getResponse(buf,0); + if (recLen==0) + return 0; // no response by now + + if (buf[0]==2 && buf[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); + } + } + + */ + + +// ------------------------------------------------------------------------- + +char dcBL_loadBinary(char withDisplay) +{ + // same function as in "tabFw" + //uint8_t uit8tmp; + uint32_t ultmp, fileLen; + QString tmpStr="", s2tmp=""; + + qDebug()<<"dcBL loading DC2c binary..."; + QFile file("../dc2c4.bin"); + if (!file.exists()) + { + //qDebug()<<"file _own_H2B_dc2.bin does not exist"; + dcBL_writeText("file _own_H2B_dc2.bin does not exist"); + return 1; + } + if (!file.open(QIODevice::ReadOnly) ) + { + //qDebug()<<"cannot open"; + dcBL_writeText("cannot open"); + return 1; + } + + //qDebug()<<"loading...."; + //qDebug()<<"size: " << file.size() <<"\n"; + if (withDisplay) + { + s2tmp="loading file with "; + tmpStr.setNum(file.size()); + s2tmp.append(tmpStr); + s2tmp.append(" bytes"); + dcBL_writeText(s2tmp); + } + QByteArray myBin = file.readAll(); + fileLen=uint32_t(file.size()); + + // Rest des Blockes mit 0xFF füllen + for (ultmp=fileLen; ultmp<(fileLen+70); ultmp++) + myBin[ultmp]=char(0xFF); + + /* // Kontrolle: + qDebug()<<"dcBL_loadBinary: "; + int ii=59500; + do + { + uit8tmp=uint8_t(myBin[ii++]); + s2tmp.clear(); + //qDebug() << uit8tmp << " "; // Anzeige in dez + s2tmp.setNum(uit8tmp,16); + qDebug() << s2tmp << " "; // Anzeige in hex + + } while (ii<60100); + */ + + dcBL_importBinFile(myBin, fileLen, withDisplay); + return 0; + +} + + +static QByteArray dcBL_AtbBinFile; +static uint32_t dcBL_fileSize; +static uint16_t dcBL_nrOfBlocks; +static uint16_t dcBL_fileCrc; +//static uint8_t dcBL_myBuf[2570000]; // same content like "dcBL_AtbBinFile" but bytewise +static uint8_t dcBL_myBuf[300000]; // same content like "dcBL_AtbBinFile" but bytewise + +bool dcBL_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) +{ + uint16_t uitmp; + uint32_t ultmp; + uint32_t LL; + QString tmpStr="", s2tmp=""; + + dcBL_AtbBinFile=readBinFile; + dcBL_fileSize=fileSize; + + //if (dcBL_fileSize>258048) // 27.3.23TS woher kommt die Zahl??? + // das hex file hat 278kB + // hex file nicht erlaubt??? + if (dcBL_fileSize>=300000) + 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, BINFILECOPY3; + uint32_t BinFileCpyLen1, BinFileCpyLen2, BinFileCpyLen3, LL; + uint8_t repeat=0, nn=0, stopp=0; + //char cc; + + do + { + //dcBL_writeText("loading 1st time:"); + //qDebug() <<"loading 1st time:"; + dcBL_loadBinary(0); + // 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(0); + // 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(0); + // file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize" + BINFILECOPY3=dcBL_AtbBinFile; + BinFileCpyLen3=dcBL_fileSize; + +//cc=BINFILECOPY2[100]; +//if (cc>0) +// BINFILECOPY2[100]=0; +//else +// BINFILECOPY2[100]=1; + + repeat=0; + if (BinFileCpyLen1 !=BinFileCpyLen2 || BinFileCpyLen1 !=BinFileCpyLen3) + { + dcBL_writeText("file length wrong"); + qDebug() <<"length error"; + + repeat=1; // load both again.... + } + if (repeat==0) + { + LL=0; stopp=0; + //qDebug() <<"1. loop"; + + do + { + if (dcBL_AtbBinFile[LL] != BINFILECOPY1[LL]) + stopp=1; + } while((++LL < dcBL_fileSize) && !stopp); + + if (stopp) + { + dcBL_writeText("file compare1 wrong "); + 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) + { + dcBL_writeText("file compare2 wrong "); + repeat=1; // load both again.... + } else + dcBL_writeText("file OK"); + } + + } while (++nn<3 && repeat); // 3 trials + + qDebug() << "compare finito " << nn << " " << repeat; + + if (repeat==0) + return true; // file OK + return false; // error, could not load correctly + +} + + + + +uint8_t dcBL_getAtbFileHeader(uint8_t *buf) +{ + // this header is prepended by the pc-direct-loader-tool + // (so the uC-BL expects this!) here it is sent seperately: + uint8_t myBuf[30], pp=0, len; + + myBuf[pp++]='A'; + myBuf[pp++]='T'; + myBuf[pp++]='B'; + myBuf[pp++]='-'; + myBuf[pp++]='D'; + myBuf[pp++]='C'; + myBuf[pp++]='2'; + myBuf[pp++]='-'; + myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETHIGHBYTE); + myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETMIDHIGHBYTE); + myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETMIDLOWBYTE); + myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETLOWBYTE); + myBuf[pp++]='-'; + myBuf[pp++]=uintTOuchar(dcBL_fileCrc, GETHIGHBYTE); + myBuf[pp++]=uintTOuchar(dcBL_fileCrc, GETLOWBYTE); + myBuf[pp++]='-'; + len=pp; + //tslib_strcpy(myBuf, buf, (len+3)); + len=dcBL_prepareDC_BLcmd(0x32, len, myBuf, buf); + return len; +} + +uint8_t dcBL_getFileBlock(uint16_t blockPointer, uint8_t *buf) +{ + // blockPointer=0....4095 + uint32_t addr, LL; //, BL; + //uint8_t uit8tmp; + //QString stemp=" "; + + addr=uint32_t(blockPointer); + addr<<=6; // *64 =Start address +/* + if ( (addr+63)>dcBL_fileSize) + { + BL=dcBL_fileSize-addr+1; // Block Length + for (LL=0; LL<64; LL++) + buf[LL]=0; + if (BL>64) BL=64; // security limitation + // only BL bytes are left to give + for (LL=0; LL0) + 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()<6 && recBuff[0]==2 && recBuff[1]==99 && recBuff[2]==52) + // && recBuff[3]==53 && recBuff[4]==98 && recBuff[5]==51 && recBuff[6]==3 ) + { + dcBL_writeText("BL started"); + dcBL_cyclCtr=0; + dcBL_step++; + return 0; + } + //qDebug()<10) // 50 gibt 6,2s + { + // cancel, report error + dcBL_writeText("cannot start BL, cancel"); + dcBL_state=3; + dcBL_step=0; // stop chain + return 0; + } */ + + dcBL_step++; + repeatCtr=0; + break; + + case 6: // request Version number + len=dcBL_readFWversion(buf); + sendWRcmd_setSendBlock160(len, buf); + dcBL_writeText("request version nr..."); + dcBL_cyclCtr=0; + dcBL_step++; + break; + + case 7: // wait for answer 2 146 45 45 95 176 3 + + if (gotResp==ISOK) + { + dcBL_state=1; // BL started + dcBL_step++; + 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 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 +/* + // 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()<<"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; +} + +// ------------------------------------------------------------------------- +// ------------------------------------------------------------------------- +// ------------------------------------------------------------------------- + + +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/hwapi.cpp b/src/hwapi.cpp new file mode 100644 index 0000000..df154a6 --- /dev/null +++ b/src/hwapi.cpp @@ -0,0 +1,3017 @@ +/* + * 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 + * + */ + +#include +#include +#include + +#include "tslib.h" +#include "hwapi.h" + +#include "sendWRcmd.h" +#include "controlBus.h" +#include "storeINdata.h" +#include "dcBL.h" +#include +#include <../plugins/interfaces.h> + + +static const QMap baudrateMap = { + {"1200" , 0}, {"9600" , 1}, {"19200" , 2}, {"38400" , 3}, + {"57600" , 4}, {"115200" , 5} +}; + +hwapi::hwapi(QWidget *parent) : QObject(parent) +{ + // constructor + //epi_resetAllDOs(); + //PI_INI(); + sendWRcmd_INI(); + + myDatif = new T_datif(); +} + + + +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); + +} + + +// ------------------------------------------------------------------------------ +// Level 0 commands, interface +// open, close, change serial interface +// actually not neccessary as it is opened automatically on program start +// start automatic READ requests +// ------------------------------------------------------------------------------ + +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 + //qDebug() << "~~>LIB" << "dc_openSerial called... " ; + + epi_setSerial(BaudNr, BaudStr, ComName, connect); + + // Actions: open serial port with parameters + for (int i = 0; i < 10; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (dc_isPortOpen()) { + return true; + } + } + return false; +} + +bool hwapi::dc_closeSerial(void) const { + epi_closeSerial(); + for (int i = 0; i < 10; ++i) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (!dc_isPortOpen()) { + return true; + } + } + return false; +} + +bool hwapi::dc_isPortOpen(void) const { + if (myDatif) { + T_prot* prot = myDatif->getProt(); + if (prot) { + T_com *com = prot->getSerialPort(); + if (com) { + return com->isPortOpen(); + } + } + } + return false; + //return epi_isSerialPortOpen(); +} + +void hwapi::dc_autoRequest(bool on) const +{ + // automatically request ALL digital and analog sensors, get time/date, get status information + if (on) + epi_startEmmision(1); + else + epi_startEmmision(0); +} + +/******************************************************************************/ +// +// LEVEL 2: Help-functions for hwapi::dc_updateDC. +// +/******************************************************************************/ +hwapi::DownloadResult hwapi::sendStatus(int ret) const { + switch (ret) { // return values of dc are: + case 0: // 0: no answer by now + return DownloadResult::NOP; // 1: error + case 10: // 10: success + return DownloadResult::OK; + default:; + } + return DownloadResult::ERROR; +} + +hwapi::DownloadResult hwapi::sendNextAddress(int bNum) const { + // sends address only if blockNumber is one of 0, 1024, 2048, 3072, 4096 + int noAnswerCount = 0; + int errorCount = 0; + if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) { + qDebug() << "addr-block" << bNum << "..."; + while (noAnswerCount <= 250) { + bl_sendAddress(bNum); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + DownloadResult const res = sendStatus(bl_wasSendingAddOK()); + if (res != DownloadResult::NOP) { + if (res == DownloadResult::ERROR) { + if (++errorCount >= 10) { + qCritical() << "addr-block" << bNum << "...FAILED"; + return res; + } + } else { // res == DownloadResult::OK + qInfo() << "addr-block" << bNum << "...OK"; + return res; + } + } else { + noAnswerCount += 1; // no answer by now + } + } + // wait max. about 3 seconds + return DownloadResult::TIMEOUT; + } + // blockNumber is not one of 0, 1024, 2048, 3072, 4096 -> do nothing + return DownloadResult::NOP; +} + +hwinf::DownloadResult hwapi::sendNextDataBlock(QByteArray const &binary, + int bNum) const { + uint8_t local[66]; + int const bAddr = bNum * 64; + int noAnswerCount = 0; + int errorCount = 0; + + memcpy(local, binary.constData() + bAddr, 64); + local[64] = local[65] = 0x00; + + qDebug() << "data for addr" << bAddr << "..."; + + while (noAnswerCount <= 250) { + bl_sendDataBlock(64, local); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + DownloadResult const res = sendStatus(bl_wasSendingDataOK()); + if (res != DownloadResult::NOP) { + if (res == DownloadResult::ERROR) { + if (++errorCount >= 10) { + qCritical() << "data for addr" << bAddr << "...FAILED"; + return res; + } + } else { + qInfo() << "data for addr" << bAddr << "...OK"; + return res; + } + } else { + noAnswerCount += 1; // no answer by now + } + } + // wait max. about 3 seconds + return DownloadResult::TIMEOUT; +} + +hwinf::DownloadResult hwapi::dc_downloadBinary(QByteArray const &b) const { + int const nBlocks = (((b.size())%64)==0) ? (b.size()/64) : (b.size()/64)+1; + + qInfo() << "total number of bytes to send to dc" << b.size(); + qInfo() << "total number of blocks to send to dc" << nBlocks; + + int bNum = 0; + DownloadResult res = DownloadResult::OK; + while (res != DownloadResult::ERROR && bNum < nBlocks) { + if ((res = sendNextAddress(bNum)) != DownloadResult::ERROR) { + if ((res = sendNextDataBlock(b, bNum)) != DownloadResult::ERROR) { + bNum += 1; + } + } + } + if (res != DownloadResult::ERROR) { + bl_sendLastBlock(); + } + return res; +} + +bool hwapi::startBootloader() const { + qDebug() << "starting bootloader..."; + int nTry = 5; + while (--nTry >= 0) { + bl_startBL(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + if (bl_isUp()) { + qInfo() << "starting bootloader...OK"; + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + return true; + } + } + qCritical() << "starting bootloader...FAILED"; + return false; +} + +bool hwapi::stopBootloader() const { + qDebug() << "stopping bootloader..."; + int nTry = 5; + while (--nTry >= 0) { + bl_stopBL(); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + if (!bl_isUp()) { + qInfo() << "stopping bootloader...OK"; + return true; + } + } + qCritical() << "stopping bootloader...FAILED"; + return false; +} + +// br is a index into a table, used for historical reasons. +bool hwapi::openSerial(int br, QString baudrate, QString comPort) const { + qDebug() << "opening serial" << br << baudrate << comPort << "..."; + if (dc_openSerial(br, baudrate, comPort, 1)) { // 1 for connect + qInfo() << "opening serial" << br << baudrate << comPort << "...OK"; + return true; + } + qCritical() << "opening serial" << br << baudrate << comPort << "...FAILED"; + return false; +} + +bool hwapi::closeSerial(QString comPort) const { + qDebug() << "closing serial" << comPort << "..."; + if (dc_closeSerial()) { + qInfo() << "closing serial" << comPort << "...OK"; + return true; + } else { + qCritical() << "closing serial" << comPort << "...FAILED"; + } + return false; +} + +bool hwapi::resetDeviceController() const { + qDebug() << "resetting device controller..."; + if (stopBootloader()) { // first stop a (maybe) running bootloader + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + dc_OrderToReset(); + // wait maximally 3 seconds, before starting bootloader + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + qInfo() << "resetting device controller...OK"; + return true; + } + return false; +} + +QByteArray hwapi::loadBinaryDCFile(QString filename) const { + qDebug() << "loading dc binary" << filename << "..."; + + QFile file(filename); // closed in destructor call + if (!file.exists()) { + qCritical() << file.fileName() << "does not exist"; + return QByteArray(); + } + if (!file.open(QIODevice::ReadOnly)) { + qCritical() << "cannot open file" << file.fileName(); + return QByteArray(); + } + qInfo() << "loading dc binary" << filename << "...OK"; + return file.readAll(); +} + +bool hwapi::downloadBinaryToDC(QString const &bFile) const { + qDebug() << "sending" << bFile << "to dc..."; + QByteArray const dcBinary = loadBinaryDCFile(bFile); + if (dcBinary.size() > 0) { + if (dc_downloadBinary(dcBinary) != DownloadResult::OK) { + qCritical() << "sending" << bFile << "to dc...FAILED"; + return false; + } else { + qInfo() << "sending" << bFile << "to dc...OK"; + } + } else { + qCritical() << "sending" << bFile << "to dc...FAILED"; + qCritical() << "loading binary" << bFile << "FAILED"; + return false; + } + return true; +} + +/******************************************************************************/ +// +// LEVEL 3: hwapi::dc_updateDC. +// +/******************************************************************************/ +bool hwapi::dc_updateDC(QString bFile, QString br, QString serial) const { + if (!baudrateMap.contains(br)) { // sanity check + qCritical() << "passed wrong baudrate" << br; + return false; + } + + qDebug() << "updating dc: " << bFile << br << serial << "..."; + + if (!openSerial(baudrateMap.value(br), br, serial)) { + return false; + } + if (!resetDeviceController()) { + closeSerial(serial); + return false; + } + if (!startBootloader()) { + closeSerial(serial); + return false; + } + if (!downloadBinaryToDC(bFile)) { + stopBootloader(); + closeSerial(serial); + qCritical() << "updating dc: " << bFile << br << serial << "...FAILED"; + return false; + } + + qInfo() << "updating dc: " << bFile << br << serial << "...OK"; + + stopBootloader(); + closeSerial(serial); + return true; +} + + +// ------------------------------------------------------------------------------ +// Level 1, control device-controller (functions of µC) +// check serial connection to deviceController +// read response from DC2 (input data) +// some test function for serial communication +// also Bootloader is here +// ------------------------------------------------------------------------------ + +void hwapi::dc_requTestResponse() const +{ + sendWRcmd_setSendCommand0(SENDDIRCMD_TestSerial); +} + +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 + sendWRcmd_setSendCommand4(SENDDIRCMD_setWakeFrequ, period,0,0,0); +} + +void hwapi::dc_OrderToReset(void) const +{ + uint8_t len, buf[160]; + + len=dcBL_restartDC(buf); + sendWRcmd_setSendBlock160(len, buf); + //sendWRcmd_setSendCommand0(SENDDIRCMD_MakeReset); + // not needed, sendWRcmd_setSendBlock160() starts sending as well... +} + +QString hwapi::dc_getSerialState(void) const +{ +// geht + return epi_getTxt4comStateLine(); +} + +void hwapi::dc_clrSerialStateText(void) const +{ + epi_clrTxt4comStateLine(); +} + + + +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_loadGenerals(0); +} + +QString hwapi::dc_getSWversion(void) const +{ + return epi_loadGenerals(1); +} + +QString hwapi::dc_getState(void) const +{ + return epi_loadGenerals(2); +} + + +// ------------------------------------------------------------------------------ +// Level 2 DC2-onboard devices +// WR: set time +// RD. get time, get measure, get test results +// ------------------------------------------------------------------------------ + +// get UID, get time/date test results memory, RTC analog values + +// ---------------------------------------------------------------------------------------------------------- +// 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 +{ + sendWRcmd_setSendCommand0(SENDDIRCMD_setTime); + 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; + + 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++) qbuf[nn]=buf[nn]; + + return qbuf; +} + +QString hwapi::rtc_getDatStr() const +{ + uint8_t day, month, year, buf[20], nn; + QString qbuf; + + 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++) + qbuf[nn]=buf[nn]; + + 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; +} + + + +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; +} + +// ------------------------------------------------------------------------------ +// Level 3: digital outputs and simple switching of connected devices +// simple processes like flashing a led or open flap for 1s +// ------------------------------------------------------------------------------ + +// Locks: +uint8_t hwapi::lock_switchUpperLock(uint8_t dir) const +{ + // dir 0=off 1=up 2=down + sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEUP_LOCK ,dir,0,0,0); + return 0; +} + +uint8_t hwapi::lock_switchLowerLock(uint8_t dir) const +{ + // dir 0=off 1=up 2=down + sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEDN_LOCK ,dir,0,0,0); + return 0; +} + +void hwapi::lock_switchVaultDoor(void) const +{ + + sendWRcmd_setSendCommand0(SENDDIR_OPENVAULT); +} + +void hwapi::coin_switchRejectMotor(uint8_t dir) const +{ + + sendWRcmd_setSendCommand4(SENDDIR_REJMOT_ON, dir, 0,0,0); +} + +void hwapi::coin_rejectCoins(void) const +{ + + sendWRcmd_setSendCommand0(SENDDIR_REJMOT_RUN); +} + + +void hwapi::led_switchLedService(uint8_t on) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_LEDINSIDE, on, 0, 0, 0); +} + +void hwapi::led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_LEDTICKET, on, ton, tof, 0); +} + +void hwapi::led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_LEDPAD, on, ton, tof, 0); +} + +void hwapi::led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_LEDSTART, on, ton, tof, 0); +} + +void hwapi::led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_LEDCOIN, on, ton, tof, 0); +} + +void hwapi::fan_switchFan(bool on) const +{ + //return epi_storeDOsToSend(DOBYTE3, FAN_ON, on); + sendWRcmd_setSendCommand4(SENDDIRCMD_FAN, on, 0, 0, 0); +} + +void hwapi::alarm_switchSiren(bool on) const +{ + //return epi_storeDOsToSend(DOBYTE4, LAERM, on); + sendWRcmd_setSendCommand4(SENDDIRCMD_LAERM, on, 0, 0, 0); +} + +void hwapi::bar_OpenBarrier(bool open) const +{ + //return epi_storeDOsToSend(DOBYTE4, REL1, open); + sendWRcmd_setSendCommand4(SENDDIRCMD_REL1, open, 0, 0, 0); +} + +void hwapi::ptu_switchWake(bool WAKEACTIVE) const +{ + //return epi_storeDOsToSend(DOBYTE1, CTS_PTU, WAKEACTIVE); + sendWRcmd_setSendCommand4(SENDDIRCMD_WAKEPTU, WAKEACTIVE,0,0,0); +} + +// AUX-IO's or barcode reader +void hwapi::aux_power(bool on) const +{ +// return epi_storeDOsToSend(DOBYTE2, BARC_POW_ON, on); + sendWRcmd_setSendCommand4(SENDDIRCMD_AUXPWR, on,0,0,0); +} + +void hwapi::aux_setUsage(uint8_t PinDirection) const +{ + // bit 0= Aux1 bit5=Aux6 1=output 0=input with pullup + + // return epi_storeDOsToSend(DOBYTE6, nr, PinDirection); + sendWRcmd_setSendCommand4(SENDDIRCMD_AUXDDR, 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 + + //return epi_storeDOsToSend(DOBYTE5, nr, PinIsHigh); + sendWRcmd_setSendCommand4(SENDDIRCMD_AUXOUT, PinIsHigh,0,0,0); +} + +void hwapi::lock_switchContactPower(bool on) const +{ + //epi_storeDOsToSend(DOBYTE2, U_SW_ON, on); + sendWRcmd_setSendCommand4(SENDDIRCMD_UCONTACT_ON, 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 + +} + + +void hwapi::mif_readerOn(bool on) const +{ + // DC2 also switches and enables serial driver + sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, on,0,0,0); +} + +void hwapi::mif_creatAtbCard(uint8_t cardType) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, cardType, 0,0,0); +} + + +void hwapi::mod_switchPower(bool on) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_SWONOFF, on,0,0,0); +} + +void hwapi::mod_switchWake(bool WAKEACTIVE) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_WAKE, WAKEACTIVE,0,0,0); +} + +void hwapi::mdb_switchPower(bool on) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_POWER, on,0,0,0); +} + +void hwapi::mdb_switchWake(bool WAKEACTIVE) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_WAKE, WAKEACTIVE,0,0,0); +} + +void hwapi::credit_switchPower(bool on) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_ON, on,0,0,0); +} + +void hwapi::credit_switchWake(bool WAKEACTIVE) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_WAKE, WAKEACTIVE,0,0,0); +} + +void hwapi::shut_move(bool open) const +{ + // true:open false:close + sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_MOV, open, 0,0,0); +} + +void hwapi::esc_moveFlaps(uint8_t flap ) const +{ + // 0: close both 1: open take-flap 2: open return + sendWRcmd_setSendCommand4(SENDDIRCMD_ESCRO_MOV, flap, 0,0,0); +} + + +// ------------------------------------------------------------------------------ +// Level 3: digital inputs of connected devices +// ------------------------------------------------------------------------------ + + + +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; +} + +bool hwapi::door_isLowerDoorOpen(void) const +{ + uint8_t ret; + + ret= epi_getDI_doorSwitches(); + // bit0: upper door 1: low door 2:vault door + if (ret & 2) + return true; + return false; +} + +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; +} + + +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; +} + +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(); +} + +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(); +} + + +bool hwapi::cash_getRejectMotorHomePos(void) const +{ + return epi_getDI_rejectMotor_homepos(); +} + +uint8_t hwapi::cash_getLowPaperSensor(void) const +{ + // 0: Sensor sees paper 1: no paper 99: off + return epi_getDI_npe_sensor(); + +} + +// ------------------------------------------------------------------------------ +// Level1,2,3 RD request commands +// ------------------------------------------------------------------------------ + +// the following requests can be sent manually +// or automatically in background by: void hwapi::dc_autoRequest(bool on) +// in other words: +// if automatic-reading is on then there's no need to send any of these commands! + + +void hwapi::request_DC2serialConfig() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_SERCONF); +} + +void hwapi::request_DC2_HWversion() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_HWversion); +} + +void hwapi::request_DC2_SWversion() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_SWversion); +} + +void hwapi::request_DC2_condition() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_CONDITION); +} + +void hwapi::request_DC2_UID() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_UID); +} + +void hwapi::request_DC2_TimeAndDate() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_TIME); +} + +void hwapi::request_DC2_analogues() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_ANALOGS); +} + +void hwapi::request_DC2_digitalInputs() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_DIG_INPUTS); +} + +void hwapi::request_DC2_digitalOutputs() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_DIG_OUTPUTS); +} + +// ------------------------------------------------------------------------------ +// the folowing device state requests are deployed only if device is powered up: + +void hwapi::request_PrinterHwState() const +{ + + sendWRcmd_setSendCommand0(SEND_REQU_PRN_STATE); +} + +void hwapi::request_PrinterCurrentFonts() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_PRN_FONTS); +} + +void hwapi::request_PrinterStateComplete() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_PRN_ALL); +} + + + + + +void hwapi::request_MifareReaderState() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE); +} + +void hwapi::request_MifareCardType() const +{ + //uint8_t blkAdr=0; + //sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, blkAdr,0,0,0); + sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE); +} + +void hwapi::request_MifareAtbType() const +{ + //sendWRcmd_setSendCommand0(SEND_REQU_MIF_ATB_TYPE); + sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE); + +} + +void hwapi::request_MifareID() const +{ + uint8_t sequenceNumber=0; + sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, sequenceNumber,0,0,0); // 1st data = card sequence =blk nr (0...15) +} + +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) + sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, dataBlockNumber,0,0,0); // 1st data = card sequence =blk nr (0...15) +} + + + +void hwapi::request_MDB_Status() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETSTAT); +} + +//void hwapi::request_MDB_wakeInLine() const +//{ +// sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETWAK); +//} + +void hwapi::request_MDB_lastResponse() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETRESP); +} + +void hwapi::request_EMP_allParameters() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETALL); +} + +void hwapi::request_EMP_lastCoin() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETCOIN); + +} + + + +// ------------------------------------------------------------------------------ +// Level 3: readback digital outputs of connected devices +// these functions are not needed for normal operation +// but can be used to test and verify conditions + +// There are two options: +// 1) the important things like power-outputs and wake lines are +// measured at DC2-terminals (after transistors) and come as input to DC-board +// 2) others like Leds are read from µC-pins by DC-board +// ------------------------------------------------------------------------------ + +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(); +} + + + + + + + + +// ------------------------------------------------------------------------------ +// Level4 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; + + epi_store64ByteSendData(6, buf); + sendWRcmd_setSendCommand0(SENDDIRCMD_DEVICE_PARA); + + +} + +void hwapi::request_ReadbackDeviceSettings() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_DEVICE_PARA); +} + + +void hwapi::readback_DeviceSettings(uint8_t *length, uint8_t *data) const +{ + + epi_restoreDeviceSettings(length, data); + +} + +// .................................................................................... + +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); + + epi_store64ByteSendData(42, buf); + sendWRcmd_setSendCommand0(SENDDIRCMD_MACHINE_ID); + + +} + +void hwapi::request_ReadbackMachineID() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_MACINE_ID); +} + + +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 +{ + //bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4); + // commands are defined in PIdefines.h + sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 1, 0, 0, 0); + // paras: dat2: 1=upper door lock 2=lower + // dat1: 1=open 2=close + return 0; +} + + +uint8_t hwapi::lock_closeUpperDoor(void) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 2, 0, 0, 0); + return 0; +} + +uint8_t hwapi::lock_openLowerDoor(void) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 1, 0, 0, 0); + return 0; +} + +uint8_t hwapi::lock_closeLowerDoor(void) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 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; + sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYTIME, 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; + sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYCOIN, 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 + //sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_SENDTIME, timeIn100ms,0,0,0); + hwapi_shutterTime=timeIn_ms; + +} + + +void hwapi::esc_takeMoney(void) const +{ + // and close automatically after escrow time (1s) + sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_TAKE); +} + +void hwapi::esc_returnMoney(void) const +{ + // and close automatically after time + sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_GIVE); + +} + + + + + + + +// ---------------------------------------------------------------------------------------------------------- +// --------------------------------------------- MIFARE ----------------------------------------------------- +// ---------------------------------------------------------------------------------------------------------- + + +uint8_t hwapi::mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const +{ + // 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 present (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) + */ + + return epi_restoreMifState(buf, maxBufferSize); +} + +/* OLD data description: +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 "ATB25-1.8" +16: 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 +*/ + +bool hwapi::mif_readerIsOK(void) const +{ + + uint8_t buf[40]; // old version had 40 bytes, new version only 8 + uint8_t ret= epi_restoreMifState(buf, 40); + if (ret==0 && buf[0]>1 && buf[1]>0) + return 1; + return 0; // error +} + +bool hwapi::mif_cardAttached(void) const +{ + + uint8_t buf[40]; + uint8_t ret= epi_restoreMifState(buf, 40); + if (ret==0 && buf[0]>1 && buf[2]>0) // reader OK + if (buf[16]>0) + return 1; + return 0; // error +} + +uint8_t hwapi::mif_readResult(void) const +{ + // result: 0: unknown or still in progress + // 1: card read successful + // 2: reading error + + uint8_t buf[40]; + uint8_t ret= epi_restoreMifState(buf, 40); + // data read successful && Reader OK && card attached && ... + if (ret==0 && buf[1]>0 && buf[2]>0) + { +// 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 + + if (buf[0]==1 || buf[0]==5 || buf[0]==6) + return 2; + if (buf[0]==4) + return 1; + + } + return 0; // error + +} + + +QString hwapi::mif_cardUID(void) const +{ + QString myStr; + + uint8_t buf[65], ret; + + //uint8_t ret= epi_restoreMifState(buf, 40); + myStr.clear(); +/* + if (ret==0 && buf[0]==4 && buf[3]>0 && buf[16]>0 && buf[19]>0) + { + // UID in buf[22...29] + for (int ii=0;ii<8; ii++) + { + + myStr+=QString::number(buf[ii+22],16); + myStr+=" "; // make a gap between numbers + } + } +*/ + + ret=epi_restoreMifData(0, buf, 64); + if (ret) + return myStr; // return empty string on error + else + { + buf[8]=0; + //myStr.append(buf); + for (int ii=0;ii<8; ii++) + { + + myStr+=QString::number(buf[ii],16); // 16: return in hex format + myStr+=" "; // make a gap between numbers + } + + return myStr; + } + + +} + + +uint8_t hwapi::mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const +{ + // blkNr=0...11 return buf[64] maxBufferSize must be >=64 + + return epi_restoreMifData(blkNr, buf, maxBufferSize); + // blkNr=0...11 return buf[64] + +} + +QString hwapi::mif_getCardDataStr(uint8_t blockNumber) const +{ + // with blockNumber=0...11 + QString myStr; + uint8_t buf[66]; + + myStr.clear(); + if (blockNumber>11) + return myStr; + + epi_restoreMifData(blockNumber, buf, 66); + + for (int ii=0; ii<64; ii++) + { + //myStr+=QString::number(buf[ii],10); // decimals as ascii + myStr+=QString::number(buf[ii],16); // hex numbers as ascii + myStr+=" "; // make a gap between numbers + } + 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? + 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]; + +} + +bool hwapi::prn_isUpAndReady(void) const +{ + 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 +{ + sub_storeSendingText(buf); + epi_storeUserOfSendingTextBuffer(1,0,0,0,0); // 1=print text + + +} + + +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); +} + +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 + sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_ESC_CMD, 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; + epi_store64ByteSendData(5, buf); + sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_SETUP); +} + +void hwapi::prn_movePaper(uint8_t wayInMm, uint8_t direction) const +{ + //direction: 1=forward 2=backward + sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_MOVE, 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 + sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETFONT, font, size, width, height); +} + + +void hwapi::prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETLETT, bold, invers, underlined, 0); +} + +void hwapi::prn_cut(uint8_t kindof) const +{ + // kindof = 1: full cut 2: partial cut 3=eject (5xLF + full cut) + sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_CUT, kindof,0,0,0); +} + +void hwapi::prn_newLine(uint8_t nrOfLines) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_LF, nrOfLines, 0, 0, 0); +} + +void hwapi::prn_printCompleteFontTable(void) const +{ + sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_FONTTAB); +} + + +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; nn1278) + 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 + /* 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: possible: 0...22, expedient: 5...11 + attribute 11 : font size + p1: 6...20 12=normal 6=tiny + 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 : 1...8 = print dynData 0..7 at this place + +*/ + + + 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); + 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); + +} + +#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); + +} + +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; + } + + epi_store64ByteSendData(35, myBuf); + sendWRcmd_setSendCommand0(SENDDIRCMD_EMP_SETT); + +} + +void hwapi::emp_pollingOnOff(uint8_t on) const +{ + // on: 1=start polling the coin accepter 0=stop + sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_POLL, on,0,0,0); + +} + +void hwapi::emp_startCoinAcceptance(void) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STARPPAY, 0,0,0,0); + +} + +void hwapi::emp_stopCoinAcceptance(void) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STOPPAY, 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]); + +} + +/* +static bool emp_newCoin; +static uint8_t emp_newCoinSignal; +static uint16_t emp_newCoinValue; +static uint8_t emp_newCoinError; + +uint8_t hwapi::emp_chkIfCoinInserted(void) +{ + // retval: 1=got coin 0xFF=emp reported an error 0=got nothing + // comes only one time after each coin, vaslues are stored + uint8_t leng, data[8]; + + epi_restoreEmpCoinSignal(&leng, data); + // 5 byte per inserted coin: + // data[0]: 1=got coin, data set valid + // data[1]: emp-signal of last inserted coin + // data[2]: emp-error or warning + // data[3,4]: emp-value of last inserted coin 3=low byte + + //epi_clearEmpCoinSignal(); + + if (data[0]>0) + { + emp_newCoin=data[0]; // anything came in, coin or error or both + + if (data[0] & 0x80) + { + emp_newCoinError=data[4]; + } + if (data[0] &0x0F) + { + emp_newCoinSignal=data[1]; + emp_newCoinValue=uchar2uint(data[3], data[2]); + } + return emp_newCoin; + } + return 0; + +} + +uint8_t hwapi::emp_getInsertedCoinSignal(void) +{ + uint8_t uctmp=emp_newCoinSignal; + emp_newCoinSignal=0; // return only once + return uctmp; + +} + + +uint16_t hwapi::emp_getInsertedCoinValue(void) +{ + uint16_t uitmp=emp_newCoinValue; + emp_newCoinValue=0; // return only once + return uitmp; +} + +uint8_t hwapi::emp_getCoinError(void) +{ + uint8_t uctmp=emp_newCoinError; + emp_newCoinError=0; // return only once + return uctmp; +} +*/ + +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; +} + +// ---------------------------------------------------------------------------------------------------------- +// --------------------------------------------- Bill Validator ----------------------------------- +// ---------------------------------------------------------------------------------------------------------- +/* +// Coin checker and changer mdb4.2 / section 5 +// Level 2 Commands (predefined device msg acc. mdb manual and auto-poll) +uint8_t hwapi::mdb_bill_startPolling(bool on) +{ + // send ether one command (from list below) + // or a poll command in the proper polling grid (e.g. every 100ms) + epi_storeConfig08(mdbPollBills,on); + //sendWRcmd_setSendCommand0(SENDDIRCMD_WR_CONF_08); + return 0; +} + +// the following functions tell the DC to send a mdb command to any mdb slave +// in opposite to mdb_sendData() the exact telegrams don't have to be formed here, DC does it. +uint8_t hwapi::mdb_bill_reset() +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 1, 0, 0, 0); + + return 0; +} + +uint8_t hwapi::mdb_bill_setup() +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 2, 0, 0, 0); + + return 0; +} + +uint8_t hwapi::mdb_bill_security(uint16_t secLevel) +{ + + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 3, uint8_t(secLevel), uint8_t(secLevel>>8), 0); + + return 0; +} + +uint8_t hwapi::mdb_bill_pollManually(void) +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 4, 0, 0, 0); + + return 0; +} + +uint8_t hwapi::mdb_bill_billType(uint16_t billEnable, uint16_t escrowEnable) +{ + + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillType, + uint8_t(billEnable), uint8_t(billEnable>>8), + uint8_t(escrowEnable), uint8_t(escrowEnable>>8)); + + return 0; +} + +uint8_t hwapi::mdb_bill_escrow(uint8_t action) +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 5, action, 0, 0); + + return 0; +} + +uint16_t hwapi::mdb_bill_stacker(void) +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 6, 0, 0, 0); + + return 0; +} + +uint8_t hwapi::mdb_bill_expansion(uint8_t subCmd, uint8_t send[32]) +{ + uint8_t sendbuf[34], nn; + + // 1) insert subCmd into buffer + for (nn=0; nn<32; nn++) + sendbuf[nn+1]=send[nn]; + sendbuf[0]=subCmd; + sendbuf[33]=0; + epi_storeMdbSendData(34, sendbuf); + sendWRcmd_setSendCommand0(SENDDIRCMD_MDB_BillExp); + return 0; +} + + +uint8_t hwapi::mdb_bill_gotPollResponse(void) +{ + // 0: no response 1: got ACK 2: got NAK 3 got ACK with additional data + return epi_getMdbResponse(); // request only once, then epi_getMdbRecLength()==0 + +} + + +uint8_t hwapi::mdb_bill_getDataLen(void) +{ + // return nr of byte received from any mdb device + return epi_getMdbRecLength(); +} + +uint8_t hwapi::mdb_bill_getPollData(uint8_t *mdb_data, uint8_t maxBufferSize) +{ + uint8_t len, buf[64], LL; + len=epi_getMdbRecLength(); + epi_restoreMdbRecData(buf); // request only once, then epi_getMdbRecLength()==0 + (maxBufferSizepowerRdBk=epi_restoreReadDIs(DIBYTE0, RB_VGSM); + if (epi_cntchk_swRs1toModem()) + mod_hw_state->rsSwOk=1; + else + mod_hw_state->rsSwOk=0; + + mod_hw_state->rsDrvOk=epi_cntchk_enabDrv01(); // can never be false + mod_hw_state->HwState=false; + mod_hw_state->CommState=false; + mod_hw_state->gotAnswer=false; + + return 0; +} + + +uint8_t hwapi::mod_setCondition(uint16_t chgCmd) +{ + // e.g. change to state registered, sleep, open, off.... + return uint8_t(chgCmd); +} + +uint16_t hwapi::mod_getCondition(void) +{ + // e.g. now socket open + + return 0; +} + +bool hwapi::mod_sendBufferFree(void) +{ + // sending allowed (before writing) and sending finished (after writing) + + return 0; +} + +void hwapi::mod_wantReadData(uint16_t nrOfData) +{ + // start reading + nrOfData=0; + +} + +uint8_t hwapi::mod_sendDataBlk(uint16_t len, uint8_t *buf) +{ + len=buf[0]; + return uint8_t(len); +} + +uint16_t hwapi::mod_gotData(void) +{ + // return nr of received bytes + + return 0; +} + +uint8_t hwapi::mod_loadDataBlk(uint16_t len, uint8_t *buf) +{ + len=buf[0]; + return uint8_t(len); + + +} + +uint8_t hwapi::mod_setupSerial(struct TserialParams serialParameter) +{ + // Baudrate and so on... + return 0; +} + +uint8_t hwapi::mod_getCurrentSerialSettings(struct TserialParams *serialParameter) +{ + // Baudrate and so on... + + return 0; +} +*/ + + + + + + + + + + +// neu, 25.8.21 + + + + +QString hwapi::dc_getTxt4RsDiagWin(void) const +{ + return epi_getTxt4RsDiagWin(); +} + +void hwapi::dc_clrTxt4RsDiagWin(void) const +{ + epi_clrTxt4RsDiagWin(); +} + +QString hwapi::dc_get2ndTxt4RsDiagWin(void) const +{ + return epi_get2ndTxt4RsDiagWin(); +} + +void hwapi::dc_clr2ndTxt4RsDiagWin(void) const +{ + epi_clr2ndTxt4RsDiagWin(); +} + +QString hwapi::dc_getTxt4HsStateLine(void) const +{ + // Crash! + return epi_getTxt4HsStateLine(); +} + +void hwapi::dc_clrTxt4HsStateLine(void) const +{ + epi_clrTxt4HsStateLine(); +} + + +QString hwapi::dc_getTxt4masterStateLine(void) const +{ + return epi_getTxt4masterStateLine(); +} + +void hwapi::dc_clrTxt4masterStateLine(void) const +{ + epi_clrTxt4masterStateLine(); +} + +QString hwapi::dc_getTxt4resultStateLine(void) const +{ + return epi_getTxt4resultStateLine(); +} + +void hwapi::dc_clrTxt4resultStateLine(void) const +{ + epi_clrTxt4resultStateLine(); +} + +QString hwapi::dc_getdataStateLine(void) const +{ + return epi_getTxt4dataStateLine(); +} + +void hwapi::dc_clrTxt4dataStateLine(void) const +{ + epi_clrTxt4dataStateLine(); +} + + +QString hwapi::dc_getdatifLine(void) const +{ + return epi_getTxt4datifLine(); +} + +void hwapi::dc_clrTxt4datifLine(void) const +{ + epi_clrTxt4datifLine(); +} + + + + +// using DC2 Bootloader + +void hwapi::bl_iniChain(void) const +{ + dcBL_iniChain(); +} + + +bool hwapi::bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const +{ + return dcBL_importBinFile(readBinFile, fileSize, withDispl); +} + +uint8_t hwapi::bl_activatBootloader(uint8_t *sendData) const +{ + return dcBL_activatBootloader(sendData); +} + +uint8_t hwapi::bl_startChain(void) const +{ + return dcBL_startChain(); +} + +uint8_t hwapi::bl_readBLversion(uint8_t *sendData) const +{ + // minimum size of sendData-buffer: 5byte retval: length + + return dcBL_readBLversion(sendData); +} + +uint8_t hwapi::bl_readFWversion(uint8_t *sendData) const +{ + // minimum size of sendData-buffer: 5byte retval: length + return dcBL_readFWversion(sendData); + +} + +uint8_t hwapi::bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const +{ +// 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); + +} + +uint8_t hwapi::bl_exitBL(uint8_t *sendData) const +{ + // minimum size of sendData-buffer: 5byte retval: length + return dcBL_exitBL(sendData); +} + +void hwapi::led_switchLedIllumination(uint8_t on) const +{ + if (on) + { + + } + +} + + + +// neu, 25.3.23 + +void hwapi::bl_rebootDC(void) const +{ + uint8_t len, buf[20]; + + len=dcBL_restartDC(buf); + sendWRcmd_setSendBlock160(len, buf); +} + +void hwapi::bl_startBL(void) const { + uint8_t len, buf[20]; + memset(buf, 0x00, sizeof(buf)); + + len=dcBL_activatBootloader(buf); + sendWRcmd_setSendBlock160(len, buf); +} + +bool hwapi::bl_checkBL(void) const +{ + uint8_t len, buf[20]; + + //len=dcBL_readBLversion(buf); + len=dcBL_readFWversion(buf); + sendWRcmd_setSendBlock160(len, buf); + + return (len > 0); +} + +bool hwapi::bl_isUp(void) const +{ + uint8_t receivedData[160]; + uint8_t LL; + + memset(receivedData, 0x00, sizeof(receivedData)); + + LL=epi_getRawRecLength(); + if (LL>0) + { + epi_getRawReceivedData(receivedData); + //epi_clrRawReceivedString(); + + //qDebug() << " *** got " << LL << " data bytes from BL: " << + // receivedData[0] << " " << receivedData[1] << " " << receivedData[2] << " " << + // receivedData[3] << " " << receivedData[4] << " " << receivedData[5] << " "; + + // response to "readFWversion" + if (receivedData[0]==2 && receivedData[1]==146 && receivedData[2]==45 && + receivedData[3]==45 && receivedData[4] ==95 && receivedData[5]==176) + { + dcBL_iniLoading(); + return true; + } + // response to "start BL" + if (receivedData[0]==2 && receivedData[1]==101 && receivedData[2]==48 && + receivedData[3]==223 && receivedData[4] ==131 ) + { + dcBL_iniLoading(); + return true; + } + + } + return false; +} + + +void hwapi::bl_sendAddress(u_int16_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 + // uint8_t dcBL_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData) + // minimum size of sendData-buffer: 13byte retval: length (9...13) + sendWRcmd_setSendBlock160(len, buf); // send command to BL + } +} + +uint8_t hwapi::bl_wasSendingAddOK(void) const +{ + // return val: 0: no response by now 1:error 10: OK + + return dcBL_sendSuccess(0x21); + // return val: 0: no response by now 1:error 10: OK + // lastCommand=0x21 for sendAddr or 0x22 for send data + +} + +void hwapi::bl_openBinary(void) const +{ + + dcBL_loadBinary(0); +} + +void hwapi::bl_sendDataBlock(uint8_t length, u_int8_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); +/* hier ist alles richtig + qDebug() << "bl_sendDataBlock "< +#include "controlBus.h" +#include "dcBL.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 +} + +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); + } else + { + RdDataLength=DATALEN_RECEIVE_FAST; + mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_FAST); + } +} + +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(WriteCmd); + +} + +void T_prot::setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr) +{ + WriteCommand=WriteCmd; + WriteAddr=WrAddr; + WrDataLength=0; + for (int nn=0; nnsetRecLen(WriteCmd); + +} + +void T_prot::setUserWriteData(uint16_t WriteCmd) +{ + WriteCommand=WriteCmd; + WriteAddr=0; + WrDataLength=0; + for (int nn=0; nnsetRecLen(WriteCmd); + +} + +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(WriteCmd); + +} + +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(WriteCmd); + +} + +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(WriteCmd); + +} + +void T_prot::setUserReadData( uint16_t ReadCmd, uint16_t RdAddr, uint16_t reserv) +{ + ReadCommand=ReadCmd; + ReadAddr=RdAddr; + reserve=reserv; + SendDataValid |=2; + readAddress=RdAddr; // store here already because it's no longer returned from slave + readSource=ReadCmd; +} + +void T_prot::setUserReadData( uint16_t ReadCmd, uint16_t RdAddr) +{ + ReadCommand=ReadCmd; + ReadAddr=RdAddr; + reserve=0; + SendDataValid |=2; + readAddress=RdAddr; // store here already because it's no longer returned from slave + readSource=ReadCmd; +} + +void T_prot::setUserReadData( uint16_t ReadCmd) +{ + ReadCommand=ReadCmd; + ReadAddr=0; + reserve=0; + SendDataValid |=2; + readAddress=0; // store here already because it's no longer returned from slave + 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); // how many?? + //readAddress= // needed?? + + //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); + +} + +/* +void T_prot::startPacking(void) +{ + uint16_t mycrc; + uint16_t uitmp, sendLen; + uint8_t uctmp, nn, pp, CrcLp; + char sendBuffer[FRAME_MAXLEN], ctmp; + + //qDebug() << "prot start packing "<>=8; + sendBuffer[2]= char(uitmp); + + uitmp=WriteCommand; + sendBuffer[3]= char(uitmp); + uitmp>>=8; + sendBuffer[4]= char(uitmp); + + uitmp=WriteAddr; + sendBuffer[5]= char(uitmp); + uitmp>>=8; + sendBuffer[6]= char(uitmp); + + uitmp=ReadCommand; + sendBuffer[7]= char(uitmp); + uitmp>>=8; + sendBuffer[8]= char(uitmp); + + uitmp=ReadAddr; + sendBuffer[9]= char(uitmp); + uitmp>>=8; + sendBuffer[10]= char(uitmp); + + uitmp=reserve; + sendBuffer[11]= '-'; //char(uitmp); + uitmp>>=8; + sendBuffer[12]= '-'; //char(uitmp); + + sendBuffer[13]= char(WrDataLength); + CrcLp= 14 + WrDataLength; + + if (kindOfData) // 0: binaries, 1:text + { + for (nn=0; nn>=8; + sendBuffer[CrcLp+1]=char(mycrc); + sendLen=CrcLp+2; + + sendBuffer[CrcLp+2]=13; + sendBuffer[CrcLp+3]=10; + sendLen+=2; + + // send to VCP: + QByteArray packBuff; + packBuff.clear(); + packBuff.append(sendBuffer, sendLen); // ohne sendLen wird beim ersten \0 abgeschnitten!!! + mySerialPort->writeToSerial(packBuff, sendLen); + // void T_com::writeToSerial(const QByteArray &data, uint16_t sendLength) +} +*/ + +// --------------------------------------------------------------------------------------------------------- +// 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; + + } + myString.setNum(result); + + // Daten abspeichern, könnten vom BL sein: + gpi_storeRawReceivedData(uint8_t(recLength), recBuffer); + emit rawDataRecieved(); + + } else + { + //& result ==0 + gpi_setTxt4masterStateLine("slave response OK"); + // Daten OK, also prüfe Inhalt. + // Konnte der Slave das Master-Command verwenden oder hatte es Fehler? + // konnte der Slave die geforderten Daten ausgeben (DOs, AOs)? + // konnte der Slave die geforderten Daten einlesen (AIs, DIs)? + + //CheckInResult(recBuffer); // Ergebnisse des Slaves anzeigen + // stimmt nicht mehr bei FastProt + + ShowFastInData(recBuffer); // Eingangs-Daten des Slaves anzeigen + } + emit framerecieved(); + //qDebug() << "framereceived emitted"; +} + + +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 ( (rawInLen FRAME_DATALEN) //[9]=reported data lenght + return 3; // reported datalen too big + + if ((datalen !=(rawInLen-12)) && (datalen !=(rawInLen-13)) && (datalen !=(rawInLen-14)) ) + { + // angehängtes CR und/oder LF tolerieren + qDebug() << "wrong data length, " << datalen << " " << rawInLen; + return 4; // data len does not match to complete length + + } + crcL_Addr=datalen+10; // weil im definierten protocol 10 bytes vor den Daten stehen + recCrc=0; + + recCrc=uchar2uint(uint8_t(Inbuf[crcL_Addr+1]), uint8_t(Inbuf[crcL_Addr])); + myCrc=0; + for (nn=0; nnSlave) + 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; + //readSource already set with sending + readAddress=0; + // RdDataLength already set with sending + if (RdDataLength>FRAME_DATALEN) + RdDataLength=FRAME_DATALEN; + for (int ii=0; iiFRAME_DATALEN) + RdDataLength=FRAME_DATALEN; + for (int ii=0; ii +#include +#include +#include "tslib.h" +#include "sendWRcmd.h" + + +void indat_PrnPwr(void); + + +void sendWRcmd_INI(void) +{ + + sendWRcmd_clrCmdStack(); + sendWRcmd_clrCmd4Stack(); + +} + +// 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; nn=CMDSTACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + nextAsynchsendCmd0[nrOfCmdsInQueue++]=nextCmd; + //qDebug() << "PI cmd queued:"<< nextCmd << ", saved, pp=" << nrOfCmdsInQueue; + return true; // ok, will be sent +} + +uint16_t sendWRcmd_getSendCommand0(void) +{ + uint16_t nxtAsynchCmd; + uint8_t nn; + if (nrOfCmdsInQueue==0 || nrOfCmdsInQueue>CMDSTACKDEPTH) + return 0; // error + nxtAsynchCmd=nextAsynchsendCmd0[0]; + // move Puffer down by one element + for (nn=0; nn0) + nrOfCmdsInQueue--; + //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; +/* 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_clrCmd4Stack(void) +{ + uint8_t nn; + for (nn=0; nn=CMD4STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + nextAsynchsendCmd4[nrOfCmds4InQueue]=nextCmd; + nextCmd4para1[nrOfCmds4InQueue]=dat1; + nextCmd4para2[nrOfCmds4InQueue]=dat2; + nextCmd4para3[nrOfCmds4InQueue]=dat3; + nextCmd4para4[nrOfCmds4InQueue]=dat4; + //qDebug() << "data with 4 data byte saved, pp=" << nrOfCmds4InQueue; + //qDebug() << " dat1=" << nextCmd4para1[nrOfCmds4InQueue] << " dat2=" << nextCmd4para2[nrOfCmds4InQueue] + // << " dat3=" << nextCmd4para3[nrOfCmds4InQueue] << " dat4=" << nextCmd4para4[nrOfCmds4InQueue]; + nrOfCmds4InQueue++; + 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; + + 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 + for (nn=0; nn0) + nrOfCmds4InQueue--; + //qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue; + return nxtAsynchCmd; +} + + + + + +static uint16_t nextAsynchsendCmd8[CMD8STACKDEPTH]; +static uint8_t nextCmd8para1[CMD8STACKDEPTH]; +static uint8_t nextCmd8para2[CMD8STACKDEPTH]; +static uint16_t nextCmd8para3[CMD8STACKDEPTH]; +static uint32_t nextCmd8para4[CMD8STACKDEPTH]; +static uint8_t nrOfCmds8InQueue; + +void sendWRcmd_clrCmd8Stack(void) +{ + uint8_t nn; + for (nn=0; nn=CMD8STACKDEPTH) + { + qDebug() << "cannot save cmd because stack is full"; + return false; // not possible + } + nextAsynchsendCmd8[nrOfCmds8InQueue]=nextCmd; + nextCmd8para1[nrOfCmds8InQueue]=dat1; + nextCmd8para2[nrOfCmds8InQueue]=dat2; + nextCmd8para3[nrOfCmds8InQueue]=dat3; + nextCmd8para4[nrOfCmds8InQueue]=dat4; + nrOfCmds8InQueue++; + 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; + uint8_t nn; + + if (nrOfCmds8InQueue==0 || nrOfCmds8InQueue>CMD4STACKDEPTH) + return 0; // error + nxtAsynchCmd=nextAsynchsendCmd8[0]; + *dat1=nextCmd8para1[0]; + *dat2=nextCmd8para2[0]; + *dat3=nextCmd8para3[0]; + *dat4=nextCmd8para4[0]; + + // move buffer down by one element + for (nn=0; nn0) + nrOfCmds8InQueue--; + 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) +{ + //qDebug() << "pi epi: storing send data"; + if (leng>160) leng=160; + sendAsyDatLen=leng; + tslib_strclr(sendAsynchDataBuf, 0, 160); + for (uint8_t nn=0; nn=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(Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES); + + for (nn=0; nn0) + pPrnDataBuff--; + pp=pPrnDataBuff; + // example: pp=4: then buffers [0...3] are still occupied, pp=0: all buffers empty + + // now clear highest copyed line (which got free now) + tslib_strclr(Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES); + + // optionally: clear all remaining higher lines: + for (nn=(pp+1); nn0: nr of 64byte-blocks + return (pPrnDataBuff); +} + + + + + diff --git a/src/storeINdata.cpp b/src/storeINdata.cpp new file mode 100644 index 0000000..33e09e3 --- /dev/null +++ b/src/storeINdata.cpp @@ -0,0 +1,1572 @@ +#include +#include +#include +#include "storeINdata.h" +#include "tslib.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) +{ + indat_savePrnPwr=isOn; +} + +bool indat_isPrinterOn() +{ + return indat_savePrnPwr; +} + + +static bool indat_saveMifPwr; + +void indat_storeMifarePower(bool isOn) +{ + indat_saveMifPwr=isOn; +} + +bool indat_isMifareOn() +{ + return indat_saveMifPwr; +} + + +static bool indat_MdbIsOn; + +void indat_storeMDBisOn(bool isOn) +{ + indat_MdbIsOn=isOn; +} + +bool indat_isMdbOn() +{ + return indat_MdbIsOn; +} + + +// ////////////////////////////////////////////////////////////////////////// + + + +static uint8_t ndbs, pari, nsb, br; + +void gpi_storeSlaveSerParams(uint8_t slaveBaudRate, uint8_t NrDataBits, + uint8_t parity, uint8_t NrStopBits) +{ + // store numbers + ndbs=NrDataBits; + pari=parity; + nsb=NrStopBits; + br=slaveBaudRate; +} + +void epi_getSlaveSerParams(uint8_t *slaveBaudRate, uint8_t *NrDataBits, + uint8_t *parity, uint8_t *NrStopBits) +{ + *NrDataBits=ndbs; + *parity=pari; + *NrStopBits=nsb; + *slaveBaudRate=br; + +} + +QString epi_getSlaveParamSTR() +{ + QString mySt; + mySt.clear(); + switch (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; + } + mySt.append(ndbs+0x30); + + mySt.append(pari); + mySt.append(nsb+0x30); +//mySt="Hallo"; + return mySt; +} + + + + +static QString genStrings[MAXNROF_GENSTR]; + // 0=HW 1=SW 2=State + +void gpi_storeGenerals(uint8_t genNr, QString text) +{ + // 0=HW 1=SW 2=State + if (genNr umformen in hexstring + + QString myStr; + for (int ii=0;ii<8; ii++) + { + + myStr+=QString::number(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) +{ + getGlobalTime.squareOutMode=squMode; +} + +uint8_t epi_getSquareMode() +{ + return 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; nn05 + mystr.append(':'); + //tempStr.clear(); + tempStr.setNum(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(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(getGlobalTime.Year,10); // itoa decimal + YYstr=tmpStr.rightJustified(4,'0',false); // immer vierstellig + YYstr[0]='2'; // 2000 dazu + + tmpStr.setNum(getGlobalTime.Month,10); + MMstr=tmpStr.rightJustified(2,'0',false); + + tmpStr.setNum(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 (aiNr9) + { + 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) +{ + + di_doorSwitch=0; + if (upperDoor) di_doorSwitch |=1; + if (lowerDoor) di_doorSwitch |=2; + if (vaultDoor) di_doorSwitch |=4; + +// qDebug()<<"storeINdata: "<0) + return true; + return false; +} + +bool epi_getDO_serialMux2isSetToCredit(void) +{ + // mux2 off: serial is switched to credit card terminal + if ((do_serialSwitch & 4)==0) + return true; + return false; +} + +bool epi_getDO_serialMux2isSetToMifare(void) +{ + // mux2 on: serial is switched to mifare reader + if ((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 + do_ledsAndFan=ledState; +} + +bool epi_getDO_led_coin(void) +{ + if (do_ledsAndFan & 1) + return true; + return false; +} + +bool epi_getDO_led_front(void) +{ + if (do_ledsAndFan & 2) + return true; + return false; +} + +bool epi_getDO_led_ticket(void) +{ + if (do_ledsAndFan & 4) + return true; + return false; +} + +bool epi_getDO_led_pin(void) +{ + if (do_ledsAndFan & 8) + return true; + return false; +} + +bool epi_getDO_led_start(void) +{ + if (do_ledsAndFan & 16) + return true; + return false; +} + +bool epi_getDO_led_inside(void) +{ + if (do_ledsAndFan & 32) + return true; + return false; +} + +bool epi_getDO_fan(void) +{ + if (do_ledsAndFan & 64) + return true; + return false; +} + + + +static uint8_t do_laermUndRelay; +void gpi_storeDO_sirenAndRelay(uint8_t sirenRelay) +{ + // bit0: siren 1:relay + do_laermUndRelay=sirenRelay; +} + +bool epi_getDO_sirene(void) +{ + if (do_laermUndRelay & 1) + return true; + return false; +} + +bool epi_getDO_relay(void) +{ + if (do_laermUndRelay & 2) + return true; + return false; +} + +static uint8_t do_ptuWake; +void gpi_storeDO_ptuWake(uint8_t state) +{ + do_ptuWake=state; +} + +bool epi_getDO_ptuWake(void) +{ + if (do_ptuWake>0) + return true; + return false; +} + +static uint8_t do_auxPower; +void gpi_storeDO_auxPower(uint8_t pwr) +{ + do_auxPower=pwr; +} + +bool epi_getDO_auxPower(void) +{ + if (do_auxPower>0) + return true; + return false; +} + + + +static uint8_t do_coinShutter; +void gpi_storeDO_coinShutter(uint8_t state) +{ + do_coinShutter=state; +} + +bool epi_getDO_coinShutterOpen(void) +{ + // bit0: Coin shutter output, bit1: input-test-output + if (do_coinShutter & 1) + return true; + return false; +} + +bool epi_getDO_coinShutterTest(void) +{ + // bit0: Coin shutter output, bit1: input-test-output + if (do_coinShutter & 2) + return true; + return false; +} + +static uint8_t do_coinEscrow; + +void gpi_storeDO_coinEscrow(uint8_t state) +{ + do_coinEscrow=state; +} + +uint8_t epi_getDO_coinEscrow(void) +{ + // retval: 1:return flap is open 2:take flap is open 0:closed + if (do_coinEscrow &1) + return 1; // return flap is open + if (do_coinEscrow &2) + return 2; // take flap is open + return 0; +} + +static uint8_t do_printerPower; + +void gpi_storeDO_printerPwrOn(uint8_t state) +{ + do_printerPower=state; +} + +uint8_t epi_getDO_printerPwr(void) +{ + return 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; nn11 || maxBufferSize<64) + return 1; // error + + for (uint8_t nn=0; nn<64; nn++) + buf[nn]=Sdata_MIF_DATA[blkNr][nn]; + + return 0; // ois OK +} + +//------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------ + + +static uint8_t Sdata_PRN_STATE[pi_prnStateArraySize]; + +void epi_restorePrinterState(uint8_t *buf) +{ + uint8_t nn; + + for (nn=0; nn64) leng=64; + Sdata_empNrOfsettings=leng; + tslib_strcpy(data, Sdata_emp_settingsBuff, leng); +} + +void epi_restoreEmpSettings(uint8_t *leng, uint8_t *data) +{ + + *leng=Sdata_empNrOfsettings; + tslib_strcpy(Sdata_emp_settingsBuff, data, Sdata_empNrOfsettings); +} + + +// ...................................................................... +// 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 ) +{ + if (ctr_gotCoin0) // with FastProtocol only one coin + { + vv=uchar2uint(data[pp+4], data[pp+3]); + sub_enterData(data[pp], data[pp+1], data[pp+2], vv ); + +//qDebug()<< "emp IN data: " << data[pp] << " " << data[pp+1] +// << " " <64) leng=64; + Sdata_NrOfDeviceSetting=leng; + tslib_strcpy(data, Sdata_DeviceSettingBuff, leng); +} + +void epi_restoreDeviceSettings(uint8_t *leng, uint8_t *data) +{ + + *leng=Sdata_NrOfDeviceSetting; + tslib_strcpy(Sdata_DeviceSettingBuff, data, Sdata_NrOfDeviceSetting); +} + + + + +static uint8_t Sdata_NrOfMachineIDSetting; +static uint8_t Sdata_NrOfMachineIDBuff[66]; + +void gpi_storeMachineIDsettings(uint8_t leng, uint8_t *data) +{ + if (leng>64) leng=64; + Sdata_NrOfMachineIDSetting=leng; + tslib_strcpy(data, Sdata_NrOfMachineIDBuff, leng); +} + +void epi_restoreMachineIDsettings(uint8_t *leng, uint8_t *data) +{ + + *leng=Sdata_NrOfMachineIDSetting; + tslib_strcpy(Sdata_NrOfMachineIDBuff, data, Sdata_NrOfMachineIDSetting); +} + + + + + + + + + diff --git a/src/tslib.cpp b/src/tslib.cpp new file mode 100644 index 0000000..5cbc983 --- /dev/null +++ b/src/tslib.cpp @@ -0,0 +1,557 @@ +#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[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; +} + + +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); +} +*/ + +// ----------------------------------------------------------------------------------------------- +