Compare commits

...

1 Commits

Author SHA1 Message Date
fb75074955 Checking to test compilation 2023-04-26 14:39:32 +02:00
15 changed files with 1520 additions and 1633 deletions

View File

@ -11,7 +11,9 @@ HEADERS += $${PWD}/include/com.h \
$${PWD}/include/sendWRcmd.h \
$${PWD}/include/storeINdata.h \
$${PWD}/include/tslib.h \
$${PWD}/include/shared_mem_buffer.h
$${PWD}/include/shared_mem_buffer.h \
$${PWD}/include/serial_port_thread.h \
$${PWD}/include/serial_port_worker.h
SOURCES += $${PWD}/src/com.cpp \
$${PWD}/src/controlBus.cpp \
@ -22,4 +24,6 @@ SOURCES += $${PWD}/src/com.cpp \
$${PWD}/src/sendWRcmd.cpp \
$${PWD}/src/storeINdata.cpp \
$${PWD}/src/tslib.cpp \
$${PWD}/src/shared_mem_buffer.cpp
$${PWD}/src/shared_mem_buffer.cpp \
$${PWD}/src/serial_port_thread.cpp \
$${PWD}/src/serial_port_worker.cpp

View File

@ -78,7 +78,7 @@ uint8_t dcBL_getResult(void);
#define RAW_BL_DATALEN 150
void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t *receivedData);
void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t const *receivedData);
uint8_t epi_getRawReceivedData(uint8_t *receivedData);
// retval=length, will be zeroed after first reading

View File

@ -148,21 +148,23 @@
// highest priority
#define CMDSTACKDEPTH 16
// #define CMDSTACKDEPTH 16
// means: up to 16 cmd can be stored. They are issued one by one every 100ms
void sendWRcmd_clrCmdStack(void);
bool sendWRcmd_setSendCommand0(uint16_t nextCmd);
bool sendWRcmd_setSendCommand0(uint16_t nextCmd, uint8_t dat1=0, uint8_t dat2=0,
uint8_t dat3=0, uint8_t dat4=0);
// GUI or app sends a command to DC transfered by serial
uint16_t sendWRcmd_getSendCommand0(void);
uint16_t sendWRcmd_getSendCommand0(uint8_t *dat1=0, uint8_t *dat2=0,
uint8_t *dat3=0, uint8_t *dat4=0);
// lower priority
#define CMD4STACKDEPTH 8
// #define CMD4STACKDEPTH 8
void sendWRcmd_clrCmd4Stack(void);
bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4);
uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4);
#define CMD8STACKDEPTH 4
// #define CMD8STACKDEPTH 4
void sendWRcmd_clrCmd8Stack(void);
bool sendWRcmd_setSendCommand8(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint16_t dat3, uint32_t dat4);
uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3, uint32_t *dat4);
@ -171,7 +173,7 @@ uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3,
// lowest priority
// wait for resonse before send next!
bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t *buf);
bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t const *buf);
uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf);
// retval = *leng
@ -179,7 +181,7 @@ void sendWRcmd_INI(void);
uint8_t epi_store64ByteSendData(uint8_t length, uint8_t *buf);
uint8_t epi_store64ByteSendData(uint8_t length, uint8_t const *buf);
// HWapi writes data to be forwarded to DC and further to mdb-device
// not batched! don't use twice within 100ms
@ -211,7 +213,7 @@ uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2, uint8_t *
// user=1: Text-Print is using this buffer
// 2: QR-code-Printer is using this buffer
#define FDCMD_STACKDEPTH 16
//#define FDCMD_STACKDEPTH 16
void sendFDcmd_clrStack(void);
bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4);
// write Command to memory, wait for transport
@ -223,9 +225,9 @@ uint8_t check4FDshortCmd(void);
uint8_t check4freeFDshortCmd(void);
// returns number of free places in short-command stack
#define FDLONG_STACKDEPTH 16
//#define FDLONG_STACKDEPTH 16
void longFDcmd_clrStack(void);
bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data);
bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t const *data);
// write Command to memory, wait for transport
// data buffer size always 64! data[64], padded with 0
bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data);

View File

@ -0,0 +1,22 @@
#ifndef SERIAL_PORT_THREAD_H_INCLUDED
#define SERIAL_PORT_THREAD_H_INCLUDED
#include <QThread>
#include <QString>
#include <QEventLoop>
class SerialPortThread : public QThread {
Q_OBJECT
QEventLoop m_loop;
public:
SerialPortThread(QObject *parent = nullptr);
virtual ~SerialPortThread();
virtual void run() override;
QEventLoop &getEventLoop() { return m_loop; }
};
#endif // SERIAL_PORT_THREAD_H_INCLUDED

View File

@ -0,0 +1,121 @@
#ifndef SERIAL_PORT_WORKER_H_INCLUDED
#define SERIAL_PORT_WORKER_H_INCLUDED
#include <QObject>
#include <QString>
#include <QTimer>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QThread>
#include <assert.h>
#include <condition_variable>
#include <mutex>
#include <queue>
#include <deque>
#include <iostream>
#include <atomic>
struct Command {
enum : uint16_t {PRIORITY_1, PRIORITY_2, PRIORITY_3, PRIORITY_4, END_MARK};
enum : uint16_t {QUIT_SENTINEL = 0x1000, SEND_BLOCK_SIZE = 160};
uint32_t m_priority;
uint16_t m_priorityClass;
uint16_t m_cmdId;
char *m_sendBuffer;
char *m_recvBuffer;
uint8_t m_sendBufferLength;
uint8_t m_recvBufferLength; // expected result length
static std::atomic<uint8_t> m_nextSendBufferIndex;
static std::atomic<uint8_t> m_nextRecvBufferIndex;
static char m_sendBuffers[256][SEND_BLOCK_SIZE];
static char m_recvBuffers[256][SEND_BLOCK_SIZE];
static uint32_t getNextCommandPriority(uint8_t cmdType);
static char *getNextSendBuffer();
static char *getNextRecvBuffer();
public:
Command(uint16_t cmdId, uint8_t sendBufferLength, uint8_t recvBufferLength, uint8_t priorityClass);
Command();
friend bool operator< (Command const& lhs, Command const& rhs) {
return lhs.m_priority < rhs.m_priority;
}
friend std::ostream& operator<< (std::ostream& os, Command const& cmd) {
return os << "{ " << cmd.m_priority << ", '" << cmd.m_priority << "' } ";
}
};
/// \brief SerialPortWorker
///
/// SerialPortWorker sends and receives data from serial port
///
class SerialPortWorker : public QThread {
Q_OBJECT
/// \brief Internal serial port.
QSerialPort m_serialPort;
/// \brief Internal serial port info.
QSerialPortInfo m_serialPortInfo;
/// \brief Flag indicating if serial port is opened.
bool m_serialPortOpened;
/// \brief Port name of serial port.
QString m_portName;
/// \brief Baudrate of internal serial port.
enum QSerialPort::BaudRate m_baudRate;
std::priority_queue<Command, std::deque<Command>> m_sendQueue;
std::deque<Command> m_recvQueue;
std::mutex m_sendQueueMutex;
std::mutex m_recvQueueMutex;
std::condition_variable m_sendQueueCondVar;
std::condition_variable m_recvQueueCondVar;
std::atomic<uint32_t> m_bytesWritten;
std::atomic<uint32_t> m_bytesAvailable;
SerialPortWorker(QString portName, QSerialPort::BaudRate baudRate, QObject *parent = nullptr);
Command getNextCommand();
void insertResult(Command const &result);
enum : uint16_t {TIMEOUT = 100, WAIT_TIME_MAX = 1000};
public:
~SerialPortWorker();
SerialPortWorker(SerialPortWorker const &) = delete;
void operator=(SerialPortWorker const &) = delete;
// serial port im plugin anlegen. erst dann kann getInstance() benutzt werden
static SerialPortWorker &getInstance(QString portName, QSerialPort::BaudRate baudRate, QObject *parent = nullptr) {
static SerialPortWorker serialPortWorker(portName, baudRate, parent);
return serialPortWorker;
}
bool openSerialPort();
void closeSerialPort();
bool isPortOpen() const { return m_serialPortOpened; }
void insertCommand(Command const &cmd);
bool getNextResult(Command &result, int timeout = 1000);
virtual void run() override;
void quit();
private slots:
void getBytesAvailable();
bool getNumberOfBytesWritten(qint64);
};
#endif // SERIAL_PORT_WORKER_H_INCLUDED

View File

