/** ****************************************************************************** * @file : KWireLess.c * @brief : K-WireLess Protocol program body ****************************************************************************** */ #include "KWireLess2.h" #include "functions.h" #include "string.h" #include "PLCFunctions.h" #include "stm32f0xx_hal.h" /************************************************************************************************************************************** Demo 程序流程 RadioEnableMaster=true 为主机端,主机端发送一个"PING"数据后切换到接收,等待从机返回的应答"PONG"数据LED闪烁 RadioEnableMaster=false 为从机端,从机端接收到主机端发过来的"PING"数据后LED闪烁并发送一个"PONG"数据作为应答 ***************************************************************************************************************************************/ #define USE_MODEM_LORA //#define USE_MODEM_FSK /* #if defined( USE_MODEM_LORA ) #define LORA_BANDWIDTH 1 // [0: 125 kHz, // 1: 250 kHz, // 2: 500 kHz, // 3: Reserved] #define LORA_SPREADING_FACTOR 8 // [SF5..SF12] #define LORA_CODINGRATE 4 // [1: 4/5, // 2: 4/6, // 3: 4/7, // 4: 4/8] #define LORA_PREAMBLE_LENGTH 4 // Same for Tx and Rx */ #define LORA_SYMBOL_TIMEOUT 0 // Symbols #define LORA_FIX_LENGTH_PAYLOAD_ON false #define LORA_IQ_INVERSION_ON false /* #elif defined( USE_MODEM_FSK ) #define FSK_FDEV 20e3 // Hz #define FSK_DATARATE 19.2e3 // bps #define FSK_BANDWIDTH 60e3 // Hz >> DSB in sx126x #define FSK_AFC_BANDWIDTH 200e3 // Hz #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx #define FSK_FIX_LENGTH_PAYLOAD_ON false #else #error "Please define a modem in the compiler options." #endif */ /* #define nChannelSpacing 530000 // Hz #define TX_OUTPUT_POWER 16 // 22 dBm */ extern bool IrqFired; //bool RadioEnableMaster=true;//主从选择 //uchar nRadioChannel = 0; //uchar nRadioAddr = 1; uint16_t crc_value; #define MixAddr(x,y) ((x<<4)|(y)) /*! * Radio events function pointer */ #define MASTER_RX_TIMEOUT_VALUE 80 //mS #define SLAVE_RX_TIMEOUT_VALUE 400 //mS #define CYCLE_TIME 80 //mS const stWLConfig defaultWLConfig = { .RF_T_Freq = 430620000, // uint32_t Hz .RF_R_Freq = 430620000, // uint32_t //Hz .nChnSpacing = 530, // uint16_t ChannelSpacing; //kHz .nCycleTime = CYCLE_TIME, // CycleTime // .ModemType = 1, // //0: FSK, 1: LoRa .workMode = 3, // 0, None 1, Uni, 2 Thr, 3 Multi1, 4 Multi2, 5 MulMa .nChannel = 0, .bMaster = 0, .nRadioAddr =1 , .bEnableMulti = 0, .Tx_Power = 20, // uchar Tx_Power; .LoraBandWidth = 1, // uchar LoraBandWidth; // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved ] .LoRaFactor = 5, // uchar LoRaFactor; // [SF5 .. SF 12] .LoRaCodingRate = 1, // uchar LoRaCodingRate; // [1 : 4/5, 2: 4/6, 3: 4/7, 4: 4/8 .NetWorkAddr = 0x00, // uint8_t NetWorkAddr; .DeviceAddr = 0x0102, // uint16_t DeviceAddr; .bEnableAddr = 0, // uchar bEnableAddr; .bEnableEncrypt = 0, // uchar bEnableEncrypt; .bEnableRelay = 0, // uchar bEnableRelay; .LoRaPreambleLen = 4, // uchar LoRaPreamble_Len; // 2 - 12 .bAutoPower = 1, .bAutoReSend = 1, // 自动重发 }; //stWLConfig * pWLCfg = (stWLConfig *)&defaultWLConfig; static RadioEvents_t RadioEvents; stWLConfig WLCfg ; stWLRunStat KwRunStat; typedef enum { LOWPOWER, RX, RX_TIMEOUT, RX_ERROR, TX, TX_TIMEOUT, }States_t; #define WL_RX_BUFFER_SIZE 160 // Define the payload size here #define WL_TX_BUFFER_SIZE 160 // Define the payload size here uint16_t nTimeOnAir; /* const uint8_t PingMsg[] = "PING"; const uint8_t PongMsg[] = "PONG"; */ //uint16_t BufferSize = BUFFER_SIZE; uint8_t KwRx_Buffer[WL_RX_BUFFER_SIZE]; uint8_t KwTx_Buffer[WL_TX_BUFFER_SIZE]; #define WL_TT_EACH_SIZE 64 // transparent transmission byte size for each send States_t State = LOWPOWER; int8_t RssiValue = 0; int8_t SnrValue = 0; emKWStates KW_State=KW_UNINIT; void LedToggle(void) { // GPIO_WriteBit( LED1_PORT, LED1_PIN,Bit_RESET);//LED闪烁 // HAL_Delay_nMS(10); // GPIO_WriteBit( LED1_PORT, LED1_PIN,Bit_SET); LL_GPIO_TogglePin(GPIOC,LL_GPIO_PIN_13); } int LoadKwConfig(void) { stStoredWLConfig * pstStoredWLCFG = (stStoredWLConfig *)(STORE_KWCONFIG_BASE); if (pstStoredWLCFG->BlockSign == 0x55AA && pstStoredWLCFG->BlockType == 0x05) { WLCfg = pstStoredWLCFG->WLConfig; } else { WLCfg = defaultWLConfig; } return 0; } int SaveKwConfig(void) { // stStoredWLConfig * pstStoredWLCFG = (stStoredWLConfig *)(STORE_KWCONFIG_BASE); stStoredWLConfig theStoredWLCFG; theStoredWLCFG.BlockSign = 0x55AA; theStoredWLCFG.BlockType = 0x05; theStoredWLCFG.nSeq = 1; theStoredWLCFG.nSize = sizeof(stWLConfig); theStoredWLCFG.WLConfig = WLCfg; theStoredWLCFG.nCRC16 = 0x0000; EraseAndWriteToFlashMem(&theStoredWLCFG, (void *)STORE_KWCONFIG_BASE, sizeof(stStoredWLConfig)); return 0; } int KWireLessInit(bool bRadioEnableMaster, uint32_t nChannel, uint8_t nRadioAddr) { stWLConfig * pWLCfg = & WLCfg; pWLCfg->bMaster = bRadioEnableMaster; // Radio initialization RadioEvents.TxDone = OnTxDone; RadioEvents.RxDone = OnRxDone; RadioEvents.TxTimeout = OnTxTimeout; RadioEvents.RxTimeout = OnRxTimeout; RadioEvents.RxError = OnRxError; RadioEvents.CadDone = OnCadDone; Radio.Init( &RadioEvents ); pWLCfg->nChannel = nChannel; KwRunStat.RF_Freq = pWLCfg->RF_T_Freq + pWLCfg->nChannel * pWLCfg->nChnSpacing*1000; Radio.SetChannel( KwRunStat.RF_Freq ); pWLCfg->nRadioAddr = nRadioAddr; KwRunStat.nCurClient = 1; // Radio.WriteBuffer(0x06C0,data,2); // Radio.ReadBuffer(0x06C0,test,2); #if defined( USE_MODEM_LORA ) /* Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); // */ Radio.SetTxConfig( MODEM_LORA, pWLCfg->Tx_Power, 0, pWLCfg->LoraBandWidth, pWLCfg->LoRaFactor, pWLCfg->LoRaCodingRate, pWLCfg->LoRaPreambleLen, LORA_FIX_LENGTH_PAYLOAD_ON, true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); Radio.SetRxConfig( MODEM_LORA, pWLCfg->LoraBandWidth, pWLCfg->LoRaFactor, pWLCfg->LoRaCodingRate, 0, pWLCfg->LoRaPreambleLen, LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); Radio.SetMaxPayloadLength(MODEM_LORA,32); #elif defined( USE_MODEM_FSK ) Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, FSK_DATARATE, 0, FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, true, 0, 0, 0, 3000 ); Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, true, 0, 0,false, false ); #else #error "Please define a modem in the compiler options.." #endif SX126xSetRxTxFallbackMode(0x40); // 0x40-> FS 0x30 -> SD_XOSC 0x20 -> SD_RC SX126xSetCadParams(LORA_CAD_02_SYMBOL,22,10,LORA_CAD_ONLY,1); nTimeOnAir = Radio.TimeOnAir(MODEM_LORA,14); KwRunStat.nTimeOnAir = nTimeOnAir; // KMem.WDT[38]=nTimeOnAir; KwRunStat.runStep=RS_IDLE; KMem.WDT[0]++; KwRunStat.Tx_Power = WLCfg.Tx_Power; KwRunStat.LoraBandWidth = WLCfg.LoraBandWidth; KwRunStat.LoRaFactor = WLCfg.LoRaFactor; KwRunStat.LoRaCodingRate = WLCfg.LoRaCodingRate; KwRunStat.LoRaPreambleLen = WLCfg.LoRaPreambleLen; return 0; } int KwResetRf() { // LoadKwConfig(); // KWireLessInit(RadioEnableMaster,nRadioChannel); Radio.Standby(); KwRunStat.runStep=RS_IDLE; return 0; } int KwStartRecv(int nChnd) { Radio.Standby(); Radio.SetChannel( KwRunStat.RF_Freq ); Radio.SetRxConfig( MODEM_LORA, WLCfg.LoraBandWidth, WLCfg.LoRaFactor, WLCfg.LoRaCodingRate, 0, WLCfg.LoRaPreambleLen, LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); Radio.SetMaxPayloadLength(MODEM_LORA,32); Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); KwRunStat.runStep=RS_RECVING; KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); return 0; } int KWireLessStart(void) { if(WLCfg.bMaster) { KWLMasterSendReqPkt(1); } else { KwStartRecv(1); } // while( 1 ) // { // Radio.IrqProcess( ); // Process Radio IRQ // } return 0; } void OnTxDone( void ) { KwRunStat.bMasterSent = 1; KwRunStat.bMasterRecved = 0; KwRunStat.runStep=RS_IDLE; KMem.WDT[42]++; KwRunStat.ClientStat[KwRunStat.nCurClient].lastSenttime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); Radio.Standby(); if (WLCfg.bMaster) { Radio.Rx( MASTER_RX_TIMEOUT_VALUE ); //进入接收 } else { KwStartRecv(1); //Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); //进入接收 } KwRunStat.runStep=RS_RECVING; KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); LL_GPIO_TogglePin(GPIOC,LL_GPIO_PIN_14); // int us2=GetTick(); // KMem.ScanTimeuS=us2-KMem.LastScanTime; // KMem.LastScanTime = us2; // if (KMem.ScanTimeuS < KMem.MinScanTimeuS) {KMem.MinScanTimeuS = KMem.ScanTimeuS;} // if (KMem.ScanTimeuS > KMem.MaxScanTimeuS) {KMem.MaxScanTimeuS = KMem.ScanTimeuS;} } void OnTxTimeout( void ) { KwRunStat.runStep=RS_IDLE; KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].TXErr++; Radio.Standby(); // KMem.WDT[44]++; } bool bThisRxError=0; void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) { KMem.WDT[44] = size; if (size <= 120) { memcpy( KwRx_Buffer, payload, size ); memcpy(&KMem.WDT[64],payload,size); }else { } Radio.Standby(); KwRunStat.runStep = RS_IDLE; KwRunStat.curStat = 0; KwRunStat.ClientStat[KwRunStat.nCurClient].latancy = GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime; RssiValue = rssi; SnrValue = snr; KwRunStat.ClientStat[KwRunStat.nCurClient].RSSI = RssiValue; KwRunStat.ClientStat[KwRunStat.nCurClient].SNR = SnrValue; KwRunStat.ClientStat[KwRunStat.nCurClient].recvCount++; // KwRunStat.CtnLstPkts=0; if(WLCfg.bMaster) { KWLMasterParsePkt(WLCfg.nChannel,size); //KWLMasterSendReqPkt(1); } else //slave { KWLSlaveParsePkt(WLCfg.nChannel,size); } if (bThisRxError) { bThisRxError=0; // return; } } void OnRxTimeout( void ) { KwRunStat.runStep=RS_IDLE; Radio.Standby(); stClientStat * pClientStat = &KwRunStat.ClientStat[KwRunStat.nCurClient]; pClientStat->lastErrTime = GetTick() - pClientStat->lastAckTime; pClientStat->lastAckTime = GetTick(); KwRunStat.Tx_Power+=6; //丢包, 增加发射功率 if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } SX126xSetRfTxPower(KwRunStat.Tx_Power); KMem.WDT[45]++; pClientStat->LostPackets++; pClientStat->CtnLstPkts++; if (pClientStat->CtnLstPkts > pClientStat->MaxCtnLstPkts) {pClientStat->MaxCtnLstPkts = pClientStat->CtnLstPkts;} // KwRunStat.ErrStat=500; if (pClientStat->CtnLstPkts > 2) { KwRunStat.ErrStat=500;} if (pClientStat->CtnLstPkts ==3 ) {pClientStat->Err1Count++;} if (pClientStat->CtnLstPkts > 5) { KwRunStat.ErrStat=5000;} if (pClientStat->CtnLstPkts == 6) {pClientStat->Err2Count++;} if (pClientStat->CtnLstPkts > 9) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } if (pClientStat->CtnLstPkts == 10) {pClientStat->Err3Count++;} if ((pClientStat->CtnLstPkts &0x0f) == 0x0f) { KMem.WDT[51]++; KwResetRf(); Radio.Standby(); // KWireLessStart(); } if(WLCfg.bMaster) { //KWLMasterSendReqPkt(1); } else { KwStartRecv(1); // Radio.Standby(); // Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); // KwRunStat.runStep=RS_RECVING; // KwRunStat.lastActTime = GetTick(); // KwRunStat.lastRecvtime = GetTick(); } } void OnRxError( void ) { KwStartRecv(1); // Radio.Standby(); // Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); // KwRunStat.runStep=RS_RECVING; // KwRunStat.lastActTime = GetTick(); // KwRunStat.lastRecvtime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].RXErr++; KMem.WDT[46]++; bThisRxError=1; KwRunStat.ClientStat[KwRunStat.nCurClient].lastErrTime = GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime; if(WLCfg.bMaster) { // SendPingMsg(); } else { /* // Radio.Rx( RX_TIMEOUT_VALUE ); //KwRunStat.lastActTime = GetTick(); KwRunStat.LostPackets++; KwRunStat.CtnLstPkts++; if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} // KwRunStat.ErrStat=500; if (KwRunStat.CtnLstPkts > 1) { KwRunStat.ErrStat=500; } if (KwRunStat.CtnLstPkts == 2) {KwRunStat.Err1Count++;} if (KwRunStat.CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} if (KwRunStat.CtnLstPkts == 4) {KwRunStat.Err2Count++;} if (KwRunStat.CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } if (KwRunStat.CtnLstPkts == 7) {KwRunStat.Err3Count++;} */ } // Radio.Standby(); } void OnCadDone( bool channelActivityDetected) { KMem.WDT[60]++; KwRunStat.ClientStat[KwRunStat.nCurClient].CADDoneCount++; KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); KMem.WDT[16] = KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime - KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime; if (channelActivityDetected) { KwRunStat.ClientStat[KwRunStat.nCurClient].CADNgCount++; KMem.WDT[61]++; Radio.StartCad(); KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); } else { KwRunStat.ClientStat[KwRunStat.nCurClient].CADOkCount++; KMem.WDT[62]++; if (WLCfg.bMaster) { if (KwRunStat.curStat == 0 ){ //&& stat == RF_IDLE ) //200mS // Radio.Standby(); KWireLessStart(); }else { Radio.Standby(); KWireLessStart(); } }else { KWLSlaveSendRplyPkt(1); } } return; } int KWLMasterParsePkt(int nChn,int size) { bool CRC_OK =1; ///* crc_value=RadioComputeCRC(KwRx_Buffer,size-2,CRC_TYPE_IBM);//计算得出要发送数据包CRC值 if (KwRx_Buffer[size-2] != (crc_value&0xff) && KwRx_Buffer[size-1] != (crc_value >> 8)) { KwRunStat.ClientStat[KwRunStat.nCurClient].CRCErr++; KwRunStat.ErrStat=500; CRC_OK = 0; }else { CRC_OK = 1; } //*/ pstKwPacket p1 = (pstKwPacket) KwRx_Buffer; if(CRC_OK && p1->STSign == enRplySign ) //memcmp(RX_Buffer,PongMsg,4)==0 { if (p1->DstAddr == MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr)) { KwRunStat.bMasterRecved = 1; LedToggle();//LED闪烁 KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime=GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts=0; if (p1->Stat==0) { KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI = KwRx_Buffer[10]; KwRunStat.ClientStat[KwRunStat.nCurClient].tSNR = KwRx_Buffer[11]; if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI > -50) { if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} }else if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI < -60) { KwRunStat.Tx_Power+=6; if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } SX126xSetRfTxPower(KwRunStat.Tx_Power); } }else if (p1->Stat==1){ KwRunStat.ClientStat[KwRunStat.nCurClient].targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); }else if (p1->Stat==2) { KwRunStat.ClientStat[KwRunStat.nCurClient].targetRecvdCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); }else if (p1->Stat==3) { } KMem.WDT[41]=(-KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI) + ((-KwRunStat.ClientStat[KwRunStat.nCurClient].tSNR)<<8); KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); // 数据透传 数据的发送成功与否,需要在对方的应答包中确认 if (KwRunStat.sizesending > 0) { // 确认正在发送的,发送成功 KwRunStat.sentsize += KwRunStat.sizesending; KwRunStat.sizesending = 0; if (KwRunStat.sentsize >= KwRunStat.sizetosend) { //整体 发送完成 KwRunStat.sizetosend =0; KwRunStat.sentsize = 0; KwRunStat.ttAirSize = 0; // 发送完成 } } // 接受到对方发来的数据 if (p1->bHasData && size >= 14+3 ) { // int nFulllen1 = KwRx_Buffer[12]; int nthislen2 = KwRx_Buffer[13]; if (size >= 14 + nthislen2) { if (p1->bHead) { // 数据包的起始, 一个新的数据包的开始 KwRunStat.ttRxSize = 0; // SendPacket(1, "H", 1); } memcpy (KwRunStat.ttRxBuf1 + KwRunStat.ttRxSize , KwRx_Buffer + 14 , nthislen2); KwRunStat.ttRxSize += nthislen2; if (p1->bTail) { // 已经收到完整的一个数据包 KwRunStat.ttRxRecved =1; KwRunStat.ErrStat=500; // SendPacket(1, "T", 1); // 后续数据包处理流程 ; if (Uart1Mode == 1) { // 处于透传模式, 数据发回去。 SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); } KwRunStat.ttRxSize = 0; KwRunStat.ttRxRecved = 0; // 暂时流程,全部发回去。 // memcpy (KwRunStat.ttTxBuf1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); // KwRunStat.sizetosend = KwRunStat.ttRxSize; // KwRunStat.sentsize = 0; // KwRunStat.sizesending = 0; } } } /* if (KwRunStat.ttAirSize > 0) { if (KwRunStat.bttAirHeader) { KwRunStat.ttRxRecved=0; } memcpy(KwRunStat.ttRxBuf1 + KwRunStat.ttRxRecved,KwRunStat.ttAirBuf, KwRunStat.ttAirSize); KwRunStat.ttRxRecved += KwRunStat.ttAirSize; if (KwRunStat.bttAirTail) { // 收到 一个数据包的最后部分 KwRunStat.ttRxSize = KwRunStat.ttRxRecved; if (Uart1Mode == 1) { // 处于透传模式, 数据发回去。 SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); } KwRunStat.ttRxSize = 0; KwRunStat.ttRxRecved = 0; } KwRunStat.ttAirSize = 0; } */ } } return 0; } int KWLSlaveParsePkt(int nChn,int size) { bool CRC_OK =1; pstKwPacket p1 = (pstKwPacket) KwRx_Buffer; ///* crc_value=RadioComputeCRC(KwRx_Buffer,size-2,CRC_TYPE_IBM);//计算得出要发送数据包CRC值 if (KwRx_Buffer[size-2] != (crc_value&0xff) && KwRx_Buffer[size-1] != (crc_value >> 8)) { KwRunStat.ClientStat[KwRunStat.nCurClient].CRCErr++; // KwRunStat.ErrStat=500; CRC_OK = 0; }else { CRC_OK = 1; if (p1->STSign != enReqSign) { KwRunStat.ClientStat[KwRunStat.nCurClient].PktErr++; }else { if (p1->DstAddr != MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr)) { KwRunStat.ClientStat[KwRunStat.nCurClient].ChnErr++; KwRunStat.ClientStat[KwRunStat.nCurClient].nErrChn = p1->DstAddr; } } } //*/ if(CRC_OK && p1->STSign == enReqSign && p1->DstAddr == MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr))// memcmp(RX_Buffer,PingMsg,4)==0 && ) { LedToggle();//LED闪烁 KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime=GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].lastAckTime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts=0; int nSeq = p1->nSeq; if (nSeq==0) { KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI = KwRx_Buffer[10]; KwRunStat.ClientStat[KwRunStat.nCurClient].tSNR = KwRx_Buffer[11]; if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI > -50) { if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} }else if (KwRunStat.ClientStat[KwRunStat.nCurClient].tRSSI < -60) { KwRunStat.Tx_Power+=6; if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } SX126xSetRfTxPower(KwRunStat.Tx_Power); } }else if (nSeq==1){ KwRunStat.ClientStat[KwRunStat.nCurClient].targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); }else if (nSeq==2) { KwRunStat.ClientStat[KwRunStat.nCurClient].targetRecvdCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); }else if (nSeq==3) { } KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); // 数据透传 数据的发送成功与否,需要在对方的应答包中确认 if (KwRunStat.sizesending > 0) { // 确认正在发送的,发送成功 KwRunStat.sentsize += KwRunStat.sizesending; KwRunStat.sizesending = 0; if (KwRunStat.sentsize >= KwRunStat.sizetosend) { //整体 发送完成 KwRunStat.sizetosend =0; KwRunStat.sentsize = 0; KwRunStat.ttAirSize = 0; // 发送完成 } } if (p1->bHasData && size >= 14+3 ) { // int nFulllen1 = KwRx_Buffer[12]; int nthislen2 = KwRx_Buffer[13]; if (size >= 14 + nthislen2) { // 收到一个合格的携带传统数据的 包。 if (p1->bHead) { // 数据段的起始, 一个新的数据段的开始 KwRunStat.ttRxSize = 0; } memcpy (KwRunStat.ttRxBuf1 + KwRunStat.ttRxSize, KwRx_Buffer + 14 , nthislen2); KwRunStat.ttRxSize += nthislen2; if (p1->bTail) { // 已经收到完整的一个数据段 KwRunStat.ttRxRecved =1; KwRunStat.ErrStat=500; // 后续数据段处理流程 ; if (Uart1Mode == 1) { // 处于透传模式, 数据发回去。 SendPacket(1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); } KwRunStat.ttRxSize = 0; KwRunStat.ttRxRecved = 0; // 暂时流程,全部发回去。 // memcpy (KwRunStat.ttTxBuf1, KwRunStat.ttRxBuf1, KwRunStat.ttRxSize); // KwRunStat.sizetosend = KwRunStat.ttRxSize; // KwRunStat.sentsize = 0; // KwRunStat.sizesending = 0; // KwRunStat.ttRxRecved = 0; // KwRunStat.ttRxSize = 0; } } } KWLSlaveSendRplyPkt(1); // Radio.StartCad(); // KMem.WFY[0]=(RX_Buffer[4]<<8) + RX_Buffer[5]; // KMem.WFY[1]=(RX_Buffer[6]<<8) + RX_Buffer[7]; } else { KwStartRecv(1); // Radio.Rx( SLAVE_RX_TIMEOUT_VALUE ); // KwRunStat.runStep=RS_RECVING; // KwRunStat.lastActTime = GetTick(); // KwRunStat.lastRecvtime = GetTick(); } return 0; } int KWLMasterSendReqPkt(int nChn) { int len1=12; pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; p1->STSign = enReqSign; p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); p1->Func = 0x3; KwRunStat.nSeq = (KwRunStat.nSeq + 1)&0x03; p1->Stat = KwRunStat.nSeq; //0x00; p1->Data[0]=KMem.WFY[1]; p1->Data[1]=KMem.WFY[1]>>8; p1->Data[2]=KMem.WFY[2]; p1->Data[3]=KMem.WFY[2]>>8; if (p1->Stat == 0) { KwTx_Buffer[10] = RssiValue; KwTx_Buffer[11] = SnrValue; }else if (p1->Stat == 1){ memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount,4); }else if (p1->Stat == 2) { memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].recvCount,4); }else if (p1->Stat == 3) { } // 受限于空中包大小的限制, 透传数据可能需要分几次发送。 // 发送方负责拆包, 接收方负责 合包, 发送方发送第一个包,有起始标志, 发送方发送最后一个包,有结束标志。 // 如果只有一个包的数据,则同时具有起始和结束标志。 // 中间的数据包,不具有起始标志,也不具有结束标志。 // 利用包序列号来保证 中间 的数据包的 完整性 和顺序正确性。 // 先实现1个包的转发。 if (KwRunStat.sizetosend > 0) { uchar bStart=0,bEnd=1; int16_t thisToSend = KwRunStat.sizetosend - KwRunStat.sentsize; if (thisToSend > WL_TT_EACH_SIZE) { thisToSend = WL_TT_EACH_SIZE; bEnd=0;} if (KwRunStat.sentsize == 0) { // 第一次发送 bStart = 1; } memcpy(KwRunStat.ttAirBuf, KwRunStat.ttTxBuf1 + KwRunStat.sentsize , thisToSend); // 发送数据, 如果上次有,继续上次的发。 KwRunStat.sizesending = thisToSend; KwRunStat.ttAirSize = thisToSend; // KwRunStat.sentsize = 0; KwRunStat.bttAirHeader = bStart; KwRunStat.bttAirTail = bEnd; p1->bHasData=1; p1->bHead = bStart; p1->bTail = bEnd; KwTx_Buffer[len1] = KwRunStat.sizetosend; KwTx_Buffer[len1+1] = thisToSend; memcpy( KwTx_Buffer + len1 + 2 , KwRunStat.ttTxBuf1 + KwRunStat.sentsize, thisToSend); len1 += 2 + thisToSend; } crc_value=RadioComputeCRC(KwTx_Buffer,len1,CRC_TYPE_IBM);//计算得出要发送数据包CRC值 KwTx_Buffer[len1]=crc_value; KwTx_Buffer[len1+1]=crc_value>>8; KMem.WDT[56]=crc_value; KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount++; KwRunStat.ClientStat[KwRunStat.nCurClient].cycleTime = GetTick()- KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime ; KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime = GetTick(); Radio.Send( KwTx_Buffer, len1+2); KwRunStat.runStep=RS_SENDING; KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); return 0; } int KWLSlaveSendRplyPkt(int nChn) { int len1=12; pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; p1->STSign = enRplySign; p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); p1->Func = 0x3; p1->Stat = (p1->Stat + 1) &0x03; //0x00; p1->Data[0]=KMem.WFY[1]; p1->Data[1]=KMem.WFY[1]>>8; p1->Data[2]=KMem.WFY[2]; p1->Data[3]=KMem.WFY[2]>>8; if (p1->Stat == 0) { KwTx_Buffer[10] = RssiValue; KwTx_Buffer[11] = SnrValue; }else if (p1->Stat == 1){ memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount,4); }else if (p1->Stat == 2) { memcpy(KwTx_Buffer+8,&KwRunStat.ClientStat[KwRunStat.nCurClient].recvCount,4); }else if (p1->Stat == 3) { } // 受限于空中包大小的限制, 透传数据可能需要分几次发送。 // 发送方负责拆包, 接收方负责 合包, 发送方发送第一个包,有起始标志, 发送方发送最后一个包,有结束标志。 // 如果只有一个包的数据,则同时具有起始和结束标志。 // 中间的数据包,不具有起始标志,也不具有结束标志。 // 利用包序列号来保证 中间 的数据包的 完整性 和顺序正确性。 // 先实现1个包的转发。 if (KwRunStat.sizetosend > 0) { uchar bStart=0,bEnd=1; int16_t thisToSend = KwRunStat.sizetosend - KwRunStat.sentsize; if (thisToSend > WL_TT_EACH_SIZE) { thisToSend = WL_TT_EACH_SIZE; bEnd=0;} if (KwRunStat.sentsize == 0) { // 第一次发送 bStart = 1; } memcpy(KwRunStat.ttAirBuf, KwRunStat.ttTxBuf1 + KwRunStat.sentsize , thisToSend); // 发送数据, 如果上次有,继续上次的发。 KwRunStat.sizesending = thisToSend; KwRunStat.ttAirSize = thisToSend; // KwRunStat.sentsize = 0; KwRunStat.bttAirHeader = bStart; KwRunStat.bttAirTail = bEnd; p1->bHasData=1; p1->bHead = bStart; p1->bTail = bEnd; KwTx_Buffer[len1] = KwRunStat.sizetosend; KwTx_Buffer[len1+1] = thisToSend; memcpy( KwTx_Buffer + len1 + 2 , KwRunStat.ttTxBuf1 + KwRunStat.sentsize, thisToSend); len1 += 2 + thisToSend; } crc_value=RadioComputeCRC(KwTx_Buffer,len1,CRC_TYPE_IBM);//计算得出要发送数据包CRC值 KwTx_Buffer[len1]=crc_value; KwTx_Buffer[len1+1]=crc_value>>8; Radio.Send( KwTx_Buffer, len1+2); KwRunStat.runStep=RS_SENDING; KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].sentCount++; KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime = GetTick(); return 0; } int KWL_Process(int nChn) { RadioStatus_t rs = SX126xGetStatus(); KMem.WDT[1] = rs.Value; RadioError_t er = SX126xGetDeviceErrors(); KMem.WDT[2] = er.Value; KMem.WDT[3] = SX126xGetIrqStatus(); KMem.WDT[4] = SX126xGetRssiInst(); KMem.WDT[5] = GetRadioBusyPin(); RadioState_t stat = Radio.GetStatus(); KMem.WDT[32]=stat; // KMem.WDT[38]=Radio.Rssi(MODEM_FSK); if (WLCfg.bMaster){ KWLMasterProc(nChn); }else //slave { KWLSlaveProc(nChn); } if (KwRunStat.RunStat) KwRunStat.RunStat--; if (KwRunStat.ErrStat) KwRunStat.ErrStat--; return 0; } int KWLMasterProc(int nChn) { RadioState_t stat = Radio.GetStatus(); switch (KwRunStat.runStep){ case RS_IDLE: if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime > (WLCfg.nCycleTime) *10 ||KwRunStat.sizetosend > 0 ){ Radio.StartCad(); KwRunStat.runStep = RS_MASTER_CAD; KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime = GetTick(); } break; case RS_MASTER_CAD: if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastActTime > 15) { KwRunStat.ClientStat[KwRunStat.nCurClient].CADTimeOut++; KwRunStat.runStep = RS_IDLE; Radio.Standby(); KMem.WDT[17]++; KwResetRf(); } break; case RS_SENDING: break; case RS_SENT: break; case RS_RECVING: if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastSendtime > (WLCfg.nCycleTime) *10 || KwRunStat.bMasterRecved){ KwRunStat.ErrStat=5000; KwRunStat.ClientStat[KwRunStat.nCurClient].LostPackets++; KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts++; KwRunStat.Tx_Power+=6; //丢包, 增加发射功率 if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } SX126xSetRfTxPower(KwRunStat.Tx_Power); if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > KwRunStat.ClientStat[KwRunStat.nCurClient].MaxCtnLstPkts) {KwRunStat.ClientStat[KwRunStat.nCurClient].MaxCtnLstPkts = KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts;} // KwRunStat.ErrStat=500; if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > 1) { KwRunStat.ErrStat=2000;} if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts == 2) {KwRunStat.ClientStat[KwRunStat.nCurClient].Err1Count++;} if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts == 4) {KwRunStat.ClientStat[KwRunStat.nCurClient].Err2Count++;} if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } if (KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts == 7) {KwRunStat.ClientStat[KwRunStat.nCurClient].Err3Count++;} if ((KwRunStat.ClientStat[KwRunStat.nCurClient].CtnLstPkts &0x0f) == 0x0f) { KMem.WDT[51]++; KwResetRf(); // LoadKwConfig(); // KWireLessInit(RadioEnableMaster,nRadioChannel); // Radio.Standby(); // KWireLessStart(); } KwRunStat.runStep = RS_IDLE; } break; case RS_RECVED: KwRunStat.runStep = RS_IDLE; break; default: break; } /* if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10){ if (!KwRunStat.bMasterRecved) { KwRunStat.ErrStat=5000; KwRunStat.LostPackets++; KwRunStat.CtnLstPkts++; if (KwRunStat.CtnLstPkts > KwRunStat.MaxCtnLstPkts) {KwRunStat.MaxCtnLstPkts = KwRunStat.CtnLstPkts;} // KwRunStat.ErrStat=500; if (KwRunStat.CtnLstPkts > 1) { KwRunStat.ErrStat=2000;} if (KwRunStat.CtnLstPkts == 2) {KwRunStat.Err1Count++;} if (KwRunStat.CtnLstPkts > 3) { KwRunStat.ErrStat=5000;} if (KwRunStat.CtnLstPkts == 4) {KwRunStat.Err2Count++;} if (KwRunStat.CtnLstPkts > 6) { KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } if (KwRunStat.CtnLstPkts == 7) {KwRunStat.Err3Count++;} if ((KwRunStat.CtnLstPkts &0x0f) == 0x0f) { KMem.WDT[51]++; // LoadKwConfig(); // KWireLessInit(RadioEnableMaster,nRadioChannel); // Radio.Standby(); // KWireLessStart(); } } } */ /* if (KwRunStat.curStat == 0 ){ //&& stat == RF_IDLE ) //200mS // Radio.Standby(); KWireLessStart(); }else { Radio.Standby(); KWireLessStart(); } */ return 0; } int KWLSlaveProc(int nChn) { RadioState_t stat = Radio.GetStatus(); if (stat == RF_IDLE){ KMem.WDT[48]++; Radio.Standby(); KWireLessStart(); } if (stat == RF_RX_RUNNING ){ if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime > ((SLAVE_RX_TIMEOUT_VALUE + 10 )*10)){ KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); KwRunStat.ClientStat[KwRunStat.nCurClient].StepErr1++; KMem.WDT[49]++; Radio.Standby(); KWireLessStart(); } } if (stat == RF_CAD && GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime > ((2 )*10)){ KwRunStat.ClientStat[KwRunStat.nCurClient].StepErr2++; KwRunStat.ClientStat[KwRunStat.nCurClient].CADTimeOut++; KMem.WDT[50]++; Radio.Standby(); KWireLessStart(); } if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime > 4000){ // 200mS // KwRunStat.ErrStat=500; KwRunStat.ErrStat=500; // Radio.Standby(); // KWireLessStart(); } if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvdtime > 12000){ // 1200mS KwRunStat.ErrStat=5000; KMem.WFX[1]=0; } if (GetTick() - KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime > 16000){ KMem.WDT[52]++; KwResetRf(); Radio.Standby(); KWireLessStart(); KwRunStat.ClientStat[KwRunStat.nCurClient].lastRecvtime = GetTick(); } return 0; }