/** ****************************************************************************** * @file : KBus.c * @brief : K-Bus Protocol program body ****************************************************************************** */ #include "KBus.h" #include "functions.h" #include "string.h" #include "stm32f0xx.h" unsigned char bKBusMaster=0,bKBusSlave=0,bKBusRepeater=0;; unsigned char PacketBuf1[128]; unsigned char PacketBuf2[128]; unsigned char BufferIn[16]={0}; unsigned char BufferOut[16]={0}; stChnStat KBusChnStats[8]; unsigned char nStationID=0; unsigned char nChilds; int ChildStat[16]; unsigned char nCurPollId=0; unsigned char nSeq=0; volatile unsigned char KBusMasterRecved=1; volatile unsigned char KBusMasterRecvOK=1; volatile unsigned char KBusSlaveRecved=1; unsigned int KBusSendTimeuS=0; volatile int KBusRecvTimeuS=0; int KBusDelayuS=0; int KBusMaxDelayuS=0; int ThisuS; volatile unsigned int nSlaveTick=0; int Clk3=0; int SendTime,Latancy,LatancyClk,SendClk; volatile int nCount2=0; int TimeOutCount=0; int LastCircleStartTime=0; int CircleTime=0; unsigned char Datas[128]; volatile int PacketLength = 0; unsigned char KBusBCC(void * pData, int nSize) { unsigned char k; k=0; for (int i=0;iSign=StartSign; p1->DstHost=dst; p1->SrcAddr=src; p1->nCMD=nType; p1->nSEQ=nSEQ; int PacketLenth=0; switch (nType) { case cmdNone: break; case cmdPing: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdPingReply: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdRead: break; case cmdReadReply: break; case cmdWrite: break; case cmdWriteReply: p1->PacketLen=DataLen; if (DataLen !=0 ) memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdGetVersion: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdVerInfo: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdExChgData: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdExChgDataReply: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdSyncRead: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdSyncWrite: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdSequenRead: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; case cmdSyncTime: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stKBPacket)+DataLen+1; break; default: break; } return PacketLenth; } int KBusCheckPacket(int nChn, pKBPacket p1, int nLen1) { if (p1->Sign != StartSign) { Uart2Stat.NotPacketErr++; KBusChnStats[nCurPollId].NotPkgErr++; return -1; } int DataLen=p1->PacketLen; if (DataLen>MaxPacketLength) { Uart2Stat.LengthErr++; KBusChnStats[nCurPollId].PkgLenErr++; return -1; } if (nLen1data[DataLen+1] != EndSign) // { // KBusChnStats[nCurPollId].NoEndErr++; // Uart2Stat.LengthErr++; // return -2; // } unsigned char thisBCC=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); if (thisBCC != p1->data[DataLen]) {//BCC Error; Uart2Stat.BCCerr++; KBusChnStats[nCurPollId].BCCErr++; return -4; } return 0; } int KBusSlaveCheckPacket(int nChn, pKBPacket p1, int nLen1) { if (p1->Sign != StartSign) { Uart2Stat.NotPacketErr++; KBusChnStats[0].ClientNotPktErr++; return -1; } int DataLen=p1->PacketLen; if (DataLen>MaxPacketLength) { Uart2Stat.LengthErr++; KBusChnStats[0].ClientPkgLenErr++; return -1; } if (nLen1data[DataLen+1] != EndSign) // { // KBusChnStats[nCurPollId].NoEndErr++; // Uart2Stat.LengthErr++; // return -2; // } unsigned char thisBCC=KBusBCC(p1,sizeof(stKBPacket)+DataLen-1); if (thisBCC != p1->data[DataLen]) {//BCC Error; Uart2Stat.BCCerr++; KBusChnStats[0].ClientBccErr++; return -4; } return 0; } int KBusMasterParsePacket(int nChn, pKBPacket p1, int Len1) { int DataLen=p1->PacketLen; KBusChnStats[nCurPollId].RecvPackets++; pKBPacket p2=(pKBPacket)PacketBuf2; int PacketLen=0; //LL_GPIO_TogglePin(GPIOA,LL_GPIO_PIN_6); int ChildId=p1->SrcAddr; unsigned char nIndex; switch (p1->nCMD) { case cmdNone: break; case cmdPing: BufferIn[ChildId]=p1->data[0]; PacketLen=KBusMakePacket(p2,0,nCurPollId,cmdPingReply,p1->nSEQ,DataLen,p1->data); SendPacket(nChn, p2, PacketLen); break; case cmdPingReply: KBusDelayuS=ThisuS-KBusSendTimeuS; if (KBusDelayuS > KBusMaxDelayuS) KBusMaxDelayuS = KBusDelayuS; BufferIn[ChildId]=p1->data[0]; //RunStat=100; KBusChnStats[nCurPollId].CtnLstPkts=0; KBusChnStats[nCurPollId].Delay=KBusDelayuS; if (KBusDelayuS > KBusChnStats[nCurPollId].MaxDelay) KBusChnStats[nCurPollId].MaxDelay=KBusDelayuS; //PutOutput(outputvalue); KBusMasterRecvOK=1; break; case cmdRead: break; case cmdReadReply: break; case cmdWrite: break; case cmdWriteReply: KBusMasterRecved=1; break; case cmdGetVersion: break; case cmdVerInfo: break; case cmdExChgData: BufferIn[0]=p1->data[0]; //PutOutput(outputvalue); //memcpy(DispBuf,p1->data+2,8); p1->data[0]=BufferOut[0]; PacketLen=KBusMakePacket(p2,nStationID,0,cmdExChgDataReply,p1->nSEQ,DataLen,p1->data); SendPacket(nChn, p2, PacketLen); break; case cmdExChgDataReply: KBusDelayuS=ThisuS-KBusSendTimeuS; if (KBusDelayuS > KBusMaxDelayuS) KBusMaxDelayuS = KBusDelayuS; #if (BOARD_TYPE == 14) BufferIn[ChildId]=p1->data[0]; KMem.WXB[ChildId-1]=BufferIn[ChildId]; if (KMRunStat.WorkMode==0) { // KMem.WY[0]= KMem.WX[1]+(KMem.WX[2]<<8) ; // PutOutput (KMem.WY[0]); } #else BufferIn[ChildId]=p1->data[0]; KMem.WX[ChildId]=BufferIn[ChildId]; if (KMRunStat.WorkMode==0) { KMem.WY[0]= KMem.WX[1]+(KMem.WX[2]<<8) ; PutOutput (KMem.WY[0]); } #endif //RunStat=100; KBusChnStats[nCurPollId].CtnLstPkts=0; KBusChnStats[nCurPollId].Delay=KBusDelayuS; if (KBusDelayuS > KBusChnStats[nCurPollId].MaxDelay) KBusChnStats[nCurPollId].MaxDelay=KBusDelayuS; //PutOutput(outputvalue); nIndex=p1->data[3]; KBusChnStats[nCurPollId].ClientDatas[nIndex]=p1->data[4]|(p1->data[5]<<8)|(p1->data[6]<<16)|(p1->data[7]<<24); KBusMasterRecvOK=1; break; default: break; } // nCurPollId ++; // if (nCurPollId > nChilds) // { // nCurPollId=1; // } return 0; } unsigned char nClientDataIndex=0; int KBusSlaveParsePacket(int nChn, pKBPacket p1, int Len1) { Uart2Stat.OKPacket++; int DataLen=p1->PacketLen; //int nSrcAddr=p1->SrcAddr; int nDstHost=p1->DstHost; // KBusRecvTimeuS=ThisuS; // KBusSlaveRecved=1; pKBPacket p2=(pKBPacket)PacketBuf2; int PacketLen=0; unsigned char nIndex = p1->nSEQ & 0x07; if (nDstHost!=nStationID && nDstHost != 0xff) { KBusChnStats[0].ClientMisIdPkts++; return -1; } if (nDstHost==nStationID || nDstHost==0xff) { KBusRecvTimeuS=ThisuS; KBusSlaveRecved=1; switch (p1->nCMD) { case cmdNone: break; case cmdPing: BufferIn[0]=p1->data[0]; //PutOutput(outputvalue); //memcpy(DispBuf,p1->data+2,8); p1->data[0]=BufferOut[0]; KBusRecvTimeuS=ThisuS; PacketLen=KBusMakePacket(p2,nStationID,0,cmdPingReply,p1->nSEQ,DataLen,p1->data); KBusChnStats[0].ClientSendPkts++; SendPacket(nChn, p2, PacketLen); break; case cmdPingReply: break; case cmdRead: break; case cmdReadReply: break; case cmdWrite: //memcpy(DispBuf,p1->data,DataLen); PacketLen=KBusMakePacket(p2,1,0,cmdWriteReply,p1->nSEQ,0,0); KBusChnStats[0].ClientSendPkts++; SendPacket(nChn, p2, PacketLen); break; case cmdWriteReply: break; case cmdGetVersion: break; case cmdVerInfo: break; case cmdExChgData: BufferIn[0]=p1->data[0]; nSlaveTick=p1->data[4]+(p1->data[5]<<8);//+(p1->data[6]<<16)+(p1->data[7]<<24); #if (BOARD_TYPE == 14) // PutOutput(BufferIn[0]); //PutOutput(outputvalue); //memcpy(DispBuf,p1->data+2,8); nIndex=nClientDataIndex; // KBusChnStats[0].ClientDatas[7]++; // BufferOut[0]=GetInput(); // BufferOut[0]=GetInput(); #else PutOutput(BufferIn[0]); //PutOutput(outputvalue); //memcpy(DispBuf,p1->data+2,8); nIndex=nClientDataIndex; // KBusChnStats[0].ClientDatas[7]++; // BufferOut[0]=GetInput(); BufferOut[0]=GetInput(); #endif p1->data[0]=BufferOut[0]; p1->data[3]=nIndex; p1->data[4]=KBusChnStats[0].ClientDatas[nIndex]; p1->data[5]=KBusChnStats[0].ClientDatas[nIndex]>>8; p1->data[6]=KBusChnStats[0].ClientDatas[nIndex]>>16; p1->data[7]=KBusChnStats[0].ClientDatas[nIndex]>>24; nClientDataIndex++; if (nClientDataIndex >= 10) { nClientDataIndex=0;} PacketLen=KBusMakePacket(p2,nStationID,0,cmdExChgDataReply,p1->nSEQ,DataLen,p1->data); KBusChnStats[0].ClientSendPkts++; SendPacket(nChn, p2, PacketLen); break; case cmdExChgDataReply: break; case cmdSyncRead: break; case cmdSyncWrite: break; case cmdSequenRead: break; case cmdSyncTime: nSlaveTick=p1->data[0]+(p1->data[1]<<8)+(p1->data[2]<<16)+(p1->data[3]<<24); break; default: break; } } return 0; } int KBusParsePacket(int nChn, pKBPacket p1, int Len1) { ThisuS=GetuS(); int Result=0; if (bKBusMaster) { KBusMasterRecved=1; Result=KBusCheckPacket(nChn, p1, Len1); if (Result != S_OK) { return Result; } KBusMasterRecvOK=1; Result=KBusMasterParsePacket(nChn, p1, Len1); return Result; } if (bKBusSlave) { KBusChnStats[0].ClientRecvPkts++; Result=KBusSlaveCheckPacket(nChn, p1, Len1); if (Result != S_OK) { return Result; } KBusChnStats[0].ClientTimeOutErr=KMem.RunStat; Result=KBusSlaveParsePacket(nChn, p1, Len1); return Result; } //int len1=p1->PacketLen; // if (p1->DstHost!=255&&p1->DstHost!=2) return -3; // pKBPacket p2=(pKBPacket)PacketBuf2; // Uart2Stat.OKPacket++; return Result; } /* int InitMachine(stMachineConfig * pConfig) { return S_OK; } int SetConfig(void) { return S_OK; } int StartConfig(void) { return S_OK; } int SetMasterConfig(void) { return S_OK; } int StartPolling(void) { return S_OK; } int ReadData(void) { return S_OK; } int WriteData(void) { return S_OK; } int GetStat(void) { return S_OK; } */ int KBusRepeaterFunc(int nChn) { KMem.WY[0]=KMem.WX[0]; if ((KMem.nRunCount &0x7f) == 88) { nCount2++; ToggleRunLed(); // int len1=sprintf(str1,"%d %d Cfg %02X Input %02X \r\n",nCount,nCount2,EffJumperSW,MyKeyStat1); // PutStr(str1,len1); } return 0; } int KBusMasterFunc(int nChn) { uint32_t tick1=HAL_GetTick(); uint32_t thisuS=GetuS(); int len1=0; if ((KBusMasterRecved && KBusMasterRecvOK && thisuS-KBusSendTimeuS>50) || thisuS-KBusSendTimeuS>1000u) { if (!KBusMasterRecvOK) { TimeOutCount++; Uart2Stat.TimeOutErr++; KBusChnStats[nCurPollId].LostPackets++; KBusChnStats[nCurPollId].CtnLstPkts++; if (!KBusMasterRecved) {KBusChnStats[nCurPollId].TimeOutErr++;} if (KBusChnStats[nCurPollId].CtnLstPkts>KBusChnStats[nCurPollId].MaxCtnLstPkts) {KBusChnStats[nCurPollId].MaxCtnLstPkts=KBusChnStats[nCurPollId].CtnLstPkts;} if (KBusChnStats[nCurPollId].CtnLstPkts>3) { KBusChnStats[nCurPollId].Stat=0; KMem.ErrStat=200; {BufferIn[nCurPollId]=0;} } // LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_7); }else { KBusChnStats[nCurPollId].Stat=1; KMem.RunStat=100; } nCurPollId ++; if (nCurPollId > nChilds) { CircleTime=thisuS-LastCircleStartTime; LastCircleStartTime=thisuS; nSeq++; nCurPollId=1; } #if (BOARD_TYPE == 14) if (KMRunStat.WorkMode==0) { // KMem.WX[0]= GetInput(); // KMem.WY[1]=KMem.WX[0]&0xff; // KMem.WY[2]=(KMem.WX[0]>>8)&0xff; } // BufferOut[1]=KMem.WY[1]; // BufferOut[2]=KMem.WY[2]; #else if (KMRunStat.WorkMode==0) { KMem.WX[0]= GetInput(); KMem.WY[1]=KMem.WX[0]&0xff; KMem.WY[2]=(KMem.WX[0]>>8)&0xff; } BufferOut[1]=KMem.WY[1]; BufferOut[2]=KMem.WY[2]; #endif Datas[0]=BufferOut[nCurPollId]; Datas[1]=BufferOut[nCurPollId+1];; Datas[2]=KBusChnStats[nCurPollId].Stat; Datas[3]=0; Datas[4]=tick1&0xff; Datas[5]=(tick1>>8)&0xff; Datas[6]=(tick1>>16)&0xff; Datas[7]=(tick1>>24)&0xff; KBusSendTimeuS=thisuS; len1=KBusMakePacket((pKBPacket)PacketBuf1,0,nCurPollId,cmdExChgData,nSeq,8,Datas); SendPacket(nChn, (pKBPacket)PacketBuf1, len1); KBusChnStats[nCurPollId].SendPackets++; KBusChnStats[nCurPollId].SendTimeInterval=KBusSendTimeuS-KBusChnStats[nCurPollId].LastSentTimeuS; KBusChnStats[nCurPollId].LastSentTimeuS=KBusSendTimeuS; // PacketLength = len1; SendTime=tick1; KBusMasterRecved=0; KBusMasterRecvOK=0; // LL_GPIO_TogglePin(GPIOA,LL_GPIO_PIN_5); //ToggleErrLed(); // ToggleOut8(); } // Clk3=SysTick->VAL; // LL_GPIO_TogglePin(GPIOA,LL_GPIO_PIN_4); // HAL_Delay(1); return 0; } int KBusSlaveFunc(int nChn) { int ThisuS=GetuS(); int thisRecvTime=KBusRecvTimeuS; if (KBusSlaveRecved) { KMem.RunStat=8000; KBusSlaveRecved=0; }else if ((ThisuS - thisRecvTime) >12000u) { KMem.ErrStat=8000; KMem.SDD[17]=1; KMem.SDD[18]=ThisuS; KMem.SDD[19]=KBusRecvTimeuS; }else if ( ThisuS > (thisRecvTime + 12000u)) { KMem.ErrStat=8000; KMem.SDD[17]=2; KMem.SDD[18]=ThisuS; KMem.SDD[19]=KBusRecvTimeuS; } return 0; }