@ -6,7 +6,33 @@
#include <QSharedMemory>
// TODO: pid eintragen und convars/mutexe eintragen
#ifdef __linux__
#include <pthread.h>
// PTHREAD_PROCESS_SHARED
#else
// WIN32
#endif
struct SharedMemBuffer {
int init;
char appName[32];
pid_t pid;
pthread_condattr_t sndCndA;
pthread_cond_t sndCndV;
pthread_mutexattr_t sndMtxA;
pthread_mutex_t sndMtx;
pthread_condattr_t rcvCndA;
pthread_cond_t rcvCndV;
pthread_mutexattr_t rcvMtxA;
pthread_mutex_t rcvMtx;
struct rs {
char comportName[16]; // z.B. "COM48"
char baudStr[16]; // z.B. "19200"
@ -18,104 +44,125 @@ struct SharedMemBuffer {
char AutoEmissionOn; // 1: zyklisch Anfragen zum Slave senden
struct datif {
#define DATIF_MAXCMDS 16
uint16_t sendingPeriod;
bool sendingPer_changed;
uint8_t OutCmdpara1;
uint8_t OutCmdpara2;
uint8_t OutCmdpara3;
uint8_t OutCmdpara4;
uint16_t OutCmdpara5;
uint32_t OutCmdpara6;
uint8_t dataStep;
uint8_t scanStep;
uint8_t RDBLKNR;
uint8_t cycl_running;
} datif;
#if 0
// controlBus.cpp
char txt4comStateLine[32];
char txt4HsStateLine[32];
char txt4masterStateLine[32];
char txt4resultStateLine[32];
char txt4dataLine[32];
char txt4datifReceive[32];
char txt4diagWindow[32];
char sndTxt4diagWindow[32];
bool Sdata_serialTestResult[32];
uint8_t Sdata_pProtResultOk[32];
uint16_t Sdata_receivedDataLength[32];
uint8_t Sdata_receivedDataBlock[64];
struct txt4 {
char comStateLine[32];
char HsStateLine[32];
char masterStateLine[32];
char resultStateLine[32];
char dataLine[32];
char datifReceive[32];
char diagWindow[32];
char sndDiagWindow[32];
} txt4;
// datif.cpp
uint8_t dif_dataStep;
uint8_t dif_scanStep;
uint8_t RDBLKNR;
uint8_t datif_OutCmdpara1;
uint8_t datif_OutCmdpara2;
uint8_t datif_OutCmdpara3;
uint8_t datif_OutCmdpara4;
uint16_t datif_OutCmdpara5;
uint32_t datif_OutCmdpara6;
uint8_t cycl_running;
// dcBL.cpp
uint8_t dcBL_LastBLcmd; // stored the last sent cmd in order to analys response
uint8_t dcBL_AtbBinFile[300000];
uint32_t dcBL_fileSize;
uint16_t dcBL_nrOfBlocks;
uint16_t dcBL_fileCrc;
uint8_t dcBL_myBuf[300000]; // same content like "dcBL_AtbBinFile" but bytewise
char BlResp[50][32];
uint8_t dcBL_step;
uint8_t dcBL_state;
uint16_t dcBL_BlkCtr;
uint16_t dcBL_cyclCtr;
struct dcBL {
#define SIZEBLRESP 50
#define RAW_BL_DATALEN 150
uint8_t LastBLcmd; // stored the last sent cmd in order to analys response
uint8_t AtbBinFile[300000];
uint32_t fileSize;
uint16_t nrOfBlocks;
uint16_t fileCrc;
uint8_t myBuf[300000]; // same content like "dcBL_AtbBinFile" but bytewise
char Resp[SIZEBLRESP][32];
int pResp;
uint8_t step;
uint8_t state;
uint16_t BlkCtr;
uint16_t cyclCtr;
uint16_t repeatCtr;
uint8_t Sdata_rawData[150];
uint8_t Sdata_LengthRawData;
} dcBL;
// hwapi.cpp
uint16_t hwapi_shutterTime;
struct {
uint16_t shutterTime;
char ticketTemplate[1024];
} hwapi;
// sendWRcmd.cpp
uint16_t nextAsynchsendCmd0[16];
uint8_t nrOfCmdsInQueue;
uint16_t nextAsynchsendCmd4[8];
uint8_t nextCmd4para1[8];
uint8_t nextCmd4para2[8];
uint8_t nextCmd4para3[8];
uint8_t nextCmd4para4[8];
uint8_t nrOfCmds4InQueue;
uint16_t nextAsynchsendCmd8[4];
uint8_t nextCmd8para1[4];
uint8_t nextCmd8para2[4];
uint16_t nextCmd8para3[4];
uint32_t nextCmd8para4[4];
uint8_t nrOfCmds8InQueue;
struct {
uint8_t sendAsynchDataBuf[160]; // no stack, only ONE buffer
uint8_t sendAsyDatLen;
uint8_t Sdata_mdbSendBuffer[64];
uint8_t Sdata_mdbSendLen;
uint8_t prnDataParameters[4];
uint8_t prnDataBufferUser;
char Sdata_PRN_TEXT[20][64];
uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK
uint8_t nextFDwrCmd[16];
uint8_t nextFDrdCmd[16];
uint8_t nextFDblkNr[16];
} next;
uint8_t nextFDpara1[16];
uint8_t nextFDpara2[16];
uint8_t nextFDpara3[16];
uint8_t nextFDpara4[16];
uint8_t p_nextFDcmdsInQueue;
uint8_t longFDwrCmd[16];
uint8_t longFDrdCmd[16];
uint8_t longFDblkNr[16];
uint8_t longFDlength[16];
struct { // highest priority
#define CMDSTACKDEPTH 16
// up to 16 cmd can be stored. They are issued one by one every 100ms
uint16_t AsynchSend[CMDSTACKDEPTH];
uint8_t para1[CMDSTACKDEPTH]; /* used to streamline source */
uint8_t para2[CMDSTACKDEPTH]; /* used to streamline source */
uint8_t para3[CMDSTACKDEPTH]; /* used to streamline source */
uint8_t para4[CMDSTACKDEPTH]; /* used to streamline source */
uint8_t nrOfCmdsInQueue;
} Cmd0;
uint8_t longFDpara[16][64];
uint8_t p_longFDcmdsInQueue;
struct { // lower priority
// Command Stack for commands with 4 parameters
#define CMD4STACKDEPTH 8
uint16_t AsynchSend[CMD4STACKDEPTH];
uint8_t para1[CMD4STACKDEPTH];
uint8_t para2[CMD4STACKDEPTH];
uint8_t para3[CMD4STACKDEPTH];
uint8_t para4[CMD4STACKDEPTH];
uint8_t nrOfCmdsInQueue;
} Cmd4;
// storeInData.cpp
bool indat_savePrnPwr;
bool indat_saveMifPwr;
bool indat_MdbIsOn;
#endif
struct {
#define CMD8STACKDEPTH 4
uint16_t AsynchSend[CMD8STACKDEPTH];
uint8_t para1[CMD8STACKDEPTH];
uint8_t para2[CMD8STACKDEPTH];
uint16_t para3[CMD8STACKDEPTH];
uint32_t para4[CMD8STACKDEPTH];
uint8_t nrOfCmdsInQueue;
} Cmd8;
struct { // short command, 4 data bytes
#define FDCMD_STACKDEPTH 16
uint8_t wrCmd[FDCMD_STACKDEPTH];
uint8_t rdCmd[FDCMD_STACKDEPTH];
uint8_t blkNr[FDCMD_STACKDEPTH];
uint8_t para1[FDCMD_STACKDEPTH];
uint8_t para2[FDCMD_STACKDEPTH];
uint8_t para3[FDCMD_STACKDEPTH];
uint8_t para4[FDCMD_STACKDEPTH];
uint8_t cmdsInQueue;
} FDShort;
struct { // long command, 64 data bytes
#define FDLONG_STACKDEPTH 16
uint8_t wrCmd[FDLONG_STACKDEPTH];
uint8_t rdCmd[FDLONG_STACKDEPTH];
uint8_t blkNr[FDLONG_STACKDEPTH];
uint8_t length[FDLONG_STACKDEPTH];
uint8_t para[FDLONG_STACKDEPTH][64];
uint8_t cmdsInQueue;
} FDLong;
struct {
uint8_t DataParameters[4];
uint8_t DataBufferUser;
uint8_t pDataBuff; // points to next PRINTER_BLOCK
} prn;
struct {
bool savePrnPwr;
bool saveMifPwr;
bool MdbIsOn;
} indat;
uint8_t ndbs;
uint8_t pari;
@ -170,10 +217,13 @@ struct SharedMemBuffer {
#define NROFMIFSTATEBYTES 40
#define PRN_STATE_ARRAY_SIZE 20
#define PRN_STATE_FONT_SIZE 20
#define MAXNROF_PRNBYTES 64
#define MAXNROF_PRNBLOCKS 20
uint8_t MIF_STATE[NROFMIFSTATEBYTES];
uint8_t MIF_DATA[12][64];
uint8_t PRN_STATE[PRN_STATE_ARRAY_SIZE];
uint8_t PRN_FONTS[PRN_STATE_FONT_SIZE];
char PRN_TEXT[MAXNROF_PRNBLOCKS][MAXNROF_PRNBYTES];
bool mdb_busRdy;
bool mdb_V12on;
bool mdb_V5on;
@ -193,6 +243,10 @@ struct SharedMemBuffer {
uint8_t pProtResultOk;
uint16_t receivedDataLength;
uint8_t receivedDataBlock[64];
uint8_t rawData[150];
uint8_t LengthRawData;
uint8_t mdbSendBuffer[64];
uint8_t mdbSendLen;
} Sdata;
uint8_t mif_cardType;

View File

@ -97,65 +97,63 @@ bool gpi_PeriodicSendTimeHasChanged() {
// ///////////////////////////////////////////////////////////////////////////////////
// linke Spalte, über Connect Button
static QString txt4comStateLine;
QString epi_getTxt4comStateLine(void) {
// GUI: get Text for serial Comport-State Line
return txt4comStateLine;
return SharedMemBuffer::getDataConst()->txt4.comStateLine;
}
void gpi_setTxt4comStateLine(QString txtline) {
// serial: write Text to be displayed in serial Comport-State line (like "connected")
txt4comStateLine.clear();
if (txtline=="")
txt4comStateLine.clear();
else
txt4comStateLine=txtline;
memset(SharedMemBuffer::getData()->txt4.comStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.comStateLine));
memcpy(SharedMemBuffer::getData()->txt4.comStateLine,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.comStateLine)-1);
}
void epi_clrTxt4comStateLine() {
txt4comStateLine.clear();
memset(SharedMemBuffer::getData()->txt4.comStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.comStateLine));
}
// rechte Spalte, oberste Statuszeile
// I) "Handshakes" (serial Control) flow.cpp
// geht überhaupt was raus? kommt überhaupt was zurück?
static QString txt4HsStateLine;
QString epi_getTxt4HsStateLine(void) {
return txt4HsStateLine;
return SharedMemBuffer::getDataConst()->txt4.HsStateLine;
}
void gpi_setTxt4HsStateLine(QString txtline) {
txt4HsStateLine.clear();
if (txtline=="")
txt4HsStateLine.clear();
else
txt4HsStateLine=txtline;
// serial: write Text to be displayed in serial Comport-State line (like "connected")
memset(SharedMemBuffer::getData()->txt4.HsStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.HsStateLine));
memcpy(SharedMemBuffer::getData()->txt4.HsStateLine,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.HsStateLine)-1);
}
void epi_clrTxt4HsStateLine() {
txt4HsStateLine.clear();
memset(SharedMemBuffer::getData()->txt4.HsStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.HsStateLine));
}
// II) Master receive state (empfangenes Telgramm OK? crc? length? )
// Statuszeile Auswertung der SlaveResponse (serial Frame, CRC usw) (prot.cpp)
static QString txt4masterStateLine;
QString epi_getTxt4masterStateLine(void) {
return txt4masterStateLine;
return SharedMemBuffer::getDataConst()->txt4.masterStateLine;
}
void gpi_setTxt4masterStateLine(QString txtline) {
txt4masterStateLine.clear();
if (txtline=="")
txt4masterStateLine.clear();
else
txt4masterStateLine=txtline;
memset(SharedMemBuffer::getData()->txt4.masterStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.masterStateLine));
memcpy(SharedMemBuffer::getData()->txt4.masterStateLine,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.masterStateLine)-1);
}
void epi_clrTxt4masterStateLine() {
txt4masterStateLine.clear();
memset(SharedMemBuffer::getData()->txt4.masterStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.masterStateLine));
}
//---------------------------------------------------------------------------------------------
@ -164,110 +162,96 @@ void epi_clrTxt4masterStateLine() {
// entweder Empfangsfehler anzeigen (crc? length?) oder result OUT-OK, OUT_ERR, IN_OK, IN_ERR
// Hintergrund: wenn der Slave Fehler im Master-Telegramm gefunden hat, dann kann er es auch
// nicht verwenden und nichts ausgeben oder einlesen
static QString txt4resultStateLine;
QString epi_getTxt4resultStateLine(void) {
return txt4resultStateLine;
return SharedMemBuffer::getDataConst()->txt4.resultStateLine;
}
void gpi_setTxt4resultStateLine(QString txtline) {
txt4resultStateLine.clear();
if (txtline=="")
txt4resultStateLine.clear();
else
txt4resultStateLine=txtline;
memset(SharedMemBuffer::getData()->txt4.resultStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.resultStateLine));
memcpy(SharedMemBuffer::getData()->txt4.resultStateLine,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.resultStateLine)-1);
}
void epi_clrTxt4resultStateLine() {
txt4resultStateLine.clear();
memset(SharedMemBuffer::getData()->txt4.resultStateLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.resultStateLine));
}
//---------------------------------------------------------------------------------------------
// IV Statuszeile Empfangsdaten
static QString txt4dataLine;
QString epi_getTxt4dataStateLine(void) {
// GUI: get Text for serial Comport-State Line
return txt4dataLine;
return SharedMemBuffer::getDataConst()->txt4.dataLine;
}
void gpi_setTxt4dataStateLine(QString txtline) {
// serial: write Text to be displayed in serial Comport-State line (like "connected")
txt4dataLine.clear();
if (txtline=="")
txt4dataLine.clear();
else
txt4dataLine=txtline;
memset(SharedMemBuffer::getData()->txt4.dataLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.dataLine));
memcpy(SharedMemBuffer::getData()->txt4.dataLine,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.dataLine)-1);
}
void epi_clrTxt4dataStateLine() {
txt4dataLine.clear();
memset(SharedMemBuffer::getData()->txt4.dataLine,
0x00, sizeof(SharedMemBuffer::getData()->txt4.dataLine));
}
//---------------------------------------------------------------------------------------------
// 5. Zeile: Datif Ergebnis, Daten brauchbar?
static QString txt4datifReceive;
QString epi_getTxt4datifLine(void) {
return txt4datifReceive;
return SharedMemBuffer::getDataConst()->txt4.datifReceive;
}
void gpi_setTxt4datifLine(QString txtline) {
txt4datifReceive.clear();
if (txtline=="")
txt4datifReceive.clear();
else
txt4datifReceive=txtline;
memset(SharedMemBuffer::getData()->txt4.datifReceive,
0x00, sizeof(SharedMemBuffer::getData()->txt4.datifReceive));
memcpy(SharedMemBuffer::getData()->txt4.datifReceive,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.datifReceive)-1);
}
void epi_clrTxt4datifLine() {
txt4datifReceive.clear();
memset(SharedMemBuffer::getData()->txt4.datifReceive,
0x00, sizeof(SharedMemBuffer::getData()->txt4.datifReceive));
}
//---------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------
static QString txt4diagWindow;
QString epi_getTxt4RsDiagWin(void) {
return txt4diagWindow;
return SharedMemBuffer::getDataConst()->txt4.diagWindow;
}
void gpi_setTxt4RsDiagWin(QString txtline) {
txt4diagWindow.clear();
if (txtline=="")
txt4diagWindow.clear();
else
txt4diagWindow=txtline;
memset(SharedMemBuffer::getData()->txt4.diagWindow,
0x00, sizeof(SharedMemBuffer::getData()->txt4.diagWindow));
memcpy(SharedMemBuffer::getData()->txt4.diagWindow,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.diagWindow)-1);
}
void epi_clrTxt4RsDiagWin() {
txt4diagWindow.clear();
memset(SharedMemBuffer::getData()->txt4.diagWindow,
0x00, sizeof(SharedMemBuffer::getData()->txt4.diagWindow));
}
//---------------------------------------------------------------------------------------------
static QString sndTxt4diagWindow;
QString epi_get2ndTxt4RsDiagWin(void) {
return sndTxt4diagWindow;
return SharedMemBuffer::getDataConst()->txt4.sndDiagWindow;
}
void gpi_set2ndTxt4RsDiagWin(QString txtline) {
sndTxt4diagWindow.clear();
if (txtline=="")
sndTxt4diagWindow.clear();
else
sndTxt4diagWindow=txtline;
memset(SharedMemBuffer::getData()->txt4.sndDiagWindow,
0x00, sizeof(SharedMemBuffer::getData()->txt4.sndDiagWindow));
memcpy(SharedMemBuffer::getData()->txt4.sndDiagWindow,
txtline.toStdString().c_str(),
sizeof(SharedMemBuffer::getData()->txt4.sndDiagWindow)-1);
}
void epi_clr2ndTxt4RsDiagWin() {
sndTxt4diagWindow.clear();
memset(SharedMemBuffer::getData()->txt4.sndDiagWindow,
0x00, sizeof(SharedMemBuffer::getData()->txt4.sndDiagWindow));
}
// ///////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1772,8 +1772,7 @@ void hwapi::readback_machineIDdata(uint8_t *length, uint8_t *data) const
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
{
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);
@ -1801,54 +1800,39 @@ uint8_t hwapi::lock_closeLowerDoor(void) const
return 0;
}
void hwapi::shut_openOnce(void) const
{
void hwapi::shut_openOnce(void) const {
// and close automatic after shutter time
uint16_t zeit=hwapi_shutterTime;
zeit/=100;
uint16_t zeit = (SharedMemBuffer::getDataConst()->hwapi.shutterTime) / 100;
sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYTIME, uint8_t(zeit) ,0,0,0);
}
void hwapi::shut_openForCoin(bool start) const
{
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;
uint16_t zeit = (SharedMemBuffer::getDataConst()->hwapi.shutterTime) / 100;
sendWRcmd_setSendCommand4(SENDDIRCMD_SHUTOPENBYCOIN, uint8_t(start), uint8_t(zeit),0,0);
}
void hwapi::shut_sendOpeningTime(uint16_t timeIn_ms ) const
{
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;
SharedMemBuffer::getData()->hwapi.shutterTime = timeIn_ms;
}
void hwapi::esc_takeMoney(void) const
{
void hwapi::esc_takeMoney(void) const {
// and close automatically after escrow time (1s)
sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_TAKE);
}
void hwapi::esc_returnMoney(void) const
{
void hwapi::esc_returnMoney(void) const {
// and close automatically after time
sendWRcmd_setSendCommand0(SENDDIRCMD_ESCRO_GIVE);
}
// ----------------------------------------------------------------------------------------------------------
// --------------------------------------------- MIFARE -----------------------------------------------------
// ----------------------------------------------------------------------------------------------------------

9
src/main.cpp Normal file
View File

@ -0,0 +1,9 @@
#include <QCoreApplication>
#include "tslib.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
return a.exec();
}

