/** ****************************************************************************** * @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 ChnStats[8]; unsigned char nAddr=0; unsigned char nChilds; int ChildStat[16]; unsigned char nCurPollId=0; unsigned char nSeq=0; volatile unsigned char MasterRecved=1; volatile unsigned char MasterRecvOK=1; volatile unsigned char SlaveRecved=1; unsigned int SendTimeuS=0; volatile int RecvTimeuS=0; int DelayuS=0; int MaxDelayuS=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(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdPingReply: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+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(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdGetVersion: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdVerInfo: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdExChgData: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdExChgDataReply: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdSyncRead: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdSyncWrite: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdSequenRead: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; case cmdSyncTime: p1->PacketLen=DataLen; memcpy(p1->data,pData,DataLen); p1->data[DataLen]=KBusBCC(p1,sizeof(stPacket)+DataLen-1); p1->data[DataLen+1]=EndSign; PacketLenth=sizeof(stPacket)+DataLen+1; break; default: break; } return PacketLenth; } int KBusCheckPacket(int nChn, pPacket p1, int nLen1) { if (p1->Sign != StartSign) { Uart2Stat.NotPacketErr++; ChnStats[nCurPollId].NotPkgErr++; return -1; } int DataLen=p1->PacketLen; if (DataLen>MaxPacketLength) { Uart2Stat.LengthErr++; ChnStats[nCurPollId].PkgLenErr++; return -1; } if (nLen1data[DataLen+1] != EndSign) // { // ChnStats[nCurPollId].NoEndErr++; // Uart2Stat.LengthErr++; // return -2; // } unsigned char thisBCC=KBusBCC(p1,sizeof(stPacket)+DataLen-1); if (thisBCC != p1->data[DataLen]) {//BCC Error; Uart2Stat.BCCerr++; ChnStats[nCurPollId].BCCErr++; return -4; } return 0; } int KBusSlaveCheckPacket(int nChn, pPacket p1, int nLen1) { if (p1->Sign != StartSign) { Uart2Stat.NotPacketErr++; ChnStats[0].ClientNotPktErr++; return -1; } int DataLen=p1->PacketLen; if (DataLen>MaxPacketLength) { Uart2Stat.LengthErr++; ChnStats[0].ClientPkgLenErr++; return -1; } if (nLen1data[DataLen+1] != EndSign) // { // ChnStats[nCurPollId].NoEndErr++; // Uart2Stat.LengthErr++; // return -2; // } unsigned char thisBCC=KBusBCC(p1,sizeof(stPacket)+DataLen-1); if (thisBCC != p1->data[DataLen]) {//BCC Error; Uart2Stat.BCCerr++; ChnStats[0].ClientBccErr++; return -4; } return 0; } int KBusMasterParsePacket(int nChn, pPacket p1, int Len1) { int DataLen=p1->PacketLen; ChnStats[nCurPollId].RecvPackets++; pPacket p2=(pPacket)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: DelayuS=ThisuS-SendTimeuS; if (DelayuS > MaxDelayuS) MaxDelayuS = DelayuS; BufferIn[ChildId]=p1->data[0]; //RunStat=100; ChnStats[nCurPollId].CtnLstPkts=0; ChnStats[nCurPollId].Delay=DelayuS; if (DelayuS > ChnStats[nCurPollId].MaxDelay) ChnStats[nCurPollId].MaxDelay=DelayuS; //PutOutput(outputvalue); MasterRecvOK=1; break; case cmdRead: break; case cmdReadReply: break; case cmdWrite: break; case cmdWriteReply: MasterRecved=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,nAddr,0,cmdExChgDataReply,p1->nSEQ,DataLen,p1->data); SendPacket(nChn, p2, PacketLen); break; case cmdExChgDataReply: DelayuS=ThisuS-SendTimeuS; if (DelayuS > MaxDelayuS) MaxDelayuS = DelayuS; #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; ChnStats[nCurPollId].CtnLstPkts=0; ChnStats[nCurPollId].Delay=DelayuS; if (DelayuS > ChnStats[nCurPollId].MaxDelay) ChnStats[nCurPollId].MaxDelay=DelayuS; //PutOutput(outputvalue); nIndex=p1->data[3]; ChnStats[nCurPollId].ClientDatas[nIndex]=p1->data[4]|(p1->data[5]<<8)|(p1->data[6]<<16)|(p1->data[7]<<24); MasterRecvOK=1; break; default: break; } // nCurPollId ++; // if (nCurPollId > nChilds) // { // nCurPollId=1; // } return 0; } unsigned char nClientDataIndex=0; int KBusSlaveParsePacket(int nChn, pPacket p1, int Len1) { Uart2Stat.OKPacket++; int DataLen=p1->PacketLen; //int nSrcAddr=p1->SrcAddr; int nDstHost=p1->DstHost; // RecvTimeuS=ThisuS; // SlaveRecved=1; pPacket p2=(pPacket)PacketBuf2; int PacketLen=0; unsigned char nIndex = p1->nSEQ & 0x07; if (nDstHost!=nAddr && nDstHost != 0xff) { ChnStats[0].ClientMisIdPkts++; return -1; } if (nDstHost==nAddr || nDstHost==0xff) { RecvTimeuS=ThisuS; SlaveRecved=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]; RecvTimeuS=ThisuS; PacketLen=KBusMakePacket(p2,nAddr,0,cmdPingReply,p1->nSEQ,DataLen,p1->data); ChnStats[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); ChnStats[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; // ChnStats[0].ClientDatas[7]++; // BufferOut[0]=GetInput(); // BufferOut[0]=GetInput(); #else PutOutput(BufferIn[0]); //PutOutput(outputvalue); //memcpy(DispBuf,p1->data+2,8); nIndex=nClientDataIndex; // ChnStats[0].ClientDatas[7]++; // BufferOut[0]=GetInput(); BufferOut[0]=GetInput(); #endif p1->data[0]=BufferOut[0]; p1->data[3]=nIndex; p1->data[4]=ChnStats[0].ClientDatas[nIndex]; p1->data[5]=ChnStats[0].ClientDatas[nIndex]>>8; p1->data[6]=ChnStats[0].ClientDatas[nIndex]>>16; p1->data[7]=ChnStats[0].ClientDatas[nIndex]>>24; nClientDataIndex++; if (nClientDataIndex >= 10) { nClientDataIndex=0;} PacketLen=KBusMakePacket(p2,nAddr,0,cmdExChgDataReply,p1->nSEQ,DataLen,p1->data); ChnStats[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, pPacket p1, int Len1) { ThisuS=GetuS(); int Result=0; if (bKBusMaster) { MasterRecved=1; Result=KBusCheckPacket(nChn, p1, Len1); if (Result != S_OK) { return Result; } MasterRecvOK=1; Result=KBusMasterParsePacket(nChn, p1, Len1); return Result; } if (bKBusSlave) { ChnStats[0].ClientRecvPkts++; Result=KBusSlaveCheckPacket(nChn, p1, Len1); if (Result != S_OK) { return Result; } ChnStats[0].ClientTimeOutErr=KMem.RunStat; Result=KBusSlaveParsePacket(nChn, p1, Len1); return Result; } //int len1=p1->PacketLen; // if (p1->DstHost!=255&&p1->DstHost!=2) return -3; // pPacket p2=(pPacket)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 ((MasterRecved && MasterRecvOK && thisuS-SendTimeuS>50) || thisuS-SendTimeuS>1000u) { if (!MasterRecvOK) { TimeOutCount++; Uart2Stat.TimeOutErr++; ChnStats[nCurPollId].LostPackets++; ChnStats[nCurPollId].CtnLstPkts++; if (!MasterRecved) {ChnStats[nCurPollId].TimeOutErr++;} if (ChnStats[nCurPollId].CtnLstPkts>ChnStats[nCurPollId].MaxCtnLstPkts) {ChnStats[nCurPollId].MaxCtnLstPkts=ChnStats[nCurPollId].CtnLstPkts;} if (ChnStats[nCurPollId].CtnLstPkts>3) { ChnStats[nCurPollId].Stat=0; KMem.ErrStat=200; {BufferIn[nCurPollId]=0;} } // LL_GPIO_SetOutputPin(GPIOA,LL_GPIO_PIN_7); }else { ChnStats[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]=ChnStats[nCurPollId].Stat; Datas[3]=0; Datas[4]=tick1&0xff; Datas[5]=(tick1>>8)&0xff; Datas[6]=(tick1>>16)&0xff; Datas[7]=(tick1>>24)&0xff; SendTimeuS=thisuS; len1=KBusMakePacket((pPacket)PacketBuf1,0,nCurPollId,cmdExChgData,nSeq,8,Datas); SendPacket(nChn, (pPacket)PacketBuf1, len1); ChnStats[nCurPollId].SendPackets++; ChnStats[nCurPollId].SendTimeInterval=SendTimeuS-ChnStats[nCurPollId].LastSentTimeuS; ChnStats[nCurPollId].LastSentTimeuS=SendTimeuS; // PacketLength = len1; SendTime=tick1; MasterRecved=0; MasterRecvOK=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=RecvTimeuS; if (SlaveRecved) { KMem.RunStat=8000; SlaveRecved=0; }else if ((ThisuS - thisRecvTime) >12000u) { KMem.ErrStat=8000; KMem.SDD[17]=1; KMem.SDD[18]=ThisuS; KMem.SDD[19]=RecvTimeuS; }else if ( ThisuS > (thisRecvTime + 12000u)) { KMem.ErrStat=8000; KMem.SDD[17]=2; KMem.SDD[18]=ThisuS; KMem.SDD[19]=RecvTimeuS; } return 0; }