From f51062010e1c3801a54aaf0e8ab5bf7481f43d6d Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 17 Mar 2023 11:22:09 +0100 Subject: [PATCH] Adding src files (sax) --- src/com.cpp | 389 +++++++ src/controlBus.cpp | 415 +++++++ src/datIf.cpp | 1292 ++++++++++++++++++++++ src/dcBL.cpp | 1269 ++++++++++++++++++++++ src/hwapi.cpp | 2501 +++++++++++++++++++++++++++++++++++++++++++ src/prot.cpp | 525 +++++++++ src/sendWRcmd.cpp | 435 ++++++++ src/storeINdata.cpp | 1516 ++++++++++++++++++++++++++ src/tslib.cpp | 557 ++++++++++ 9 files changed, 8899 insertions(+) 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/src/com.cpp b/src/com.cpp new file mode 100644 index 0000000..c260856 --- /dev/null +++ b/src/com.cpp @@ -0,0 +1,389 @@ +#include "com.h" +#include +//#include "controlBus.h" + +////////////////////////////////////////////////////////////////////////////////// +/// +/// serial hardware layer +/// +////////////////////////////////////////////////////////////////////////////////// + + +// ------------------------------------------------------------------------------------------------------------- +// --------- 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 + +} + + + + +T_com::~T_com() +{ + if (CatSerial->isOpen()) + CatSerial->close(); +} + + +void T_com::ser_ISR100ms() +{ + // call every 100ms to check if user(HMI) wants to connect or disconnect + + //qDebug() << "~~>LIB" << "checking connect button... " ; + + uint8_t chkConn = gpi_getSerialConn(); // from global GUI buffer (Sdata) + switch (chkConn) + { + case 0: // 0 button "connect" was just released + closeSerialPort(); + gpi_serialChanged(); // set chkConn to 2, thus getting edge + break; + case 1: // 1 button "connect" was just pressed + open_Serial_Port(); + gpi_serialChanged(); // set chkConn to 2, thus getting edge + break; + } + + + if (CatSerial->isOpen()) + gpi_serialIsOpen(true); + else + gpi_serialIsOpen(false); + +} + +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------- + +char T_com::open_Serial_Port() +{ + bool ret; + QString myString=nullptr, myPortName=nullptr, myBaudStr=nullptr; + int myBaudNr; + + if (CatSerial->isOpen()) + return 0; // opening twice is not allowed + + //qDebug() << "connecting..." << myPortName; + myPortName=gpi_getComPortName(); // was selected and stored from GUI + CatSerial->setPortName(myPortName); + myBaudNr=gpi_getBaudNr(); // was selected and stored from GUI + switch (myBaudNr) + { + // 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 + case 0: CatSerial->setBaudRate(QSerialPort::Baud1200); myBaudStr="1200"; break; + case 1: CatSerial->setBaudRate(QSerialPort::Baud9600); myBaudStr="9600"; break; + case 2: CatSerial->setBaudRate(QSerialPort::Baud19200); myBaudStr="19200"; break; + case 3: CatSerial->setBaudRate(QSerialPort::Baud38400); myBaudStr="38400"; break; + case 4: CatSerial->setBaudRate(QSerialPort::Baud57600); myBaudStr="57600"; break; + case 5: CatSerial->setBaudRate(QSerialPort::Baud115200); myBaudStr="115200"; break; + } + + CatSerial->setDataBits(QSerialPort::Data8); + // alt: QSerialPort::Data5,6,7,8 + + CatSerial->setParity(QSerialPort::NoParity); + // alt: EvenParity, OddParity, NoParity + + CatSerial->setStopBits(QSerialPort::OneStop); + // alternative: OneStop, TwoStop, OneAndHalfStop + + CatSerial->setFlowControl(QSerialPort::NoFlowControl); + // alt: HardwareControl, SoftwareControl, NoFlowControl + + ret=CatSerial->open(QIODevice::ReadWrite); + // alt: QIODevice::ReadWrite QIODevice::ReadOnly QIODevice::WriteOnly + if (!ret) + { + myString.clear(); + myString = "error "; + myString.append(CatSerial->errorString()); + qDebug() << myString; + gpi_setTxt4comStateLine(myString); + return 0; + } else + { + myString.clear(); + myString.append(myPortName); + //lang=myString.size(); + myString.append(" opened with "); + myString.append(myBaudStr); + myString.append(" 8N1"); + qDebug() << myString; + gpi_setTxt4comStateLine(myString); + gpi_setTxt4RsDiagWin(myString+"\n"); + + } + + return 0; +} + +void T_com::closeSerialPort() +{ + if (CatSerial->isOpen()) + { + qDebug() << "closing connection"; + CatSerial->close(); + gpi_setTxt4comStateLine("closed"); + gpi_setTxt4RsDiagWin("closed"); + + } +} + + +void T_com::readSomeBytes(void) +{ + // called by serial-read-detection + // restart off-time as input flow is ongoing + serRecTime->stop(); + serRecTime->start(20); // in ms + +} + +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 + 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) +{ + rs_comportName = ComName; + rs_baudStr = BaudStr; + rs_baudNr = BaudNr; // 0=1200 1=9600 2=19200 3=38400 4=57600 5=115200 oder -1 + rs_connect = connect; // 0/1 + +} + +void epi_closeSerial(void) +{ + rs_connect=0; +} + + +void gpi_serialChanged(void) +{ + // serial confirms that port was closed or opened + rs_connect=2; // Flanke, nur 1x öffnen/schließen +} + +uint8_t gpi_getSerialConn(void) +{ + return rs_connect; +} + + +int gpi_getBaudNr(void) +{ + return rs_baudNr; +} + +QString gpi_getComPortName(void) +{ + return rs_comportName; +} + +static bool rs_portIsOpen; + +void gpi_serialIsOpen(bool offen) +{ + rs_portIsOpen=offen; +} + +bool epi_isSerialPortOpen() +{ + // true: port is open false: port is closed + 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; + + +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(100); // 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; + +} + +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 (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) + { + 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) + { + 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) + { + 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) + { + qDebug() << "datif: sending 160 byte block, len: " << dataBufLen; + datif_OUT_SendRandomData(dataSendBuf, dataBufLen); + BlockCounter=0; + return 0; + } + + dbl=gpi_chk4remainingText(); + if (dbl>0) + { + 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; + 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=5; + +return 0; + +} + + +char T_datif::isPortOpen(void) +{ + return (myDCIF->isPortOpen()); +} + + +// ############################################################################## +// ############################################################################## +// ############################################################################## +// Empfangsdaten einsortieren +// ---------------------------------------------------------------------------------------------- + + + +//void T_datif::StoredRecData(bool neu) +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(); + } +} + +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 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; ii0: 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(); +} + +// 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_OutCmdpara3; + data[4]=0; data[5]=0; + + myDCIF->setUserWriteData(WRcmd, 0, nrOfWrData, data); + myDCIF->setUserReadData(RDcmd); + myDCIF->sendUserData(selectedSlaveAddr); +} + +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); +} + + +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]) + 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 + +} + +// 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); + 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); + +} + +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); + +} + + + diff --git a/src/dcBL.cpp b/src/dcBL.cpp new file mode 100644 index 0000000..a1d1e8c --- /dev/null +++ b/src/dcBL.cpp @@ -0,0 +1,1269 @@ +//#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(); + + 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; + return 10; // OK + } + if (buf[0] !=2) + { + dcBL_writeText("error wrong start"); + //exactError=2; + return 10; // OK + } + if (buf[0]==2 && buf[1]=='e' && buf[2]=='0' ) + { + dcBL_writeText("error wrong crc"); + //exactError=3; // DC reports wrong crc + return 1; // error + } + if (buf[0]==2 && buf[1]==dcBL_LastBLcmd ) + { + dcBL_writeText("error wrong cmd"); + //exactError=4; // wrong cmd + return 10; // OK + } + //tmpStr.clear(); + //tmpStr.setNum(exactError); + //dcBL_writeText(tmpStr); + return 1; // error +} + + + +// ----------------------------------------------------------------------------------------------- +// --- 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=""; + + //QFile file("/own/H2B/dc2.hex"); // laesst sich genauso oeffnen + QFile file("/own/H2B/dc2.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[257000]; // 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) + 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 10: // send length and crc + len=dcBL_getAtbFileHeader(buf); + sendWRcmd_setSendBlock160(len, buf); + dcBL_writeText("sending header"); + + dcBL_BlkCtr=0; // normal 0 + + dcBL_cyclCtr=0; + dcBL_step++; + break; + + case 11: // wait for answer 2 178 102 105 3 + + if (gotResp==ISOK) + { + 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 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; +} + +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..bcfd10c --- /dev/null +++ b/src/hwapi.cpp @@ -0,0 +1,2501 @@ +/* + * 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 "tslib.h" +#include "hwapi.h" + +#include "sendWRcmd.h" +#include "controlBus.h" +#include "storeINdata.h" +#include "dcBL.h" +#include +#include "interfaces.h" + + + +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 +// ------------------------------------------------------------------------------ + +void 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 +} + +void hwapi::dc_closeSerial(void) const +{ + epi_closeSerial(); +} + +bool hwapi::dc_isPortOpen(void) const +{ + return epi_isSerialPortOpen(); +} + +void hwapi::dc_autoRequest(bool on) const +{ + // automatically request ALL digital and analog sensors, get time/date, get status information + if (on) + epi_startEmmision(1); + else + epi_startEmmision(0); +} + +// ------------------------------------------------------------------------------ +// 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 +{ + //qDebug() << "HWapi: send cmd open vault"; + sendWRcmd_setSendCommand0(SENDDIR_OPENVAULT); +} + +void hwapi::coin_switchRejectMotor(uint8_t dir) const +{ + //qDebug() << "HWapi: send cmd open vault"; + sendWRcmd_setSendCommand4(SENDDIR_REJMOT_ON, dir, 0,0,0); +} + +void hwapi::coin_rejectCoins(void) const +{ + //qDebug() << "HWapi: send cmd open vault"; + sendWRcmd_setSendCommand0(SENDDIR_REJMOT_RUN); +} + + +void hwapi::led_switchLedIllumination(uint8_t on) const +{ + sendWRcmd_setSendCommand4(SENDDIRCMD_LEDILLU, on, 0, 0, 0); +} + +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::laerm_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 +{ + return epi_getDI_mifarePwr(); +} + +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(); +} + +bool hwapi::cash_getLowPaperSensor(void) const +{ + 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_MIFREADER); +} + +void hwapi::request_MifareCardType() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_MIFCARD); +} + +void hwapi::request_MifareAtbType() const +{ + sendWRcmd_setSendCommand0(SEND_REQU_MIF_ATB_TYPE); +} + +void hwapi::request_MifareData() const +{ + //sendWRcmd_setSendCommand0(SEND_REQU_MIF_DATA); +} + + + +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 + + return epi_restoreMifState(buf, maxBufferSize); +} + +/* 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]; + uint8_t ret= epi_restoreMifState(buf, 40); + if (ret==0 && buf[0]>1 && buf[3]>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[3]>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[3]>0 && buf[16]>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[40]; + 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 + } + } + 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); +} + + + + + + diff --git a/src/prot.cpp b/src/prot.cpp new file mode 100644 index 0000000..ca3cda0 --- /dev/null +++ b/src/prot.cpp @@ -0,0 +1,525 @@ +#include "prot.h" +#include +#include "controlBus.h" +#include "dcBL.h" + + +T_prot::T_prot() +{ + + mySerialPort = new T_com(); + connect(mySerialPort, SIGNAL(receivingFinished()), this, SLOT( analyseRecData() )); + //connect(mySerialPort, SIGNAL(receivingFinished()), this, SLOT( receivFin() )); + //connect(mySerialPort, SIGNAL(sendingFinished()), this, SLOT(sendeFin())); + kindOfData=0; // 0: binaries, 1:text + +} + + +// --------------------------------------------------------------------------------------------------------- +// sending..... +// --------------------------------------------------------------------------------------------------------- + +bool T_prot::isPortOpen(void) +{ + return mySerialPort->isPortOpen(); +} + +bool T_prot::isSerialFree(void) +{ + return true; // ohne HS's kann er nicht blockiert sein +} + + +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; nnFRAME_DATALEN) + WrDataLength=FRAME_DATALEN; + + for (int nn=0; nnBL_DATA_LEN) BLsendDataLength=BL_DATA_LEN; + for (int nn=0; nnwriteToSerial(packBuf_2, BLsendDataLength); + + + } else + startPacking(); +} + +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); + + if (recLength>FRAME_MAXLEN) + recLength=FRAME_MAXLEN; + for (int nn=0; nn0) + { + // dann anzeigen und ende + 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); + + 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 + + CheckInData(recBuffer); // Eingangs-Daten des Slaves anzeigen + } + emit framerecieved(); + //qDebug() << "framereceived emitted"; +} + + + +uint8_t T_prot::FramecheckInData(uint8_t *Inbuf, uint16_t LL) +{ + + uint16_t rawInLen=LL, crcL_Addr, recCrc, myCrc, nn, datalen, nxt; + + if (rawInLen<12) + { + qDebug("prot: got %d bytes only", rawInLen); + return 1; // wrong length + } + + if ( Inbuf[0] != '<') + return 2; // wrong start sign + + datalen=uint16_t(Inbuf[9]); + if ( datalen > 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::CheckInData(uint8_t *recBuffer) +{ + QString myString=nullptr, tempStr=nullptr; + + RecSlaveAddr=recBuffer[1]; + if (recBuffer[2]==0 && recBuffer[4]==0) // comand result=OK und read result =OK, + // dann sind die Eingangsdaten gültig + { + myString.append("valid INdata: "); + INdataValid=true; + readSource=uchar2uint(recBuffer[6],recBuffer[5]); + readAddress=uchar2uint(recBuffer[8],recBuffer[7]); + //lastWakeSrc=uint8_t(recBuffer[4]); + RdDataLength=uint8_t(recBuffer[9]); + if (RdDataLength>FRAME_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..3cd1c0f --- /dev/null +++ b/src/storeINdata.cpp @@ -0,0 +1,1516 @@ +#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[3]; + // 0=HW 1=SW 2=State + +void gpi_storeGenerals(uint8_t genNr, QString text) +{ + // 0=HW 1=SW 2=State + if (genNr<3) + { + genStrings[genNr]=text; + //qDebug() << "store gen's: " << genNr << " " < umformen in hexstring + + QString myStr; + for (int ii=0;ii<8; ii++) + myStr+=QString::number(Sdata_UIDstr[ii],16); + 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; + +} + +uint8_t epi_getDI_doorSwitches(void) +{ + // bit0: upper door 1: low door 2:vault door + return di_doorSwitch; +} + +static uint8_t di_vaultSwitch; +void gpi_storeDI_vaultSwitches(uint8_t CashBoxIn, uint8_t BillBoxIn) +{ + di_vaultSwitch=0; + if (CashBoxIn) di_vaultSwitch |=1; + if (BillBoxIn) di_vaultSwitch |=2; +} + +uint8_t epi_getDI_vaultSwitches(void) +{ + // bit0: cash box 1: bill box in + return di_vaultSwitch; +} + +static uint8_t di_lockSwitch; +void gpi_storeDI_lockSwitches(uint8_t indatUL, uint8_t indatLL) +{ + // D5: bit 0: upper lockbar up bit1:down + // D6: bit 0: lower lockbar up bit1:down + di_lockSwitch=0; + if (indatUL & 1) di_lockSwitch |=1; + if (indatUL & 2) di_lockSwitch |=2; + if (indatLL & 1) di_lockSwitch |=4; + if (indatLL & 2) di_lockSwitch |=8; +} + +uint8_t epi_getDI_lockSwitches(void) +{ + // retval: bit 0: upper lockbar up bit1: upper lockbar is down + // bit 2: lower lockbar up bit1: lower lockbar is down + + return di_lockSwitch; +} + +static uint8_t di_opto; +void gpi_storeDI_optos(uint8_t indatOpto) +{ + // OptoIn bit 0,1: optoin 1,2 + di_opto=0; + if (indatOpto & 1) di_opto |=1; + if (indatOpto & 2) di_opto |=2; + +} + +uint8_t epi_getDI_optos(void) +{ + // bit0: opto in 1 1: opto in 2 + return di_opto; +} + + +static uint8_t di_aux; +void gpi_storeDI_auxIn(uint8_t indatAuxIn) +{ + // Aux0...5 + di_aux=indatAuxIn; +} + +uint8_t epi_getDI_auxIn(void) +{ + // bit0: auxin 1 ... 5: auxin 6 + return di_aux; +} + + +static bool di_wakeFromPtu; +void gpi_storeDI_ptuWake(uint8_t indat) +{ + if (indat) + di_wakeFromPtu=true; + else + di_wakeFromPtu=false; +} + +bool epi_getDI_ptuWake(void) +{ + return di_wakeFromPtu; +} + + +static bool di_wakeFromMdb; +void gpi_storeDI_mbdWake(uint8_t indat) +{ + if (indat) + di_wakeFromMdb=true; + else + di_wakeFromMdb=false; +} + +bool epi_getDI_mdbWake(void) +{ + return di_wakeFromMdb; +} + + +static bool di_PrnReady; +void gpi_storeDI_prnReady(uint8_t indat) +{ + if (indat) + di_PrnReady=true; + else + di_PrnReady=false; +} + +bool epi_getDI_prnReady(void) +{ + return di_PrnReady; +} + + +static bool di_CoinAttach; +void gpi_storeDI_CoinAttach(uint8_t indat) +{ + if (indat) + di_CoinAttach=true; + else + di_CoinAttach=false; +} + +bool epi_getDI_CoinAttach(void) +{ + return di_CoinAttach; +} + +static bool di_CoinEscrowOpen; +void gpi_storeDI_CoinEscrow(uint8_t indat) +{ + if (indat) + di_CoinEscrowOpen=true; + else + di_CoinEscrowOpen=false; +} + +bool epi_getDI_CoinEscrow(void) +{ + return di_CoinEscrowOpen; +} + + +static bool di_mifCardTap; +void gpi_storeDI_mifareCardTapped(uint8_t indat) +{ + if (indat) + di_mifCardTap=true; + else + di_mifCardTap=false; +} + +bool epi_getDI_mifareCardTapped(void) +{ + return di_mifCardTap; +} + + +static bool di_wakeFromModem; +void gpi_storeDI_modemWake(uint8_t indat) +{ + if (indat) + di_wakeFromModem=true; + else + di_wakeFromModem=false; +} + +bool epi_getDI_modemWake(void) +{ + return di_wakeFromModem; +} + + + +static bool di_contactPwrOn; + +void gpi_storeDI_contactPowerIsOn(bool di_contact_PwrOn) +{ + di_contactPwrOn=di_contact_PwrOn; +} + +bool epi_getDI_contactPwr(void) +{ + // invertiert! + if (di_contactPwrOn) + return false; + return true; +} + +static bool di_mifarePwrOn; + +void gpi_storeDI_MifarePowerIsOn(bool di_mifare_PwrOn) +{ + di_mifarePwrOn=di_mifare_PwrOn; +} + +bool epi_getDI_mifarePwr(void) +{ + return di_mifarePwrOn; +} + +static bool di_rdbk_mdbTxd; + +void gpi_storeDI_readbackMdbTxD(bool di_rdbkMdbTxd) +{ + di_rdbk_mdbTxd=di_rdbkMdbTxd; +} + +bool epi_getDI_mdbTxd(void) +{ + return di_rdbk_mdbTxd; +} + +static bool di_AuxPwrOn; + +void gpi_storeDI_AuxPowerIsOn(bool di_Aux_PwrOn) +{ + di_AuxPwrOn=di_Aux_PwrOn; +} + +bool epi_getDI_auxPwr(void) +{ + return di_AuxPwrOn; +} + +static bool di_gsmPwrOn; + +void gpi_storeDI_GsmPowerIsOn(bool di_gsm_PwrOn) +{ + di_gsmPwrOn=di_gsm_PwrOn; +} + +bool epi_getDI_gsmPwr(void) +{ + return di_gsmPwrOn; +} + +static bool di_creditPwrOn; + +void gpi_storeDI_CreditPowerIsOn(bool di_credit_PwrOn) +{ + // invertieren!!! + if (di_credit_PwrOn) + di_creditPwrOn=0; + else + di_creditPwrOn=1; +} + +bool epi_getDI_creditPwr(void) +{ + return di_creditPwrOn; +} + +static bool di_printerPwrOn; + +void gpi_storeDI_PrinterPowerIsOn(bool di_printer_PwrOn) +{ + di_printerPwrOn=di_printer_PwrOn; +} + +bool epi_getDI_printerPwr(void) +{ + return di_printerPwrOn; +} + +static bool di_mdbPwrOn; + +void gpi_storeDI_MdbPowerIsOn(bool di_mdb_PwrOn) +{ + di_mdbPwrOn=di_mdb_PwrOn; +} + +bool epi_getDI_mdbPwr(void) +{ + return di_mdbPwrOn; +} + +static bool di_rejMot_home; + +void gpi_storeDI_rejMot_home(bool di) +{ + di_rejMot_home=di; +} + +bool epi_getDI_rejectMotor_homepos(void) +{ + return di_rejMot_home; +} + +static bool di_npe_sensor; + +void gpi_storeDI_paperLow(bool di) +{ + di_npe_sensor=di; +} + +bool epi_getDI_npe_sensor(void) +{ + return di_npe_sensor; +} + + + +// /////////////////////////////////////////////////////////////////////////////////// +// readaback digital outputs +// /////////////////////////////////////////////////////////////////////////////////// + + +/* +D0 bit0: MDB devices 0=off 1=on + bit1: MDB bus power + bit2: MDB WakeOut + +D1=Printer +D2=Credit +D3=Modem + +D5: serial drv on/off, Serial mux1, Serial mux2 +D6: Leds, Fan, +D7: Siren and relay +D8: PtuWakeOut +D9: Power Aux/Barcode +D10: AuxDir 1...6 +D11: AuxOut 1...6 +D12: Coin shutter output +D13: CoinEscrow Outputs +*/ + +static uint8_t do_mbdRxTst; +void gpi_storeDO_mdbRxTst(uint8_t mdbRxTst) +{ + do_mbdRxTst=mdbRxTst; +} + +bool epi_getDO_mdbRxTestOut(void) +{ + if (do_mbdRxTst & 1) + return true; + return false; +} + +static uint8_t do_motorBits; +void gpi_storeDO_motorOutputs(uint8_t Pwr) +{ + //D1: motor outputs bit0: upper lock forw bit 1 backw + // Bit2: lowLock forw bit3: LL backw + do_motorBits=Pwr; +} + +uint8_t epi_getDO_motorOuts(void) +{ + // bit0: upper lock forward bit 1 backward + // bit2: lower lock forward bit 3 backward + return do_motorBits; +} + + + +static uint8_t do_serialSwitch; // serial drv on/off, Serial mux1, Serial mux2 +void gpi_storeDO_serialSwitch(uint8_t state)// serial drv on/off, Serial mux1, Serial mux2 +{ + do_serialSwitch=state; +} + +uint8_t epi_getDO_serialSwitch(void) +{ + // serial drv on/off, Serial mux1, Serial mux2 + return do_serialSwitch; +} + +bool epi_getDO_serialDriverIsOn(void) +{ + + if ( do_serialSwitch & 1) + return true; + return false; +} + +bool epi_getDO_serialMux1isSetToPrinter(void) +{ + // mux1 off: serial is switched to printer + if ((do_serialSwitch & 2)==0) + return true; + return false; +} + +bool epi_getDO_serialMux1isSetToModem(void) +{ + // mux1 on: serial is switched to modem + if ((do_serialSwitch & 2)>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) +{ + 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) +{ + 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) + { + 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); +} +*/ + +// ----------------------------------------------------------------------------------------------- +