/* * API to the PSA2020 Hardware * All data come in from device controller via serial interface and will be stored * PI is updated every 100ms * This api uses stored data and returns them in the following functions * created: Q1/2020 TS until Q2/21 14.7.23TS: patch for correct printer state in line 3364 in sys_getDeviceConditions(struct T_moduleCondition *devCond) const 8.9.2023 two new functions (end of file) for mifare test. Interface version 4.4 DC4.40...4.43 14.09.2023: Verriegelung eingebaut, nur noch gültige Abr.Daten zurückgeben, Suchbegriff: alle Mifare-Funktionen ueberprueft und ggf verbessert 18.09.2023: Signal "Kasse entnommen" und Signale "Tuer auf/zu" ueberprueft 20.9.2023: in datif die Abfrage der DynMachineData massiv beschleunigt und hier in hwapi die entprellten Werte fuer Tueren und Kasse verwenden. Problem war: Signal "Kasse entnommen" war zu langsam -> manchmal abr nicht gesendet */ #include "hwapi.h" static uint32_t hwapi_lastStartAmount; static uint32_t hwapi_lastTotalAmount; static uint8_t hwapi_cash_lastCollectionState; static uint8_t hwapi_paymentStarted; static uint8_t hwapi_lastDoorState; static uint8_t bl_startupStep; hwapi::hwapi(QWidget *parent) : QObject(parent) { // constructor // create or attach shared memory segment m_sharedMem = SharedMem::getShm(sizeof(SharedMem)); if (m_sharedMem) { if (m_sharedMem->isAttached()) { qInfo() << "Shared memory (" << sizeof(SharedMem) << "bytes) created and attached"; } } else { qCritical() << "Creating/attaching shared memory failed"; } //if (shdMem_firstUse()) // für Master raus // { #ifdef THIS_IS_CA_MASTER #ifdef THIS_IS_CA_SLAVE #error "SLAVE LIB COMPILED INTO MASTER" #endif myDatif = new T_datif(); // für die CAslave-Lib auskommentieren! #endif #ifdef THIS_IS_CA_SLAVE #ifdef THIS_IS_CA_MASTER #error "MASTER LIB COMPILED INTO MASTER" #endif #endif // } runProcess = new T_runProc(); sendWRcmd_INI(); hwapi_TimerPayment = new QTimer(); hwapi_TimerPayment->setSingleShot(true); QTimer *hwapi_callPayProc = new QTimer(); connect(hwapi_callPayProc, SIGNAL(timeout()), this, SLOT(hwapi_slotPayProc())); hwapi_callPayProc->setSingleShot(false); hwapi_callPayProc->start(100); // in ms // hwapi_triggerBL = new QTimer(); // connect(hwapi_triggerBL, SIGNAL(timeout()), this, SLOT(bl_performComplStart())); // hwapi_triggerBL->setSingleShot(false); // hwapi_triggerBL->stop(); hwapi_lastStartAmount=0; hwapi_lastTotalAmount=0; hwapi_cash_lastCollectionState=0; hwapi_paymentStarted=0; //csv_startCreatingFile(FILENAME_SHAREDDATA); hwapi_lastDoorState=0; // default: all doors (should be) closed, coin box inserted // bit0: upper door 1:middle 2:lower 3=cash-box out bl_startupStep=0; // connect(runProcess, SIGNAL(runProc_coinCollectionJustStarted()), this, SLOT(hwapi_coinCollectionJustStarted())); // geht nicht zuverlaessig! connect(runProcess, SIGNAL(runProc_coinCollectionJustStarted()), this, SLOT(sub_slotCoin01())); connect(runProcess, SIGNAL(runProc_coinCollectionAborted()), this, SLOT(sub_slotCoin02())); // hwapi_coinCollectionAborted())); connect(runProcess, SIGNAL(runProc_gotNewCoin()), this, SLOT(sub_slotCoin03())); // hwapi_gotNewCoin())); connect(runProcess, SIGNAL(runProc_payStopByMax()), this, SLOT(sub_slotCoin04())); // hwapi_payStopByMax())); connect(runProcess, SIGNAL(runProc_payStopByPushbutton()), this, SLOT(sub_slotCoin05())); // hwapi_payStopByPushbutton())); connect(runProcess, SIGNAL(runProc_payStopByEscrow()), this, SLOT(sub_slotCoin06())); // hwapi_payStopByEscrow())); connect(runProcess, SIGNAL(runProc_payStopByError()), this, SLOT(sub_slotCoin07())); // hwapi_payStopByError())); connect(runProcess, SIGNAL(runProc_payStopByTimeout()), this, SLOT(sub_slotCoin08())); // hwapi_payStopByTimeout())); connect(runProcess, SIGNAL(runProc_payCancelled()), this, SLOT(sub_slotCoin09())); // hwapi_payCancelled())); connect(runProcess, SIGNAL(runProc_coinProcessJustStopped()), this, SLOT(sub_slotCoin10())); // hwapi_coinProcessJustStopped())); connect(runProcess, SIGNAL(runProc_doorServiceDoorOpened()), this, SLOT(sub_slotCoin11())); // hwapi_doorServiceDoorOpened())); connect(runProcess, SIGNAL(runProc_doorVaultDoorOpened()), this, SLOT(sub_slotCoin12())); // hwapi_doorVaultDoorOpened())); connect(runProcess, SIGNAL(runProc_doorCoinBoxRemoved()), this, SLOT(sub_slotCoin13())); // hwapi_doorCoinBoxRemoved())); connect(runProcess, SIGNAL(runProc_doorCoinBoxInserted()), this, SLOT(sub_slotCoin14())); // hwapi_doorCoinBoxInserted())); connect(runProcess, SIGNAL(runProc_doorCBinAndAllDoorsClosed()), this, SLOT(sub_slotCoin15())); // hwapi_doorCBinAndAllDoorsClosed())); connect(runProcess, SIGNAL(runProc_doorAllDoorsClosed()), this, SLOT(sub_slotCoin16())); // hwapi_doorAllDoorsClosed())); } void hwapi::hwapi_slotPayProc(void) { } void hwapi::sub_slotCoin01(void) { emit hwapi_coinCollectionJustStarted(); //qDebug()<<"hwapi::sub_slotCoin01()"; } void hwapi::sub_slotCoin02(void) { emit hwapi_coinCollectionAborted(); //qDebug()<<"hwapi::sub_slotCoin02()"; } void hwapi::sub_slotCoin03(void) { emit hwapi_gotNewCoin(); //qDebug()<<"hwapi::sub_slotCoin03()"; } void hwapi::sub_slotCoin04(void) { emit hwapi_payStopByMax(); //qDebug()<<"hwapi::sub_slotCoin04()"; } void hwapi::sub_slotCoin05(void) { emit hwapi_payStopByPushbutton(); //qDebug()<<"hwapi::sub_slotCoin05()"; } void hwapi::sub_slotCoin06(void) { emit hwapi_payStopByEscrow(); qDebug()<<"hwapi::sub_slotCoin06()"; } void hwapi::sub_slotCoin07(void) { emit hwapi_payStopByError(); //qDebug()<<"hwapi::sub_slotCoin07()"; } void hwapi::sub_slotCoin08(void) { emit hwapi_payStopByTimeout(); //qDebug()<<"hwapi::sub_slotCoin08()"; } void hwapi::sub_slotCoin09(void) { emit hwapi_payCancelled(); //qDebug()<<"hwapi::sub_slotCoin09()"; } void hwapi::sub_slotCoin10(void) { emit hwapi_coinProcessJustStopped(); //qDebug()<<"hwapi::sub_slotCoin10()"; } void hwapi::sub_slotCoin11(void) { emit hwapi_doorServiceDoorOpened(); } void hwapi::sub_slotCoin12(void) { emit hwapi_doorVaultDoorOpened(); } void hwapi::sub_slotCoin13(void) { emit hwapi_doorCoinBoxRemoved(); } void hwapi::sub_slotCoin14(void) { emit hwapi_doorCoinBoxInserted(); } void hwapi::sub_slotCoin15(void) { emit hwapi_doorCBinAndAllDoorsClosed(); } void hwapi::sub_slotCoin16(void) { emit hwapi_doorAllDoorsClosed(); } /* void hwapi::sub_storeSendingText(QByteArray *buf) const { char local[70], copie[1350]; // 64byte more then max buffer size! int LL, nn, len, maxruns=20; epi_resetPrinterStack(); // make a copy of the incoming byteArray as the byteArray can not be moved (crash!) tslib_strclr(copie, 0, 1350); LL=buf->length(); for (nn=0; nnat(nn); } tslib_strclr(local, 0, 66); LL=buf->length(); if (LL>1280) { qDebug()<<"reducing text size from " << LL << " to 1280 bytes"; LL=1280; // Limit size } else qDebug()<<"\n printing text with " << LL << " bytes: "; do { len=tslib_getMinimum(LL, 64); tslib_strclr(local, 0, 66); for (nn=0; nn0 && LL>0); } */ bool hwapi::dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const { // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 // BaudStr: for exapmle "19200" // ComName: for example "COM48" // connect: 0, 1 #ifdef THIS_IS_CA_MASTER //qDebug() << "~~>LIB" << "dc_openSerial called... " ; epi_setSerial(BaudNr, BaudStr, ComName, connect); // Actions: open serial port with parameters #else BaudStr=ComName=""; BaudNr=0; connect=0; // to avoid compiler warning qCritical()<<"hwapi: error CAslave cannot open serial"; return false; return BaudNr; // to avoid compiler warning return connect; // to avoid compiler warning #endif epi_setNowIsBootload(false); return true; } void hwapi::dc_closeSerial(void) const { #ifdef THIS_IS_CA_MASTER epi_closeSerial(); #else qCritical()<<"hwapi: error CAslave cannot close serial"; #endif } bool hwapi::dc_isPortOpen(void) const { return epi_isSerialPortOpen(); } void hwapi::dc_autoRequest(bool on) const { // automatically request ALL digital and analog sensors, get time/date, get status information epi_startEmmision(on); } void hwapi::dc_requTestResponse() const { //sendWRcmd_ setSendCommand0(SENDDIRCMD_TestSerial); // CMD2DC_TestSerial // replace by new command form: sendFDcmd_set(0, CMD2DC_TestSerial, 0,0,0,0,0); } bool hwapi::dc_readAnswTestResponse() const { return epi_getResult_serialTestOK(); } uint8_t hwapi::dc_isRequestDone(void) const { // retval: 0: request is still in progress // 1: answer from DC2 was OK // 2: wrong answer from DC2 return epi_getResultOfLastRequest(); } uint16_t hwapi::dc_getCompletePayLoad(uint16_t plBufSiz, uint8_t *payLoad) const { // get data back in *pl, max 64 byte, can be used for diagnosis // retval = nr of bytes received. If host buffer too small then // only plBufSíz bytes are copied to pl // plBufSíz=size of host buffer return epi_getLastPayLoad( plBufSiz, payLoad); } void hwapi::dc_setWakeFrequency(uint8_t period) const { // RTC wakes DC2 (and PTU) by hardware signal every 32seconds // change wake signal period to 1...64s sendFDcmd_set(0, CMD2DC_setWakeFrequ,0, period,0,0,0); } void hwapi::dc_OrderToReset(void) const { uint8_t len, buf[160]; len=dcBL_restartDC(buf); sendWRcmd_setSendBlock160(len, buf); } QString hwapi::dc_getSerialState(void) const { #ifdef THIS_IS_CA_MASTER return epi_getTxt4comStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clrSerialStateText(void) const { #ifdef THIS_IS_CA_MASTER epi_clrTxt4comStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } void hwapi::bl_sendDataDirectly(uint8_t length, uint8_t *buf) const { // send without protocol frame, needed for the DC bootloader sendWRcmd_setSendBlock160(length, buf); } uint8_t hwapi::getRawRecLength(void) const { return epi_getRawRecLength(); } uint8_t hwapi::getRawReceivedData(uint8_t *receivedData) const { return epi_getRawReceivedData(receivedData); } QString hwapi::dc_getSerialParams(void) const { return epi_getSlaveParamSTR(); } QString hwapi::dc_getHWversion(void) const { return epi_loadHWver(); } QString hwapi::dc_getSWversion(void) const { return epi_loadSWver(); } QString hwapi::dc_getState(void) const { return epi_loadDCstate(); } // ---------------------------------------------------------------------------------------------------------- // Date and Time // ---------------------------------------------------------------------------------------------------------- uint8_t hwapi::rtc_getDateTime(struct Trtc_DateTime *rtc_DateTime) const { // void epi_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss); // void epi_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd); // void epi_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday); uint8_t H, M, S; uint16_t unused16; uint32_t unused32; epi_getTime(&H, &M, &S); rtc_DateTime->rtc_hour=H; rtc_DateTime->rtc_min=M; rtc_DateTime->rtc_sec=S; epi_getDate(&H, &M, &S); rtc_DateTime->rtc_year=H; rtc_DateTime->rtc_month=M; rtc_DateTime->rtc_dayOfMonth=S; epi_getToday(&H, &unused16, &unused32); rtc_DateTime->rtc_dayOfWeek=H; return 0; } uint8_t hwapi::rtc_setDateTime(void) const { //vorher nur: sendWRcmd_setSendCommand0(SENDDIRCMD_setTime); // send PC time/date to slave //uint8_t hour,min, sec, year, month, day, dayOfWeek, //uint8_t dayOfYear, isLeap, weekOfYear; uint8_t buff[15]; uint16_t uitmp; QTime *systTime = new QTime(); // qDebug() << systTime->currentTime().hour() <<":" // << systTime->currentTime().minute() <<":" // << systTime->currentTime().second(); buff[0]=uint8_t(systTime->currentTime().hour()); buff[1]=uint8_t(systTime->currentTime().minute()); buff[2]=uint8_t(systTime->currentTime().second()); QDate *systDate = new QDate(); systDate->currentDate(); uitmp= uint16_t(systDate->currentDate().year()); buff[3]=uint8_t(uitmp); buff[4]=uint8_t(uitmp>>8); buff[5]=uint8_t(systDate->currentDate().month()); buff[6]=uint8_t(systDate->currentDate().day()); buff[7]=uint8_t(systDate->currentDate().dayOfWeek()); // uitmp=systDate->currentDate().dayOfYear(); // buff[8]=uint8_t(uitmp); // buff[9]=uint8_t(uitmp>>8); // buff[10]=uint8_t(systDate->currentDate().isLeapYear(systDate->currentDate().year())); // buff[11]=uint8_t(systDate->currentDate().weekNumber()); //weekOfYear // buff[12]=0; longFDcmd_set(CMD2DC_sendTime,0,0,8,buff); return 0; } void hwapi::rtc_getTime(uint8_t *hh, uint8_t *mm, uint8_t *ss) const { epi_getTime(hh, mm, ss); } void hwapi::rtc_getDate(uint8_t *yy, uint8_t *mm, uint8_t *dd) const { epi_getDate(yy, mm, dd); } uint8_t hwapi::rtc_getToday(uint8_t *dow, uint16_t *minOfToday, uint32_t *secOfToday) const { // dow=day of week, 1=monday...7 // minOfToday: 0=midnight...1439= 23:59 // secOfToday: 0=midnight...86399= 23:59:59 epi_getToday(dow, minOfToday, secOfToday); return 0; } bool hwapi::rtc_isLeapYear(uint8_t *lastLeapYear, uint8_t *NextLeapYear) const { return epi_isLeapYear(lastLeapYear, NextLeapYear); } bool hwapi::rtc_isLeapYear(void) const { return epi_isLeapYear(); } void hwapi::rtc_getWeek(uint8_t *DayOfWeek, uint8_t *HoursOfWeek, uint16_t *MinutesOfWeek) const { epi_getSpecialWeekTimeDate(DayOfWeek, HoursOfWeek, MinutesOfWeek); } void hwapi::rtc_getMonth(uint8_t *DayOfMonth, uint16_t *HoursOfMonth, uint16_t *MinutesOfMonth) const { epi_getSpecialMonthTimeDate(DayOfMonth, HoursOfMonth, MinutesOfMonth); } void hwapi::rtc_getYear(uint16_t *DayOfYear, uint16_t *HoursOfYear, uint32_t *MinutesOfYear) const { epi_getSpecialYearTimeDate(DayOfYear, HoursOfYear, MinutesOfYear); } QString hwapi::rtc_getTimStr() const { uint8_t hh, mm, ss, buf[20], nn; QString qbuf; char ctmp; qbuf.clear(); for (nn=0; nn<20; nn++) buf[nn]=0; epi_getTime(&hh, &mm, &ss); GetTimeString(hh, mm, ss, HourSys24h, MITSEK, buf); // about 12byte long for (nn=0; nn<20; nn++) { ctmp=buf[nn]; qbuf[nn]=ctmp; } return qbuf; } QString hwapi::rtc_getDatStr() const { uint8_t day, month, year, buf[20], nn; QString qbuf; char ctmp; qbuf.clear(); for (nn=0; nn<20; nn++) buf[nn]=0; epi_getDate(&year, &month, &day); GetDateString(day, month, 0x20, year, DateFormatDeutsch, 0, buf); for (nn=0; nn<20; nn++) { ctmp= buf[nn]; qbuf[nn]=ctmp; } return qbuf; } QString hwapi::rtc_getTimDatStr() const { // style: 0: hh:mm 1: hh:mm:ss QString qbuf; qbuf.clear(); qbuf.append(rtc_getTimStr()); qbuf.append(" "); qbuf.append(rtc_getDatStr()); return qbuf; } // UID void hwapi::dc_getUID8byte(uint8_t *buf8byteUid) const { epi_getUIDdec(buf8byteUid); } QString hwapi::dc_getUIDstr() const { return epi_getUIDstr(); } uint64_t hwapi::dc_getUIDnumber(void) const { uint64_t retval=0; uint8_t buf8byteUid[12], nn; epi_getUIDdec(buf8byteUid); for (nn=8; nn>0; nn--) { retval+=buf8byteUid[nn-1]; retval<<=8; // *256 } return retval; } // ---------------------------------------------------------------------------------------------------------- // analogs // ---------------------------------------------------------------------------------------------------------- uint32_t hwapi::dc_getTemperature(void) const { // return epi_loadMeasureValue(MEASCHAN_TEMPERATURE); } QString hwapi::dc_getTemperaturStr(void) const { return epi_getSlaveTemperatureStr(); } uint32_t hwapi::dc_getVoltage(void) const { // in mV, e.g. 12300 = 12,3V return epi_loadMeasureValue(MEASCHAN_VOLTAGE); } QString hwapi::dc_getVoltagStr(void) const { return epi_getSlaveVoltageStr(); } bool hwapi::dc_mainFuseIsOk(void) const { uint32_t ulong=epi_loadMeasureValue(MEASCHAN_VOLTAGE); // in mV, e.g. 12300 = 12,3V if (ulong>3000) return true; return false; } // ------------------------------------------------------------------------------ // digital outputs // ------------------------------------------------------------------------------ // Locks: uint8_t hwapi::lock_switchUpperLock(uint8_t dir) const { // dir 0=off 1=up 2=down sendFDcmd_set(CMD2DC_MOV_UPLOCK,0,0, dir,0,0,0); return 0; } uint8_t hwapi::lock_switchLowerLock(uint8_t dir) const { // dir 0=off 1=up 2=down sendFDcmd_set(CMD2DC_MOV_DNLOCK,0,0, dir,0,0,0); return 0; } void hwapi::lock_switchVaultDoor(void) const { sendFDcmd_set(CMD2DC_VAULT_DOOR,0,0, 0,0,0,0); } void hwapi::coin_switchRejectMotor(uint8_t dir) const { sendFDcmd_set(CMD2DC_REJMOT_ON,0,0, dir,0,0,0); } void hwapi::coin_rejectCoins(void) const { sendFDcmd_set(CMD2DC_REJMOT_RUN,0,0, 0,0,0,0); } void hwapi::led_switchLedService(uint8_t on) const { sendFDcmd_set(CMD2DC_LED_IN, CMD2DC_RdBkAllOutputs, 0, on, 0, 0, 0); } void hwapi::led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const { sendFDcmd_set(CMD2DC_LED_TICKET, CMD2DC_RdBkAllOutputs,0, on, ton, tof, 0); } void hwapi::led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const { sendFDcmd_set(CMD2DC_LED_PIN, CMD2DC_RdBkAllOutputs, 0, on, ton, tof, 0); } void hwapi::led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const { sendFDcmd_set(CMD2DC_LED_START, CMD2DC_RdBkAllOutputs,0, on, ton, tof, 0); } void hwapi::led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const { sendFDcmd_set(CMD2DC_LED_COIN, CMD2DC_RdBkAllOutputs, 0, on, ton, tof, 0); } void hwapi::fan_switchFan(bool on) const { sendFDcmd_set(CMD2DC_FAN, CMD2DC_RdBkAllOutputs,0, on, 0, 0, 0); } void hwapi::alarm_switchSiren(bool on) const { sendFDcmd_set(CMD2DC_SIREN, CMD2DC_RdBkAllOutputs,0, on, 0, 0, 0); } void hwapi::bar_OpenBarrier(bool open) const { sendFDcmd_set(CMD2DC_BARRIER, CMD2DC_RdBkAllOutputs,0, open, 0, 0, 0); } void hwapi::ptu_switchWake(bool WAKEACTIVE) const { sendFDcmd_set(CMD2DC_WAKEPTU,0,0, WAKEACTIVE,0,0,0); } // AUX-IO's or barcode reader void hwapi::aux_power(bool on) const { sendFDcmd_set(CMD2DC_SWITCHAUXPWR, CMD2DC_RdBkAllOutputs, 0, on,0,0,0); } void hwapi::aux_setUsage(uint8_t PinDirection) const { // bit 0= Aux1 bit5=Aux6 1=output 0=input with pullup sendFDcmd_set(CMD2DC_SWITCHAUXDDR, CMD2DC_RdBkAllOutputs,0, PinDirection,0,0,0); } void hwapi::aux_setOutputs(uint8_t PinIsHigh) const { // PinIsHigh bit 0..5 =Aux1...6 1=output high 0=set output low sendFDcmd_set(CMD2DC_SWITCHAUXOUT, CMD2DC_RdBkAllOutputs,0, PinIsHigh,0,0,0); } void hwapi::lock_switchContactPower(bool on) const { sendFDcmd_set(CMD2DC_UCONTACTON, 0,0, on, 0,0,0); } void hwapi::prn_switchPower(bool on) const { // also switches and enables serial driver //sendWRcmd_ setSendCommand4(SENDDIRCMD_PRN2_SWONOFF, on,0,0,0); indat_storePrinterPower(on); // PRINTER-ON/OFF zusätzlich statisch abspeichern // Status-request soll nur gesendet werden wenn der Drucker ein ist // Status-Abfrage (hier in HWapi) gibt 0 zurück wenn power-off // dito mit allen anderen Geräten! // pi ---> storeINdata.cpp speichert diese statische Info (printer on/off) UND // auch alles rückgelesene sendFDcmd_set(CMD2DC_PRINTERON,0,0, on,0,0,0); } void hwapi::mif_readerOn(bool on) const { // DC2 also switches and enables serial driver //sendWRcmd_ setSendCommand4(SENDDIRCMD_MIF_SWONOFF, on,0,0,0); sendFDcmd_set(CMD2DC_MIFREADERON,0,0, on,0,0,0); indat_storeMifarePower(on); if (on==false) { gpi_clearMifAtbData(); // neu 14.9.23 gpi_clearMifHwData(); // neu 8.9.23 } } void hwapi::mif_creatAtbCard(uint8_t cardType) const { sendFDcmd_set(CMD2DC_MIFREADERON,0,0, cardType,0,0,0); indat_storeMifarePower(cardType); } void hwapi::mod_switchPower(bool on) const { sendFDcmd_set(CMD2DC_MOD_ON,0,0, on,0,0,0); } void hwapi::mod_switchWake(bool WAKEACTIVE) const { sendFDcmd_set(CMD2DC_MOD_WAK,0,0, WAKEACTIVE,0,0,0); } void hwapi::mdb_switchPower(bool on) const { sendFDcmd_set(CMD2DC_MDB_ON,0,0, on,0,0,0); indat_storeMDBisOn(CMD2DC_MDB_ON); } void hwapi::mdb_switchWake(bool WAKEACTIVE) const { sendFDcmd_set(CMD2DC_MDB_SETWAK,0,0, WAKEACTIVE,0,0,0); } void hwapi::credit_switchPower(bool on) const { sendFDcmd_set(CMD2DC_CRED_ON,0,0, on,0,0,0); } void hwapi::credit_switchWake(bool WAKEACTIVE) const { sendFDcmd_set(CMD2DC_CRED_WAK,0,0, WAKEACTIVE,0,0,0); } void hwapi::shut_move(bool open) const { // true:open false:close sendFDcmd_set(CMD2DC_SHUTTER_OPEN, 0,0, open, 0,0,0); } void hwapi::esc_moveFlaps(uint8_t flap ) const { // 0: close both 1: open take-flap 2: open return sendFDcmd_set(CMD2DC_ESCR_OPEN,0,0, flap, 0,0,0); } // ------------------------------------------------------------------------------ // door, cashbox and lock switches // ------------------------------------------------------------------------------ uint8_t hwapi::door_getSwitches(void) const { // retval // bit0: upper door 1: low door 2:vault door uint8_t ret; ret= epi_getDI_doorSwitches(); // bit0: upper door 1: low door 2:vault door ret &= 0x08; return ret; } bool hwapi::door_isUpperDoorOpen(void) const { // uint8_t ret; // ret= epi_getDI_doorSwitches(); // // bit0: upper door 1: low door 2:vault door // if (ret & 1) // return true; // return false; // new, since 20.9.23: use debounced values: struct T_dynamicCondition myDynMachCond; sys_getDynMachineConditions(&myDynMachCond); if (myDynMachCond.upperDoor==0) // 0=zu return false; return true; // report "open" even if undefined because "closed" is more important } bool hwapi::door_isLowerDoorOpen(void) const { // uint8_t ret; // ret= epi_getDI_doorSwitches(); // if (ret & 2) // return false; // return true; // new, since 20.9.23: use debounced values: struct T_dynamicCondition myDynMachCond; sys_getDynMachineConditions(&myDynMachCond); if (myDynMachCond.lowerDoor==0) // 0=zu return false; return true; // report "open" even if undefined because "closed" is more important } bool hwapi::vault_isVaultDoorOpen(void) const { // uint8_t ret; // ret= epi_getDI_doorSwitches(); // // bit0: upper door 1: low door 2:vault door // if (ret & 4) // return true; // return false; // new, since 20.9.23: use debounced values: struct T_dynamicCondition myDynMachCond; sys_getDynMachineConditions(&myDynMachCond); if (myDynMachCond.middleDoor==0) // 0=zu return false; return true; // report "open" even if undefined because "closed" is more important } uint8_t hwapi::vault_getSwitches(void) const { // retval bit0: cash box, bit 1: bill box uint8_t ret; ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in ret&=0x03; return ret; } bool hwapi::vault_isCoinVaultIn(void) const { // uint8_t ret; // ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in // if (ret & 1) // return true; // return false; // new, since 20.9.23: use debounced values: struct T_dynamicCondition myDynMachCond; sys_getDynMachineConditions(&myDynMachCond); if (myDynMachCond.CBinDebounced==0) // 0:fehlt 1:drin return false; return true; } bool hwapi::vault_isBillVaultIn(void) const { uint8_t ret; ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in if (ret & 2) return true; return false; } uint8_t hwapi::door_getLocks(void) const { // retval bit0: upper lever is up // bit1: upper lever is down // bit2: lower lever is up // bit3: lower lever is down uint8_t ret; ret= epi_getDI_lockSwitches(); // retval: bit 0: upper lockbar up bit1: upper lockbar is down // bit 2: lower lockbar up bit1: lower lockbar is down ret&=0x0F; return ret; } bool hwapi::door_upperDoorIsLocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 2) return true; return false; } bool hwapi::door_upperDoorIsUnlocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 1) return true; return false; } bool hwapi::door_lowerDoorIsLocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 8) return true; return false; } bool hwapi::door_lowerDoorIsUnlocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 4) return true; return false; } bool hwapi::bar_optoIn1isOn(void) const { uint8_t ret=epi_getDI_optos(); // bit0: opto in 1 1: opto in 2 if (ret & 1) return true; return false; } bool hwapi::bar_optoIn2isOn(void) const { uint8_t ret=epi_getDI_optos(); // bit0: opto in 1 1: opto in 2 if (ret & 2) return true; return false; } uint8_t hwapi::aux_getAuxInputs(void) const { // retval: bit0=Aux1....Bit5=Aux6 // 0: input low 1:input high uint8_t ret=epi_getDI_auxIn(); // bit0: auxin 1 ... 5: auxin 6 ret &=0x3F; return ret; } bool hwapi::ptu_WakeINisActive(void) const { return epi_getDI_ptuWake(); } bool hwapi::mdb_WakeINisActive(void) const { return epi_getDI_mdbWake(); } bool hwapi::prn_readyINisActive(void) const { return epi_getDI_prnReady(); } bool hwapi::coid_isAttached(void) const { return epi_getDI_CoinAttach(); } bool hwapi::coin_escrowIsOpen(void) const { return epi_getDI_CoinEscrow(); } bool hwapi::mif_cardIsAttached(void) const { return epi_getDI_mifareCardTapped(); } //bool hwapi::mod_WakeINisActive(void) //{ // return epi_getDI_modemWake(); //} bool hwapi::door_isContactPowerOn(void) const { return epi_getDI_contactPwr(); } bool hwapi::mif_isMifarePowerOn(void) const { bool mo=indat_isMifareOn(); bool mi=epi_getDI_mifarePwr(); if (mo && mi) return true; return false; } bool hwapi::mdb_testIsmdbTxDon(void) const { return epi_getDI_mdbTxd(); //return mdb_busVoltageOk(); gleich? } bool hwapi::aux_isAuxPowerOn(void) const { return epi_getDI_auxPwr(); } bool hwapi::mod_isGsmPowerOn(void) const { return epi_getDI_gsmPwr(); } bool hwapi::cred_isCreditPowerOn(void) const { return epi_getDI_creditPwr(); } bool hwapi::prn_isPrinterPowerOn(void) const { return epi_getDI_printerPwr(); } uint8_t hwapi::prn_PrnFuseIsOk(void) const { //retval: 0: fuse blown 1: fuse OK 2:unknown as printer power is off if (!epi_getDO_printerPwr()) return 2; // unknown as printer power is off if (epi_getDI_printerPwr()) return 1; // printer voltage is OK return 0; // fuse blown } bool hwapi::mdb_isMdbPowerOn(void) const { //return epi_getDI_mdbPwr(); // all DIs byte 4 bit 7 da ist was verschoben return mdb_deviceVoltageOK(); // gleich? aus MDB_GET_STATE=107 Byte[1] } bool hwapi::cash_getRejectMotorHomePos(void) const { // DI=low in Homepos if (epi_getDI_rejectMotor_homepos()) return 0; return 1; } uint8_t hwapi::cash_getLowPaperSensor(void) const { // 0: Sensor sees paper 1: no paper 99: off return epi_getDI_npe_sensor(); } // ------------------------------------------------------------------------------ // request commands // ------------------------------------------------------------------------------ // all read-requests can be sent manually by the following functions // or automatically in background by: void hwapi::dc_autoRequest(bool on) void hwapi::request_DC2serialConfig() const { sendFDcmd_set(0,CMD2DC_GetSerialConfig,0,0,0,0,0); } void hwapi::request_DC2_HWversion() const { sendFDcmd_set(0,CMD2DC_RdBkHWversion,0,0,0,0,0); } void hwapi::request_DC2_SWversion() const { sendFDcmd_set(0,CMD2DC_RdBkSWversion,0,0,0,0,0); } void hwapi::request_DC2_condition() const { sendFDcmd_set(0,CMD2DC_RdBkDCstate,0,0,0,0,0); } void hwapi::request_DC2_UID() const { sendFDcmd_set(0,CMD2DC_RdBkUID,0,0,0,0,0); } void hwapi::request_DC2_TimeAndDate() const { sendFDcmd_set(0,CMD2DC_RdBkTime,0,0,0,0,0); } void hwapi::request_DC2_analogues() const { sendFDcmd_set(0,CMD2DC_RdBkAnalog,0,0,0,0,0); } void hwapi::request_DC2_digitalInputs() const { sendFDcmd_set(0,CMD2DC_GetAllInputs,0,0,0,0,0); } void hwapi::request_DC2_digitalOutputs() const { sendFDcmd_set(0,CMD2DC_RdBkAllOutputs,0,0,0,0,0); } // ------------------------------------------------------------------------------ // the folowing device state requests are deployed only if device is powered up: void hwapi::request_PrinterHwState() const { sendFDcmd_set(0,CMD2DC_RdBk_PrnState,0,0,0,0,0); } void hwapi::request_PrinterCurrentFonts() const { sendFDcmd_set(0,CMD2DC_RdBk_PrnFonts,0,0,0,0,0); } void hwapi::request_PrinterStateComplete() const { sendFDcmd_set(0,CMD2DC_RdBk_AllPrnData,0,0,0,0,0); } void hwapi::request_MifareReaderState() const { sendFDcmd_set(0, 24, 0, 0,0,0,0); // return reader type, card state and type and card UID } void hwapi::request_MifareCardType() const { sendFDcmd_set(0, 109, 0, 0,0,0,0); // ATB Card Type: upper/lower door, test card and card holder } void hwapi::request_MifareAtbType() const { sendFDcmd_set(0,25,0,0,0,0,0); } void hwapi::request_MifareID() const { this->request_MifareReaderState(); } void hwapi::request_MifareData(uint8_t dataBlockNumber) const { if (dataBlockNumber<12) // 1k cards return 12 data blocks, 4k cards would return 54 data blocks (not implemented) sendFDcmd_set(0,28,0, dataBlockNumber,0,0,0); // 1st data = card sequence =blk nr (0...15) } void hwapi::request_MDB_Status() const { sendFDcmd_set(0,CMD2DC_MDB_GET_STATE,0,0,0,0,0); } //void hwapi::request_MDB_wakeInLine() const //{ // sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETWAK); //} void hwapi::request_MDB_lastResponse() const { sendFDcmd_set(0,CMD2DC_MDB_GETRESP,0,0,0,0,0); } void hwapi::request_EMP_allParameters() const { sendFDcmd_set(0,CMD2DC_EMP_GET_ALL,0,0,0,0,0); } void hwapi::request_EMP_lastCoin() const { sendFDcmd_set(0,CMD2DC_EMP_GOTCOIN,0,0,0,0,0); } // ------------------------------------------------------------------------------ // readback digital outputs of connected devices // these functions are not needed for normal operation // but can be used to test and verify conditions // ------------------------------------------------------------------------------ bool hwapi::test_getDO_mdbRXtst(void) const { return epi_getDO_mdbRxTestOut(); } uint8_t hwapi::lock_getDO_motors(void) const { // bit0: upper lock forward bit 1 backward // bit2: lower lock forward bit 3 backward return epi_getDO_motorOuts(); } uint8_t hwapi::test_serialState(void) const { // test on-board signals for the serials // serial drv on/off, Serial mux1, Serial mux2 uint8_t ret=epi_getDO_serialSwitch(); // serial drv on/off, Serial mux1, Serial mux2 ret &=0x07; return ret; } bool hwapi::test_serialIsOn(void) const { return epi_getDO_serialDriverIsOn(); } bool hwapi::test_serialMux1isSetToPrinter(void) const { return epi_getDO_serialMux1isSetToPrinter(); // mux1 off: serial is switched to printer } bool hwapi::test_serialMux1isSetToModem(void) const { return epi_getDO_serialMux1isSetToModem(); // mux1 on: serial is switched to modem } bool hwapi::test_serialMux2isSetToCredit(void) const { return epi_getDO_serialMux2isSetToCredit(); // mux2 off: serial is switched to credit card terminal } bool hwapi::test_serialMux2isSetToMifare(void) const { return epi_getDO_serialMux2isSetToMifare(); // mux2 on: serial is switched to mifare reader } bool hwapi::led_coinIsOn(void) const { return epi_getDO_led_coin(); } bool hwapi::led_frontIsOn(void) const { return epi_getDO_led_front(); } bool hwapi::led_ticketIsOn(void) const { return epi_getDO_led_ticket(); } bool hwapi::led_pinIsOn(void) const { return epi_getDO_led_pin(); } bool hwapi::led_StartIsOn(void) const { return epi_getDO_led_start(); } bool hwapi::led_insideIsOn(void) const { return epi_getDO_led_inside(); } bool hwapi::fan_isOn(void) const { return epi_getDO_fan(); } bool hwapi::siren_isOn(void) const { return epi_getDO_sirene(); } bool hwapi::bar_relayIsOn(void) const { return epi_getDO_relay(); } bool hwapi::ptu_WakeOutIsOn(void) const { return epi_getDO_ptuWake(); } bool hwapi::aux_powerIsOn(void) const { return epi_getDO_auxPower(); } bool hwapi::coin_shutterIsOpen(void) const { return epi_getDO_coinShutterOpen(); } bool hwapi::coin_shutterTestOutput(void) const { return epi_getDO_coinShutterTest(); } uint8_t hwapi::coin_escrowFlapOpened(void) const { // retval: 1:return flap is open 2:take flap is open 0:closed return epi_getDO_coinEscrow(); } // ------------------------------------------------------------------------------ // devices are operated by DC // processes with more then one devices // timer controlled or long term processes // ------------------------------------------------------------------------------ void hwapi::sendDeviceSettings(uint8_t kindOfPrinter, uint8_t kindOfCoinChecker, uint8_t kindOfMifareReader, uint8_t suppressSleep, uint8_t kindOfModem, uint8_t kindOfCredit) const { uint8_t buf[64]; tslib_strclr(buf,0,64); buf[0]=kindOfPrinter; buf[1]=kindOfCoinChecker; buf[2]=kindOfMifareReader; buf[3]=suppressSleep; buf[4]=kindOfModem; buf[5]=kindOfCredit; longFDcmd_set(CMD2DC_DEVICE_PARAM, 0, 0, 6, buf); } void hwapi::request_ReadbackDeviceSettings() const { sendFDcmd_set(0,CMD2DC_RDBK_DEV_PARA,0,0,0,0,0); } void hwapi::readback_DeviceSettings(uint8_t *length, uint8_t *data) const { epi_restoreRbDeviceSettings(length, data); /* buf66[0]=devPara.kindOfPrinter; buf66[1]=devPara.kindOfCoinChecker; buf66[2]=devPara.kindOfMifareReader; buf66[3]=devPara.suppressSleepMode; buf66[4]=devPara.kindOfModem; buf66[5]=devPara.kindOfCreditcard; buf66[6]=devPara.CoinEscrow; buf66[7]=devPara.CoinRejectUnit; buf66[8]=devPara.CoinShutter; buf66[9]=devPara.BillAcceptor; buf66[10]=devPara.usevaultLock; buf66[11]=devPara.autoAlarm; buf66[12]=devPara.autoOpen; buf66[13]=devPara.printAccReceipt; buf66[14]=devPara.printDoorReceipt; buf66[15]=devPara.printTokenTicket; uitmp=devPara.VaultFullWarnLevel; buf66[16]=swl_getOneByteFromUint(uitmp, GETLOWBYT); buf66[17]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); uitmp=devPara.VaultFullErrorLevel; buf66[18]=swl_getOneByteFromUint(uitmp, GETLOWBYT); buf66[19]=swl_getOneByteFromUint(uitmp, GETHIGHBYT); */ } // .................................................................................... void hwapi::sendMachineID(uint16_t customerNr, uint16_t machineNr, uint16_t borough, uint16_t zone, uint16_t alias, char *location) const { uint8_t buf[64]; tslib_strclr(buf,0,64); buf[0]=uint2uchar(customerNr, LOWBYTE); buf[1]=uint2uchar(customerNr, HIGHBYTE); buf[2]=uint2uchar(machineNr, LOWBYTE); buf[3]=uint2uchar(machineNr, HIGHBYTE); buf[4]=uint2uchar(borough, LOWBYTE); buf[5]=uint2uchar(borough, HIGHBYTE); buf[6]=uint2uchar(zone, LOWBYTE); buf[7]=uint2uchar(zone, HIGHBYTE); buf[8]=uint2uchar(alias, LOWBYTE); buf[9]=uint2uchar(alias, HIGHBYTE); tslib_strcpy(location, &buf[10], 32); longFDcmd_set(CMD2DC_SEND_MACH_ID,0,0,42,buf); } void hwapi::request_ReadbackMachineID() const { sendFDcmd_set(0,CMD2DC_RDBK_MACH_ID,0,0,0,0,0); } void hwapi::readback_machineIDdata(uint8_t *length, uint8_t *data) const { epi_restoreMachineIDsettings(length, data); } // .................................................................................... static uint16_t hwapi_shutterTime; // locks, 2.Level: (Motor stops automatical on end switch or by 5s timeout) uint8_t hwapi::lock_openUpperDoor(void) const { // paras: dat2: 1=upper door lock 2=lower // dat1: 1=open 2=close sendFDcmd_set(CMD2DC_UPPER_DOOR,0,0,1,0,0,0); return 0; } uint8_t hwapi::lock_closeUpperDoor(void) const { sendFDcmd_set(CMD2DC_UPPER_DOOR,0,0,2,0,0,0); return 0; } uint8_t hwapi::lock_openLowerDoor(void) const { sendFDcmd_set(CMD2DC_LOWER_DOOR,0,0,1,0,0,0); return 0; } uint8_t hwapi::lock_closeLowerDoor(void) const { sendFDcmd_set(CMD2DC_LOWER_DOOR,0,0,2,0,0,0); return 0; } void hwapi::shut_openOnce(void) const { // and close automatic after shutter time uint16_t zeit=hwapi_shutterTime; zeit/=100; sendFDcmd_set(CMD2DC_SHUTTER_OPEN3S, 0,0,uint8_t(zeit) ,0,0,0); } void hwapi::shut_openForCoin(bool start) const { // start=true: start opening flap if coin is attached // start=false: stop process uint16_t zeit=hwapi_shutterTime; zeit/=100; sendFDcmd_set(CMD2DC_SHUTTER_COIN, 0,0,uint8_t(start), uint8_t(zeit),0,0); } void hwapi::shut_sendOpeningTime(uint16_t timeIn_ms ) const { // after this time without retrigger the flap is closed hwapi_shutterTime=timeIn_ms; } void hwapi::esc_takeMoney(void) const { // and close automatically after escrow time (1s) sendFDcmd_set(CMD2DC_ESCR_TAKE,0,0,0,0,0,0); } void hwapi::esc_returnMoney(void) const { // and close automatically after time sendFDcmd_set(CMD2DC_ESCR_RETURN,0,0,0,0,0,0); } // ---------------------------------------------------------------------------------------------------------- // --------------------------------------------- MIFARE ----------------------------------------------------- // ---------------------------------------------------------------------------------------------------------- // fixed, 8.9.23 uint8_t hwapi::mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const { // retval 0=OK 1=error if (maxBufferSize<64) return 0; epi_restoreMifHwData(buf, 64); return 0; } bool hwapi::mif_readerIsOK(void) const { // return true if mifare reader is power, serial connected and is the correct one uint8_t mifData[66]; epi_restoreMifHwData(mifData, 66); /* stand 8.9.23 struct T_Mifare { UCHAR ReaderState; // 1: OK 0: not OK UCHAR res1; 2: UCHAR ReaderVersion[10]; 12: UCHAR CardPresent; UCHAR CardSelected; UCHAR Cardtype; UCHAR CardAllowed; // 0,1 nur Mifare Classic 1k und 4k zugelassen UCHAR CardSize; // 1 or 4 (kB) UCHAR LengOfUid; // 4 or 7 (byte) 18: UCHAR UID[8]; // 4 byte oder 7 byte, Format binär // 26 byte bis hier UCHAR res2; UCHAR res3; 28: ULONG UidH; // bei 4byte Uid alles 0 ULONG UidL; 36: UCHAR SectorLogged; // result of loggin: 2=success 3=failed 1=no_tag 8=addr overflow F0=wrongCmd UCHAR CurrentSector; UCHAR RD_WR_Result; UCHAR res4; // 40byte lang }; */ if (mifData[0]==0) return false; // Type=currently "SL025-1.8" if (mifData[2]=='S' && mifData[3]=='L' && mifData[4]=='0' && mifData[5]=='2' && mifData[6]=='5' ) return true; return false; } bool hwapi::mif_cardAttached(void) const // gefixt am 8.9.23 { return mif_cardIsAttached(); } uint8_t hwapi::mif_readResult(void) const // geht nicht { // 1: read card successful 0: not uint8_t mifData[66]; epi_restoreMifHwData(mifData, 66); /* stand 8.9.23 struct T_Mifare { UCHAR ReaderState; // 1: OK 0: not OK UCHAR res1; 2: UCHAR ReaderVersion[10]; 12: UCHAR CardPresent; UCHAR CardSelected; UCHAR Cardtype; UCHAR CardAllowed; // 0,1 nur Mifare Classic 1k und 4k zugelassen UCHAR CardSize; // 1 or 4 (kB) UCHAR LengOfUid; // 4 or 7 (byte) 18: UCHAR UID[8]; // 4 byte oder 7 byte, Format binär // 26 byte bis hier UCHAR res2; UCHAR res3; 28: ULONG UidH; // bei 4byte Uid alles 0 ULONG UidL; 36: UCHAR SectorLogged; // result of loggin: 2=success 3=failed 1=no_tag 8=addr overflow F0=wrongCmd UCHAR CurrentSector; UCHAR RD_WR_Result; UCHAR res4; // 40byte lang }; */ if (mifData[12]>0 && mifData[15]>0 && (mifData[16]==1 || mifData[16]==4) && (mifData[17]==4 || mifData[17]==7)) return 1; return 0; // error } QString hwapi::mif_cardUID(void) const // OK { // new, 8.9.23, works QString myStr; uint8_t mifData[66]; epi_restoreMifHwData(mifData, 66); myStr.clear(); // UID in buf[18...25] for (int ii=0;ii<8; ii++) { myStr+=QString::number(mifData[ii+18],16); myStr+=" "; // make a gap between numbers } return myStr; } uint8_t hwapi::mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const { // come in with cmd 28 return blkNr+buf[0]+maxBufferSize; // just to get rid of warning } QString hwapi::mif_getCardDataStr(uint8_t blockNumber) const { // come in with cmd 28 // with blockNumber=0...11 QString myStr; myStr.clear(); if (blockNumber>11) return myStr; else return myStr; } // ---------------------------------------------------------------------------------------------------------- // --------------------------------------------- PRINTER ---------------------------------------------------- // ---------------------------------------------------------------------------------------------------------- // already above: // void hwapi::prn_switchPower(bool on) 0x2A01 // bool hwapi::prn_readyINisActive(void) // bool hwapi::prn_isPrinterPowerOn(void) // void hwapi::request_PrinterHwState() 0x2A02 // void hwapi::request_PrinterCurrentFonts() 0x2A12 // void hwapi::request_PrinterStateComplete() // =request_PrinterHwState + request_PrinterCurrentFonts uint8_t hwapi::prn_getHwState(struct Tprn_hw_state *prn_hw_state) const { // return printer hardware state: power is on? rs-driver on? rs_switch ok? hw-ready-line ok? // printer on error or ok? return runProcess->prn_getHwState(prn_hw_state); } bool hwapi::prn_isUpAndReady(void) const { // 25.5.2023: geht nicht richtig :( bringt immer false obwohl Drucker OK struct Tprn_hw_state prnHwNow; prn_getHwState(&prnHwNow); if (prnHwNow.inIdle && prnHwNow.rsSwOk && prnHwNow.rsDrvOk && prnHwNow.powerRdBk ) return true; return false; } void hwapi::prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const { uint8_t prnFonts[22]; epi_restorePrinterFonts(&prnFonts[0]); prn_fonts->currFont = prnFonts[0]; prn_fonts->currSize = prnFonts[1]; prn_fonts->currHeigth= prnFonts[2]; prn_fonts->currWidth = prnFonts[3]; prn_fonts->nowBold = prnFonts[4]; prn_fonts->nowInvers = prnFonts[5]; prn_fonts->nowUnderlined= prnFonts[6]; prn_fonts->currDensity = prnFonts[7]; prn_fonts->currSpeed = prnFonts[8]; prn_fonts->nowAligned = prnFonts[9]; } void hwapi::prn_sendText(QByteArray *buf) const { uint16_t nn, pp, mm, leng_byt, leng_blk, llb, freeStak; uint8_t tmp66[66]; qCritical() << __PRETTY_FUNCTION__ << "RESET DC DATA VALID"; epi_clearDynMachineConditions(); // 24.6.23 gpi_storeDcDataValid(0); // komplett aendern 11.9.23 memset(tmp66,0,66); leng_byt=buf->size(); freeStak=check4freeFDstack(); freeStak<<=6; if ( leng_byt > freeStak) { leng_byt=freeStak; // shorten the buffer as we cannot return an error (void function) } llb=leng_byt % 64; // length of last block, >0 if not dividable by 64 leng_blk=leng_byt / 64; pp=0; for (nn=0; nnat(pp++); longFDcmd_set(CMD2DC_PRI_PRINT_TXT, 0,0,64, tmp66); } if (llb>0) { //leng_blk++; // z.B. 200 = 3 volle blocks und ein block mit nur 8byte memset(tmp66,0,66); for (mm=0; mmat(pp++); for (mm=llb; mm<64; mm++) tmp66[mm]=0; longFDcmd_set(CMD2DC_PRI_PRINT_TXT, 0,0,64, tmp66); } } void hwapi::prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const { // send three byte through to printer, see printers manual //sendWRcmd _setSendCommand8(SENDDIRCMD_PRN_SYS_CMD, para1, para2, 0, para3); hat gar nicht funktioniert uint8_t data[64]; uint32_t ultmp=para3; memset(data, 0,64); data[0]=para1; data[1]=para2; data[2]=0; data[3]=0; data[4]=uint8_t(ultmp); ultmp>>=8; data[5]=uint8_t(ultmp); ultmp>>=8; data[6]=uint8_t(ultmp); ultmp>>=8; data[7]=uint8_t(ultmp); longFDcmd_set(CMD2DC_PRI_SYS_CMD, 0, 0, 8, data); // getestet auf richtige uebertragung am 11.9.23TS } void hwapi::prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const { // send four byte through to printer, see printers manual sendFDcmd_set(CMD2DC_PRI_ESC_CMD, 0,0, para1, para2, para3, para4); } void hwapi::prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density, uint8_t alignment, uint8_t orientation) const { // send 5 byte: byte 0,1: speed 5...250 mm/s // byte2: density 0....(25)....50 // byte3: alignment 'l', 'c', 'r' = left, center, right // byte4: orientation 0, 90, 180 = 0°, 90°, 180° rotation (by now not supported!) // not batched! don't use twice within 100ms uint8_t buf[10]; uint16_t uitmp; uitmp=paperSpeed; buf[0]=uint8_t(uitmp); uitmp>>=8; buf[1]=uint8_t(uitmp); buf[2]=density; buf[3]=alignment; buf[4]=orientation; buf[5]=0; longFDcmd_set(CMD2DC_PRI_SETUP,0,0,5, buf); } void hwapi::prn_movePaper(uint8_t wayInMm, uint8_t direction) const { //direction: 1=forward 2=backward sendFDcmd_set(CMD2DC_PRI_MOVE, 0,0, wayInMm, direction, 0,0); } void hwapi::prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const { // font = kind of font 0...8 // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge // width: 0...4 0=1x 1=2x 2=4x (huge!) 3=8x 4=16x (3,4 make no sense) // heigth: 0...7 = 1x...8x only 0,1,2,(3) make sense sendFDcmd_set(CMD2DC_PRI_SETFONT, 0,0, font, size, width, height); } void hwapi::prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const { sendFDcmd_set(CMD2DC_PRI_SETLETTER, 0, 0, bold, invers, underlined, 0); } void hwapi::prn_cut(uint8_t kindof) const { // kindof = 1: full cut 2: partial cut 3=eject (5xLF + full cut) sendFDcmd_set(CMD2DC_PRI_CUT, 0,0, kindof,0,0,0); } void hwapi::prn_newLine(uint8_t nrOfLines) const { sendFDcmd_set(CMD2DC_PRI_LF, 0,0, nrOfLines, 0, 0, 0); } void hwapi::prn_printCompleteFontTable(void) const { sendFDcmd_set(CMD2DC_PRI_PRIFONTTABLE,0,0,0,0,0,0); } void hwapi::prn_printBarcode(uint8_t kindOf, uint8_t withText, uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const { uint8_t buf[66], nn; //uint16_t uitmp; if (dataLeng>58) dataLeng=58; buf[0]=kindOf; buf[1]=withText; buf[2]=offset; buf[3]=rotation; buf[4]=dataLeng; // rest: Barcode-data: for (nn=0; nnclear(); } void hwapi::prn_printQRcode(void) const { // which was sent before sendFDcmd_set(CMD2DC_PRI_QR_CODE,0,0,0,0,0,0); } void hwapi::prn_printLogo(uint8_t nrOfLogo, uint8_t offset ) const { sendFDcmd_set(CMD2DC_PRI_LOGOFROMFLASH, 0,0, nrOfLogo, offset, 0, 0); } // ......................................................... // Parking Ticket (print out) designer - obsolete // ......................................................... /* static QByteArray ticketTemplate; void hwapi::pri_startTicketDesign(void) const { ticketTemplate.clear(); } int hwapi::pri_TD_getCurrentSize(void) const { return ticketTemplate.size(); } bool hwapi::pri_TD_addText(QByteArray text) const { if ((ticketTemplate.length() + text.length())>1278) return false; ticketTemplate.append(text); qDebug()<<"\nText added "<1266) return false; ticketTemplate.append(tmpStr); return true; } */ //bool hwapi::pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const //{ // always add 8 byte to the ticket layout: ESC & group & attribute & parameter1...5 /* char tmpStr[10]; // command has always fixed length of 8 byte if (ticketTemplate.length()>1270) return false; if (group<50 || group>59) return false; if (attribute<10 || attribute>30) return false; tmpStr[0]=0x1B; // ESC tmpStr[1]=group; tmpStr[2]=attribute; tmpStr[3]=p1; tmpStr[4]=p2; tmpStr[5]=p3; tmpStr[6]=p4; tmpStr[7]=p5; ticketTemplate.append(tmpStr, 8); qDebug()<<"\ncmd added "<1277) return false; ticketTemplate.append("\n"); return true; } bool hwapi::pri_TD_addSign(char sign) const { if (ticketTemplate.length()>1277) return false; ticketTemplate.append(sign); return true; } char hwapi::prn_clearDocument(uint8_t documentNumber) const { if (documentNumber>15) return false; sendWRcmd_ setSendCommand4(SENDDIRCMD_PRN_CLEARDOC, documentNumber, 0, 0, 0); CMD2DC_PRI_CLEAR_DOC return true; } bool hwapi::prn_store_Document(uint8_t documentNumber ) const { // send to DC // documentNumber=0...15, stored in Eeprom // maximal 1280 bytes each // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc) // 0x1B=start of embedded command (next 7bytes = command) if (documentNumber>15) return false; sub_storeSendingText(&ticketTemplate); epi_storeUserOfSendingTextBuffer(3,documentNumber,0,0,0); // 3=store document return true; } bool hwapi::prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const { if (documentNumber>15) return false; epi_store64ByteSendData(64, &(dynTicketData->licensePlate[0])); sendWRcmd_ setSendCommand4(SENDDIRCMD_PRN_DOC, documentNumber, 0, 0, 0); return true; } */ // ---------------------------------------------------------------------------------------------------------- // ------------------------------------------- MDB Bus ------------------------------------------------------ // ---------------------------------------------------------------------------------------------------------- void hwapi::mdb_sendBusReset(void) const { //sendWRcmd_ setSendCommand4(SENDDIRCMD_MDB_RES, 0,0,0,0); sendFDcmd_set(CMD2DC_MDB_DORESET, 0,0, 0,0,0,0); } #define mdb_device_coinChk 0 #define mdb_device_changer 1 #define mdb_device_bill 2 //#define mdb_device_credit 3 // obsolete void hwapi::mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const { //sendWRcmd _setSendCommand4(SENDDIRCMD_MDB_SENDCMD, toMdbDevice, mdbCommand, 0,0); sendFDcmd_set(CMD2DC_MDB_SENDCMD, 0,0, toMdbDevice, mdbCommand, 0,0); } void hwapi::mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const { // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs uint8_t myBuf[64], ii; tslib_strclr(myBuf, 0, 64); myBuf[0]=toMdbDevice; myBuf[1]=mdbCommand; if (nrOfData>34) nrOfData=34; myBuf[2]=nrOfData; for (ii=0; ii>=8; myBuf[1]=uint8_t (uitmp); myBuf[2]=tokenChannel; pp=3; for (ii=0; ii<16; ii++) { uitmp=coinDenomination[ii]; myBuf[pp]=uint8_t(uitmp); uitmp>>=8; myBuf[pp+1]=uint8_t(uitmp); pp+=2; } longFDcmd_set(CMD2DC_EMP_SET,0,0,35, myBuf); } void hwapi::emp_pollingOnOff(uint8_t on) const { // on: 1=start polling the coin accepter 0=stop sendFDcmd_set(CMD2DC_EMP_STARTPOLL, 0,0, on,0,0,0); } void hwapi::emp_startCoinAcceptance(void) const { sendFDcmd_set(CMD2DC_EMP_STARTPAY, 0,0, 0,0,0,0); } void hwapi::emp_stopCoinAcceptance(void) const { sendFDcmd_set(CMD2DC_EMP_STOPPAY, 0,0, 0,0,0,0); } void hwapi::emp_getAllParameters(struct T_emp *emp) const { uint8_t leng, data[66], ii, pp; epi_restoreEmpSettings(&leng, data); // expected length = 64 byte // get 64 bytes about EMP: see h-file emp->gotSetup = data[0]; emp->state = data[1]; emp->shaft = data[2]; emp->countryCode= uchar2uint(data[4], data[3]); emp->scale = data[5]; emp->decimals = data[6]; for (ii=0; ii<16; ii++) emp->coinValues[ii] = data[7+ii]; emp->coinAccept = uchar2uint(data[24], data[23]); emp->tokenChannel = data[25]; emp->pollingRunning = data[26]; emp->paymentRunning = data[27]; pp=28; for (ii=0; ii<16; ii++) { emp->denomination[ii] = uchar2uint(data[pp+1], data[pp]); pp+=2; } emp->routing= uchar2uint(data[61], data[60]); } uint8_t hwapi::emp_chkIfCoinInserted(void) const { // retval: 0...16 coins left in FIFO return epi_isNewCoinLeft(); } void hwapi::emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const { epi_restoreEmpCoinSignal(valid, signal, error, value); } uint8_t hwapi::emp_giveLastCoin(uint16_t *value, uint8_t *signal) const { // retval: 0: NO coin stored 1: valid coin 2: got wrong coin or coin denied // value: if retval1: value of the coin if reval=2: error number // signal: channel nr reported from checker uint8_t valid, chan, error; uint16_t wert; epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert); if (valid && error==0xFF ) { *value=wert; *signal=chan; return 1; } if (valid && error<0xFF ) { *value=error; *signal=chan; // normally 0, but sometimes we get both return 2; } return 0; } uint8_t hwapi::emp_returnLastCoin(uint16_t *value, uint8_t *signal) const { // use this for coin changer uint8_t valid, chan, error; uint16_t wert; epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert); if (error) { *value=0; *signal=error; return 0; } *value=wert; *signal=chan; return valid; } QString hwapi::dc_getTxt4RsDiagWin(void) const { #ifdef THIS_IS_CA_MASTER return epi_getTxt4RsDiagWin(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clrTxt4RsDiagWin(void) const { #ifdef THIS_IS_CA_MASTER epi_clrTxt4RsDiagWin(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } QString hwapi::dc_get2ndTxt4RsDiagWin(void) const { #ifdef THIS_IS_CA_MASTER return epi_get2ndTxt4RsDiagWin(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clr2ndTxt4RsDiagWin(void) const { #ifdef THIS_IS_CA_MASTER epi_clr2ndTxt4RsDiagWin(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } QString hwapi::dc_getTxt4HsStateLine(void) const { #ifdef THIS_IS_CA_MASTER // Crash! return epi_getTxt4HsStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clrTxt4HsStateLine(void) const { #ifdef THIS_IS_CA_MASTER epi_clrTxt4HsStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } QString hwapi::dc_getTxt4masterStateLine(void) const { #ifdef THIS_IS_CA_MASTER return epi_getTxt4masterStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clrTxt4masterStateLine(void) const { #ifdef THIS_IS_CA_MASTER epi_clrTxt4masterStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } QString hwapi::dc_getTxt4resultStateLine(void) const { #ifdef THIS_IS_CA_MASTER return epi_getTxt4resultStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clrTxt4resultStateLine(void) const { #ifdef THIS_IS_CA_MASTER epi_clrTxt4resultStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } QString hwapi::dc_getdataStateLine(void) const { #ifdef THIS_IS_CA_MASTER return epi_getTxt4dataStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clrTxt4dataStateLine(void) const { #ifdef THIS_IS_CA_MASTER epi_clrTxt4dataStateLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } QString hwapi::dc_getdatifLine(void) const { #ifdef THIS_IS_CA_MASTER return epi_getTxt4datifLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; return ""; #endif } void hwapi::dc_clrTxt4datifLine(void) const { #ifdef THIS_IS_CA_MASTER epi_clrTxt4datifLine(); #else qCritical()<<"hwapi: error CAslave cannot use serial"; #endif } // ---------------------------------------------------------------------------------------------------------- // -------- DC Bootloader 1.Version // obsolete // ---------------------------------------------------------------------------------------------------------- // obsolete void hwapi::bl_iniChain(void) const { } // obsolete bool hwapi::bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const { // copy file from QByteArray into local buffer for sending to DC // calculate size, nr_of_blocks and crc // just for special usage return dcBL_importBinFile(readBinFile, fileSize, withDispl); } // obsolete uint8_t hwapi::bl_activatBootloader(uint8_t *sendData) const { //return dcBL_activatBootloader(sendData); // just for special usage return sendData[0]; } // obsolete uint8_t hwapi::bl_startChain(void) const { // obsolete //return dcBL_startChain(); return 0; } // obsolete uint8_t hwapi::bl_readBLversion(uint8_t *sendData) const { // minimum size of sendData-buffer: 5byte retval: length // just for special usage return dcBL_readBLversion(sendData); } // obsolete uint8_t hwapi::bl_readFWversion(uint8_t *sendData) const { // minimum size of sendData-buffer: 5byte retval: length return dcBL_readFWversion(sendData); } // obsolete uint8_t hwapi::bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const { // just for very special usage // make BL protocol, retval = outbuf length (5...133) // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 // Data length = 0...64 // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 return dcBL_prepareDC_BLcmd(Cmd, SendDataLength, sendData, outBuf); } // obsolete uint8_t hwapi::bl_exitBL(uint8_t *sendData) const { // returns command to be sent to DC-BL in order to stop the BL // just for very special usage // minimum size of sendData-buffer: 5byte retval: length return dcBL_exitBL(sendData); } // obsolete void hwapi::led_switchLedIllumination(uint8_t on) const { sendFDcmd_set(CMD2DC_LED_IN, CMD2DC_RdBkAllOutputs, 0, on, 0, 0, 0); } // ------------------------------------------------------------------------------------ // 27.3.2023: Use Device-Controller's Bootloader to send hex-file // ------------------------------------------------------------------------------------ void hwapi::bl_rebootDC(void) const // tested 26.09.2023 { // send command to normal DC-Program requesting a restart // BL is working for 5s after power-on-reset. runProcess->bl_rebootDC(); } void hwapi::bl_startBL(void) const // tested 26.09.2023 { // use this function within the first 5s after reboot to startup the BL, // otherwise the BL jumps to normal DC application runProcess->bl_startBL(); } void hwapi::bl_checkBL(void) const // tested 26.09.2023 { // call this function in order to get information, afterwards use "bl_isUp()" runProcess->bl_checkBL(); } bool hwapi::bl_isUp(void) const // tested 26.09.2023 { return runProcess->bl_isUp(); } // obsolete, better use auto function listed further down void hwapi::bl_sendAddress(uint16_t blockNumber) const { // send start address, nr of 64byte-block, start with 0 // will be sent only for folling block-numbers: // 0, 1024, 2048, 3072 and 4096, so basically every 64kByte uint32_t dcBL_BlkCtr=(uint32_t)blockNumber; uint8_t len, buf[20]; tslib_strclr(buf, 0, 20); if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096) { dcBL_BlkCtr*=64; len=dcBL_sendFlashStartAddr2BL(dcBL_BlkCtr, buf); // make command string // minimum size of sendData-buffer: 13byte retval: length (9...13) sendWRcmd_setSendBlock160(len, buf); // send command to BL } } // obsolete, better use auto function listed further down uint8_t hwapi::bl_wasSendingAddOK(void) const { // return val: 0: no response by now 1:error 10: OK return dcBL_sendSuccess(0x21); } void hwapi::bl_openBinary(void) const { } // obsolete, better use auto function listed further down void hwapi::bl_sendDataBlock(uint8_t length, uint8_t *buffer) const { // send 64 byte from bin file uint8_t LL=length, sendBuf[80], sendLen; if (LL>64) LL=64; tslib_strclr(sendBuf,0,80); sendLen=dcBL_prepareDC_BLcmd(0x22, LL, buffer, sendBuf); // pack into protocol frame sendWRcmd_setSendBlock160(sendLen, sendBuf); // send 140 bytes delay(100); } // obsolete, better use auto function listed further down void hwapi::bl_sendLastBlock(void) const { uint8_t len, buf[20]; len=dcBL_writeLastPage(buf); sendWRcmd_setSendBlock160(len, buf); } // obsolete, better use auto function listed further down uint8_t hwapi::bl_wasSendingDataOK(void) const { // return val: 0: no response by now 1:error 10: OK return dcBL_sendSuccess(0x22); } void hwapi::bl_stopBL(void) const // tested 26.09.2023 { uint8_t len, buf[20]; len=dcBL_exitBL(buf); sendWRcmd_setSendBlock160(len, buf); epi_setNowIsBootload(false); } // ------------------------------------------------------------------------------------ // 6.4.2023: new functions for coin collection and printing // some new system functions // ------------------------------------------------------------------------------------ // use: // bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4); // write Command to memory, wait for transport // bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data); // write Command to memory, wait for transport // data buffer size always 64! data[64], padded with 0 bool hwapi::rtc_setTimeDateDirect(struct Trtc_DateTime *DateTime) const { // return true if successful. could fail if more the 8 commands are waiting uint8_t temp[66]; bool b_ret; /* in interfaces.h: struct Trtc_DateTime { uint8_t rtc_hour; uint8_t rtc_min; uint8_t rtc_sec; uint8_t rtc_dayOfMonth; uint8_t rtc_month; uint8_t rtc_year; uint8_t rtc_dayOfWeek; }; */ tslib_strclr(temp,0,66); temp[0]= DateTime->rtc_hour; temp[1]= DateTime->rtc_min; temp[2]= DateTime->rtc_sec; temp[3]= 20; temp[4]= DateTime->rtc_year; temp[5]= DateTime->rtc_month; temp[6]= DateTime->rtc_dayOfMonth; temp[7]= DateTime->rtc_dayOfWeek; b_ret=longFDcmd_set(20,0,0,8,temp); return b_ret; } bool hwapi::rtc_getExtendedTime(uint8_t *leng, uint8_t *data) const { epi_restoreExtendedTime(leng, data); return true; /* buf[0]=GlobTime.Hours; buf[1]=GlobTime.Min; buf[2]=GlobTime.Sec; buf[3]=GlobTime.Year; buf[4]=GlobTime.Month; buf[5]=GlobTime.Day; buf[6]=GlobTime.DOW; buf[7]=' '; // immer auf 32bit auffüllen sonst Speicherproblem beim Master! uitmp=GlobTime.MinOfDay; buf[8]=swl_getOneByteFromUint(uitmp, 0); buf[9]=swl_getOneByteFromUint(uitmp, 1); buf[10]=' '; buf[11]=' '; ultmp=GlobTime.SecOfDay; buf[12]=swl_getOneByteFromUlong(ultmp, 0); buf[13]=swl_getOneByteFromUlong(ultmp, 1); buf[14]=swl_getOneByteFromUlong(ultmp, 2); buf[15]=swl_getOneByteFromUlong(ultmp, 3); buf[16]=swl_isLeap(GlobTime.Year); buf[17]=swl_getNextLeapYear(GlobTime.Year); buf[18]=swl_getLastLeapYear(GlobTime.Year); buf[19]=swl_hoursOfThisWeek(GlobTime.DOW, GlobTime.Hours); uitmp=swl_minutesOfThisWeek(GlobTime.DOW, GlobTime.Hours, GlobTime.Min); buf[20]=swl_getOneByteFromUint(uitmp, 0); // 0=low byte 1=high byte buf[21]=swl_getOneByteFromUint(uitmp, 1); uitmp=swl_hoursOfThisMonth(GlobTime.Day, GlobTime.Hours); buf[22]=swl_getOneByteFromUint(uitmp, 0); buf[23]=swl_getOneByteFromUint(uitmp, 1); uitmp=swl_minutesOfThisMonth(GlobTime.Day, GlobTime.Hours, GlobTime.Min); buf[24]=swl_getOneByteFromUint(uitmp, 0); buf[25]=swl_getOneByteFromUint(uitmp, 1); uitmp=swl_GetDaysOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day); buf[26]=swl_getOneByteFromUint(uitmp, 0); buf[27]=swl_getOneByteFromUint(uitmp, 1); uitmp=swl_GetHoursOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day, GlobTime.Hours); buf[28]=swl_getOneByteFromUint(uitmp, 0); buf[29]=swl_getOneByteFromUint(uitmp, 1); buf[30]=0; buf[31]=0; ultmp= swl_GetMinutesOfYear(GlobTime.Year, GlobTime.Month, GlobTime.Day, GlobTime.Hours, GlobTime.Min); buf[32]=swl_getOneByteFromUlong(ultmp, 0); buf[33]=swl_getOneByteFromUlong(ultmp, 1); buf[34]=swl_getOneByteFromUlong(ultmp, 2); buf[35]=swl_getOneByteFromUlong(ultmp, 3); buf[36]=rtc_getSqwaveSettings(); buf[37]=0; buf[38]=0; buf[39]=0; ultmp= 0; // Minutes of the Millenium buf[40]=swl_getOneByteFromUlong(ultmp, 0); buf[41]=swl_getOneByteFromUlong(ultmp, 1); buf[42]=swl_getOneByteFromUlong(ultmp, 2); buf[43]=swl_getOneByteFromUlong(ultmp, 3); dc2prot_setReadData(44, buf); */ } bool hwapi::rtc_getExtendedTime(struct T_extTime *exTime) const { uint8_t len; uint16_t LL, nn; uint8_t *start; uint8_t buf[66]; epi_restoreExtendedTime(&len, buf); // Puffer in struct eintragen: LL=sizeof(struct T_extTime); start = &(exTime->Hours); nn=0; do { *start = buf[nn]; start++; } while(++nn800) dateiLang=800; tslib_strcpy(content, inhaltOfJson, dateiLang); // enthaelt genaue Laenge, Rest =0 nrOfBlocks=dateiLang/64; if (dateiLang%64>0) nrOfBlocks++; dateiLang=nrOfBlocks; dateiLang<<=6; // auf volle 64byte aufgerundet // check free memory frei=check4freeFDstack(); // Command-Stack sollte 16 Commands fassen, je 64byte Nutzdaten = 1024byte // frei gibt also die Anzahl freier 64byte Bloecke zurueck // das Json-File hat max 800 byte = 13 bloecke if (frei<16) // Puffer muss ganz leer sein! nicht dass was durcheinander kommt return false; // Start- und Stop auch als langes Kommando schicken // PROBLEM: wuerden sie in einem anderen Batch gespeichert (short command stack), // dann kann die Reihenfolge nicht gewaehrleistet werden // Das Startkommando muss sicher zuerst kommen // Das Abschlusskommando muss sicher zuletzt kommen tslib_strclr(temp,0,65); temp[0]=dateiArt; temp[1]=NummDesTempl; longFDcmd_set(30, 0,0, 2,temp); // sende "Starte-file-DL" uitmp=0; bn=0; do { biox_CopyBlock(inhaltOfJson, uitmp, temp, 0, 64); longFDcmd_set(31,0, bn++, 64, temp); //uitmp<<=6; // falsch uitmp+=64; } while(uitmp < dateiLang); longFDcmd_set(32, 0,0, 0,temp); // Abschluss return true; } static uint8_t lastSentDynData[64]; //char prn_dynPrnVal[8][8]; bool hwapi::prn_sendDynamicPrnValues(uint8_t *dynPrnVal ) const { // dynPrnVal = array of 8 Variables with 8 byte each, come as ascii string // like: char prn_dynPrnVal[8][8]; // return true if sending, false if cmd-stack is full //uint8_t temp[66]; //tslib_strcpy(dynPrnVal, temp, 64); // Vorsicht, kann \0en enthalten memcpy(lastSentDynData, dynPrnVal, 64); return longFDcmd_set(33,39,0, 64, lastSentDynData); } bool hwapi::prn_printTemplate(uint8_t nrOftemplate) const // print one of the templates loaded by Json prior // nr = 1..32 { // return true if sending, false if cmd-stack is full qCritical() << __PRETTY_FUNCTION__ << "RESET DC DATA VALID"; epi_clearDynMachineConditions(); // 24.6.23 gpi_storeDcDataValid(0); return sendFDcmd_set(152, 0,0, nrOftemplate,0,0,0); } void hwapi::log_getHoldAccountNumbers(uint8_t *nrOfVals, uint16_t *accNr ) const { // returns all acc nrs of the backuped vault records // use: uint16_t backupedAccNumbers[8] epi_restoreDCbackupAccNr(nrOfVals, accNr); } bool hwapi::log_selectVaultRecord(uint16_t accountNr ) const { // return true if sending, false if cmd-stack is full // and trigger transfer uint8_t dat1, dat2; bool ret; uint8_t frei=check4freeFDstack(); if (frei<8) return false; sendFDcmd_clrStack(); epi_startSupervision(); epi_iniVRstorage(); dat1=uint2uchar(accountNr, LOWBYTE); dat2=uint2uchar(accountNr, HIGHBYTE); ret=sendFDcmd_set(153, 0,0, dat1,dat2,0,0); // select this record // true means "will be sent" sendFDcmd_set(0,38,0, 0,0,0,0); // return VaultRecord block-Nr.0 sendFDcmd_set(0,38,1, 0,0,0,0); // return VaultRecord block-Nr.1 sendFDcmd_set(0,38,2, 0,0,0,0); // return VaultRecord block-Nr.2 sendFDcmd_set(0,38,3, 0,0,0,0); // return VaultRecord block-Nr.3 sendFDcmd_set(0,38,4, 0,0,0,0); // return VaultRecord block-Nr.4 sendFDcmd_set(0,38,5, 0,0,0,0); // return VaultRecord block-Nr.5 // 38: <100 to get long 64byte response return ret; } bool hwapi::log_chkIfVaultRecordAvailable(void) const { // return true if completly received if ( epi_checkIfVaultRecordAvailable() ) { return true; } return false; } //uint8_t hwapi::log_getAvailableVaultBlocks(void) const bool hwapi::log_getVaultRecord(struct T_vaultRecord *retVR) const // which was selected by: log_selectVaultRecord() // to be forwarded to Ismas // return true if completly received { #define MAXLENOFVAULTREC 400 uint16_t LL, nn, len; char *start; uint8_t buf[MAXLENOFVAULTREC]; bool ret; ret=epi_restoreVaultRecord(&len, buf); // true if completly received if (ret==false) return false; // Puffer in struct eintragen: LL=sizeof(struct T_vaultRecord); if (LL>MAXLENOFVAULTREC) LL=MAXLENOFVAULTREC; start = &retVR->startbuffer[0]; nn=0; // 14.9.23 neu: Datensatz erst pruefen, [0..3] enthaelt "Psa>" und [4,5 =Abr.Nr] uint16_t ds_acc_nr=uchar2uint(buf[5], buf[4]); if (buf[0]=='P' && buf[1]=='s' && buf[2]=='a' && buf[3]=='>' && ds_acc_nr<60000) { // valid data, copy data to struct do { *start = buf[nn]; start++; } while(++nncash_startPayment(amount); } uint8_t hwapi::cash_paymentProcessing(void) const { // no need to use // will be called automatically uint8_t collActiv=0; collActiv = runProcess->cash_paymentProcessing(); return collActiv; } uint32_t hwapi::getInsertedAmount(void) const { uint32_t ultmp; ultmp=epi_CurrentPaymentGetAmount(); if (ultmp>65000) ultmp=0; // 19.6.23 qDebug() << "current inserted amount: "<< ultmp; return ultmp; } uint16_t hwapi::getLastInsertedCoin(void) const { uint32_t ultmp; ultmp=epi_CurrentPaymentGetLastCoin(); qDebug() << "last inserted coin: "<< ultmp; return ultmp; } bool hwapi::getAllInsertedCoins(uint16_t *types, uint16_t *values) const { // alle bei diesem Verkauf eingeworfenen Münzen sind gespeichert, max 64 return epi_CurrentPaymentGetAllCoins(types, values); } bool hwapi::cash_cancelPayment(void) const // and return coins { // DB1: 1=encash 2=cancel & return coins // 3=stop and keep coins in escrow //epi_setNowCoinPay(false); // new since 20.9.23 // am 6.12.23 wieder raus, waehrend Druck und wechseln auch schnell abfragen //qCritical() << "cash cancel payment and return coins"; return sendFDcmd_set(156, 0,0, 2,0,0,0); } bool hwapi::cash_stopPayment(void) const // and keep coins in escrow { // DB1: 1=encash 2=cancel & return coins // 3=stop and keep coins in escrow //epi_setNowCoinPay(false); // new since 20.9.23 // am 6.12.23 wieder raus, waehrend Druck und wechseln auch schnell abfragen //qCritical() << "cash stop payment and keep coins in escrow"; // qCritical() << "emitting signal StopByPushbutton 2"; emit hwapi_payStopByPushbutton(); return sendFDcmd_set(156, 0,0, 3,0,0,0); } // after ticket/goods issue: bool hwapi::vend_success(void) const // conclude payment process, encash all inserted coins to vault. Printing was successful // if possible return change { // DB1: 1=encash 2=cancel & return coins // 3=stop and keep coins in escrow epi_setNowCoinPay(false); // new since 20.9.23 //qCritical() << "printing finished, encash coins"; return sendFDcmd_set(156, 0,0, 1,0,0,0); } bool hwapi::vend_failed(void) const // conclude payment process and return all inserted coins { // DB1: 1=encash 2=cancel & return coins // 3=stop and keep coins in escrow epi_setNowCoinPay(false); // new since 20.9.23 //qCritical() << "printing failed, encash coins"; return sendFDcmd_set(156, 0,0, 2,0,0,0); } // obsolete uint8_t hwapi::mif_getCardType(QString *cardholder) const { // return 1,2,3,4 = upper, lower access card, printer test, coin test // cardholder: 7byte Name-String uint8_t type=0, nn; // buf[8], char ctmp=0; for (nn=0;nn<8; nn++) { cardholder[nn]=ctmp; } return type; } uint64_t hwapi::sys_getWakeSource(void) const { // retval: 6 bytes, bit coded, 1=event keeps DC awake return epi_getWakeSources(); } uint8_t hwapi::sys_getWakeReason(void) const { // Master was woken by following reason: // 1: MDB Event // 2: Coin Event // ( 3: Master Event) - will not set the wake line // ( 4: 32s pulse) - will not set the wake line // 5: Door Event // ( 6: Diag Event) - will not set the wake line // 7: 30min-Pulse for HB return epi_getWakeReason(); } void hwapi::sys_getDeviceConditions(uint8_t *leng, uint8_t *data) const { //uint8_t leng, data[66]; epi_restoreDeviceConditions(leng, data); } void hwapi::sys_getDeviceConditions(struct T_moduleCondition *devCond) const { uint16_t LL, nn; uint8_t *start; uint8_t buf[70], leng; epi_restoreDeviceConditions(&leng, buf); // Puffer in struct eintragen: LL=sizeof(struct T_moduleCondition); start = &devCond->ram; nn=0; do { *start = buf[nn]; start++; } while(++nnprinter=200; // not connected else if (zustand & 0x1C) devCond->printer=201; // on error else if (zustand & 0x02) devCond->printer=202; // no paper else if (zustand & 0x01) devCond->printer=100; // low paper // ------------------ end of patch ------------------------------------------------- } void hwapi::sys_getDynMachineConditions(uint8_t *leng, uint8_t *data) const { epi_restoreDynMachineConditions(leng, data); } void hwapi::sys_getDynMachineConditions(struct T_dynamicCondition *dynMachCond) const { uint16_t LL, nn; char *start; uint8_t buf[70], leng; epi_restoreDynMachineConditions(&leng, buf); // Puffer in struct eintragen: LL=sizeof(struct T_dynamicCondition); start = &dynMachCond->allDoorsDebounced; nn=0; do { *start = buf[nn]; start++; } while(++nnkindOfPrinter; nn=0; do { buf[nn] = *start; start++; } while(++nnepi_restore64BdevParameter(&LL, buf); // wozu die??? epi_restoreRbDeviceSettings(&LL, buf); // viel besser, stimmt immer // Puffer in struct eintragen: start = &deviceSettings->kindOfPrinter; nn=0; do { *start = buf[nn]; start++; } while(++nn8)) return false; qCritical() << __PRETTY_FUNCTION__ << "RESET DC DATA VALID"; epi_clearDynMachineConditions(); // 24.6.23 gpi_storeDcDataValid(0); return sendFDcmd_set(158, 0,0, nrOfKombi,0,0,0); } void hwapi::lock_triggerUpperSolenoid(void) const { sendFDcmd_set(159, 0,0, 0,0,0,0); } void hwapi::lock_triggerLowerSolenoid(void) const { sendFDcmd_set(160, 0,0, 0,0,0,0); } bool hwapi::doors_supervise(void) const { // no need to use // will be called automatically // new from 2023.06.12, generate some signals: //virtual void hwapi_ doorServiceDoorOpened(void) const=0; //virtual void hwapi_ doorVaultDoorOpened(void) const=0; //virtual void hwapi_ doorCBinAndAllDoorsClosed(void) const=0; //virtual void hwapi_ doorAllDoorsClosed(void) const=0; //virtual void hwapi_ doorCoinBoxRemoved(void) const=0; return runProcess->doors_supervise(); } bool hwapi::dc_isAutoRequestOn(void) const { return gpi_isEmmisionOn(); } uint16_t hwapi::log_getLatestAccountNumber(void) const { // new function 27.6.2023 // latest = highest, by now 8 records are stored in DC, prepare for 32 #define maxNrElements 8 uint8_t anz, nn; uint16_t nummern[maxNrElements], highest=0; memset(nummern, 0, sizeof(uint16_t)*maxNrElements); log_getHoldAccountNumbers(&anz, nummern); if (anz>maxNrElements) anz=maxNrElements; for (nn=0; nnhighest) highest=nummern[nn]; return highest; } uint8_t hwapi::log_getAvailableVaultBlocks(void) const { // return 0x0011 1111 if all 6 blocks arer loaded (one bit per block) return epi_getLoadedVaultBlocks(); } uint8_t hwapi::log_getAnswerToLastSlaveRequest(void) const { // use only for ONE request/command // return: 0xFF: result unknown // 0=OK // 1= wrong length 2=wrong start sign 5= wrong crc // 6= slave: master cmd was wrong 7: slave: could not write/read data // 8=timeout, got no response from slave return epi_getLastResult(); } // use for important and extended commands (print more templates, print ticket...) void hwapi::log_startSupervision(void) const { epi_startSupervision(); } uint8_t hwapi::log_getAnswerToLastCmdBatch(void) const { // 0xFF: no command sent by now // 0: started, in progress // 1: done and OK // 2: done and error return epi_getBatchResult(); } bool hwapi::log_getVaultData(uint8_t *data) const { // get vault record in linear 8bit buffer with 384 byte uint16_t len=384; uint8_t buf[400]; bool ret; int nn; ret=epi_restoreVaultRecord(&len, buf); if (ret==false) return false; // 14.9.23 neu: Datensatz erst pruefen, [0..3] enthaelt "Psa>" und [4,5 =Abr.Nr] uint16_t ds_acc_nr=uchar2uint(buf[5], buf[4]); if (buf[0]=='P' && buf[1]=='S' && buf[2]=='A' && buf[3]=='>' && ds_acc_nr<60000) { // valid data, return data for (nn=0; nn<384; nn++) data[nn]= buf[nn]; return true; } else { // wrong data, clear array for (nn=0; nn<384; nn++) data[nn]=0; return false; } return false; } // new from 1.8.23 bool hwapi::prn_printOneAccountReceipt(uint16_t accountNr) const { qCritical() << __PRETTY_FUNCTION__ << "RESET DC DATA VALID"; // print one out of eight stored last accounting receipts // function log_getHoldAccountNumbers() gives a list of acc-Nr. of the stored receipts epi_clearDynMachineConditions(); // 24.6.23 gpi_storeDcDataValid(0); uint8_t frei=check4freeFDstack(); if (frei<2) return false; uint8_t dat1, dat2; dat1=uint2uchar(accountNr, LOWBYTE); dat2=uint2uchar(accountNr, HIGHBYTE); sendFDcmd_set(153, 0,0, dat1,dat2,0,0); // select this record sendFDcmd_set(161, 0,0, 0,0,0,0); // print this return true; } bool hwapi::prn_printAllAvailAccountReceipts(void) const { // same as: prn_printAccountReceipt() from line 1153 // return true if sending to DC OK, false if cmd-stack is full return prn_printAccountReceipt(); } uint16_t biox_crc_xmodem_update(uint16_t crc, uint8_t data) { // berechne CRC16 XModem nach Polynom x^16 + x^12 + x^5 + 1 int i; crc = crc ^ ((uint16_t)data << 8); for (i=0; i<8; i++) { if (crc & 0x8000) crc = (crc << 1) ^ 0x1021; else crc <<= 1; } return crc; } //bool hwapi::log_verifyVaultRecordByCrc(struct T_vaultRecord *retVR) const bool hwapi::log_verifyVaultRecordByCrc(void) const { // return true if CRC16 is correct, data are 100% OK. Security level 1:65536 // verification is strongly recommended before further processing // in case of "false"-result please reload from DC uint16_t myChkSum=0, nn, myOldSum=0, recCheckSum=0; uint16_t LL=332; //320; // in DC noch falsch, sollte 332 sein uint8_t val; uint8_t data[400]; memset(data,0,400); log_getVaultData(data); for (nn=0; nn=64) { epi_restoreMifAtbData(mifData, 66); for (nn=0; nn<64; nn++) buf[nn]=mifData[nn]; return true; } return false; } bool hwapi::mif_isValidAtbCard(void) const { uint8_t receivedData[66], nn; //uint32_t mifatb_cunu, mifatb_cardnu, mifatb_creditAmount, mifatb_creditTime; //QString mifatb_cardTyp, mifatb_lpr, mifatb_group, mifatb_zone; //uint8_t mifatb_times[10]; uint8_t lprbuff[20]; bool ret; epi_restoreMifAtbData(receivedData, 66); for (nn=0; nn<16; nn++) { lprbuff[nn]=char(receivedData[12+nn]); //mifatb_lpr.append(char(receivedData[12+nn])); // "AtbPsa1256Ptu5_!" = recognition ATB card } /* //mifatb_lpr.clear(); mifatb_cunu=uchar2ulong(receivedData[3], receivedData[2],receivedData[1],receivedData[0]); // 281 mifatb_cardnu=uchar2ulong(receivedData[7], receivedData[6],receivedData[5],receivedData[4]); // always 0, not used mifatb_cardTyp.clear(); for (nn=0; nn<4; nn++) mifatb_cardTyp.append(char(receivedData[8+nn])); // = "PREP" no idea what that means mifatb_group.clear(); for (nn=0; nn<8; nn++) mifatb_group.append(char(receivedData[28+nn])); // "7x§0 TPf" used for card type mifatb_zone.clear(); for (nn=0; nn<8; nn++) mifatb_zone.append(char(receivedData[36+nn])); // "PNsax001" used for personal number and shortcode for (nn=0; nn<10; nn++) mifatb_times[nn]=receivedData[44+nn]; // 0..9: (Start) day, month, year, hh, min (Stop) day, month, year, hh, min, mifatb_creditAmount= uchar2ulong(receivedData[57], receivedData[56],receivedData[55],receivedData[54]); // is used as expire date/time mifatb_creditTime = uchar2ulong(receivedData[61], receivedData[60],receivedData[59],receivedData[58]); // always 0 // qDebug()<<"got MifAtbData: "<bl_completeStart(); //hwapi_triggerBL->start(100); return true; } // select binfile-name in GUI // send binfile-name to BL-processor: bool hwapi::bl_storeFirmware(QString fileName) const { // load binary file 3x and compare // return true if loaded correctly // return false: error, could not load correctly return dcBL_loadBinSafe(fileName); } // request the number of blocks for this file uint16_t hwapi::bl_getNrOfFirmwareBlocks(void) const { // size of the loaded bin file in 64byte blocks // call after bl_storeFirmware() return dcBL_getNrOfBlocks(); } // call this function with "blockNumber"=0,1,2,3.....bl_getNrOfFirmwareBlocks //the last block "bl_getNrOfFirmwareBlocks()" is sent as conclusion command (important!) bool hwapi::bl_blockAutoLoad(uint16_t blockNumber) const { // call in loop from block number 0 up to <= "dcBL_getNrOfBlocks()" // but after every call WAIT (!) for response "bl_blockAutoResponse()" !!!! // data will be sent to DC, if neccesary addr will be sent additionally // if neccesary sending will automatically repeat up to 3times // retval: false if blockNumber>4095, true else return dcBL_sendOneBlockCpl(blockNumber); } // check out this response after every block-sending, wait until >0!!! int8_t hwapi::bl_blockAutoResponse(void) const { // after every "bl_blockAutoLoad()" call this until response // retval 0: wait 1: OK, blk was sent 2: OK, transfer complete // 3: error despite repeating, cancel. probably bin file corrupted // Max duration: 3x no response from BL = 900ms return dcBL_getBlockResult(); } // finally call: // void hwapi::bl_stopBL(void) const // -------------- end of bootloader --------------------------------------------------- // new from 28.9.23 and earliest from DC version 4.45 // get all versions of the DC-Jsons void hwapi::sys_requestJsonVersions(uint8_t jsonNr) const { // send one request for every single version // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. // 5=printer template 1 ..... 36= template 32 sendFDcmd_set(0, 21, jsonNr,0,0,0,0); } void hwapi::sys_getJsonVersions(uint8_t jsonNr, char *versionString) const { epi_getJsonVersion(jsonNr, versionString); // jsonNr=1...36, 1=config file (cust.Nr) 2=devices 3=cash 4=res. // 5=printer template 1 ..... 36= template 32 // length of buffer is always 16 byte } // ------------------------------------------------------------------------------------ // Coin Changer // ------------------------------------------------------------------------------------ void hwapi::changer_returnCoins(uint32_t amountInCent) const { // command to give change uint8_t buff[8]; buff[0]=ulong2uchar(amountInCent, 0); //LOWBYTE buff[1]=ulong2uchar(amountInCent, 1); //buff[2]=ulong2uchar(amountInCent, 2); //buff[3]=ulong2uchar(amountInCent, 3); // HIGHBYTE // repeat for security: buff[2]=ulong2uchar(amountInCent, 0); //LOWBYTE buff[3]=ulong2uchar(amountInCent, 1); //buff[6]=ulong2uchar(amountInCent, 2); //buff[7]=ulong2uchar(amountInCent, 3); // HIGHBYTE // longFDcmd_set(169, 0,0, 4,buff); // short cmd max 4 byte! sendFDcmd_set(169,0,0,buff[0], buff[1], buff[2], buff[3]); } void hwapi::changer_requestChangeResult(void) const { sendFDcmd_set(0, 115,0, 0,0,0,0); } uint8_t hwapi::changer_getChangeResult(uint32_t *returnedAmount) const { return epi_getChangerResult(returnedAmount); // get result of coin dispensing // receivedData[0]: 0: not yet started 1:amount returned // 2:only partial return 3: no return possible // receivedData[2,3,4,5]: returned amount } void hwapi::changer_getAllParameters(struct T_changer *mw) const { // requested automatically with 23, same like EMP uint8_t leng, data[66], pp, nn; epi_restoreEmpSettings(&leng, data); // expected length = 64 byte // get 64 bytes about Changer (mw), see interfaces.h-file mw->setup = data[0]; mw->state = data[1]; mw->level = data[2]; mw->countryCode = uchar2uint(data[4], data[3]); mw->scale = data[5]; mw->decimals= data[6]; for (nn=0; nn<16; nn++) mw->coinSetup[nn]= data[nn+7]; // 7...22 mw->intendedAcceptance = uchar2uint(data[24], data[23]); mw->tokenChannel= data[25]; mw->pollingRunning= data[26]; mw->paymentRunning= data[27]; pp=28; for (nn=0; nn<16; nn++) { mw->denomination[nn] = uchar2uint(data[pp+1], data[pp]); pp+=2; } // bis pp=60 mw->availableTubes = uchar2uint(data[61], data[60]); } void hwapi::changer_requestTubelevel(void) const { sendFDcmd_set(0, 40,0, 0,0,0,0); } void hwapi::changer_getTubelevel(struct T_chg_Tub *tubLevel) const { // don't use tubeDispens[], it's not yet correct! uint16_t LL, nn; uint8_t *start; uint8_t buf[66]; epi_restoreTubeLevel(buf); // Puffer in struct eintragen: LL=sizeof(struct T_chg_Tub); start = &(tubLevel->tubeLevel[0]); nn=0; do { *start = buf[nn]; start++; } while(++nnsetup=buf[0]; bna->FeatureLevel=buf[1]; bna->countryCode=uchar2uint(buf[3], buf[2]); bna->scalingFactor=uchar2uint(buf[5], buf[4]); bna->decimalPlace=buf[6]; bna->pad1=0; bna->stackerCap=uchar2uint(buf[8], buf[7]); bna->billSecureLevel=uchar2uint(buf[10], buf[9]); bna->hasEscrow=buf[11]; for (nn=0; nn<16; nn++) bna->accBillTypes[nn] = buf[nn+12]; bna->currentStackerLevel = uchar2uint(buf[29], buf[28]); bna->intendedAccept = uchar2uint(buf[31], buf[30]); bna->pad2=0; pp=32; for (nn=0; nn<16; nn++) { bna->billDenomination[nn] = uchar2uint(buf[pp+1], buf[pp]); pp+=2; } if (bna->setup) return true; else return false; } void hwapi::bna_requestCurrentNotes(void) const { // send command to DC in order to get transaction data sendFDcmd_set(0, 116, 0, 0, 0, 0, 0); } uint8_t hwapi::bna_getCurrentNotes(uint16_t latestBill, uint16_t *currentNotes) const { // returns number of collected bank notes since start-command (current transaction) // latestBill: not used // currentNotes[0] = last bill value // currentNotes[1] = 0/1 1 if bill in escrow 0 if bill in cash box (stacker) // currentNotes[2,3] = total sum of collected bills within this transaction // incoming data: //DB1: nr of bills (this transaction) //DB2: 1 if bill in escrow //DB3..6: collected amount //DB7,8: denomination of last bill uint8_t buf[10], haveBilInEscrow, haveNrOfBills; uint16_t lastBillVal; uint32_t collAmountThisTrans; epi_restoreBnaCollection(buf); haveNrOfBills=buf[0]; haveBilInEscrow=buf[1]; collAmountThisTrans = uchar2ulong(buf[5],buf[4],buf[3],buf[2]); lastBillVal = uchar2uint(buf[7],buf[6]); currentNotes[0]=latestBill; // just to get rid of compiler warning currentNotes[0]=lastBillVal; currentNotes[1]=haveBilInEscrow; currentNotes[2]=uint16_t(collAmountThisTrans); collAmountThisTrans>>=16; currentNotes[3]=uint16_t(collAmountThisTrans); return haveNrOfBills; } void hwapi::bna_requestStackerLevel(void) const { sendFDcmd_set(0, 42, 0, 0, 0, 0, 0); } uint16_t hwapi::bna_getStackerLevel(uint32_t *amountInStacker, uint16_t *countOfBills) const { // return val: nr of bills in stacker // countOfBills[0..7] = count of bills of bill-type 0..7 (e.g. countOfBills[0]=nr of 5€-bills in stacker) // countOfBills[8..15] = value of bill-type 0...7 // receive data: //je zwei Byte pro Wert, //1…16: Anzahl Scheine pro Typ //33…48: Wertigkeit der Typen uint8_t buf[66], nn, pp, qq; uint16_t nrOfBills[16], valueOfBills[16], anzahl=0; uint32_t totalSum=0; epi_restoreBnaContent(buf); pp=0; qq=32; for (nn=0; nn<16; nn++) { nrOfBills[nn]=uchar2uint(buf[pp+1],buf[pp]); pp+=2; valueOfBills[nn]=uchar2uint(buf[qq+1],buf[qq]); qq+=2; } //qDebug()<< "CAmaster hwapi::bna_getStackerLevel " << nrOfBills[0] <<" "<< nrOfBills[1] // <<" "<