View File

@ -1,283 +1,157 @@
#include <stdint.h>
#include <cstdint>
#include <algorithm>
#include <QString>
#include <QDebug>
#include "tslib.h"
#include "sendWRcmd.h"
#include "shared_mem_buffer.h"
void indat_PrnPwr(void);
/* convention: use simple (not rotating) FIFO Stack:
Example: nrOfCmdsInQueue=4 then
nextAsynchsendCmd0[0]=cmd1 // was stored as first
nextAsynchsendCmd0[1]=cmd2
nextAsynchsendCmd0[2]=cmd3
nextAsynchsendCmd0[3]=cmd4 // came in as last
void sendWRcmd_INI(void)
{
Send: [0] first, then move buffer 1 down:
nextAsynchsendCmd0[0]=cmd2
nextAsynchsendCmd0[1]=cmd3
nextAsynchsendCmd0[2]=cmd4
nextAsynchsendCmd0[3]=0;
nrOfCmdsInQueue=3 now
*/
template <typename T, std::size_t N>
static void *move_buffer_down_by_one(T (&buffer)[N]) {
return memmove(buffer, &buffer[1], sizeof(buffer)-sizeof(buffer[0]));
}
template <typename T, std::size_t N>
static void clear(T (&buffer)[N]) {
memset((char *)(&buffer[0]), 0x00, sizeof(buffer));
}
template <typename T, std::size_t M, std::size_t N>
static void clear(T (&buffer)[M][N]) {
memset((char *)(&buffer[0][0]), 0x00, sizeof(buffer));
}
template <typename T>
static void sendWRcmd_clearCmdStack(T &cmdStack) {
clear(cmdStack.AsynchSend);
clear(cmdStack.para1);
clear(cmdStack.para2);
clear(cmdStack.para3);
clear(cmdStack.para4);
cmdStack.nrOfCmdsInQueue = 0;
}
template <typename T, typename T1, typename T2, typename T3, typename T4>
static bool sendWRcmd_setSendCmd(T &cmdStack, uint16_t nextCmd, T1 dat1,
T2 dat2, T3 dat3, T4 dat4) {
uint8_t const &n = cmdStack.nrOfCmdsInQueue;
int const STACKDEPTH = sizeof(cmdStack.para1);
if (n < STACKDEPTH) {
cmdStack.AsynchSend[n] = nextCmd;
cmdStack.para1[n] = dat1;
cmdStack.para2[n] = dat2;
cmdStack.para3[n] = dat3;
cmdStack.para4[n] = dat4;
cmdStack.nrOfCmdsInQueue += 1;
return true; // ok, will be sent
}
qCritical() << "cannot save cmd because stack is full";
return false; // not possible
}
template <typename T, typename T1, typename T2, typename T3, typename T4>
static bool sendWRcmd_getSendCmd(T &cmdStack, T1 *dat1, T2 *dat2,
T3 *dat3, T4 *dat4) {
if (dat1 && dat2 && dat3 && dat4) {
uint8_t const &n = cmdStack.nrOfCmdsInQueue;
int const STACKDEPTH = sizeof(cmdStack.para1);
if ((n > 0) && (n <= STACKDEPTH)) {
uint16_t const nxt = cmdStack.AsynchSend[0];
move_buffer_down_by_one(cmdStack.AsynchSend);
*dat1 = cmdStack.para1[n];
*dat2 = cmdStack.para2[n];
*dat3 = cmdStack.para3[n];
*dat4 = cmdStack.para4[n];
cmdStack.nrOfCmdsInQueue = n - 1;
return nxt;
}
}
qCritical() << "cannot fetch cmd";
return 0; // error
}
void sendWRcmd_INI(void) {
sendWRcmd_clrCmdStack();
sendWRcmd_clrCmd4Stack();
sendFDcmd_clrStack();
longFDcmd_clrStack();
}
// Command Stack for commands without parameters
static uint16_t nextAsynchsendCmd0[CMDSTACKDEPTH];
static uint8_t nrOfCmdsInQueue;
/* convention: use simple (not rotating) FIFO Stack:
Example: nrOfCmdsInQueue=4 then
nextAsynchsendCmd0[0]=cmd1 // was stored as first
nextAsynchsendCmd0[1]=cmd2
nextAsynchsendCmd0[2]=cmd3
nextAsynchsendCmd0[3]=cmd4 // came in as last
Send: [0] first, then move buffer 1 down:
nextAsynchsendCmd0[0]=cmd2
nextAsynchsendCmd0[1]=cmd3
nextAsynchsendCmd0[2]=cmd4
nextAsynchsendCmd0[3]=0;
nrOfCmdsInQueue=3 now
*/
void sendWRcmd_clrCmdStack(void)
{
uint8_t nn;
for (nn=0; nn<CMDSTACKDEPTH; nn++)
nextAsynchsendCmd0[nn]=0;
nrOfCmdsInQueue=0;
void sendWRcmd_clrCmdStack(void) {
sendWRcmd_clearCmdStack(SharedMemBuffer::getData()->Cmd0);
}
void sendWRcmd_clrCmd4Stack(void) {
sendWRcmd_clearCmdStack(SharedMemBuffer::getData()->Cmd4);
}
void sendWRcmd_clrCmd8Stack(void) {
sendWRcmd_clearCmdStack(SharedMemBuffer::getData()->Cmd8);
}
bool sendWRcmd_setSendCommand0(uint16_t nextCmd)
{
bool sendWRcmd_setSendCommand0(uint16_t nextCmd, uint8_t dat1, uint8_t dat2,
uint8_t dat3, uint8_t dat4) {
// write Command to memory, wait for transport
if (nrOfCmdsInQueue>=CMDSTACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextAsynchsendCmd0[nrOfCmdsInQueue++]=nextCmd;
//qDebug() << "PI cmd queued:"<< nextCmd << ", saved, pp=" << nrOfCmdsInQueue;
return true; // ok, will be sent
return sendWRcmd_setSendCmd(SharedMemBuffer::getData()->Cmd0,
nextCmd, dat1, dat2, dat3, dat4);
}
uint16_t sendWRcmd_getSendCommand0(void)
{
uint16_t nxtAsynchCmd;
uint8_t nn, ll;
if (nrOfCmdsInQueue==0 || nrOfCmdsInQueue>CMDSTACKDEPTH)
return 0; // error
nxtAsynchCmd=nextAsynchsendCmd0[0];
// move Puffer down by one element
if (CMDSTACKDEPTH>0)
ll=CMDSTACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
nextAsynchsendCmd0[nn]=nextAsynchsendCmd0[nn+1];
if (nrOfCmdsInQueue>0)
nrOfCmdsInQueue--;
//qDebug() << "PI cmd queued:"<< nxtAsynchCmd << ", restored, pp now =" << nrOfCmdsInQueue;
return nxtAsynchCmd;
}
//---------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------
// Command Stack for commands with 4 parameters
static uint16_t nextAsynchsendCmd4[CMD4STACKDEPTH];
static uint8_t nextCmd4para1[CMD4STACKDEPTH];
static uint8_t nextCmd4para2[CMD4STACKDEPTH];
static uint8_t nextCmd4para3[CMD4STACKDEPTH];
static uint8_t nextCmd4para4[CMD4STACKDEPTH];
static uint8_t nrOfCmds4InQueue;
/* convention: use simple (not rotating) FIFO Stack:
Example: nrOfCmdsInQueue=4 then
nextAsynchsendCmd0[0]=cmd1 // was stored as first
nextAsynchsendCmd0[1]=cmd2
nextAsynchsendCmd0[2]=cmd3
nextAsynchsendCmd0[3]=cmd4 // came in as last
Send: [0] first, then move buffer 1 down:
nextAsynchsendCmd0[0]=cmd2
nextAsynchsendCmd0[1]=cmd3
nextAsynchsendCmd0[2]=cmd4
nextAsynchsendCmd0[3]=0;
nrOfCmdsInQueue=3 now
*/
void sendWRcmd_clrCmd4Stack(void)
{
uint8_t nn;
for (nn=0; nn<CMD4STACKDEPTH; nn++)
{
nextAsynchsendCmd4[nn]=0;
nextCmd4para1[nn]=0;
nextCmd4para2[nn]=0;
nextCmd4para3[nn]=0;
nextCmd4para4[nn]=0;
}
nrOfCmds4InQueue=0;
}
bool sendWRcmd_setSendCommand4(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4)
{
bool sendWRcmd_setSendCommand4(uint16_t nextCmd,
uint8_t dat1, uint8_t dat2,
uint8_t dat3, uint8_t dat4) {
// write Command to memory, wait for transport
if (nrOfCmds4InQueue>=CMD4STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextAsynchsendCmd4[nrOfCmds4InQueue]=nextCmd;
nextCmd4para1[nrOfCmds4InQueue]=dat1;
nextCmd4para2[nrOfCmds4InQueue]=dat2;
nextCmd4para3[nrOfCmds4InQueue]=dat3;
nextCmd4para4[nrOfCmds4InQueue]=dat4;
//qDebug() << "data with 4 data byte saved, pp=" << nrOfCmds4InQueue;
//qDebug() << " dat1=" << nextCmd4para1[nrOfCmds4InQueue] << " dat2=" << nextCmd4para2[nrOfCmds4InQueue]
// << " dat3=" << nextCmd4para3[nrOfCmds4InQueue] << " dat4=" << nextCmd4para4[nrOfCmds4InQueue];
nrOfCmds4InQueue++;
return true; // ok, will be sent
return sendWRcmd_setSendCmd(SharedMemBuffer::getData()->Cmd4, nextCmd, dat1,
dat2, dat3, dat4);
}
uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4)
{
uint16_t nxtAsynchCmd;
uint8_t nn, ll;
if (nrOfCmds4InQueue==0 || nrOfCmds4InQueue>CMD4STACKDEPTH)
return 0; // error
nxtAsynchCmd=nextAsynchsendCmd4[0];
*dat1=nextCmd4para1[0];
*dat2=nextCmd4para2[0];
*dat3=nextCmd4para3[0];
*dat4=nextCmd4para4[0];
//qDebug() << "cmd4 restored to send from [0]; pp=" << nrOfCmds4InQueue;
//qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] <<
// " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0];
// move Puffer down by one element
if (CMD4STACKDEPTH>0)
ll=CMD4STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
nextAsynchsendCmd4[nn]=nextAsynchsendCmd4[nn+1];
nextCmd4para1[nn]=nextCmd4para1[nn+1];
nextCmd4para2[nn]=nextCmd4para2[nn+1];
nextCmd4para3[nn]=nextCmd4para3[nn+1];
nextCmd4para4[nn]=nextCmd4para4[nn+1];
}
if (nrOfCmds4InQueue>0)
nrOfCmds4InQueue--;
//qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue;
return nxtAsynchCmd;
}
static uint16_t nextAsynchsendCmd8[CMD8STACKDEPTH];
static uint8_t nextCmd8para1[CMD8STACKDEPTH];
static uint8_t nextCmd8para2[CMD8STACKDEPTH];
static uint16_t nextCmd8para3[CMD8STACKDEPTH];
static uint32_t nextCmd8para4[CMD8STACKDEPTH];
static uint8_t nrOfCmds8InQueue;
void sendWRcmd_clrCmd8Stack(void)
{
uint8_t nn;
for (nn=0; nn<CMD8STACKDEPTH; nn++)
{
nextAsynchsendCmd8[nn]=0;
nextCmd8para1[nn]=0;
nextCmd8para2[nn]=0;
nextCmd8para3[nn]=0;
nextCmd8para4[nn]=0;
}
nrOfCmds8InQueue=0;
}
bool sendWRcmd_setSendCommand8(uint16_t nextCmd, uint8_t dat1, uint8_t dat2, uint16_t dat3, uint32_t dat4)
{
bool sendWRcmd_setSendCommand8(uint16_t nextCmd,
uint8_t dat1, uint8_t dat2,
uint16_t dat3, uint32_t dat4) {
// write Command to memory, wait for transport
if (nrOfCmds8InQueue>=CMD8STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextAsynchsendCmd8[nrOfCmds8InQueue]=nextCmd;
nextCmd8para1[nrOfCmds8InQueue]=dat1;
nextCmd8para2[nrOfCmds8InQueue]=dat2;
nextCmd8para3[nrOfCmds8InQueue]=dat3;
nextCmd8para4[nrOfCmds8InQueue]=dat4;
nrOfCmds8InQueue++;
return sendWRcmd_setSendCmd(SharedMemBuffer::getData()->Cmd8, nextCmd, dat1,
dat2, dat3, dat4);
}
uint16_t sendWRcmd_getSendCommand0(uint8_t *dat1, uint8_t *dat2,
uint8_t *dat3, uint8_t *dat4) {
return sendWRcmd_getSendCmd(SharedMemBuffer::getData()->Cmd0, dat1, dat2,
dat3, dat4);
}
uint16_t sendWRcmd_getSendCommand4(uint8_t *dat1, uint8_t *dat2,
uint8_t *dat3, uint8_t *dat4) {
return sendWRcmd_getSendCmd(SharedMemBuffer::getData()->Cmd4, dat1, dat2,
dat3, dat4);
}
uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2,
uint16_t *dat3, uint32_t *dat4) {
return sendWRcmd_getSendCmd(SharedMemBuffer::getData()->Cmd8, dat1, dat2,
dat3, dat4);
}
bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t const *buf) {
SharedMemBuffer::getData()->next.sendAsyDatLen = std::min(leng, (uint8_t)160);
clear(SharedMemBuffer::getData()->next.sendAsynchDataBuf);
memcpy((char *)(&SharedMemBuffer::getData()->next.sendAsynchDataBuf),
(char const *)(buf),
SharedMemBuffer::getDataConst()->next.sendAsyDatLen);
return true; // ok, will be sent
}
uint16_t sendWRcmd_getSendCommand8(uint8_t *dat1, uint8_t *dat2, uint16_t *dat3, uint32_t *dat4)
{
uint16_t nxtAsynchCmd;
uint8_t nn, ll;
if (nrOfCmds8InQueue==0 || nrOfCmds8InQueue>CMD8STACKDEPTH)
return 0; // error
nxtAsynchCmd=nextAsynchsendCmd8[0];
*dat1=nextCmd8para1[0];
*dat2=nextCmd8para2[0];
*dat3=nextCmd8para3[0];
*dat4=nextCmd8para4[0];
// move buffer down by one element
if (CMD8STACKDEPTH>0)
ll=CMD8STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
nextAsynchsendCmd8[nn]=nextAsynchsendCmd8[nn+1];
nextCmd8para1[nn]=nextCmd8para1[nn+1];
nextCmd8para2[nn]=nextCmd8para2[nn+1];
nextCmd8para3[nn]=nextCmd8para3[nn+1];
nextCmd8para4[nn]=nextCmd8para4[nn+1];
}
if (nrOfCmds8InQueue>0)
nrOfCmds8InQueue--;
return nxtAsynchCmd;
}
static uint8_t sendAsynchDataBuf[160]; // no stack, only ONE buffer
static uint8_t sendAsyDatLen;
bool sendWRcmd_setSendBlock160(uint8_t leng, uint8_t *buf)
{
//qDebug() << "pi epi: storing send data";
if (leng>160) leng=160;
sendAsyDatLen=leng;
tslib_strclr(sendAsynchDataBuf, 0, 160);
for (uint8_t nn=0; nn<leng; nn++)
sendAsynchDataBuf[nn]=buf[nn];
return true; // ok, will be sent
}
uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf)
{
uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf) {
//qDebug() << "pi gpi: restoring send data";
*leng=sendAsyDatLen;
for (uint8_t nn=0; nn<sendAsyDatLen; nn++)
buf[nn]=sendAsynchDataBuf[nn];
sendAsyDatLen=0;
//tslib_strclr(sendAsynchDataBuf, 0, 64);
*leng = SharedMemBuffer::getDataConst()->next.sendAsyDatLen;
memcpy((char *)buf,
(char const *)(SharedMemBuffer::getData()->next.sendAsynchDataBuf),
*leng);
SharedMemBuffer::getData()->next.sendAsyDatLen = 0;
return *leng;
}
@ -290,184 +164,141 @@ uint8_t sendWRcmd_getSendBlock160(uint8_t *leng, uint8_t *buf)
// start with: SENDDIRCMD_EXCHGMDB,
// send crude data from here to DC, DC to mdb slaves, mdb answer, return here within 50ms
static uint8_t Sdata_mdbSendBuffer[64];
static uint8_t Sdata_mdbSendLen;
uint8_t epi_store64ByteSendData(uint8_t length, uint8_t *buf)
{
uint8_t epi_store64ByteSendData(uint8_t length, uint8_t const *buf) {
// HWapi writes data to be forwarded to DC and further to mdb-device
for (uint8_t nn=0; nn<length; nn++)
Sdata_mdbSendBuffer[nn]=buf[nn];
Sdata_mdbSendLen=length;
memcpy((char *)(&SharedMemBuffer::getData()->Sdata.mdbSendBuffer[0]),
(char const *)buf, length);
SharedMemBuffer::getData()->Sdata.mdbSendLen = length;
return 0;
}
uint8_t gpi_restore64ByteSendData(uint8_t *length, uint8_t *buf)
{
uint8_t gpi_restore64ByteSendData(uint8_t *length, uint8_t *buf) {
// datif reads data to forward to dc
for (uint8_t nn=0; nn<Sdata_mdbSendLen; nn++)
buf[nn]=Sdata_mdbSendBuffer[nn];
*length=Sdata_mdbSendLen;
Sdata_mdbSendLen=0;
memcpy((char *)(buf),
(char const *)(&SharedMemBuffer::getDataConst()->Sdata.mdbSendBuffer[0]),
SharedMemBuffer::getDataConst()->Sdata.mdbSendLen);
*length = SharedMemBuffer::getDataConst()->Sdata.mdbSendLen;
SharedMemBuffer::getData()->Sdata.mdbSendLen = 0;
return 0;
}
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//---------------------------------------- Printer Text Fifo -------------------------
static uint8_t prnDataParameters[4];
static uint8_t prnDataBufferUser;
void epi_storeUserOfSendingTextBuffer(uint8_t user, uint8_t para1, uint8_t para2, uint8_t para3, uint8_t para4 )
{
void epi_storeUserOfSendingTextBuffer(uint8_t user, uint8_t para1,
uint8_t para2, uint8_t para3,
uint8_t para4 ) {
// user=1: Text-Print is using this buffer
// 2: QR-code-Printer is using this buffer
prnDataBufferUser=user;
prnDataParameters[0]=para1;
prnDataParameters[1]=para2;
prnDataParameters[2]=para3;
prnDataParameters[3]=para4;
// qDebug() << "new user stored: " << user;
SharedMemBuffer::getData()->prn.DataBufferUser = user;
SharedMemBuffer::getData()->prn.DataParameters[0] = para1;
SharedMemBuffer::getData()->prn.DataParameters[1] = para2;
SharedMemBuffer::getData()->prn.DataParameters[2] = para3;
SharedMemBuffer::getData()->prn.DataParameters[3] = para4;
}
uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2, uint8_t *para3, uint8_t *para4)
{
uint8_t gpi_getUserOfSendingTextBuffer(uint8_t *para1, uint8_t *para2,
uint8_t *para3, uint8_t *para4) {
// user=1: Text-Print is using this buffer
// 2: QR-code-Printer is using this buffer
//qDebug() << "returning user "<< prnDataBufferUser;
*para1=prnDataParameters[0];
*para2=prnDataParameters[1];
*para3=prnDataParameters[2];
*para4=prnDataParameters[3];
return prnDataBufferUser;
*para1 = SharedMemBuffer::getDataConst()->prn.DataParameters[0];
*para2 = SharedMemBuffer::getDataConst()->prn.DataParameters[1];
*para3 = SharedMemBuffer::getDataConst()->prn.DataParameters[2];
*para4 = SharedMemBuffer::getDataConst()->prn.DataParameters[3];
return SharedMemBuffer::getDataConst()->prn.DataBufferUser;
}
// Sending Text Fifo
// Sending Text Fifo
// ONE printer doc consists of 20 x 64 byte
// #define MAXNROF_PRNBYTES 64
// #define MAXNROF_PRNBLOCKS 20
static char Sdata_PRN_TEXT[MAXNROF_PRNBLOCKS][MAXNROF_PRNBYTES];
static uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK
// static char Sdata_PRN_TEXT[MAXNROF_PRNBLOCKS][MAXNROF_PRNBYTES];
// static uint8_t pPrnDataBuff; // points to next PRINTER_BLOCK
//static uint8_t pPrnDataBuff; // points to next waiting printer text
// defined above, needed if more then one text is stored (before sent)
// every block will be sent after 100ms, if 8 blocks are stored within this 100ms
// then pointer goes up to 8. Important: FIFO!!!!!!!!
void epi_resetPrinterStack(void)
{
pPrnDataBuff=0;
void epi_resetPrinterStack(void) {
SharedMemBuffer::getData()->prn.pDataBuff = 0;
}
uint8_t epi_storePrnText(char *buf, uint8_t leng)
{
uint8_t epi_storePrnText(char *buf, uint8_t leng) {
// store text from Gui in next higher free memory 0....9
uint16_t len;
uint8_t pp, nn;
uint16_t const len = std::min(leng, (uint8_t)MAXNROF_PRNBYTES);
int const pp = SharedMemBuffer::getDataConst()->prn.pDataBuff;
pp=pPrnDataBuff; // next free memory block with 64byte each
if (pp>=MAXNROF_PRNBLOCKS)
return 1; // not possible, no free mem
//len=tslib_strlen(buf); // kennt keine Binärzeichen!!!!!!
len=leng;
if (len>MAXNROF_PRNBYTES)
len=MAXNROF_PRNBYTES;
tslib_strclr(Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES);
for (nn=0; nn<len; nn++)
Sdata_PRN_TEXT[pp][nn]=buf[nn]; // copy new text into buffer
if (pPrnDataBuff<MAXNROF_PRNBLOCKS)
pPrnDataBuff++; // inc pointer if end not yet reached
// next free memory block with 64byte each
if (pp < MAXNROF_PRNBLOCKS) {
clear(SharedMemBuffer::getData()->Sdata.PRN_TEXT[pp]);
// copy new text into buffer
memcpy((char *)(&SharedMemBuffer::getData()->Sdata.PRN_TEXT[pp][0]),
(char const *)(buf), len);
// inc pointer if end not yet reached
SharedMemBuffer::getData()->prn.pDataBuff++;
return 0; // OK
}
return 1; // not possible, no free mem
}
uint8_t gpi_restorePrnText(uint8_t *retbuf)
{
uint8_t gpi_restorePrnText(uint8_t *retbuf) {
// read printer text and send to slave, size of retbuf == 64
// always read from [0] because this is the oldest (Fifo)
// then move all text lines down by one and dec pointer
int pp = SharedMemBuffer::getDataConst()->prn.pDataBuff;
uint8_t nn, pp=pPrnDataBuff;
if (pp==0) // next free memory block with 64byte each
return 1; // no text in buffer
if (pp > 0) { // next free memory block with 64byte each
// example: pp=5: then buffers [0...4] are occupied
for (nn=0; nn<MAXNROF_PRNBYTES; nn++)
retbuf[nn] = uint8_t (Sdata_PRN_TEXT[0][nn]); // restore oldest text
memcpy((char *)retbuf, // restore oldest text
(char const *)(&SharedMemBuffer::getData()->Sdata.PRN_TEXT[0][0]),
sizeof(SharedMemBuffer::getDataConst()->Sdata.PRN_TEXT[0]));
// now copy textline [1] to [0], then
// copy textline [2] to [1], then
// copy textline [3] to [2] .... upto [pp-1] to [pp-2]
// hint: copying from 9....0 would delete all strings!!!!!!
for (nn=0; nn<(pp-1); nn++)
tslib_strcpy(Sdata_PRN_TEXT[nn+1], Sdata_PRN_TEXT[nn], MAXNROF_PRNBYTES);
if (pPrnDataBuff>0)
pPrnDataBuff--;
pp=pPrnDataBuff;
for (int nn=0; nn < (pp-1); nn++) {
memmove((char *)(&SharedMemBuffer::getData()->Sdata.PRN_TEXT[nn+1][0]),
(char const *)(&SharedMemBuffer::getDataConst()->Sdata.PRN_TEXT[nn][0]),
sizeof(SharedMemBuffer::getDataConst()->Sdata.PRN_TEXT[0]));
}
if (SharedMemBuffer::getDataConst()->prn.pDataBuff > 0) {
SharedMemBuffer::getData()->prn.pDataBuff--;
}
pp = SharedMemBuffer::getDataConst()->prn.pDataBuff;
// example: pp=4: then buffers [0...3] are still occupied, pp=0: all buffers empty
// now clear highest copyed line (which got free now)
tslib_strclr(Sdata_PRN_TEXT[pp], 0, MAXNROF_PRNBYTES);
clear(SharedMemBuffer::getData()->Sdata.PRN_TEXT[pp]);
// optionally: clear all remaining higher lines:
for (nn=(pp+1); nn<MAXNROF_PRNBLOCKS; nn++)
tslib_strclr(Sdata_PRN_TEXT[nn], 0, MAXNROF_PRNBYTES);
for (int nn = (pp+1); nn < MAXNROF_PRNBLOCKS; nn++) {
clear(SharedMemBuffer::getData()->Sdata.PRN_TEXT[nn]);
}
return 0;
}
return 1; // no text in buffer
}
uint8_t gpi_chk4remainingText(void)
{
uint8_t gpi_chk4remainingText(void) {
// retval: 0: no more textline left (to send) >0: nr of 64byte-blocks
return (pPrnDataBuff);
return SharedMemBuffer::getDataConst()->prn.pDataBuff;
}
// ---------------------------------------------------------------------------------
// 11.4.23 neu, Kommando direkt an "FastDevice"-protokoll senden, nicht mehr umsetzen
// ---------------------------------------------------------------------------------
// short command, 4 data bytes
static uint8_t nextFDwrCmd[FDCMD_STACKDEPTH];
static uint8_t nextFDrdCmd[FDCMD_STACKDEPTH];
static uint8_t nextFDblkNr[FDCMD_STACKDEPTH];
static uint8_t nextFDpara1[FDCMD_STACKDEPTH];
static uint8_t nextFDpara2[FDCMD_STACKDEPTH];
static uint8_t nextFDpara3[FDCMD_STACKDEPTH];
static uint8_t nextFDpara4[FDCMD_STACKDEPTH];
static uint8_t p_nextFDcmdsInQueue;
/* convention: use simple (not rotating) FIFO Stack:
Example: nrOfCmdsInQueue=4 then
nextAsynchsendCmd0[0]=cmd1 // was stored as first
@ -483,191 +314,144 @@ Example: nrOfCmdsInQueue=4 then
nrOfCmdsInQueue=3 now
*/
void sendFDcmd_clrStack(void)
{
uint8_t nn;
for (nn=0; nn<FDCMD_STACKDEPTH; nn++)
{
nextFDwrCmd[nn]=0;
nextFDrdCmd[nn]=0;
nextFDblkNr[nn]=0;
nextFDpara1[nn]=0;
nextFDpara2[nn]=0;
nextFDpara3[nn]=0;
nextFDpara4[nn]=0;
}
p_nextFDcmdsInQueue=0;
void sendFDcmd_clrStack(void) {
clear(SharedMemBuffer::getData()->FDShort.wrCmd);
clear(SharedMemBuffer::getData()->FDShort.rdCmd);
clear(SharedMemBuffer::getData()->FDShort.blkNr);
clear(SharedMemBuffer::getData()->FDShort.para1);
clear(SharedMemBuffer::getData()->FDShort.para2);
clear(SharedMemBuffer::getData()->FDShort.para3);
clear(SharedMemBuffer::getData()->FDShort.para4);
SharedMemBuffer::getData()->FDShort.cmdsInQueue = 0;
}
bool sendFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t dat1, uint8_t dat2, uint8_t dat3, uint8_t dat4)
{
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
if (p_nextFDcmdsInQueue>=FDCMD_STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
nextFDwrCmd[p_nextFDcmdsInQueue]=nextWrCmd;
nextFDrdCmd[p_nextFDcmdsInQueue]=nextRdCmd;
nextFDblkNr[p_nextFDcmdsInQueue]=blockNum;
nextFDpara1[p_nextFDcmdsInQueue]=dat1;
nextFDpara2[p_nextFDcmdsInQueue]=dat2;
nextFDpara3[p_nextFDcmdsInQueue]=dat3;
nextFDpara4[p_nextFDcmdsInQueue]=dat4;
//qDebug() << "data with 4 data byte saved, pp=" << nrOfCmds4InQueue;
//qDebug() << " dat1=" << nextCmd4para1[nrOfCmds4InQueue] << " dat2=" << nextCmd4para2[nrOfCmds4InQueue]
// << " dat3=" << nextCmd4para3[nrOfCmds4InQueue] << " dat4=" << nextCmd4para4[nrOfCmds4InQueue];
p_nextFDcmdsInQueue++;
int const c = SharedMemBuffer::getDataConst()->FDShort.cmdsInQueue;
if (c < FDCMD_STACKDEPTH) {
SharedMemBuffer::getData()->FDShort.wrCmd[c] = nextWrCmd;
SharedMemBuffer::getData()->FDShort.rdCmd[c] = nextRdCmd;
SharedMemBuffer::getData()->FDShort.blkNr[c] = blockNum;
SharedMemBuffer::getData()->FDShort.para1[c] = dat1;
SharedMemBuffer::getData()->FDShort.para2[c] = dat2;
SharedMemBuffer::getData()->FDShort.para3[c] = dat3;
SharedMemBuffer::getData()->FDShort.para4[c] = dat4;
SharedMemBuffer::getData()->FDShort.cmdsInQueue = (c + 1);
return true; // ok, will be sent
}
qCritical() << "cannot save cmd because stack is full";
return false; // not possible
}
bool sendFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4)
{
uint8_t nn, ll;
bool sendFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum,
uint8_t *dat1, uint8_t *dat2, uint8_t *dat3, uint8_t *dat4) {
if (p_nextFDcmdsInQueue==0 || p_nextFDcmdsInQueue>FDCMD_STACKDEPTH)
return false; // not possible
int const c = SharedMemBuffer::getDataConst()->FDShort.cmdsInQueue;
*nextWrCmd=nextFDwrCmd[0];
*nextRdCmd=nextFDrdCmd[0];
*blockNum=nextFDblkNr[0];
*dat1=nextFDpara1[0];
*dat2=nextFDpara2[0];
*dat3=nextFDpara3[0];
*dat4=nextFDpara4[0];
//qDebug() << "cmd4 restored to send from [0]; pp=" << nrOfCmds4InQueue;
//qDebug() << " data1: " << nextCmd4para1[0] << " data2: " << nextCmd4para2[0] <<
// " data3: " << nextCmd4para3[0] << " data4: " << nextCmd4para4[0];
if ((c > 0) && (c <= FDCMD_STACKDEPTH)) {
*nextWrCmd = SharedMemBuffer::getDataConst()->FDShort.wrCmd[c];
*nextRdCmd = SharedMemBuffer::getDataConst()->FDShort.rdCmd[c];
*blockNum = SharedMemBuffer::getDataConst()->FDShort.blkNr[c];
*dat1 = SharedMemBuffer::getDataConst()->FDShort.para1[c];
*dat2 = SharedMemBuffer::getDataConst()->FDShort.para2[c];
*dat3 = SharedMemBuffer::getDataConst()->FDShort.para3[c];
*dat4 = SharedMemBuffer::getDataConst()->FDShort.para4[c];
// move Puffer down by one element
if (FDCMD_STACKDEPTH>0)
ll=FDCMD_STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
nextFDwrCmd[nn]=nextFDwrCmd[nn+1];
nextFDrdCmd[nn]=nextFDrdCmd[nn+1];
nextFDblkNr[nn]=nextFDblkNr[nn+1];
nextFDpara1[nn]=nextFDpara1[nn+1];
nextFDpara2[nn]=nextFDpara2[nn+1];
nextFDpara3[nn]=nextFDpara3[nn+1];
nextFDpara4[nn]=nextFDpara4[nn+1];
for (int m = 0; m < c-1; ++m) {
int const n = m + 1;
SharedMemBuffer::getData()->FDShort.wrCmd[m] = SharedMemBuffer::getDataConst()->FDShort.wrCmd[n];
SharedMemBuffer::getData()->FDShort.rdCmd[m] = SharedMemBuffer::getDataConst()->FDShort.rdCmd[n];
SharedMemBuffer::getData()->FDShort.blkNr[m] = SharedMemBuffer::getDataConst()->FDShort.blkNr[n];
SharedMemBuffer::getData()->FDShort.para1[m] = SharedMemBuffer::getDataConst()->FDShort.para1[n];
SharedMemBuffer::getData()->FDShort.para2[m] = SharedMemBuffer::getDataConst()->FDShort.para2[n];
SharedMemBuffer::getData()->FDShort.para3[m] = SharedMemBuffer::getDataConst()->FDShort.para3[n];
SharedMemBuffer::getData()->FDShort.para4[m] = SharedMemBuffer::getDataConst()->FDShort.para4[n];
}
if (p_nextFDcmdsInQueue>0)
p_nextFDcmdsInQueue--;
//qDebug() << "cmd4 after push down: pp=" << nrOfCmds4InQueue;
SharedMemBuffer::getData()->FDShort.cmdsInQueue = c - 1;
return true; // ok, will be sent
}
uint8_t check4FDshortCmd(void)
{
// returns number of waiting command, max FDCMD_STACKDEPTH
return p_nextFDcmdsInQueue;
}
uint8_t check4freeFDshortCmd(void)
{
// returns number of free places in short-command stack
return FDCMD_STACKDEPTH - p_nextFDcmdsInQueue;
}
// long command, 64 data bytes
static uint8_t longFDwrCmd[FDLONG_STACKDEPTH];
static uint8_t longFDrdCmd[FDLONG_STACKDEPTH];
static uint8_t longFDblkNr[FDLONG_STACKDEPTH];
static uint8_t longFDlength[FDLONG_STACKDEPTH];
static uint8_t longFDpara[FDLONG_STACKDEPTH][64];
static uint8_t p_longFDcmdsInQueue;
void longFDcmd_clrStack(void)
{
uint8_t nn, mm;
for (nn=0; nn<FDLONG_STACKDEPTH; nn++)
{
longFDwrCmd[nn]=0;
longFDrdCmd[nn]=0;
longFDblkNr[nn]=0;
longFDlength[nn]=0;
for (mm=0; mm<64; mm++)
longFDpara[nn][mm]=0;
}
p_longFDcmdsInQueue=0;
return false; // not possible
}
uint8_t check4FDshortCmd(void) { // returns number of waiting command, max FDCMD_STACKDEPTH
return SharedMemBuffer::getDataConst()->FDShort.cmdsInQueue;
}
bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum, uint8_t length, uint8_t *data)
{
uint8_t check4freeFDshortCmd(void) { // returns number of free places in short-command stack
return FDCMD_STACKDEPTH - SharedMemBuffer::getDataConst()->FDShort.cmdsInQueue;
}
void longFDcmd_clrStack(void) {
clear(SharedMemBuffer::getData()->FDLong.wrCmd);
clear(SharedMemBuffer::getData()->FDLong.rdCmd);
clear(SharedMemBuffer::getData()->FDLong.blkNr);
clear(SharedMemBuffer::getData()->FDLong.length);
clear(SharedMemBuffer::getData()->FDLong.para);
SharedMemBuffer::getData()->FDLong.cmdsInQueue = 0;
}
bool longFDcmd_set(uint8_t nextWrCmd, uint8_t nextRdCmd, uint8_t blockNum,
uint8_t length, uint8_t const *data) {
// write Command to memory, wait for transport
// data buffer size always 64! data[64], padded with 0
uint8_t nn;
if (p_longFDcmdsInQueue>=FDLONG_STACKDEPTH)
{
qDebug() << "cannot save cmd because stack is full";
return false; // not possible
}
longFDwrCmd[p_longFDcmdsInQueue]=nextWrCmd;
longFDrdCmd[p_longFDcmdsInQueue]=nextRdCmd;
longFDblkNr[p_longFDcmdsInQueue]=blockNum;
longFDlength[p_longFDcmdsInQueue]=length;
for (nn=0; nn<64; nn++)
longFDpara[p_longFDcmdsInQueue][nn]=data[nn];
int const c = SharedMemBuffer::getDataConst()->FDLong.cmdsInQueue;
p_longFDcmdsInQueue++;
if (c > 0 && c <= FDLONG_STACKDEPTH) {
SharedMemBuffer::getData()->FDLong.wrCmd[c] = nextWrCmd;
SharedMemBuffer::getData()->FDLong.rdCmd[c] = nextRdCmd;
SharedMemBuffer::getData()->FDLong.blkNr[c] = blockNum;
SharedMemBuffer::getData()->FDLong.length[c] = length;
memcpy((char *)SharedMemBuffer::getData()->FDLong.para[c],
(char const *)data,
sizeof(SharedMemBuffer::getDataConst()->FDLong.para[0]));
SharedMemBuffer::getData()->FDLong.cmdsInQueue = c + 1;
return true; // ok, will be sent
}
qCritical() << "cannot save cmd because stack is full";
return false; // not possible
}
bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum, uint8_t *length, uint8_t *data)
{
uint8_t nn, mm, ll;
bool longFDcmd_get(uint8_t *nextWrCmd, uint8_t *nextRdCmd, uint8_t *blockNum,
uint8_t *length, uint8_t *data) {
if (p_longFDcmdsInQueue==0 || p_longFDcmdsInQueue>FDLONG_STACKDEPTH)
return false; // not possible
int const c = SharedMemBuffer::getDataConst()->FDLong.cmdsInQueue;
*nextWrCmd= longFDwrCmd[0];
*nextRdCmd= longFDrdCmd[0];
*blockNum = longFDblkNr[0];
*length = longFDlength[0];
for (mm=0; mm<64; mm++)
data[mm] = longFDpara[0][mm];
if (c > 0 && c <= FDLONG_STACKDEPTH) {
*nextWrCmd = SharedMemBuffer::getDataConst()->FDLong.wrCmd[c];
*nextRdCmd = SharedMemBuffer::getDataConst()->FDLong.rdCmd[c];
*blockNum = SharedMemBuffer::getDataConst()->FDLong.blkNr[c];
*length = SharedMemBuffer::getDataConst()->FDLong.length[c];
memcpy((char *)data,
(char const *)SharedMemBuffer::getDataConst()->FDLong.para[c],
sizeof(SharedMemBuffer::getDataConst()->FDLong.para[0]));
// move Puffer down by one element
if (FDLONG_STACKDEPTH>0)
ll=FDLONG_STACKDEPTH-1;
else
ll=0;
for (nn=0; nn<ll; nn++)
{
longFDwrCmd[nn] = longFDwrCmd[nn+1];
longFDrdCmd[nn] = longFDrdCmd[nn+1];
longFDblkNr[nn] = longFDblkNr[nn+1];
longFDlength[nn] = longFDlength[nn+1];
for (mm=0; mm<64; mm++)
longFDpara[nn][mm] = longFDpara[nn+1][mm];
for (int m = 0; m < c-1; ++m) {
int const n = m + 1;
SharedMemBuffer::getData()->FDLong.wrCmd[m] = SharedMemBuffer::getDataConst()->FDLong.wrCmd[n];
SharedMemBuffer::getData()->FDLong.rdCmd[m] = SharedMemBuffer::getDataConst()->FDLong.rdCmd[n];
SharedMemBuffer::getData()->FDLong.blkNr[m] = SharedMemBuffer::getDataConst()->FDLong.blkNr[n];
SharedMemBuffer::getData()->FDLong.length[m] = SharedMemBuffer::getData()->FDLong.length[n];
memcpy((char *)SharedMemBuffer::getData()->FDLong.para[m],
(char const *)SharedMemBuffer::getData()->FDLong.para[n],
sizeof(SharedMemBuffer::getDataConst()->FDLong.para[0]));
}
if (p_longFDcmdsInQueue>0)
p_longFDcmdsInQueue--;
SharedMemBuffer::getData()->FDLong.cmdsInQueue = c - 1;
return true; // ok, will be sent
}
qCritical() << "cannot save cmd because stack is full";
return false; // not possible
}
uint8_t check4FDlongCmd(void)
{
// returns number of waiting command
return p_longFDcmdsInQueue;
uint8_t check4FDlongCmd(void) { // returns number of waiting command
return SharedMemBuffer::getDataConst()->FDLong.cmdsInQueue;
}
uint8_t check4freeFDlongCmd(void)
{
// returns number of free places in command stack
return FDLONG_STACKDEPTH - p_longFDcmdsInQueue;
uint8_t check4freeFDlongCmd(void) { // returns number of free places in command stack
return FDLONG_STACKDEPTH - SharedMemBuffer::getDataConst()->FDLong.cmdsInQueue;
}

View File

@ -0,0 +1,15 @@
#include "serial_port_thread.h"
SerialPortThread::SerialPortThread(QObject *parent)
: QThread(parent) {
this->setObjectName("SerialPortThread");
}
SerialPortThread::~SerialPortThread() {
m_loop.quit();
}
void SerialPortThread::run() {
m_loop.exec();
}

244
src/serial_port_worker.cpp Normal file
View File

@ -0,0 +1,244 @@
#include "serial_port_worker.h"
#include "serial_port_thread.h"
#include <QDebug>
#include <QCoreApplication>
std::atomic<uint8_t> Command::m_nextSendBufferIndex{0};
std::atomic<uint8_t> Command::m_nextRecvBufferIndex{0};
char Command::m_sendBuffers[256][SEND_BLOCK_SIZE]{{0}};
char Command::m_recvBuffers[256][SEND_BLOCK_SIZE]{{0}};
uint32_t Command::getNextCommandPriority(uint8_t priorityClass) {
static std::atomic<std::uint32_t> priority_1{0};
static std::atomic<std::uint32_t> priority_2{1000000000};
static std::atomic<std::uint32_t> priority_3{2000000000};
static std::atomic<std::uint32_t> priority_4{3000000000};
switch (priorityClass) {
case PRIORITY_1:
return priority_1.fetch_add(1);
case PRIORITY_2:
return priority_2.fetch_add(1);
case PRIORITY_3:
return priority_3.fetch_add(1);
case PRIORITY_4:
return priority_4.fetch_add(1);
}
return -1;
}
char *Command::getNextSendBuffer() {
uint8_t const nextIndex = m_nextSendBufferIndex.fetch_add(1);
return &m_sendBuffers[nextIndex][0];
}
char *Command::getNextRecvBuffer() {
uint8_t const nextIndex = m_nextRecvBufferIndex.fetch_add(1);
return &m_recvBuffers[nextIndex][0];
}
Command::Command(uint16_t cmdId, uint8_t sendBufferLength,
uint8_t recvBufferLength, uint8_t priorityClass)
: m_priority(getNextCommandPriority(priorityClass))
, m_priorityClass(priorityClass)
, m_cmdId(cmdId)
, m_sendBuffer(Command::getNextSendBuffer())
, m_recvBuffer(Command::getNextRecvBuffer())
, m_sendBufferLength(sendBufferLength)
, m_recvBufferLength(recvBufferLength) {
memset(m_sendBuffer, 0x00, sizeof(m_sendBuffers[0]));
}
Command::Command()
: m_priority(0)
, m_priorityClass(0)
, m_cmdId(0)
, m_sendBuffer(0)
, m_recvBuffer(0)
, m_sendBufferLength(0)
, m_recvBufferLength(0) {
}
/**
* \brief Constructor for SerialPort
*
* @date 08.11.2022 first draft.
*
*/
SerialPortWorker::SerialPortWorker(QString portName, enum QSerialPort::BaudRate baudRate, QObject *parent)
: QThread(parent)
, m_serialPort()
, m_serialPortOpened(false)
, m_portName(portName)
, m_baudRate(baudRate)
, m_bytesWritten(0) {
this->setObjectName("SerialPortWorker");
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
if (!info.isNull()) {
qDebug() << "Name .......... " << info.portName();
qDebug() << "Description ... " << info.description();
qDebug() << "Manufacturer .. " << info.manufacturer();
qDebug() << "SerialNumber .. " << info.serialNumber();
if (info.hasProductIdentifier()) {
qDebug() << "Product-ID .... " << info.productIdentifier();
}
if (info.hasVendorIdentifier()) {
qDebug() << "Vendor-ID ..... " << info.vendorIdentifier();
}
qDebug() << "Location ...... " << info.systemLocation();
if (info.portName() == m_portName) {
m_serialPortInfo = info;
}
}
}
if (m_serialPortInfo.portName() == m_portName) {
m_serialPort.setPort(m_serialPortInfo);
m_serialPort.setPortName(m_portName);
m_serialPort.setDataBits(QSerialPort::Data8);
m_serialPort.setParity(QSerialPort::NoParity);
m_serialPort.setStopBits(QSerialPort::OneStop);
m_serialPort.setFlowControl(QSerialPort::NoFlowControl);
m_serialPortOpened = m_serialPort.open(QIODevice::ReadWrite);
}
}
SerialPortWorker::~SerialPortWorker() {
closeSerialPort();
}
void SerialPortWorker::run() {
SerialPortThread serialPortThread;
this->moveToThread(&serialPortThread); // not really necessary
// Note: because this thread is moved to serialPortThread, the event loop
// used will be the one of serialPortThread (this-thread does not even have one).
// This is the only purpose of serialPortThread.
serialPortThread.start();
connect(&m_serialPort, SIGNAL(readyRead()), this, SLOT(getBytesAvailable()));
connect(&m_serialPort, SIGNAL(bytesWritten(qint64)), this, SLOT(getNumberOfBytesWritten(qint64)));
while (m_serialPortOpened) {
Command nextCmd = getNextCommand();
if (nextCmd.m_cmdId == Command::QUIT_SENTINEL) {
break;
}
QByteArray data(nextCmd.getNextSendBuffer(), nextCmd.m_sendBufferLength);
m_bytesWritten = 0;
m_serialPort.write(data);
// process events in event loop of associated thread
serialPortThread.getEventLoop().processEvents(QEventLoop::ExcludeUserInputEvents, TIMEOUT);
int maxWaitTime = WAIT_TIME_MAX;
while (maxWaitTime > 0 && m_bytesWritten < (uint32_t)data.size()) {
if (!m_serialPort.waitForBytesWritten(100)) { // wait timeout-ms for the bytes to be written
// process events in event loop of associated thread
serialPortThread.getEventLoop().processEvents(QEventLoop::ExcludeUserInputEvents, TIMEOUT);
maxWaitTime -= TIMEOUT;
}
}
if (m_bytesWritten == (uint32_t)data.size()) { // data written, wait for result
if (nextCmd.m_recvBufferLength > 0) {
// process events in event loop of associated thread
serialPortThread.getEventLoop().processEvents(QEventLoop::ExcludeUserInputEvents, TIMEOUT);
maxWaitTime = WAIT_TIME_MAX;
while (maxWaitTime > 0 && m_bytesAvailable < nextCmd.m_recvBufferLength) {
if (!m_serialPort.waitForReadyRead(100)) {
// process events in event loop of associated thread
serialPortThread.getEventLoop().processEvents(QEventLoop::ExcludeUserInputEvents, TIMEOUT);
maxWaitTime -= TIMEOUT;
}
}
uint32_t const bytesAvailable = m_bytesAvailable;
if (bytesAvailable == nextCmd.m_recvBufferLength) {
QByteArray result = m_serialPort.read(bytesAvailable);
if (!result.isEmpty() && ((uint32_t)result.size() == bytesAvailable)) {
memcpy(nextCmd.m_recvBuffer, result.data(), bytesAvailable);
insertResult(nextCmd);
}
} else {
// error
}
}
} else {
// error
}
} // while (m_serialPortOpened)
serialPortThread.quit();
serialPortThread.wait();
}
bool SerialPortWorker::openSerialPort() {
if (!m_serialPortOpened) {
return m_serialPort.open(QIODevice::ReadWrite);
}
return false; // opening twice is not allowed
}
void SerialPortWorker::closeSerialPort() {
if (m_serialPortOpened) {
m_serialPort.close();
m_serialPortOpened = false;
}
}
void SerialPortWorker::quit() {
Command cmd(Command::QUIT_SENTINEL, 0, 0, Command::PRIORITY_1);
insertCommand(cmd);
}
void SerialPortWorker::insertCommand(Command const &cmd) {
{ std::lock_guard<std::mutex> lock(m_sendQueueMutex);
m_sendQueue.push(cmd);
} // release lock
m_sendQueueCondVar.notify_one();
}
Command SerialPortWorker::getNextCommand() {
Command nextCmd;
{ std::unique_lock<std::mutex> lock(m_sendQueueMutex);
m_sendQueueCondVar.wait(lock, [this]{ return !this->m_sendQueue.empty(); });
nextCmd = m_sendQueue.top();
m_sendQueue.pop();
} // release lock
return nextCmd;
}
void SerialPortWorker::insertResult(Command const &result) {
{ std::lock_guard<std::mutex> lock(m_recvQueueMutex);
m_recvQueue.push_back(result);
} // release lock
m_recvQueueCondVar.notify_one();
}
bool SerialPortWorker::getNextResult(Command &nextResult, int timeout) {
bool timed_out = false;
{ std::unique_lock<std::mutex> lock(m_recvQueueMutex);
if (m_recvQueueCondVar.wait_for(lock, std::chrono::milliseconds(timeout),
[this]{ return !this->m_recvQueue.empty(); })) {
nextResult = m_recvQueue.front();
m_recvQueue.pop_front();
return true;
} else {
timed_out = true;
}
} // release lock
return (timed_out == false);
}
void SerialPortWorker::getBytesAvailable() {
m_bytesAvailable += m_serialPort.bytesAvailable();
}
bool SerialPortWorker::getNumberOfBytesWritten(qint64 bytesWritten) {
if (bytesWritten > 0) {
m_bytesWritten += (uint32_t)bytesWritten;
return true;
}
return false;
}

View File

@ -1,6 +1,7 @@
#include "shared_mem_buffer.h"
#include <QDebug>
#include <QCoreApplication>
#include <atomic>
#ifdef QT_POSIX_IPC
@ -12,6 +13,12 @@
#include <sys/ipc.h> // ftok
#endif
#ifdef __linux__
#include <unistd.h>
#endif
#define PROCESS_SHARED (PTHREAD_PROCESS_SHARED)
// std::atomic_bool SharedMemBuffer::__sharedMemLocked{false};
QSharedMemory *SharedMemBuffer::getShm(std::size_t size) {
@ -22,6 +29,83 @@ QSharedMemory *SharedMemBuffer::getShm(std::size_t size) {
shMem.setKey(fkey);
if (!shMem.isAttached()) {
if (shMem.create(size)) {
// the creator is the owner of the shared-memory segment
SharedMemBuffer *shm = (SharedMemBuffer *)(shMem.data());
if (shm) {
shm->init = 0;
// mark the shm
memset(shm->appName, 0x00, sizeof(shm->appName));
strncpy(shm->appName,
QCoreApplication::applicationName().toLocal8Bit().constData(),
sizeof(shm->appName)-1);
shm->pid = getpid();
// create condition variables plus associated mutexes for
// sending/receiving commands to dc
int r = 0;
if ((r = pthread_mutexattr_init(&shm->sndMtxA)) != 0) {
qCritical() << "init mutex attribute"
<< strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_mutexattr_setpshared(
&shm->sndMtxA, PTHREAD_PROCESS_SHARED) != 0)) {
qCritical() << "set s-mutex attribute to process shared"
<< strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_mutex_init(&shm->sndMtx,
&shm->sndMtxA) != 0)) {
qCritical() << "init s-mutex" << strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_condattr_init(&shm->sndCndA) != 0)) {
qCritical() << "init s-mutex" << strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_condattr_setpshared(
&shm->sndCndA, PTHREAD_PROCESS_SHARED) != 0)) {
qCritical() << "init s-cond attribute to process shared"
<< strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_cond_init(&shm->sndCndV,
&shm->sndCndA) != 0)) {
qCritical() << "init s-condvar" << strerror(errno) << r;
}
if ((r = pthread_mutexattr_init(&shm->rcvMtxA)) != 0) {
qCritical() << "init r-mutex attribute"
<< strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_mutexattr_setpshared(
&shm->rcvMtxA, PTHREAD_PROCESS_SHARED) != 0)) {
qCritical() << "set r-mutex attribute to process shared"
<< strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_mutex_init(&shm->rcvMtx,
&shm->rcvMtxA) != 0)) {
qCritical() << "init r-mutex" << strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_condattr_init(&shm->rcvCndA) != 0)) {
qCritical() << "init r-mutex" << strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_condattr_setpshared(
&shm->rcvCndA, PTHREAD_PROCESS_SHARED) != 0)) {
qCritical() << "init r-cond attribute to process shared"
<< strerror(errno) << r;
}
if ((r == 0) &&
(r = pthread_cond_init(&shm->rcvCndV,
&shm->rcvCndA) != 0)) {
qCritical() << "init s-condvar" << strerror(errno) << r;
}
shm->init = 1;
}
return &shMem;
} else {
if (shMem.error() == QSharedMemory::AlreadyExists) {