/* * API to the PSA2020 Hardware * All data come in from device controller via serial interface and will be stored * PI is updated every 100ms * This api uses stored data and returns them in the following functions * created: Q1/2020 TS until Q2/21 * */ #include #include #include #include #include #include "tslib.h" #include "hwapi.h" #include "sendWRcmd.h" #include "controlBus.h" #include "storeINdata.h" #include "dcBL.h" #include "shared_mem_buffer.h" #include #include #include "interfaces.h" static uint32_t hwapi_lastStartAmount; static const QMap baudrateMap = { {"1200" , 0}, {"9600" , 1}, {"19200" , 2}, {"38400" , 3}, {"57600" , 4}, {"115200" , 5} }; hwapi::hwapi(QObject *parent) : QObject(parent) { // create or attach shared memory segment // !!! The compoment creating the shared memory MUST be ATBQT !!! m_sharedMem = SharedMemBuffer::getShm(sizeof(SharedMemBuffer)); if (m_sharedMem) { if (m_sharedMem->isAttached()) { qInfo() << "Shared memory (" << sizeof(SharedMemBuffer) << "bytes) created and attached"; } } else { qCritical() << "Creating/attaching shared memory failed"; } sendWRcmd_INI(); myDatif = new T_datif(); connect(myDatif, SIGNAL(datif_templatePrintFinished_OK()), this, SLOT(hwapi_slotPrintFinished_OK())); connect(myDatif, SIGNAL(datif_templatePrintFinished_Err()), this, SLOT(hwapi_slotPrintFinished_Err())); connect(myDatif, SIGNAL(datif_gotNewCoin()), this, SLOT(hwapi_slotGotCoin())); } hwapi::~hwapi() { if (m_sharedMem && m_sharedMem->isAttached()) { m_sharedMem->detach(); } } void hwapi::hwapi_slotPrintFinished_OK(void) { emit hwapi_templatePrintFinished_OK(); } void hwapi::hwapi_slotPrintFinished_Err(void) { emit hwapi_templatePrintFinished_Err(); } void hwapi::hwapi_slotGotCoin(void) { // new coin was inserted while transaction and new amount reported: emit hwapi_gotNewCoin(); uint32_t newSum=epi_CurrentPaymentGetAmount(); if (newSum>=hwapi_lastStartAmount) emit hwapi_vendStopByMax(); } void hwapi::sub_storeSendingText(QByteArray *buf) const { char local[70], copie[1350]; // 64byte more then max buffer size! int LL, nn, len, maxruns=20; epi_resetPrinterStack(); // make a copy of the incoming byteArray as the byteArray can not be moved (crash!) tslib_strclr(copie, 0, 1350); LL=buf->length(); for (nn=0; nnat(nn); } tslib_strclr(local, 0, 66); LL=buf->length(); if (LL>1280) { qDebug()<<"reducing text size from " << LL << " to 1280 bytes"; LL=1280; // Limit size } else qDebug()<<"\n printing text with " << LL << " bytes: "; do { len=tslib_getMinimum(LL, 64); tslib_strclr(local, 0, 66); for (nn=0; nn0 && LL>0); } // ------------------------------------------------------------------------------ // Level 0 commands, interface // open, close, change serial interface // actually not neccessary as it is opened automatically on program start // start automatic READ requests // ------------------------------------------------------------------------------ bool hwapi::dc_openSerial(int BaudNr, QString BaudStr, QString ComName, uint8_t connect) const { // BaudNr: 0:1200 1:9600 2:19200 3:38400 4:57600 5:115200 // BaudStr: for exapmle "19200" // ComName: for example "COM48" // connect: 0, 1 //qDebug() << "~~>LIB" << "dc_openSerial called... " ; epi_setSerial(BaudNr, BaudStr, ComName, connect); // Actions: open serial port with parameters for (int i = 0; i < 10; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); if (dc_isPortOpen()) { return true; } } return false; } QStringList hwapi::dc_getStatus() const { QStringList status; if (m_sharedMem) { SharedMemBuffer const *shMem = SharedMemBuffer::getDataConst(); status += QString("comport : %1").arg(shMem->rs.comportName); status += QString("baudrate : %1").arg(shMem->rs.baudNr); status += QString("baudNr : %1").arg(shMem->rs.baudStr); status += QString("connect : %1").arg(shMem->rs.connect); status += QString("port open: %1").arg(shMem->rs.portIsOpen); // to be continued } return status; } bool hwapi::dc_closeSerial(void) const { epi_closeSerial(); for (int i = 0; i < 10; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); if (!dc_isPortOpen()) { return true; } } return false; } bool hwapi::dc_isPortOpen(void) const { if (myDatif) { T_prot* prot = myDatif->getProt(); if (prot) { T_com *com = prot->getSerialPort(); if (com) { return com->isPortOpen(); } } } return false; //return epi_isSerialPortOpen(); } void hwapi::dc_autoRequest(bool on) const { // automatically request ALL digital and analog sensors, get time/date, get status information if (on) epi_startEmmision(1); else epi_startEmmision(0); } /******************************************************************************/ // // LEVEL 2: Help-functions for hwapi::dc_updateDC. // /******************************************************************************/ hwapi::DownloadResult hwapi::sendStatus(int ret) const { switch (ret) { // return values of dc are: case 0: // 0: no answer by now return DownloadResult::NOP; // 1: error case 10: // 10: success return DownloadResult::OK; default:; } return DownloadResult::ERROR; } hwapi::DownloadResult hwapi::sendNextAddress(int bNum) const { // sends address only if blockNumber is one of 0, 1024, 2048, 3072, 4096 int noAnswerCount = 0; int errorCount = 0; if ( bNum==0 || bNum==1024 || bNum==2048 || bNum==3072 || bNum==4096 ) { qDebug() << "addr-block" << bNum << "..."; while (noAnswerCount <= 250) { bl_sendAddress(bNum); std::this_thread::sleep_for(std::chrono::milliseconds(100)); DownloadResult const res = sendStatus(bl_wasSendingAddOK()); if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { qCritical() << "addr-block" << bNum << "...FAILED"; return res; } } else { // res == DownloadResult::OK qInfo() << "addr-block" << bNum << "...OK"; return res; } } else { noAnswerCount += 1; // no answer by now } } // wait max. about 3 seconds return DownloadResult::TIMEOUT; } // blockNumber is not one of 0, 1024, 2048, 3072, 4096 -> do nothing return DownloadResult::NOP; } hwinf::DownloadResult hwapi::sendNextDataBlock(QByteArray const &binary, int bNum) const { uint8_t local[66]; int const bAddr = bNum * 64; int noAnswerCount = 0; int errorCount = 0; memcpy(local, binary.constData() + bAddr, 64); local[64] = local[65] = 0x00; qDebug() << "data for addr" << bAddr << "..."; while (noAnswerCount <= 250) { bl_sendDataBlock(64, local); std::this_thread::sleep_for(std::chrono::milliseconds(10)); DownloadResult const res = sendStatus(bl_wasSendingDataOK()); if (res != DownloadResult::NOP) { if (res == DownloadResult::ERROR) { if (++errorCount >= 10) { qCritical() << "data for addr" << bAddr << "...FAILED"; return res; } } else { qInfo() << "data for addr" << bAddr << "...OK"; return res; } } else { noAnswerCount += 1; // no answer by now } } // wait max. about 3 seconds return DownloadResult::TIMEOUT; } hwinf::DownloadResult hwapi::dc_downloadBinary(QByteArray const &b) const { int const nBlocks = (((b.size())%64)==0) ? (b.size()/64) : (b.size()/64)+1; qInfo() << "total number of bytes to send to dc" << b.size(); qInfo() << "total number of blocks to send to dc" << nBlocks; int bNum = 0; DownloadResult res = DownloadResult::OK; while (res != DownloadResult::ERROR && bNum < nBlocks) { if ((res = sendNextAddress(bNum)) != DownloadResult::ERROR) { if ((res = sendNextDataBlock(b, bNum)) != DownloadResult::ERROR) { bNum += 1; } } } if (res != DownloadResult::ERROR) { bl_sendLastBlock(); } return res; } bool hwapi::startBootloader() const { qDebug() << "starting bootloader..."; int nTry = 5; while (--nTry >= 0) { bl_startBL(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); if (bl_isUp()) { qInfo() << "starting bootloader...OK"; std::this_thread::sleep_for(std::chrono::milliseconds(500)); return true; } } qCritical() << "starting bootloader...FAILED"; return false; } bool hwapi::stopBootloader() const { qDebug() << "stopping bootloader..."; int nTry = 5; while (--nTry >= 0) { bl_stopBL(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); if (!bl_isUp()) { qInfo() << "stopping bootloader...OK"; return true; } } qCritical() << "stopping bootloader...FAILED"; return false; } // br is a index into a table, used for historical reasons. bool hwapi::openSerial(int br, QString baudrate, QString comPort) const { qDebug() << "opening serial" << br << baudrate << comPort << "..."; if (dc_openSerial(br, baudrate, comPort, 1)) { // 1 for connect qInfo() << "opening serial" << br << baudrate << comPort << "...OK"; return true; } qCritical() << "opening serial" << br << baudrate << comPort << "...FAILED"; return false; } bool hwapi::closeSerial(QString comPort) const { qDebug() << "closing serial" << comPort << "..."; if (dc_closeSerial()) { qInfo() << "closing serial" << comPort << "...OK"; return true; } else { qCritical() << "closing serial" << comPort << "...FAILED"; } return false; } bool hwapi::resetDeviceController() const { qDebug() << "resetting device controller..."; if (stopBootloader()) { // first stop a (maybe) running bootloader std::this_thread::sleep_for(std::chrono::milliseconds(1000)); dc_OrderToReset(); // wait maximally 3 seconds, before starting bootloader std::this_thread::sleep_for(std::chrono::milliseconds(1500)); qInfo() << "resetting device controller...OK"; return true; } return false; } QByteArray hwapi::loadBinaryDCFile(QString filename) const { qDebug() << "loading dc binary" << filename << "..."; QFile file(filename); // closed in destructor call if (!file.exists()) { qCritical() << file.fileName() << "does not exist"; return QByteArray(); } if (!file.open(QIODevice::ReadOnly)) { qCritical() << "cannot open file" << file.fileName(); return QByteArray(); } qInfo() << "loading dc binary" << filename << "...OK"; return file.readAll(); } bool hwapi::downloadBinaryToDC(QString const &bFile) const { qDebug() << "sending" << bFile << "to dc..."; QByteArray const dcBinary = loadBinaryDCFile(bFile); if (dcBinary.size() > 0) { if (dc_downloadBinary(dcBinary) != DownloadResult::OK) { qCritical() << "sending" << bFile << "to dc...FAILED"; return false; } else { qInfo() << "sending" << bFile << "to dc...OK"; } } else { qCritical() << "sending" << bFile << "to dc...FAILED"; qCritical() << "loading binary" << bFile << "FAILED"; return false; } return true; } /******************************************************************************/ // // LEVEL 3: hwapi::dc_updateDC. // /******************************************************************************/ bool hwapi::dc_updateDC(QString bFile, QString br, QString serial) const { if (!baudrateMap.contains(br)) { // sanity check qCritical() << "passed wrong baudrate" << br; return false; } qDebug() << "updating dc: " << bFile << br << serial << "..."; if (!openSerial(baudrateMap.value(br), br, serial)) { return false; } if (!resetDeviceController()) { closeSerial(serial); return false; } if (!startBootloader()) { closeSerial(serial); return false; } if (!downloadBinaryToDC(bFile)) { stopBootloader(); closeSerial(serial); qCritical() << "updating dc: " << bFile << br << serial << "...FAILED"; return false; } qInfo() << "updating dc: " << bFile << br << serial << "...OK"; stopBootloader(); closeSerial(serial); return true; } /******************************************************************************/ // // LEVEL 3: hwapi::dc_updatePrinterTemplate // /******************************************************************************/ bool hwapi::dc_updatePrinterTemplate(enum FileTypeJson type, QVector templatesIdx, QVector fnames, QString br, QString serial) const { // sanity checks if (!baudrateMap.contains(br)) { qCritical() << "passed wrong baudrate" << br; return false; } if (templatesIdx.size() != fnames.size()) { qCritical() << "list sizes must be equal" << br; return false; } if (!std::all_of(templatesIdx.cbegin(), templatesIdx.cend(), [](int i) { return i >= 1 && i <= 32; })) { qCritical() << "wrong template indices"; return false; } if (type != FileTypeJson::PRINTER) { qCritical() << "wrong file type" << (uint8_t)type; return false; } qDebug() << "updating: " << fnames << br << serial << "..."; if (!serial.isNull()) { if (!openSerial(baudrateMap.value(br), br, serial)) { return false; } } int nTry = 50; while (!sys_ready4sending()) { // wait max. 5 seconds std::this_thread::sleep_for(std::chrono::milliseconds(100)); if (--nTry <= 0) { qCritical() << "sys not ready for sending"; if (!serial.isNull()) { closeSerial(serial); } return false; } } bool ret = true; for (int i = 0; i < fnames.size(); ++i) { QFile file(fnames[i]); if (file.exists() && file.open(QIODevice::ReadOnly)) { QByteArray ba = file.readAll(); if (ba.size() <= 800) { // max. size is 800 bytes if (sys_sendJsonFileToDc((uint8_t)(type), templatesIdx[i], (uint8_t *)ba.data())) { std::this_thread::sleep_for(std::chrono::seconds(1)); qInfo() << "sent file" << fnames[i] << "to dc"; } } } else { qCritical() << fnames[i] << "!!! does not exist!!!"; ret = false; continue; } } if (!serial.isNull()) { closeSerial(serial); } return ret; } bool hwapi::dc_printTemplate(enum FileTypeJson type, QVector templateIdx, QString br, QString serial) const { // sanity checks if (!baudrateMap.contains(br)) { qCritical() << "passed wrong baudrate" << br; return false; } if (!std::all_of(templateIdx.cbegin(), templateIdx.cend(), [](int i) { return i >= 1 && i <= 32; })) { qCritical() << "wrong template indices"; return false; } if (type != FileTypeJson::PRINTER) { qCritical() << "wrong file type" << (uint8_t)type; return false; } qDebug() << "printing: " << templateIdx << br << serial << "..."; if (!serial.isNull()) { if (!openSerial(baudrateMap.value(br), br, serial)) { return false; } } int nTry = 50; while (!sys_ready4sending()) { // wait max. 5 seconds std::this_thread::sleep_for(std::chrono::milliseconds(100)); if (--nTry <= 0) { qCritical() << "sys not ready for sending"; if (!serial.isNull()) { closeSerial(serial); } return false; } } bool ret = true; struct T_dynDat dynTicketData; memset (&dynTicketData, 0x00, sizeof(dynTicketData)); // lassen sich auch veraendern memcpy(&dynTicketData.licensePlate[0], "WEN1230", 8); memcpy(&dynTicketData.vendingPrice[0], "1234", 8); memcpy(&dynTicketData.parkingEnd[0], "12:00:00", 8); memcpy(&dynTicketData.currentTime[0], "14:15:00", 8); memcpy(&dynTicketData.currentDate[0], "01.01.2023", 8); for (int i = 0; i < templateIdx.size(); ++i) { // dynamische Daten werden gespeichert if (prn_sendDynamicPrnValues(&dynTicketData.licensePlate[0])) { // angabe welches template beim drucken benutzt werden soll std::this_thread::sleep_for(std::chrono::milliseconds(1000)); if (prn_printTemplate(templateIdx[i])) { qDebug() << "printing template" << templateIdx[i]; std::this_thread::sleep_for(std::chrono::seconds(3)); } } else { ret = false; continue; } } if (!serial.isNull()) { closeSerial(serial); } return ret; } // ------------------------------------------------------------------------------ // 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; 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; } uint32_t hwapi::dc_getTemperature(void) const { // return epi_loadMeasureValue(MEASCHAN_TEMPERATURE); } QString hwapi::dc_getTemperaturStr(void) const { return epi_getSlaveTemperatureStr(); } uint32_t hwapi::dc_getVoltage(void) const { // in mV, e.g. 12300 = 12,3V return epi_loadMeasureValue(MEASCHAN_VOLTAGE); } QString hwapi::dc_getVoltagStr(void) const { return epi_getSlaveVoltageStr(); } bool hwapi::dc_mainFuseIsOk(void) const { uint32_t ulong=epi_loadMeasureValue(MEASCHAN_VOLTAGE); // in mV, e.g. 12300 = 12,3V if (ulong>3000) return true; return false; } // ------------------------------------------------------------------------------ // Level 3: digital outputs and simple switching of connected devices // simple processes like flashing a led or open flap for 1s // ------------------------------------------------------------------------------ // Locks: uint8_t hwapi::lock_switchUpperLock(uint8_t dir) const { // dir 0=off 1=up 2=down sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEUP_LOCK ,dir,0,0,0); return 0; } uint8_t hwapi::lock_switchLowerLock(uint8_t dir) const { // dir 0=off 1=up 2=down sendWRcmd_setSendCommand4(SENDDIRCMD_MOVEDN_LOCK ,dir,0,0,0); return 0; } void hwapi::lock_switchVaultDoor(void) const { sendWRcmd_setSendCommand0(SENDDIR_OPENVAULT); } void hwapi::coin_switchRejectMotor(uint8_t dir) const { sendWRcmd_setSendCommand4(SENDDIR_REJMOT_ON, dir, 0,0,0); } void hwapi::coin_rejectCoins(void) const { sendWRcmd_setSendCommand0(SENDDIR_REJMOT_RUN); } void hwapi::led_switchLedService(uint8_t on) const { sendWRcmd_setSendCommand4(SENDDIRCMD_LEDINSIDE, on, 0, 0, 0); } void hwapi::led_switchLedPaper(uint8_t on, uint8_t ton, uint8_t tof) const { sendWRcmd_setSendCommand4(SENDDIRCMD_LEDTICKET, on, ton, tof, 0); } void hwapi::led_switchLedPinPad(uint8_t on, uint8_t ton, uint8_t tof) const { sendWRcmd_setSendCommand4(SENDDIRCMD_LEDPAD, on, ton, tof, 0); } void hwapi::led_switchLedStart(uint8_t on, uint8_t ton, uint8_t tof) const { sendWRcmd_setSendCommand4(SENDDIRCMD_LEDSTART, on, ton, tof, 0); } void hwapi::led_switchLedCoinbassin(uint8_t on, uint8_t ton, uint8_t tof) const { sendWRcmd_setSendCommand4(SENDDIRCMD_LEDCOIN, on, ton, tof, 0); } void hwapi::fan_switchFan(bool on) const { //return epi_storeDOsToSend(DOBYTE3, FAN_ON, on); sendWRcmd_setSendCommand4(SENDDIRCMD_FAN, on, 0, 0, 0); } void hwapi::alarm_switchSiren(bool on) const { //return epi_storeDOsToSend(DOBYTE4, LAERM, on); sendWRcmd_setSendCommand4(SENDDIRCMD_LAERM, on, 0, 0, 0); } void hwapi::bar_OpenBarrier(bool open) const { //return epi_storeDOsToSend(DOBYTE4, REL1, open); sendWRcmd_setSendCommand4(SENDDIRCMD_REL1, open, 0, 0, 0); } void hwapi::ptu_switchWake(bool WAKEACTIVE) const { //return epi_storeDOsToSend(DOBYTE1, CTS_PTU, WAKEACTIVE); sendWRcmd_setSendCommand4(SENDDIRCMD_WAKEPTU, WAKEACTIVE,0,0,0); } // AUX-IO's or barcode reader void hwapi::aux_power(bool on) const { // return epi_storeDOsToSend(DOBYTE2, BARC_POW_ON, on); sendWRcmd_setSendCommand4(SENDDIRCMD_AUXPWR, on,0,0,0); } void hwapi::aux_setUsage(uint8_t PinDirection) const { // bit 0= Aux1 bit5=Aux6 1=output 0=input with pullup // return epi_storeDOsToSend(DOBYTE6, nr, PinDirection); sendWRcmd_setSendCommand4(SENDDIRCMD_AUXDDR, PinDirection,0,0,0); } void hwapi::aux_setOutputs(uint8_t PinIsHigh) const { // PinIsHigh bit 0..5 =Aux1...6 1=output high 0=set output low //return epi_storeDOsToSend(DOBYTE5, nr, PinIsHigh); sendWRcmd_setSendCommand4(SENDDIRCMD_AUXOUT, PinIsHigh,0,0,0); } void hwapi::lock_switchContactPower(bool on) const { //epi_storeDOsToSend(DOBYTE2, U_SW_ON, on); sendWRcmd_setSendCommand4(SENDDIRCMD_UCONTACT_ON, on, 0,0,0); } void hwapi::prn_switchPower(bool on) const { // also switches and enables serial driver sendWRcmd_setSendCommand4(SENDDIRCMD_PRN2_SWONOFF, on,0,0,0); indat_storePrinterPower(on); // PRINTER-ON/OFF zusätzlich statisch abspeichern // Status-request soll nur gesendet werden wenn der Drucker ein ist // Status-Abfrage (hier in HWapi) gibt 0 zurück wenn power-off // dito mit allen anderen Geräten! // pi ---> storeINdata.cpp speichert diese statische Info (printer on/off) UND // auch alles rückgelesene } void hwapi::mif_readerOn(bool on) const { // DC2 also switches and enables serial driver sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, on,0,0,0); } void hwapi::mif_creatAtbCard(uint8_t cardType) const { sendWRcmd_setSendCommand4(SENDDIRCMD_MIF_SWONOFF, cardType, 0,0,0); } void hwapi::mod_switchPower(bool on) const { sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_SWONOFF, on,0,0,0); } void hwapi::mod_switchWake(bool WAKEACTIVE) const { sendWRcmd_setSendCommand4(SENDDIRCMD_MOD_WAKE, WAKEACTIVE,0,0,0); } void hwapi::mdb_switchPower(bool on) const { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_POWER, on,0,0,0); } void hwapi::mdb_switchWake(bool WAKEACTIVE) const { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_WAKE, WAKEACTIVE,0,0,0); } void hwapi::credit_switchPower(bool on) const { sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_ON, on,0,0,0); } void hwapi::credit_switchWake(bool WAKEACTIVE) const { sendWRcmd_setSendCommand4(SENDDIRCMD_CRED_WAKE, WAKEACTIVE,0,0,0); } void hwapi::shut_move(bool open) const { // true:open false:close sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_MOV, open, 0,0,0); } void hwapi::esc_moveFlaps(uint8_t flap ) const { // 0: close both 1: open take-flap 2: open return sendWRcmd_setSendCommand4(SENDDIRCMD_ESCRO_MOV, flap, 0,0,0); } // ------------------------------------------------------------------------------ // Level 3: digital inputs of connected devices // ------------------------------------------------------------------------------ uint8_t hwapi::door_getSwitches(void) const { // retval // bit0: upper door 1: low door 2:vault door uint8_t ret; ret= epi_getDI_doorSwitches(); // bit0: upper door 1: low door 2:vault door ret &= 0x08; return ret; } bool hwapi::door_isUpperDoorOpen(void) const { uint8_t ret; ret= epi_getDI_doorSwitches(); // bit0: upper door 1: low door 2:vault door if (ret & 1) return true; return false; } bool hwapi::door_isLowerDoorOpen(void) const { uint8_t ret; ret= epi_getDI_doorSwitches(); // bit0: upper door 1: low door 2:vault door if (ret & 2) return true; return false; } bool hwapi::vault_isVaultDoorOpen(void) const { uint8_t ret; ret= epi_getDI_doorSwitches(); // bit0: upper door 1: low door 2:vault door if (ret & 4) return true; return false; } uint8_t hwapi::vault_getSwitches(void) const { // retval bit0: cash box, bit 1: bill box uint8_t ret; ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in ret&=0x03; return ret; } bool hwapi::vault_isCoinVaultIn(void) const { uint8_t ret; ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in if (ret & 1) return true; return false; } bool hwapi::vault_isBillVaultIn(void) const { uint8_t ret; ret=epi_getDI_vaultSwitches(); // bit0: cash box 1: bill box in if (ret & 2) return true; return false; } uint8_t hwapi::door_getLocks(void) const { // retval bit0: upper lever is up // bit1: upper lever is down // bit2: lower lever is up // bit3: lower lever is down uint8_t ret; ret= epi_getDI_lockSwitches(); // retval: bit 0: upper lockbar up bit1: upper lockbar is down // bit 2: lower lockbar up bit1: lower lockbar is down ret&=0x0F; return ret; } bool hwapi::door_upperDoorIsLocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 2) return true; return false; } bool hwapi::door_upperDoorIsUnlocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 1) return true; return false; } bool hwapi::door_lowerDoorIsLocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 8) return true; return false; } bool hwapi::door_lowerDoorIsUnlocked(void) const { uint8_t ret; ret= epi_getDI_lockSwitches(); if (ret & 4) return true; return false; } bool hwapi::bar_optoIn1isOn(void) const { uint8_t ret=epi_getDI_optos(); // bit0: opto in 1 1: opto in 2 if (ret & 1) return true; return false; } bool hwapi::bar_optoIn2isOn(void) const { uint8_t ret=epi_getDI_optos(); // bit0: opto in 1 1: opto in 2 if (ret & 2) return true; return false; } uint8_t hwapi::aux_getAuxInputs(void) const { // retval: bit0=Aux1....Bit5=Aux6 // 0: input low 1:input high uint8_t ret=epi_getDI_auxIn(); // bit0: auxin 1 ... 5: auxin 6 ret &=0x3F; return ret; } bool hwapi::ptu_WakeINisActive(void) const { return epi_getDI_ptuWake(); } bool hwapi::mdb_WakeINisActive(void) const { return epi_getDI_mdbWake(); } bool hwapi::prn_readyINisActive(void) const { return epi_getDI_prnReady(); } bool hwapi::coid_isAttached(void) const { return epi_getDI_CoinAttach(); } bool hwapi::coin_escrowIsOpen(void) const { return epi_getDI_CoinEscrow(); } bool hwapi::mif_cardIsAttached(void) const { return epi_getDI_mifareCardTapped(); } //bool hwapi::mod_WakeINisActive(void) //{ // return epi_getDI_modemWake(); //} bool hwapi::door_isContactPowerOn(void) const { return epi_getDI_contactPwr(); } bool hwapi::mif_isMifarePowerOn(void) const { bool mo=indat_isMifareOn(); bool mi=epi_getDI_mifarePwr(); if (mo && mi) return true; return false; } bool hwapi::mdb_testIsmdbTxDon(void) const { return epi_getDI_mdbTxd(); } bool hwapi::aux_isAuxPowerOn(void) const { return epi_getDI_auxPwr(); } bool hwapi::mod_isGsmPowerOn(void) const { return epi_getDI_gsmPwr(); } bool hwapi::cred_isCreditPowerOn(void) const { return epi_getDI_creditPwr(); } bool hwapi::prn_isPrinterPowerOn(void) const { return epi_getDI_printerPwr(); } uint8_t hwapi::prn_PrnFuseIsOk(void) const { //retval: 0: fuse blown 1: fuse OK 2:unknown as printer power is off if (!epi_getDO_printerPwr()) return 2; // unknown as printer power is off if (epi_getDI_printerPwr()) return 1; // printer voltage is OK return 0; // fuse blown } bool hwapi::mdb_isMdbPowerOn(void) const { return epi_getDI_mdbPwr(); } bool hwapi::cash_getRejectMotorHomePos(void) const { return epi_getDI_rejectMotor_homepos(); } uint8_t hwapi::cash_getLowPaperSensor(void) const { // 0: Sensor sees paper 1: no paper 99: off return epi_getDI_npe_sensor(); } // ------------------------------------------------------------------------------ // Level1,2,3 RD request commands // ------------------------------------------------------------------------------ // the following requests can be sent manually // or automatically in background by: void hwapi::dc_autoRequest(bool on) // in other words: // if automatic-reading is on then there's no need to send any of these commands! void hwapi::request_DC2serialConfig() const { sendWRcmd_setSendCommand0(SEND_REQU_SERCONF); } void hwapi::request_DC2_HWversion() const { sendWRcmd_setSendCommand0(SEND_REQU_HWversion); } void hwapi::request_DC2_SWversion() const { sendWRcmd_setSendCommand0(SEND_REQU_SWversion); } void hwapi::request_DC2_condition() const { sendWRcmd_setSendCommand0(SEND_REQU_CONDITION); } void hwapi::request_DC2_UID() const { sendWRcmd_setSendCommand0(SEND_REQU_UID); } void hwapi::request_DC2_TimeAndDate() const { sendWRcmd_setSendCommand0(SEND_REQU_TIME); } void hwapi::request_DC2_analogues() const { sendWRcmd_setSendCommand0(SEND_REQU_ANALOGS); } void hwapi::request_DC2_digitalInputs() const { sendWRcmd_setSendCommand0(SEND_REQU_DIG_INPUTS); } void hwapi::request_DC2_digitalOutputs() const { sendWRcmd_setSendCommand0(SEND_REQU_DIG_OUTPUTS); } // ------------------------------------------------------------------------------ // the folowing device state requests are deployed only if device is powered up: void hwapi::request_PrinterHwState() const { sendWRcmd_setSendCommand0(SEND_REQU_PRN_STATE); } void hwapi::request_PrinterCurrentFonts() const { sendWRcmd_setSendCommand0(SEND_REQU_PRN_FONTS); } void hwapi::request_PrinterStateComplete() const { sendWRcmd_setSendCommand0(SEND_REQU_PRN_ALL); } void hwapi::request_MifareReaderState() const { sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE); } void hwapi::request_MifareCardType() const { //uint8_t blkAdr=0; //sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, blkAdr,0,0,0); sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE); } void hwapi::request_MifareAtbType() const { //sendWRcmd_setSendCommand0(SEND_REQU_MIF_ATB_TYPE); sendWRcmd_setSendCommand0(SEND_REQU_MIFSTATE); } void hwapi::request_MifareID() const { uint8_t sequenceNumber=0; sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, sequenceNumber,0,0,0); // 1st data = card sequence =blk nr (0...15) } void hwapi::request_MifareData(uint8_t dataBlockNumber) const { if (dataBlockNumber<12) // 1k cards return 12 data blocks, 4k cards would return 54 data blocks (not implemented) sendWRcmd_setSendCommand4(SEND_REQU_MIFDATA, dataBlockNumber,0,0,0); // 1st data = card sequence =blk nr (0...15) } void hwapi::request_MDB_Status() const { sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETSTAT); } //void hwapi::request_MDB_wakeInLine() const //{ // sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETWAK); //} void hwapi::request_MDB_lastResponse() const { sendWRcmd_setSendCommand0(SEND_REQU_MDB_GETRESP); } void hwapi::request_EMP_allParameters() const { sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETALL); } void hwapi::request_EMP_lastCoin() const { sendWRcmd_setSendCommand0(SEND_REQU_EMP_GETCOIN); } // ------------------------------------------------------------------------------ // Level 3: readback digital outputs of connected devices // these functions are not needed for normal operation // but can be used to test and verify conditions // There are two options: // 1) the important things like power-outputs and wake lines are // measured at DC2-terminals (after transistors) and come as input to DC-board // 2) others like Leds are read from µC-pins by DC-board // ------------------------------------------------------------------------------ bool hwapi::test_getDO_mdbRXtst(void) const { return epi_getDO_mdbRxTestOut(); } uint8_t hwapi::lock_getDO_motors(void) const { // bit0: upper lock forward bit 1 backward // bit2: lower lock forward bit 3 backward return epi_getDO_motorOuts(); } uint8_t hwapi::test_serialState(void) const { // test on-board signals for the serials // serial drv on/off, Serial mux1, Serial mux2 uint8_t ret=epi_getDO_serialSwitch(); // serial drv on/off, Serial mux1, Serial mux2 ret &=0x07; return ret; } bool hwapi::test_serialIsOn(void) const { return epi_getDO_serialDriverIsOn(); } bool hwapi::test_serialMux1isSetToPrinter(void) const { return epi_getDO_serialMux1isSetToPrinter(); // mux1 off: serial is switched to printer } bool hwapi::test_serialMux1isSetToModem(void) const { return epi_getDO_serialMux1isSetToModem(); // mux1 on: serial is switched to modem } bool hwapi::test_serialMux2isSetToCredit(void) const { return epi_getDO_serialMux2isSetToCredit(); // mux2 off: serial is switched to credit card terminal } bool hwapi::test_serialMux2isSetToMifare(void) const { return epi_getDO_serialMux2isSetToMifare(); // mux2 on: serial is switched to mifare reader } bool hwapi::led_coinIsOn(void) const { return epi_getDO_led_coin(); } bool hwapi::led_frontIsOn(void) const { return epi_getDO_led_front(); } bool hwapi::led_ticketIsOn(void) const { return epi_getDO_led_ticket(); } bool hwapi::led_pinIsOn(void) const { return epi_getDO_led_pin(); } bool hwapi::led_StartIsOn(void) const { return epi_getDO_led_start(); } bool hwapi::led_insideIsOn(void) const { return epi_getDO_led_inside(); } bool hwapi::fan_isOn(void) const { return epi_getDO_fan(); } bool hwapi::siren_isOn(void) const { return epi_getDO_sirene(); } bool hwapi::bar_relayIsOn(void) const { return epi_getDO_relay(); } bool hwapi::ptu_WakeOutIsOn(void) const { return epi_getDO_ptuWake(); } bool hwapi::aux_powerIsOn(void) const { return epi_getDO_auxPower(); } bool hwapi::coin_shutterIsOpen(void) const { return epi_getDO_coinShutterOpen(); } bool hwapi::coin_shutterTestOutput(void) const { return epi_getDO_coinShutterTest(); } uint8_t hwapi::coin_escrowFlapOpened(void) const { // retval: 1:return flap is open 2:take flap is open 0:closed return epi_getDO_coinEscrow(); } 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_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); 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); /* buf66[0]=swl_getOneByteFromUint(machPara.customerNumber, GETLOWBYT); buf66[1]=swl_getOneByteFromUint(machPara.customerNumber, GETHIGHBYT); buf66[2]=swl_getOneByteFromUint(machPara.machineNumber, GETLOWBYT); buf66[3]=swl_getOneByteFromUint(machPara.machineNumber, GETHIGHBYT); buf66[4]=swl_getOneByteFromUint(machPara.borough, GETLOWBYT); buf66[5]=swl_getOneByteFromUint(machPara.borough, GETHIGHBYT); buf66[6]=swl_getOneByteFromUint(machPara.zone, GETLOWBYT); buf66[7]=swl_getOneByteFromUint(machPara.zone, GETHIGHBYT); buf66[8]=swl_getOneByteFromUint(machPara.alias, GETLOWBYT); buf66[9]=swl_getOneByteFromUint(machPara.alias, GETHIGHBYT); for (pp=0; pp<32; pp++) buf66[10+pp]=machPara.location[pp]; dc2prot_setReadData(42, buf66); */ } // .................................................................................... static uint16_t hwapi_shutterTime; // locks, 2.Level: (Motor stops automatical on end switch or by 5s timeout) uint8_t hwapi::lock_openUpperDoor(void) const { //bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4); // commands are defined in PIdefines.h sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 1, 0, 0, 0); // paras: dat2: 1=upper door lock 2=lower // dat1: 1=open 2=close return 0; } uint8_t hwapi::lock_closeUpperDoor(void) const { sendWRcmd_setSendCommand4(SENDDIRCMD_OPENUP_DOOR, 2, 0, 0, 0); return 0; } uint8_t hwapi::lock_openLowerDoor(void) const { sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 1, 0, 0, 0); return 0; } uint8_t hwapi::lock_closeLowerDoor(void) const { sendWRcmd_setSendCommand4(SENDDIRCMD_OPENDN_DOOR, 2, 0, 0, 0); return 0; } void hwapi::shut_openOnce(void) const { // and close automatic after shutter time uint16_t zeit=hwapi_shutterTime; zeit/=100; sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYTIME, uint8_t(zeit) ,0,0,0); } void hwapi::shut_openForCoin(bool start) const { // start=true: start opening flap if coin is attached // start=false: stop process uint16_t zeit=hwapi_shutterTime; zeit/=100; sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYCOIN, uint8_t(start), uint8_t(zeit),0,0); } void hwapi::shut_sendOpeningTime(uint16_t timeIn_ms ) const { // after this time without retrigger the flap is closed //sendWRcmd_setSendCommand4(SENDDIRCMD_SHUT_SENDTIME, timeIn100ms,0,0,0); hwapi_shutterTime=timeIn_ms; } void hwapi::esc_takeMoney(void) const { // and close automatically after escrow time (1s) sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_TAKE); } void hwapi::esc_returnMoney(void) const { // and close automatically after time sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_GIVE); } // ---------------------------------------------------------------------------------------------------------- // --------------------------------------------- MIFARE ----------------------------------------------------- // ---------------------------------------------------------------------------------------------------------- uint8_t hwapi::mif_returnReaderStateAndCardType(uint8_t *buf, uint8_t maxBufferSize) const { // retval 0=OK 1=error host buffer too small /* data description: new fast version: byte 0= still the same: current read state: 0=power off 1=reader-fault 2=ready 3=just reading 4=read complete 5=read partial, removed too early 6=state unknown byte 1: reader state 1=ok 0=nok byte 2: card present (0,1) byte 3: card selected (0) byte 4: card type: 0...5 byte 5: card allowed (0=no 1=MifareClassic 1k or 4k) byte 6: CardSize: 1 or 4 (kB) byte 7: length of UID 4 or 7 (byte) */ return epi_restoreMifState(buf, maxBufferSize); } /* OLD data description: byte 0: current read state: 0=power off 1=reader-fault 2=ready 3=just reading 4=read complete 5=read partial, removed too early 6=state unknown byte 1,2: read data length from card 3: 1=reader is OK (reported serial nr is OK) 0=wrong or no reader 4...15: reader version, expected "ATB25-1.8" 16: 1=card is present 0:not 17: 0 18: card type reported from reader 19: 1=allowed card type 0=not 20: card size: 1 or 4 (dec) = card size 21: LengthOfUID: 4 or 7 (dec) (byte) 22: UID 8 byte in hex byte 30: sector logged: 0 byte 31: current sector: 0 byte 32: result, always 0 */ bool hwapi::mif_readerIsOK(void) const { uint8_t buf[40]; // old version had 40 bytes, new version only 8 uint8_t ret= epi_restoreMifState(buf, 40); if (ret==0 && buf[0]>1 && buf[1]>0) return 1; return 0; // error } bool hwapi::mif_cardAttached(void) const { uint8_t buf[40]; uint8_t ret= epi_restoreMifState(buf, 40); if (ret==0 && buf[0]>1 && buf[2]>0) // reader OK if (buf[16]>0) return 1; return 0; // error } uint8_t hwapi::mif_readResult(void) const { // result: 0: unknown or still in progress // 1: card read successful // 2: reading error uint8_t buf[40]; uint8_t ret= epi_restoreMifState(buf, 40); // data read successful && Reader OK && card attached && ... if (ret==0 && buf[1]>0 && buf[2]>0) { // byte 0: current read state: 0=power off 1=reader-fault 2=ready // 3=just reading 4=read complete // 5=read partial, removed too early // 6=state unknown if (buf[0]==1 || buf[0]==5 || buf[0]==6) return 2; if (buf[0]==4) return 1; } return 0; // error } QString hwapi::mif_cardUID(void) const { QString myStr; uint8_t buf[65], ret; //uint8_t ret= epi_restoreMifState(buf, 40); myStr.clear(); /* if (ret==0 && buf[0]==4 && buf[3]>0 && buf[16]>0 && buf[19]>0) { // UID in buf[22...29] for (int ii=0;ii<8; ii++) { myStr+=QString::number(buf[ii+22],16); myStr+=" "; // make a gap between numbers } } */ ret=epi_restoreMifData(0, buf, 64); if (ret) return myStr; // return empty string on error else { buf[8]=0; //myStr.append(buf); for (int ii=0;ii<8; ii++) { myStr+=QString::number(buf[ii],16); // 16: return in hex format myStr+=" "; // make a gap between numbers } return myStr; } } uint8_t hwapi::mif_getCardDataDec(uint8_t blkNr, uint8_t *buf, uint8_t maxBufferSize) const { // blkNr=0...11 return buf[64] maxBufferSize must be >=64 return epi_restoreMifData(blkNr, buf, maxBufferSize); // blkNr=0...11 return buf[64] } QString hwapi::mif_getCardDataStr(uint8_t blockNumber) const { // with blockNumber=0...11 QString myStr; uint8_t buf[66]; myStr.clear(); if (blockNumber>11) return myStr; epi_restoreMifData(blockNumber, buf, 66); for (int ii=0; ii<64; ii++) { //myStr+=QString::number(buf[ii],10); // decimals as ascii myStr+=QString::number(buf[ii],16); // hex numbers as ascii myStr+=" "; // make a gap between numbers } return myStr; } // ---------------------------------------------------------------------------------------------------------- // --------------------------------------------- PRINTER ---------------------------------------------------- // ---------------------------------------------------------------------------------------------------------- // already above: // void hwapi::prn_switchPower(bool on) 0x2A01 // bool hwapi::prn_readyINisActive(void) // bool hwapi::prn_isPrinterPowerOn(void) // void hwapi::request_PrinterHwState() 0x2A02 // void hwapi::request_PrinterCurrentFonts() 0x2A12 // void hwapi::request_PrinterStateComplete() // =request_PrinterHwState + request_PrinterCurrentFonts uint8_t hwapi::prn_getHwState(struct Tprn_hw_state *prn_hw_state) const { // return printer hardware state: power is on? rs-driver on? rs_switch ok? hw-ready-line ok? // printer on error or ok? uint8_t prnHWstate[20]; epi_restorePrinterState(prnHWstate); // byte 1...6 come right from printer, see printer manual // byte 0 = all important infos: // byte 0 = 0: prnter OK, >0: error // bit0: paper low 1: no paper 2: temperature error // 3: head open 4: paper jam in cutter // 6: no response 7: bad response from printer prn_hw_state->powerRdBk = epi_getDI_printerPwr(); prn_hw_state->rsSwOk = epi_getDO_serialMux1isSetToPrinter(); // mux1 off: serial is switched to printer prn_hw_state->rsDrvOk = epi_getDO_serialDriverIsOn(); prn_hw_state->ReadyLine = epi_getDI_prnReady(); if (prnHWstate[0]==0) prn_hw_state->inIdle = true; // no errors else prn_hw_state->inIdle = false; // off or errors if (prnHWstate[0] & 1) prn_hw_state->paperNearEnd=true; else prn_hw_state->paperNearEnd = false; if (prnHWstate[0] & 2) prn_hw_state->noPaper=true; else prn_hw_state->noPaper = false; if (prnHWstate[0] & 4) prn_hw_state->ErrorTemp=true; else prn_hw_state->ErrorTemp = false; if (prnHWstate[0] & 8) prn_hw_state->HeadOpen=true; else prn_hw_state->HeadOpen = false; if (prnHWstate[0] & 16) prn_hw_state->cutterJam=true; else prn_hw_state->cutterJam = false; if (prnHWstate[0] & 64) prn_hw_state->noResponse=true; else prn_hw_state->noResponse = false; if (prnHWstate[0] & 128) prn_hw_state->badResponse=true; else prn_hw_state->badResponse = false; return prnHWstate[0]; } bool hwapi::prn_isUpAndReady(void) const { struct Tprn_hw_state prnHwNow; prn_getHwState(&prnHwNow); if (prnHwNow.inIdle && prnHwNow.rsSwOk && prnHwNow.rsDrvOk && prnHwNow.powerRdBk ) return true; return false; } void hwapi::prn_getCurrentFontSetting(struct Tprn_currentSettings *prn_fonts) const { uint8_t prnFonts[22]; epi_restorePrinterFonts(&prnFonts[0]); prn_fonts->currFont = prnFonts[0]; prn_fonts->currSize = prnFonts[1]; prn_fonts->currHeigth= prnFonts[2]; prn_fonts->currWidth = prnFonts[3]; prn_fonts->nowBold = prnFonts[4]; prn_fonts->nowInvers = prnFonts[5]; prn_fonts->nowUnderlined= prnFonts[6]; prn_fonts->currDensity = prnFonts[7]; prn_fonts->currSpeed = prnFonts[8]; prn_fonts->nowAligned = prnFonts[9]; } void hwapi::prn_sendText(QByteArray *buf) const { sub_storeSendingText(buf); epi_storeUserOfSendingTextBuffer(1,0,0,0,0); // 1=print text } void hwapi::prn_sendPrnSysCmd(uint8_t para1, uint8_t para2, uint32_t para3) const { // send three byte through to printer, see printers manual sendWRcmd_setSendCommand8(SENDDIRCMD_PRN_SYS_CMD, para1, para2, 0, para3); } void hwapi::prn_sendPrnEscCmd(uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4) const { // send four byte through to printer, see printers manual sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_ESC_CMD, para1, para2, para3, para4); } void hwapi::prn_sendPrnSetup(uint16_t paperSpeed, uint8_t density, uint8_t alignment, uint8_t orientation) const { // send 5 byte: byte 0,1: speed 5...250 mm/s // byte2: density 0....(25)....50 // byte3: alignment 'l', 'c', 'r' = left, center, right // byte4: orientation 0, 90, 180 = 0°, 90°, 180° rotation (by now not supported!) // not batched! don't use twice within 100ms uint8_t buf[10]; uint16_t uitmp; uitmp=paperSpeed; buf[0]=uint8_t(uitmp); uitmp>>=8; buf[1]=uint8_t(uitmp); buf[2]=density; buf[3]=alignment; buf[4]=orientation; buf[5]=0; epi_store64ByteSendData(5, buf); sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_SETUP); } void hwapi::prn_movePaper(uint8_t wayInMm, uint8_t direction) const { //direction: 1=forward 2=backward sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_MOVE, wayInMm, direction, 0,0); } void hwapi::prn_setFonts(uint8_t font, uint8_t size, uint8_t width, uint8_t height) const { // font = kind of font 0...8 // size = 6...20, 9..9: too tiny 10: small ...12 = normal size ...20=huge // width: 0...4 0=1x 1=2x 2=4x (huge!) 3=8x 4=16x (3,4 make no sense) // heigth: 0...7 = 1x...8x only 0,1,2,(3) make sense sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETFONT, font, size, width, height); } void hwapi::prn_setLetters(uint8_t bold, uint8_t invers, uint8_t underlined) const { sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_SETLETT, bold, invers, underlined, 0); } void hwapi::prn_cut(uint8_t kindof) const { // kindof = 1: full cut 2: partial cut 3=eject (5xLF + full cut) sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_CUT, kindof,0,0,0); } void hwapi::prn_newLine(uint8_t nrOfLines) const { sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_LF, nrOfLines, 0, 0, 0); } void hwapi::prn_printCompleteFontTable(void) const { sendWRcmd_setSendCommand0(SENDDIRCMD_PRN_FONTTAB); } void hwapi::prn_printBarcode(uint8_t kindOf, uint8_t withText, uint8_t offset, uint8_t rotation, uint8_t dataLeng, uint8_t *data) const { uint8_t buf[66], nn; //uint16_t uitmp; if (dataLeng>58) dataLeng=58; buf[0]=kindOf; buf[1]=withText; buf[2]=offset; buf[3]=rotation; buf[4]=dataLeng; // rest: Barcode-data: for (nn=0; nn1278) return false; ticketTemplate.append(text); qDebug()<<"\nText added "<1266) return false; ticketTemplate.append(tmpStr); return true; } bool hwapi::pri_TD_addCommand(char group, char attribute, char p1, char p2, char p3, char p4, char p5) const { // always add 8 byte to the ticket layout: ESC & group & attribute & parameter1...5 /* complete list of possible commands: group 50 : paper attribute 10 : move forward p1: wayInMm p2: direction attribute 11 : cut p1: kind of, 1=full 2=partial, 3=eject attribute 12 : new line(s) p1: nr of lines 1...100 group 51 : fonts attribute 10 : kind of font see description above p1: possible: 0...22, expedient: 5...11 attribute 11 : font size p1: 6...20 12=normal 6=tiny attribute 12 : font width p1: 0...4 attribute 13 : font heigth p1: 0...7 attribute 14 : switch bold print on/off p1: 0=off 1=on attribute 15 : switch invers print on/off p1: 0=off 1=on attribute 16 : switch underlined print on/off p1: 0=off 1=on group 52 : print graphics attribute 10 : print barcode with dynamic data 6 and 7 p1...p5 = kindOf, withText, offset, rotation, dataLeng, see description above attribute 11 : print QRcode with preset data attribute 12 : print Logo p1=nrOfLogo, p2=offset group 53 : print dynamics attribute 10 : 1...8 = print dynData 0..7 at this place */ char tmpStr[10]; // command has always fixed length of 8 byte if (ticketTemplate.length()>1270) return false; if (group<50 || group>59) return false; if (attribute<10 || attribute>30) return false; tmpStr[0]=0x1B; // ESC tmpStr[1]=group; tmpStr[2]=attribute; tmpStr[3]=p1; tmpStr[4]=p2; tmpStr[5]=p3; tmpStr[6]=p4; tmpStr[7]=p5; ticketTemplate.append(tmpStr, 8); qDebug()<<"\ncmd added "<1277) return false; ticketTemplate.append("\n"); return true; } bool hwapi::pri_TD_addSign(char sign) const { if (ticketTemplate.length()>1277) return false; ticketTemplate.append(sign); return true; } char hwapi::prn_clearDocument(uint8_t documentNumber) const { if (documentNumber>15) return false; sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_CLEARDOC, documentNumber, 0, 0, 0); return true; } bool hwapi::prn_store_Document(uint8_t documentNumber ) const { // send to DC // documentNumber=0...15, stored in Eeprom // maximal 1280 bytes each // allowed: 0x20...0xFF, 0x0A, 0x0C, 0x1B (LF, CR, Esc) // 0x1B=start of embedded command (next 7bytes = command) if (documentNumber>15) return false; sub_storeSendingText(&ticketTemplate); epi_storeUserOfSendingTextBuffer(3,documentNumber,0,0,0); // 3=store document return true; } bool hwapi::prn_printDocument(uint8_t documentNumber, struct T_dynDat *dynTicketData) const { if (documentNumber>15) return false; epi_store64ByteSendData(64, &(dynTicketData->licensePlate[0])); sendWRcmd_setSendCommand4(SENDDIRCMD_PRN_DOC, documentNumber, 0, 0, 0); return true; } // ---------------------------------------------------------------------------------------------------------- // ------------------------------------------- MDB Bus ------------------------------------------------------ // ---------------------------------------------------------------------------------------------------------- void hwapi::mdb_sendBusReset(void) const { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_RES, 0,0,0,0); } #define mdb_device_coinChk 0 #define mdb_device_changer 1 #define mdb_device_bill 2 //#define mdb_device_credit 3 // obsolete void hwapi::mdb_sendCommand(uint8_t toMdbDevice, uint8_t mdbCommand) const { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_SENDCMD, toMdbDevice, mdbCommand, 0,0); } void hwapi::mdb_sendMessage(uint8_t toMdbDevice, uint8_t mdbCommand, uint8_t nrOfData, uint8_t *dataBuffer) const { // nrOfData = sizeOf(dataBuffer) maximal 34 byte according mdb specs uint8_t myBuf[64], ii; tslib_strclr(myBuf, 0, 64); myBuf[0]=toMdbDevice; myBuf[1]=mdbCommand; if (nrOfData>34) nrOfData=34; myBuf[2]=nrOfData; for (ii=0; ii>=8; myBuf[1]=uint8_t (uitmp); myBuf[2]=tokenChannel; pp=3; for (ii=0; ii<16; ii++) { uitmp=coinDenomination[ii]; myBuf[pp]=uint8_t(uitmp); uitmp>>=8; myBuf[pp+1]=uint8_t(uitmp); pp+=2; } epi_store64ByteSendData(35, myBuf); sendWRcmd_setSendCommand0(SENDDIRCMD_EMP_SETT); } void hwapi::emp_pollingOnOff(uint8_t on) const { // on: 1=start polling the coin accepter 0=stop sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_POLL, on,0,0,0); } void hwapi::emp_startCoinAcceptance(void) const { sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STARPPAY, 0,0,0,0); } void hwapi::emp_stopCoinAcceptance(void) const { sendWRcmd_setSendCommand4(SENDDIRCMD_EMP_STOPPAY, 0,0,0,0); } void hwapi::emp_getAllParameters(struct T_emp *emp) const { uint8_t leng, data[66], ii, pp; epi_restoreEmpSettings(&leng, data); // expected length = 64 byte // get 64 bytes about EMP: see h-file emp->gotSetup = data[0]; emp->state = data[1]; emp->shaft = data[2]; emp->countryCode= uchar2uint(data[4], data[3]); emp->scale = data[5]; emp->decimals = data[6]; for (ii=0; ii<16; ii++) emp->coinValues[ii] = data[7+ii]; emp->coinAccept = uchar2uint(data[24], data[23]); emp->tokenChannel = data[25]; emp->pollingRunning = data[26]; emp->paymentRunning = data[27]; pp=28; for (ii=0; ii<16; ii++) { emp->denomination[ii] = uchar2uint(data[pp+1], data[pp]); pp+=2; } emp->routing= uchar2uint(data[61], data[60]); } /* static bool emp_newCoin; static uint8_t emp_newCoinSignal; static uint16_t emp_newCoinValue; static uint8_t emp_newCoinError; uint8_t hwapi::emp_chkIfCoinInserted(void) { // retval: 1=got coin 0xFF=emp reported an error 0=got nothing // comes only one time after each coin, vaslues are stored uint8_t leng, data[8]; epi_restoreEmpCoinSignal(&leng, data); // 5 byte per inserted coin: // data[0]: 1=got coin, data set valid // data[1]: emp-signal of last inserted coin // data[2]: emp-error or warning // data[3,4]: emp-value of last inserted coin 3=low byte //epi_clearEmpCoinSignal(); if (data[0]>0) { emp_newCoin=data[0]; // anything came in, coin or error or both if (data[0] & 0x80) { emp_newCoinError=data[4]; } if (data[0] &0x0F) { emp_newCoinSignal=data[1]; emp_newCoinValue=uchar2uint(data[3], data[2]); } return emp_newCoin; } return 0; } uint8_t hwapi::emp_getInsertedCoinSignal(void) { uint8_t uctmp=emp_newCoinSignal; emp_newCoinSignal=0; // return only once return uctmp; } uint16_t hwapi::emp_getInsertedCoinValue(void) { uint16_t uitmp=emp_newCoinValue; emp_newCoinValue=0; // return only once return uitmp; } uint8_t hwapi::emp_getCoinError(void) { uint8_t uctmp=emp_newCoinError; emp_newCoinError=0; // return only once return uctmp; } */ uint8_t hwapi::emp_chkIfCoinInserted(void) const { // retval: 0...16 coins left in FIFO return epi_isNewCoinLeft(); } void hwapi::emp_getNewCoinRecord(uint8_t *valid, uint8_t *signal, uint8_t *error, uint16_t *value) const { epi_restoreEmpCoinSignal(valid, signal, error, value); } uint8_t hwapi::emp_giveLastCoin(uint16_t *value, uint8_t *signal) const { // retval: 0: NO coin stored 1: valid coin 2: got wrong coin or coin denied // value: if retval1: value of the coin if reval=2: error number // signal: channel nr reported from checker uint8_t valid, chan, error; uint16_t wert; epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert); if (valid && error==0xFF ) { *value=wert; *signal=chan; return 1; } if (valid && error<0xFF ) { *value=error; *signal=chan; // normally 0, but sometimes we get both return 2; } return 0; } uint8_t hwapi::emp_returnLastCoin(uint16_t *value, uint8_t *signal) const { // use this for coin changer uint8_t valid, chan, error; uint16_t wert; epi_restoreEmpCoinSignal(&valid, &chan, &error, &wert); if (error) { *value=0; *signal=error; return 0; } *value=wert; *signal=chan; return valid; } // ---------------------------------------------------------------------------------------------------------- // --------------------------------------------- Bill Validator ----------------------------------- // ---------------------------------------------------------------------------------------------------------- /* // Coin checker and changer mdb4.2 / section 5 // Level 2 Commands (predefined device msg acc. mdb manual and auto-poll) uint8_t hwapi::mdb_bill_startPolling(bool on) { // send ether one command (from list below) // or a poll command in the proper polling grid (e.g. every 100ms) epi_storeConfig08(mdbPollBills,on); //sendWRcmd_setSendCommand0(SENDDIRCMD_WR_CONF_08); return 0; } // the following functions tell the DC to send a mdb command to any mdb slave // in opposite to mdb_sendData() the exact telegrams don't have to be formed here, DC does it. uint8_t hwapi::mdb_bill_reset() { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 1, 0, 0, 0); return 0; } uint8_t hwapi::mdb_bill_setup() { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 2, 0, 0, 0); return 0; } uint8_t hwapi::mdb_bill_security(uint16_t secLevel) { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 3, uint8_t(secLevel), uint8_t(secLevel>>8), 0); return 0; } uint8_t hwapi::mdb_bill_pollManually(void) { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 4, 0, 0, 0); return 0; } uint8_t hwapi::mdb_bill_billType(uint16_t billEnable, uint16_t escrowEnable) { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillType, uint8_t(billEnable), uint8_t(billEnable>>8), uint8_t(escrowEnable), uint8_t(escrowEnable>>8)); return 0; } uint8_t hwapi::mdb_bill_escrow(uint8_t action) { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 5, action, 0, 0); return 0; } uint16_t hwapi::mdb_bill_stacker(void) { sendWRcmd_setSendCommand4(SENDDIRCMD_MDB_BillAll, 6, 0, 0, 0); return 0; } uint8_t hwapi::mdb_bill_expansion(uint8_t subCmd, uint8_t send[32]) { uint8_t sendbuf[34], nn; // 1) insert subCmd into buffer for (nn=0; nn<32; nn++) sendbuf[nn+1]=send[nn]; sendbuf[0]=subCmd; sendbuf[33]=0; epi_storeMdbSendData(34, sendbuf); sendWRcmd_setSendCommand0(SENDDIRCMD_MDB_BillExp); return 0; } uint8_t hwapi::mdb_bill_gotPollResponse(void) { // 0: no response 1: got ACK 2: got NAK 3 got ACK with additional data return epi_getMdbResponse(); // request only once, then epi_getMdbRecLength()==0 } uint8_t hwapi::mdb_bill_getDataLen(void) { // return nr of byte received from any mdb device return epi_getMdbRecLength(); } uint8_t hwapi::mdb_bill_getPollData(uint8_t *mdb_data, uint8_t maxBufferSize) { uint8_t len, buf[64], LL; len=epi_getMdbRecLength(); epi_restoreMdbRecData(buf); // request only once, then epi_getMdbRecLength()==0 (maxBufferSizepowerRdBk=epi_restoreReadDIs(DIBYTE0, RB_VGSM); if (epi_cntchk_swRs1toModem()) mod_hw_state->rsSwOk=1; else mod_hw_state->rsSwOk=0; mod_hw_state->rsDrvOk=epi_cntchk_enabDrv01(); // can never be false mod_hw_state->HwState=false; mod_hw_state->CommState=false; mod_hw_state->gotAnswer=false; return 0; } uint8_t hwapi::mod_setCondition(uint16_t chgCmd) { // e.g. change to state registered, sleep, open, off.... return uint8_t(chgCmd); } uint16_t hwapi::mod_getCondition(void) { // e.g. now socket open return 0; } bool hwapi::mod_sendBufferFree(void) { // sending allowed (before writing) and sending finished (after writing) return 0; } void hwapi::mod_wantReadData(uint16_t nrOfData) { // start reading nrOfData=0; } uint8_t hwapi::mod_sendDataBlk(uint16_t len, uint8_t *buf) { len=buf[0]; return uint8_t(len); } uint16_t hwapi::mod_gotData(void) { // return nr of received bytes return 0; } uint8_t hwapi::mod_loadDataBlk(uint16_t len, uint8_t *buf) { len=buf[0]; return uint8_t(len); } uint8_t hwapi::mod_setupSerial(struct TserialParams serialParameter) { // Baudrate and so on... return 0; } uint8_t hwapi::mod_getCurrentSerialSettings(struct TserialParams *serialParameter) { // Baudrate and so on... return 0; } */ // neu, 25.8.21 QString hwapi::dc_getTxt4RsDiagWin(void) const { return epi_getTxt4RsDiagWin(); } void hwapi::dc_clrTxt4RsDiagWin(void) const { epi_clrTxt4RsDiagWin(); } QString hwapi::dc_get2ndTxt4RsDiagWin(void) const { return epi_get2ndTxt4RsDiagWin(); } void hwapi::dc_clr2ndTxt4RsDiagWin(void) const { epi_clr2ndTxt4RsDiagWin(); } QString hwapi::dc_getTxt4HsStateLine(void) const { // Crash! return epi_getTxt4HsStateLine(); } void hwapi::dc_clrTxt4HsStateLine(void) const { epi_clrTxt4HsStateLine(); } QString hwapi::dc_getTxt4masterStateLine(void) const { return epi_getTxt4masterStateLine(); } void hwapi::dc_clrTxt4masterStateLine(void) const { epi_clrTxt4masterStateLine(); } QString hwapi::dc_getTxt4resultStateLine(void) const { return epi_getTxt4resultStateLine(); } void hwapi::dc_clrTxt4resultStateLine(void) const { epi_clrTxt4resultStateLine(); } QString hwapi::dc_getdataStateLine(void) const { return epi_getTxt4dataStateLine(); } void hwapi::dc_clrTxt4dataStateLine(void) const { epi_clrTxt4dataStateLine(); } QString hwapi::dc_getdatifLine(void) const { return epi_getTxt4datifLine(); } void hwapi::dc_clrTxt4datifLine(void) const { epi_clrTxt4datifLine(); } // using DC2 Bootloader void hwapi::bl_iniChain(void) const { dcBL_iniChain(); } bool hwapi::bl_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl) const { return dcBL_importBinFile(readBinFile, fileSize, withDispl); } uint8_t hwapi::bl_activatBootloader(uint8_t *sendData) const { return dcBL_activatBootloader(sendData); } uint8_t hwapi::bl_startChain(void) const { return dcBL_startChain(); } uint8_t hwapi::bl_readBLversion(uint8_t *sendData) const { // minimum size of sendData-buffer: 5byte retval: length return dcBL_readBLversion(sendData); } uint8_t hwapi::bl_readFWversion(uint8_t *sendData) const { // minimum size of sendData-buffer: 5byte retval: length return dcBL_readFWversion(sendData); } uint8_t hwapi::bl_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf) const { // make BL protocol, retval = outbuf length (5...133) // bring data in correct form: start always with 0x02 finish with 0x03 and append checksum // 0x02 Cmd < ...sendData ..> CRC CRC 0x03 // Data length = 0...64 // special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80 // so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64 return dcBL_prepareDC_BLcmd(Cmd, SendDataLength, sendData, outBuf); } uint8_t hwapi::bl_exitBL(uint8_t *sendData) const { // minimum size of sendData-buffer: 5byte retval: length return dcBL_exitBL(sendData); } void hwapi::led_switchLedIllumination(uint8_t on) const { if (on) { } } // neu, 25.3.23 // ------------------------------------------------------------------------------------ // 27.3.2023: Use Device-Controller's Bootloader to send hex-file // ------------------------------------------------------------------------------------ void hwapi::bl_rebootDC(void) const { uint8_t len, buf[20]; len=dcBL_restartDC(buf); sendWRcmd_setSendBlock160(len, buf); } void hwapi::bl_startBL(void) const { uint8_t len, buf[20]; memset(buf, 0x00, sizeof(buf)); len=dcBL_activatBootloader(buf); sendWRcmd_setSendBlock160(len, buf); } bool hwapi::bl_checkBL(void) const { uint8_t len, buf[20]; //len=dcBL_readBLversion(buf); len=dcBL_readFWversion(buf); sendWRcmd_setSendBlock160(len, buf); return (len > 0); } bool hwapi::bl_isUp(void) const { uint8_t receivedData[160]; uint8_t LL; memset(receivedData, 0x00, sizeof(receivedData)); LL=epi_getRawRecLength(); if (LL>0) { epi_getRawReceivedData(receivedData); //epi_clrRawReceivedString(); //qDebug() << " *** got " << LL << " data bytes from BL: " << // receivedData[0] << " " << receivedData[1] << " " << receivedData[2] << " " << // receivedData[3] << " " << receivedData[4] << " " << receivedData[5] << " "; // response to "readFWversion" if (receivedData[0]==2 && receivedData[1]==146 && receivedData[2]==45 && receivedData[3]==45 && receivedData[4] ==95 && receivedData[5]==176) { dcBL_iniLoading(); return true; } // response to "start BL" if (receivedData[0]==2 && receivedData[1]==101 && receivedData[2]==48 && receivedData[3]==223 && receivedData[4] ==131 ) { dcBL_iniLoading(); return true; } } return false; } void hwapi::bl_sendAddress(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 // uint8_t dcBL_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData) // minimum size of sendData-buffer: 13byte retval: length (9...13) sendWRcmd_setSendBlock160(len, buf); // send command to BL } } uint8_t hwapi::bl_wasSendingAddOK(void) const { // return val: 0: no response by now 1:error 10: OK return dcBL_sendSuccess(0x21); // return val: 0: no response by now 1:error 10: OK // lastCommand=0x21 for sendAddr or 0x22 for send data } void hwapi::bl_openBinary(void) const { dcBL_loadBinary(0); } void hwapi::bl_sendDataBlock(uint8_t length, 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); /* hier ist alles richtig qDebug() << "bl_sendDataBlock "<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=check4freeFDlongCmd(); // 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; } //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 return longFDcmd_set(33,0,0, 64, temp); } 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 // 3.5.23: die dynVals und alle templates sollen am stück gesendet uint8_t data[64]; data[0]=nrOftemplate; return longFDcmd_set(152, 0,0, 1, data); } 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=check4freeFDshortCmd(); if (frei<8) return false; 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.4 // 38: <100 to get long 64byte response return ret; } bool hwapi::log_chkIfVaultRecordAvailable(void) const { // return true if completly received return epi_checkIfVaultRecordAvailable(); return false; } 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 { uint16_t LL, nn, len; char *start; uint8_t buf[400]; 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); // =320 start = &retVR->startbuffer[0]; nn=0; do { *start = buf[nn]; start++; } while(++nnram; nn=0; do { *start = buf[nn]; start++; } while(++nnallDoorsDebounced; nn=0; do { *start = buf[nn]; start++; } while(++nn0) { // print was started lastState=res; } } else { if (lastState==0) { // result hat sich auf 1 oder 2 geändert, d.h. Druck ist fertig if (res==1) { //emit hwapi_templatePrintFinished_OK(); } else if (res==2) { //emit hwapi_templatePrintFinished_Err(); } lastState=res; } } return res; } uint8_t hwapi::prn_getCurrentPrinterState() const { // 0: printer OK // bit0: near paper end bit1: no paper // bit2: temperature error bit3: error head open // bit4: paper jam in cutter // bit6: no response bit7: serial rec. error // bit5: printer not ready uint8_t lastPrinterStatus; uint8_t buf[70], leng; // 2nd way to get dyn.conditions: epi_restoreDynMachineConditions(&leng, buf); lastPrinterStatus=buf[53]; return lastPrinterStatus; } // 21.4.23TS: change function "sendDeviceSettings()" to use this struct: "struct T_devices" void hwapi::sys_sendDeviceParameter(struct T_devices *deviceSettings) const { // same as "sendDeviceSettings()" but with much more data uint8_t buf[64]; uint16_t LL, nn; tslib_strclr(buf,0,64); uint8_t *start; // den gesamten struct in einen Puffer kopieren LL=sizeof(struct T_devices); start = &deviceSettings->kindOfPrinter; nn=0; do { buf[nn] = *start; start++; } while(++nnkindOfPrinter; nn=0; do { *start = buf[nn]; start++; } while(++nn0 in case of error // is inncluded in sys_superviseSystem struct T_moduleCondition *modCond=0; sys_getDeviceConditions(modCond); struct T_dynamicCondition *dynMaCond=0; sys_getDynMachineConditions(dynMaCond); struct T_devices *devPara=0; sys_restoreDeviceParameter(devPara); if (modCond->rtc>=200) return 1; if (modCond->printer==200 || modCond->printer==201) // 200: not connected 201: printer-HW-error 202: no paper return 2; if (modCond->printer==202) return 3; if (modCond->coinBlocker>=200) return 4; if (modCond->mdbBus>=200) return 5; if (modCond->intEe>=200) return 6; if (devPara->kindOfCoinChecker==1 || devPara->kindOfCoinChecker==2) // 0: without 1=EMP820 2=EMP900 3=currenza c² (MW) { if (modCond->coinChecker>=200 || modCond->coinEscrow>=200) { // Fehler Münzver. return 7; } if (modCond->coinSafe>200) // 200: kasse fehlt 201: voll 100:fast voll 1:ok { return 8; } } else if (devPara->kindOfCoinChecker==3) { if (modCond->changer>=200) { // Fehler Münzver. return 7; } if (modCond->coinSafe>200) // 200: kasse fehlt 201: voll 100:fast voll 1:ok { return 8; } } if ( modCond->billReader>=200 && devPara->BillAcceptor>0) { // Fehler BNA return 9; } if (dynMaCond->onAlarm>0) return 10; if (dynMaCond->modeAbrech>0) return 11; if (dynMaCond->nowCardTest>0) return 12; if (dynMaCond->startupTestIsRunning>0) return 13; if (modCond->voltage>=200) return 14; if (modCond->temper>=200) return 15; return 0; } // retrigger System-Check with: // bool hwapi::sys_runCompleteTest(void) const uint8_t hwapi::sys_superviseSystem(void) const { // this function proofs if vending is possible depending of doors state struct T_dynamicCondition *dynMaCond=0; struct T_moduleCondition *modCond=0; if (!gpi_areDcDataValid()) { // es gibt keinerlei gültige Daten vom DC return 0; } // jetzt sind die DC-Daten aktuell, also reinholen: sys_getDynMachineConditions(dynMaCond); sys_getDeviceConditions(modCond); if (!modCond->allModulesChecked) { // noch keine Testergebnisse if (dynMaCond->startupTestIsRunning) return 2; // Starttest läuft gerade else return 1; // Starttest ist noch nicht gelaufen } // all doors: 99: undefined 0:closed 1:open if (dynMaCond->lowerDoor || dynMaCond->upperDoor) return 3; if (dynMaCond->middleDoor) return 4; if (sys_componentAssessment() >0) return 5; // errors found return 6; // everything fine } uint8_t hwapi::sys_getSystemErrors(void) const { return sys_componentAssessment(); }