#include "prot.h" #include #include "controlBus.h" #include "dcBL.h" T_prot::T_prot() { mySerialPort = new T_com(); connect(mySerialPort, SIGNAL(receivingFinished()), this, SLOT( analyseRecData() )); //connect(mySerialPort, SIGNAL(sendingFinished()), this, SLOT(sendeFin())); for (int nn=0; nnisPortOpen(); } bool T_prot::isSerialFree(void) { return true; // ohne HS's kann er nicht blockiert sein } void T_prot::setRecLen(uint16_t WriteCmd) { if (WriteCmd<100) { RdDataLength=DATALEN_RECEIVE_LONG; // store here already because it's no longer // returned from slave mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_LONG); } else { RdDataLength=DATALEN_RECEIVE_FAST; mySerialPort->receiveFixLen(TELEGRAMLEN_RECEIVE_FAST); } } void T_prot::setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, uint8_t *data) { WriteCommand=WriteCmd; WriteAddr=WrAddr; WrDataLength=WrDatLen; if (WrDataLength>FRAME_DATALEN) WrDataLength=FRAME_DATALEN; for (int nn=0; nnsetRecLen(WriteCmd); } void T_prot::setUserWriteData(uint16_t WriteCmd, uint16_t WrAddr) { WriteCommand=WriteCmd; WriteAddr=WrAddr; WrDataLength=0; for (int nn=0; nnsetRecLen(WriteCmd); } void T_prot::setUserWriteData(uint16_t WriteCmd) { WriteCommand=WriteCmd; WriteAddr=0; WrDataLength=0; for (int nn=0; nnsetRecLen(WriteCmd); } void T_prot::setUserWrite1DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val) { // wie oben, jedoch einfachere Datenübergabe WriteCommand=WriteCmd; WriteAddr=WrAddr; WrDataLength=1; ui8OutputData[0]=val; SendDataValid=1; // always set WR first kindOfData=0; // 0: binaries, 1:text this->setRecLen(WriteCmd); } void T_prot::setUserWrite2DB(uint16_t WriteCmd, uint16_t WrAddr, uint8_t val0, uint8_t val1) { WriteCommand=WriteCmd; WriteAddr=WrAddr; WrDataLength=2; ui8OutputData[0]=val0; ui8OutputData[1]=val1; SendDataValid=1; // always set WR first kindOfData=0; // 0: binaries, 1:text this->setRecLen(WriteCmd); } void T_prot::setUserWriteText(uint16_t WriteCmd, uint16_t WrAddr, uint8_t WrDatLen, char *data) { WriteCommand=WriteCmd; WriteAddr=WrAddr; WrDataLength=WrDatLen; if (WrDataLength>FRAME_DATALEN) WrDataLength=FRAME_DATALEN; for (int nn=0; nnsetRecLen(WriteCmd); } void T_prot::setUserReadData( uint16_t ReadCmd, uint16_t RdAddr, uint16_t reserv) { ReadCommand=ReadCmd; ReadAddr=RdAddr; reserve=reserv; SendDataValid |=2; readAddress=RdAddr; // store here already because it's no longer returned from slave readSource=ReadCmd; } void T_prot::setUserReadData( uint16_t ReadCmd, uint16_t RdAddr) { ReadCommand=ReadCmd; ReadAddr=RdAddr; reserve=0; SendDataValid |=2; readAddress=RdAddr; // store here already because it's no longer returned from slave readSource=ReadCmd; } void T_prot::setUserReadData( uint16_t ReadCmd) { ReadCommand=ReadCmd; ReadAddr=0; reserve=0; SendDataValid |=2; readAddress=0; // store here already because it's no longer returned from slave readSource=ReadCmd; } void T_prot::setBLsendData( uint8_t len, uint8_t *buf) { for (int nn=0; nnBL_DATA_LEN) BLsendDataLength=BL_DATA_LEN; for (int nn=0; nnsetRecLen(100); // how many?? //readAddress= // needed?? //qDebug()<<"prot: got BL data " << len << "bytes, "; //for (int i=0; ireceiveFixLen(nrOfbytesToReceive); } void T_prot::sendUserData(uint16_t slaveAdr) { // man könnte hier noch "SendDataValid" abfragen, // muss immer 3 sein, muss man aber nicht //qDebug() << "prot send user data "<writeToSerial(packBuf_2, BLsendDataLength); } else startFastPacking(); // quicker since 15.12.21TS //startPacking(); } void T_prot::startFastPacking(void) { uint16_t mycrc; uint16_t sendLen; uint8_t uctmp, nn, pp, CrcLp; char sendBuffer[FRAME_MAXLEN], ctmp; //qDebug() << "prot start fast packing "<9 && WriteCommand<100) { // long command 10...99 // WriteCommand==0 if only read request, then use short sending sendBuffer[0]=STARTSIGN_SEND_LONG; WrDataLength=DATALEN_SEND_LONG; // immer //qDebug() << "send long cmd, len: " << WrDataLength; } else { // fast command sendBuffer[0]=STARTSIGN_SEND_FAST; WrDataLength=DATALEN_SEND_FAST; // immer //qDebug() << "send fast cmd, len: " << WrDataLength; } sendBuffer[1]= uint8_t(WriteCommand); sendBuffer[2]= uint8_t(ReadCommand); if (WriteAddr>0) sendBuffer[3]= char(WriteAddr); // bei fast nur EINE adresse, wr hat Vorrang else sendBuffer[3]= char(ReadAddr); // beim Fast prot. ist das reserve dann ists egal was drin steht if (kindOfData) // 0: binaries, 1:text { for (nn=0; nn>=8; sendBuffer[CrcLp+1]=char(mycrc); sendLen=CrcLp+2; // send to VCP: QByteArray packBuff; packBuff.clear(); packBuff.append(sendBuffer, sendLen); // ohne sendLen wird beim ersten \0 abgeschnitten!!! mySerialPort->writeToSerial(packBuff, sendLen); } /* void T_prot::startPacking(void) { uint16_t mycrc; uint16_t uitmp, sendLen; uint8_t uctmp, nn, pp, CrcLp; char sendBuffer[FRAME_MAXLEN], ctmp; //qDebug() << "prot start packing "<>=8; sendBuffer[2]= char(uitmp); uitmp=WriteCommand; sendBuffer[3]= char(uitmp); uitmp>>=8; sendBuffer[4]= char(uitmp); uitmp=WriteAddr; sendBuffer[5]= char(uitmp); uitmp>>=8; sendBuffer[6]= char(uitmp); uitmp=ReadCommand; sendBuffer[7]= char(uitmp); uitmp>>=8; sendBuffer[8]= char(uitmp); uitmp=ReadAddr; sendBuffer[9]= char(uitmp); uitmp>>=8; sendBuffer[10]= char(uitmp); uitmp=reserve; sendBuffer[11]= '-'; //char(uitmp); uitmp>>=8; sendBuffer[12]= '-'; //char(uitmp); sendBuffer[13]= char(WrDataLength); CrcLp= 14 + WrDataLength; if (kindOfData) // 0: binaries, 1:text { for (nn=0; nn>=8; sendBuffer[CrcLp+1]=char(mycrc); sendLen=CrcLp+2; sendBuffer[CrcLp+2]=13; sendBuffer[CrcLp+3]=10; sendLen+=2; // send to VCP: QByteArray packBuff; packBuff.clear(); packBuff.append(sendBuffer, sendLen); // ohne sendLen wird beim ersten \0 abgeschnitten!!! mySerialPort->writeToSerial(packBuff, sendLen); // void T_com::writeToSerial(const QByteArray &data, uint16_t sendLength) } */ // --------------------------------------------------------------------------------------------------------- // receiving..... // --------------------------------------------------------------------------------------------------------- void T_prot::analyseRecData(void) { // Aufruf per connect aus serialcontrol wenn Daten empfangen wurden // getRecData(QByteArray &data, uint16_t &sendLength); QByteArray Indata; QString myString, tempStr; //char recBuffer[FRAME_MAXLEN]; uint8_t recBuffer[FRAME_MAXLEN]; uint16_t recLength; INdataValid=false; gpi_setTxt4HsStateLine(""); gpi_setTxt4masterStateLine(""); gpi_setTxt4resultStateLine(""); gpi_setTxt4dataStateLine(""); gpi_setTxt4datifLine(""); // read from "VCP": mySerialPort->readFromSerial(Indata, recLength); //qDebug()<<"prot: got data " << recLength; if (recLength>FRAME_MAXLEN) recLength=FRAME_MAXLEN; for (int nn=0; nn0) { // dann anzeige switch (result) { case 1: gpi_setTxt4masterStateLine("wrong length received"); break; case 2: gpi_setTxt4masterStateLine("wrong start sign received"); break; case 3: gpi_setTxt4masterStateLine("received datalen too big"); break; case 4: gpi_setTxt4masterStateLine("wrong data len received"); break; case 5: gpi_setTxt4masterStateLine("wrong crc received"); break; } myString.setNum(result); // Daten abspeichern, könnten vom BL sein: gpi_storeRawReceivedData(uint8_t(recLength), recBuffer); emit rawDataRecieved(); } else { //& result ==0 gpi_setTxt4masterStateLine("slave response OK"); // Daten OK, also prüfe Inhalt. // Konnte der Slave das Master-Command verwenden oder hatte es Fehler? // konnte der Slave die geforderten Daten ausgeben (DOs, AOs)? // konnte der Slave die geforderten Daten einlesen (AIs, DIs)? //CheckInResult(recBuffer); // Ergebnisse des Slaves anzeigen // stimmt nicht mehr bei FastProt ShowFastInData(recBuffer); // Eingangs-Daten des Slaves anzeigen } emit framerecieved(); //qDebug() << "framereceived emitted"; } uint8_t T_prot::FastCheckInData(uint8_t *Inbuf, uint16_t LL) { uint16_t rawInLen=LL, crcL_Addr, recCrc, myCrc, nn, datalen, nxt; if (Inbuf[0]!=STARTSIGN_RECEIVE_FAST && Inbuf[0]!=STARTSIGN_RECEIVE_LONG) { //qDebug() << "prot: got wrong start sign: " << Inbuf[0]; return 2; // wrong start sign } if ( (rawInLen FRAME_DATALEN) //[9]=reported data lenght return 3; // reported datalen too big if ((datalen !=(rawInLen-12)) && (datalen !=(rawInLen-13)) && (datalen !=(rawInLen-14)) ) { // angehängtes CR und/oder LF tolerieren qDebug() << "wrong data length, " << datalen << " " << rawInLen; return 4; // data len does not match to complete length } crcL_Addr=datalen+10; // weil im definierten protocol 10 bytes vor den Daten stehen recCrc=0; recCrc=uchar2uint(uint8_t(Inbuf[crcL_Addr+1]), uint8_t(Inbuf[crcL_Addr])); myCrc=0; for (nn=0; nnSlave) switch (slaveresult) { // received message (from master) analysis: // 0: got valid request // this errors can only come back from a single device (not bus) // or from a bus slave in local mode // 1: wrong start 2: wrong length // 3: wrong crc 4: wrong addr case 1: gpi_setTxt4resultStateLine("slave got wrong start sign"); break; case 2: gpi_setTxt4resultStateLine("slave got wrong length"); break; case 3: gpi_setTxt4resultStateLine("slave got wrong crc"); break; case 4: gpi_setTxt4resultStateLine("slave got wrong addr"); break; case 10: gpi_setTxt4resultStateLine("slave is in local mode"); break; case 13: gpi_setTxt4resultStateLine("local mode with wrong crc"); break; case 14: gpi_setTxt4resultStateLine("local mode with wrong addr"); break; // wenn 1..4 dann konnte der Slave das Mastertelegramm gar nicht verwenden, also hier Stoppen } if (slaveresult>0 && slaveresult<10) return 1; // Slave hat gültiges Kommando empfangen: // 2.result auswerten: // recBuffer[3]; // Write result, d.h. Ergebnis des Schreibvorganges (z.B. DOs) des Slaves // recBuffer[4]; // Read result, d.h. Ergebnis des Lesevorganges (z.B. DIs) des Slaves // bisher nicht bekannt welche Fehlercodes es gibt, also den code direkt ausgeben. // bisher bekannt: 0=OK myString.clear(); myString = "Slave OUT and IN Result: "; tempStr.setNum(Inbuf[3],16); myString.append(tempStr); myString.append(" "); tempStr.setNum(Inbuf[4],16); myString.append(tempStr); gpi_setTxt4resultStateLine(myString); return 0; } uint8_t T_prot::ShowFastInData(uint8_t *recBuffer) { QString myString=nullptr, tempStr=nullptr; uint8_t result; RecSlaveAddr=0; result=recBuffer[1]; // total result result &=0x60; // only read result (bit 5,6) if (result==0) // read result =OK, // dann sind die Eingangsdaten gültig { myString.append("valid INdata: "); INdataValid=true; //readSource already set with sending readAddress=0; // RdDataLength already set with sending if (RdDataLength>FRAME_DATALEN) RdDataLength=FRAME_DATALEN; for (int ii=0; iiFRAME_DATALEN) RdDataLength=FRAME_DATALEN; for (int ii=0; ii