
#ifndef SERIAL_FRAME_H
#define SERIAL_FRAME_H

#include <stdint.h>
#include <QMainWindow>
#include <QString>
#include <QTimer>
#include "tslib.h"
#include "com.h"

/*
 get's OUT-data from datif,
 get's IN-data from datif
 get's send command from datif
    makes frame and calls: isSerialFree(), setSendData(),
    if not free retrigger datif sending period (normally 500ms or 50ms for direct cmds)

    with control-signal: gotReceiveData():
        getRecData();
        send results to diag window/line
        send IN-data to datif
*/

#define     FRAME_DATALEN       64
#define     FRAME_MAXLEN        FRAME_DATALEN+20
#define     BL_DATA_LEN         150

#define     DATALEN_SEND_FAST            4
#define     DATALEN_SEND_LONG            64
#define     HEADERLEN_SEND               4
#define     TELEGRAMLEN_SEND_FAST        12
#define     TELEGRAMLEN_SEND_LONG        70
#define     STARTSIGN_SEND_FAST          0x3F
#define     STARTSIGN_SEND_LONG          0x3D

#define     DATALEN_RECEIVE_FAST            8
#define     DATALEN_RECEIVE_LONG            64
#define     HEADERLEN_RECEIVE               2
#define     TELEGRAMLEN_RECEIVE_FAST        12
#define     TELEGRAMLEN_RECEIVE_LONG        68
#define     STARTSIGN_RECEIVE_FAST          0x5F
#define     STARTSIGN_RECEIVE_LONG          0x5D


class T_prot : public QMainWindow
{
    Q_OBJECT

    // Dateneingang von Datif:
    uint8_t  SendDataValid;     // bit1: WR OK  bit 2: RD OK
    uint16_t slaveAddr;

    uint16_t WriteCommand;
    uint16_t WriteAddr;
    uint8_t  WrDataLength;
    uint8_t  ui8OutputData[FRAME_DATALEN];
    char     chOut_Data[FRAME_DATALEN];
    uint8_t  kindOfData;    // 0: binaries, 1:text

    uint16_t ReadCommand;
    uint16_t ReadAddr;
    uint16_t reserve;

    // Ausgangs-Daten, werden vom Datif geholt:
    // nur wenn CommandState und readState OK
    uint8_t  RecSlaveAddr;
    bool    INdataValid;        // nur true wenn CommandState OK und readState OK
    uint16_t readSource;        // diese (Eingangs-)Daten stehen im Puffer
    uint16_t readAddress;       // von dieser Adr wurden die Daten gelesen
    //uint8_t  lastWakeSrc;       // falls der Slave den Master geweckt hat
    uint8_t  RdDataLength;
    uint8_t  InputData[FRAME_DATALEN];

    // 11.11.2020:
    uint8_t  BLsendDataLength;
    uint8_t  ui8BLsendData[BL_DATA_LEN];

    T_com *mySerialPort;

    void startPacking(void);
    void startFastPacking(void);
    uint8_t FramecheckInData(uint8_t *Inbuf, uint16_t LL);
    uint8_t FastCheckInData(uint8_t *Inbuf, uint16_t LL);

    uint8_t CheckInResult(uint8_t *Inbuf);

    uint8_t ShowFastInData(uint8_t *recBuffer);
    uint8_t ShowInData(uint8_t *recBuffer); // was CheckInData
    void setRecLen(uint16_t WriteCmd);

private slots:
    void analyseRecData(void);

public:
    T_com *getSerialPort() { return mySerialPort; }
    T_com const *getSerialPort() const { return mySerialPort; }

    T_prot();
    bool isPortOpen(void);
    bool isSerialFree(void);
    void setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t  WrDatLen, uint8_t *data);
    void setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr);
    void setUserWriteData(uint16_t WriteCmd);
    void setUserWriteText(uint16_t WriteCmd, uint16_t WrAddr, uint8_t  WrDatLen, char *data);

    void setUserWrite1DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val);
    void setUserWrite2DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1);

    void setUserReadData( uint16_t ReadCmd,  uint16_t RdAddr, uint16_t reserv);
    void setUserReadData( uint16_t ReadCmd,  uint16_t RdAddr);
    void setUserReadData( uint16_t ReadCmd);

    void setBLsendData( uint8_t len, uint8_t *buf);

    void receiveFixLen(int64_t nrOfbytesToReceive);

    void sendUserData(uint16_t slaveAdr);
    bool ifDataReceived();
    bool getReceivedInData(uint8_t  *SlavAddr, uint16_t *readSrc, uint16_t *readAddr,
                           uint8_t  *RdDlen, uint8_t *receivedData);
        // retval: data valid, only one time true
signals:
    void framerecieved();   //bool gotINdata);
    void rawDataRecieved();

};

#endif // T_prot_H
