From 7eb19e6024af7f05cf94c66fb843439a3509147e Mon Sep 17 00:00:00 2001 From: QuakeGod <quakegod@sina.com> Date: 星期一, 02 九月 2024 15:30:40 +0800 Subject: [PATCH] 2024-09-02 --- ComLib/Src/GlobalDef.c | 19 - ComLib/Src/stm32f0xx_it.c | 4 ComLib/Src/functions.c | 9 ComLib/Src/KBus.c | 2 Radio_LLCC68/Radio/KWireLess.h | 101 ++++++++- Radio_LLCC68/Src/main.c | 76 +++++- Radio_LLCC68/Radio/KWireLess.c | 334 +++++++++++++++++++++++------ Radio_LLCC68/Src/BoardType.c | 2 ComLib/Inc/KMachine.h | 12 ComLib/Inc/KBus.h | 6 Radio_LLCC68/Inc/main.h | 25 ++ ComLib/Inc/GlobalDef.h | 19 - KNet.uvmpw | 4 Radio_LLCC68/Radio/src/radio.c | 2 ComLib/Src/KLink.c | 4 15 files changed, 461 insertions(+), 158 deletions(-) diff --git a/ComLib/Inc/GlobalDef.h b/ComLib/Inc/GlobalDef.h index 2b05218..7a05e85 100644 --- a/ComLib/Inc/GlobalDef.h +++ b/ComLib/Inc/GlobalDef.h @@ -11,11 +11,8 @@ #include "BoardType.h" #include "MyQueue.h" -#define DefaultUart1Baud 115200 -#define DefaultUart2Baud 1000000 -#define AlterUart2Baud 500000 -extern volatile int PendSvCount; + #pragma anon_unions typedef struct tagUartStat @@ -61,21 +58,7 @@ extern stUartStat Uart1Stat; extern stUartStat Uart2Stat; -#define Uart1RecvBufSize 256 -extern unsigned int Uart1Baud; -extern unsigned int Uart2Baud; - -extern unsigned char Uart1RecvBuf1[Uart1RecvBufSize]; -extern unsigned short Uart1RecvBuf1DataLen; - - -extern unsigned char Uart2RecvBuf1[128]; -extern unsigned short Uart2RecvBuf1DataLen; - - -extern volatile char Uart1BaudGot; -extern volatile char Uart1BaudFirstGot; //extern volatile int Uart2BaudGot; //extern volatile int Uart2BaudFirstGot; diff --git a/ComLib/Inc/KBus.h b/ComLib/Inc/KBus.h index 7c6bf07..0849ced 100644 --- a/ComLib/Inc/KBus.h +++ b/ComLib/Inc/KBus.h @@ -328,9 +328,9 @@ struct{ unsigned char nSeq:2; //序列号 unsigned char :2; - unsigned char nErr1:1; - unsigned char nErr2:1; - unsigned char bReq:1; + unsigned char nErr1:1; //错误1 + unsigned char nErr2:1; //错误2 + unsigned char bReq:1; // }; }; unsigned char DataLen; //数据载荷长度 不包括头部5个字节,不包括尾部BCC。 diff --git a/ComLib/Inc/KMachine.h b/ComLib/Inc/KMachine.h index 4ced75d..d1f709d 100644 --- a/ComLib/Inc/KMachine.h +++ b/ComLib/Inc/KMachine.h @@ -528,18 +528,26 @@ uchar nMaxStations; uchar nCurStations; uchar nHealth; - void * pPortConfig; short PortConfigType; short PortConfigSize; - void * pPortRunStatus; short PortRunStatType; short PortRunStatSize; + void * pInstance; //閫氫俊缁撴瀯瀹炰綋 + void * pPortConfig; + void * pPortRunStatus; CommFuncDef ReqCommFunc; //閫氫俊璇锋眰鍑芥暟鎸囬拡 // func2 CommReq; }stPortDef,* pstPortDef; + +typedef struct tagPortPtDef +{ + void * pt; + +}stPortPtDef,* pstPortPtDef; + typedef struct tagInterComm { int nId; diff --git a/ComLib/Src/GlobalDef.c b/ComLib/Src/GlobalDef.c index 5eaa151..69ac856 100644 --- a/ComLib/Src/GlobalDef.c +++ b/ComLib/Src/GlobalDef.c @@ -14,25 +14,6 @@ //const unsigned int DefaultUart1Baud = 230400; -unsigned int Uart1Baud = DefaultUart1Baud; -unsigned int Uart2Baud = DefaultUart2Baud; - -unsigned char Uart1RecvBuf1[Uart1RecvBufSize]; -unsigned short Uart1RecvBuf1DataLen=0; -//unsigned char Uart1RecvBuf2[128]; -//int Uart1RecvBuf2DataLen=0; - -unsigned char Uart2RecvBuf1[128]; -unsigned short Uart2RecvBuf1DataLen=0; -//unsigned char Uart2RecvBuf2[128]; -//int Uart2RecvBuf2DataLen=0; - -volatile char Uart1BaudGot=0; -volatile char Uart1BaudFirstGot=0; -volatile char Uart1DmaInts=0; -volatile char Uart2BaudGot=0; -volatile char Uart2BaudFirstGot=0; -volatile char Uart2DmaInts=0; volatile int SysConfigs; diff --git a/ComLib/Src/KBus.c b/ComLib/Src/KBus.c index 972e77e..7edba9c 100644 --- a/ComLib/Src/KBus.c +++ b/ComLib/Src/KBus.c @@ -1154,7 +1154,7 @@ int KBusSlaveRunRemoteReq(stKBusDef * pKBus, int nReqSvrId, unsigned char * pData , int Len1) { - int PacketLen; +// int PacketLen; switch (nReqSvrId) { case ReqTransBlink: KMRunStat.bLEDFlick=5; diff --git a/ComLib/Src/KLink.c b/ComLib/Src/KLink.c index 5b9381a..620e1cd 100644 --- a/ComLib/Src/KLink.c +++ b/ComLib/Src/KLink.c @@ -157,7 +157,9 @@ unsigned short nByteAddr=0; unsigned short nBitAddr=0; unsigned short DataLen=0; //p1->LoadLen; +#if (ENABLE_PLC) unsigned short nValue=0; +#endif //int nSrcAddr=p1->SrcAddr; nKLStatus.nSEQ = ((pKLStat)(&(p1->Stat)))->nSEQ;; @@ -529,7 +531,7 @@ nByteAddr=p1->Params[0] + (p1->Params[1]<<8); //pData=(UCHAR *)(&storedKMSysCfg.theKMSysCfg)+nByteAddr; pData = KMem.pPorts[nDataType]; - DataLen = sizeof(stPortDef); + DataLen = (uint32_t)&(((pstPortDef)(0))->pInstance); PacketLen=KLMakeRplyPacket(p2,nDstHost,nKLStatus.StatByte,p1->nCMD,DataLen,pData); SendPacket(nChn, p2, PacketLen); break; diff --git a/ComLib/Src/functions.c b/ComLib/Src/functions.c index 72467c5..4bca226 100644 --- a/ComLib/Src/functions.c +++ b/ComLib/Src/functions.c @@ -404,7 +404,7 @@ // NVIC_SetPendingIRQ(PendSV_IRQn); // SCB->ICSR=SCB_ICSR_PENDSVSET_Msk; //1<<SCB_ICSR_PENDSVSET_Pos; - if (Uart1RecvBuf1DataLen >0) + if (Uart1RxBuf1DataLen >0) { Uart1Stat.bPacketRecved=1; // SCB->ICSR=SCB_ICSR_PENDSVSET_Msk; //1<<SCB_ICSR_PENDSVSET_Pos; @@ -426,10 +426,10 @@ } void Uart2RecvDone() { - Uart2RecvBuf1DataLen=sizeof(Uart2RecvBuf1) - LL_DMA_GetDataLength(DMA1,LL_DMA_CHANNEL_5); + Uart2RxBuf1DataLen=sizeof(Uart2RxBuf1) - LL_DMA_GetDataLength(DMA1,LL_DMA_CHANNEL_5); Uart2Stat.bPacketRecved=1; Uart2Stat.IdelCount++; - if (Uart2RecvBuf1DataLen>0) + if (Uart2RxBuf1DataLen>0) TriggerPendSV(); // ParsePacket((pKBPacket)Uart2RecvBuf1,Uart2RecvBuf1DataLen); } @@ -467,7 +467,8 @@ int SendPacket(int nChn, void * pBuf,int len1) { if (nChn==1) { - PutStr1((char *)pBuf,len1); + Uart1SendDMA(pBuf, len1); +// PutStr1((char *)pBuf,len1); // PushIn(&Uart1Stat.QTx,p1,len1); // Uart1TriggerSendDMA(); diff --git a/ComLib/Src/stm32f0xx_it.c b/ComLib/Src/stm32f0xx_it.c index c8006ab..032448e 100644 --- a/ComLib/Src/stm32f0xx_it.c +++ b/ComLib/Src/stm32f0xx_it.c @@ -254,8 +254,8 @@ // PushOne(&Uart1Stat.QRx,ch); Uart1Stat.RecvBytes++; - Uart1RecvBuf1[Uart1RecvBuf1DataLen]=ch; - if (Uart1RecvBuf1DataLen < Uart1RecvBufSize -1 ) {Uart1RecvBuf1DataLen++;} + Uart1RxBuf1[Uart1RxBuf1DataLen]=ch; + if (Uart1RxBuf1DataLen < Uart1RxBufSize -1 ) {Uart1RxBuf1DataLen++;} //LL_USART_TransmitData8(USART1,ch); } if (LL_USART_IsActiveFlag_ORE(USART1)) diff --git a/KNet.uvmpw b/KNet.uvmpw index afa5f2b..7b392e7 100644 --- a/KNet.uvmpw +++ b/KNet.uvmpw @@ -25,12 +25,12 @@ <project> <PathAndName>.\MDK-ARM\Radio_LLCC68_C8T6_8璺棤绾挎ā鍧�.uvprojx</PathAndName> - <NodeIsActive>1</NodeIsActive> - <NodeIsExpanded>1</NodeIsExpanded> </project> <project> <PathAndName>.\MDK-ARM\KMini_New_CCT6.uvprojx</PathAndName> + <NodeIsActive>1</NodeIsActive> + <NodeIsExpanded>1</NodeIsExpanded> </project> <project> diff --git a/Radio_LLCC68/Inc/main.h b/Radio_LLCC68/Inc/main.h index 81823cb..55d4307 100644 --- a/Radio_LLCC68/Inc/main.h +++ b/Radio_LLCC68/Inc/main.h @@ -77,6 +77,31 @@ #include "KBus.h" extern stKBusDef KBus1; +#define Uart1RxBufSize 256 +#define RX2BUFSIZE 64 +#define TX2BUFSIZE 64 +#define DefaultUart1Baud 115200 +#define DefaultUart2Baud 1000000 +#define AlterUart2Baud 500000 + +extern volatile char Uart1BaudGot; +extern volatile char Uart1BaudFirstGot; + +extern unsigned char Uart1Mode; +extern unsigned int Uart1Baud; +extern unsigned int Uart2Baud; + +extern volatile int PendSvCount; + +extern unsigned char Uart1RxBuf1[Uart1RxBufSize]; +extern unsigned char Uart1TxBuf1[260]; + +extern unsigned char Uart2RxBuf1[RX2BUFSIZE]; +extern unsigned char Uart2TxBuf1[TX2BUFSIZE]; + +extern unsigned short Uart1RxBuf1DataLen; +extern unsigned short Uart2RxBuf1DataLen; + /* USER CODE END Private defines */ #ifdef __cplusplus diff --git a/Radio_LLCC68/Radio/KWireLess.c b/Radio_LLCC68/Radio/KWireLess.c index 7707420..184a407 100644 --- a/Radio_LLCC68/Radio/KWireLess.c +++ b/Radio_LLCC68/Radio/KWireLess.c @@ -113,7 +113,7 @@ */ #define MASTER_RX_TIMEOUT_VALUE 80 //mS #define SLAVE_RX_TIMEOUT_VALUE 400 //mS -#define CYCLE_TIME 120 //mS +#define CYCLE_TIME 80 //mS const stWLConfig defaultWLConfig = { @@ -159,8 +159,8 @@ -#define WL_RX_BUFFER_SIZE 256 // Define the payload size here -#define WL_TX_BUFFER_SIZE 128 // Define the payload size here +#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; /* @@ -169,9 +169,10 @@ */ //uint16_t BufferSize = BUFFER_SIZE; -uint8_t RX_Buffer[WL_RX_BUFFER_SIZE]; -uint8_t TX_Buffer[WL_TX_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; @@ -385,7 +386,7 @@ { KMem.WDT[44] = size; if (size <= 120) { - memcpy( RX_Buffer, payload, size ); + memcpy( KwRx_Buffer, payload, size ); memcpy(&KMem.WDT[64],payload,size); }else { @@ -535,12 +536,13 @@ } return; } + int KWLMasterParsePkt(int nChn,int size) { bool CRC_OK =1; ///* - crc_value=RadioComputeCRC(RX_Buffer,size-2,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� - if (RX_Buffer[size-2] != (crc_value&0xff) && RX_Buffer[size-1] != (crc_value >> 8)) + 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.CRCErr++; KwRunStat.ErrStat=500; @@ -549,7 +551,7 @@ CRC_OK = 1; } //*/ - pstKLPacket p1 = (pstKLPacket) RX_Buffer; + 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)) @@ -561,8 +563,8 @@ KwRunStat.CtnLstPkts=0; if (p1->Stat==0) { - KwRunStat.tRSSI = RX_Buffer[10]; - KwRunStat.tSNR = RX_Buffer[11]; + KwRunStat.tRSSI = KwRx_Buffer[10]; + KwRunStat.tSNR = KwRx_Buffer[11]; if (KwRunStat.tRSSI > -50) { if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} }else if (KwRunStat.tRSSI < -60) { @@ -572,18 +574,94 @@ } }else if (p1->Stat==1){ - KwRunStat.targetSentCount = RX_Buffer[8] + (RX_Buffer[9]<<8) + (RX_Buffer[10]<<16) + (RX_Buffer[11]<<24); + KwRunStat.targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); }else if (p1->Stat==2) { - KwRunStat.targetRecvdCount = RX_Buffer[8] + (RX_Buffer[9]<<8) + (RX_Buffer[10]<<16) + (RX_Buffer[11]<<24); + KwRunStat.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.tRSSI) + ((-KwRunStat.tSNR)<<8); - KMem.WFX[1]=(RX_Buffer[4]) + (RX_Buffer[5]<<8); + KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); - KMem.WFX[2]=(RX_Buffer[6]) + (RX_Buffer[7]<<8); + KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); + +// 鏁版嵁閫忎紶 鏁版嵁鐨勫彂閫佹垚鍔熶笌鍚︼紝闇�瑕佸湪瀵规柟鐨勫簲绛斿寘涓‘璁� + if (KwRunStat.sizesending > 0) { + // 纭姝e湪鍙戦�佺殑锛屽彂閫佹垚鍔� + 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; + } +*/ + } } @@ -592,10 +670,10 @@ int KWLSlaveParsePkt(int nChn,int size) { bool CRC_OK =1; - pstKLPacket p1 = (pstKLPacket) RX_Buffer; + pstKwPacket p1 = (pstKwPacket) KwRx_Buffer; ///* - crc_value=RadioComputeCRC(RX_Buffer,size-2,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� - if (RX_Buffer[size-2] != (crc_value&0xff) && RX_Buffer[size-1] != (crc_value >> 8)) + 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.CRCErr++; // KwRunStat.ErrStat=500; @@ -620,10 +698,10 @@ KwRunStat.lastRecvdtime=GetTick(); KwRunStat.lastAckTime = GetTick(); KwRunStat.CtnLstPkts=0; - - if (p1->Stat==0) { - KwRunStat.tRSSI = RX_Buffer[10]; - KwRunStat.tSNR = RX_Buffer[11]; + int nSeq = p1->nSeq; + if (nSeq==0) { + KwRunStat.tRSSI = KwRx_Buffer[10]; + KwRunStat.tSNR = KwRx_Buffer[11]; if (KwRunStat.tRSSI > -50) { if (KwRunStat.Tx_Power > 0) {KwRunStat.Tx_Power--; SX126xSetRfTxPower(KwRunStat.Tx_Power);} }else if (KwRunStat.tRSSI < -60) { @@ -631,17 +709,69 @@ if (KwRunStat.Tx_Power > WLCfg.Tx_Power) {KwRunStat.Tx_Power= WLCfg.Tx_Power; } SX126xSetRfTxPower(KwRunStat.Tx_Power); } - }else if (p1->Stat==1){ - KwRunStat.targetSentCount = RX_Buffer[8] + (RX_Buffer[9]<<8) + (RX_Buffer[10]<<16) + (RX_Buffer[11]<<24); - }else if (p1->Stat==2) { - KwRunStat.targetRecvdCount = RX_Buffer[8] + (RX_Buffer[9]<<8) + (RX_Buffer[10]<<16) + (RX_Buffer[11]<<24); - }else if (p1->Stat==3) { + }else if (nSeq==1){ + KwRunStat.targetSentCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (nSeq==2) { + KwRunStat.targetRecvdCount = KwRx_Buffer[8] + (KwRx_Buffer[9]<<8) + (KwRx_Buffer[10]<<16) + (KwRx_Buffer[11]<<24); + }else if (nSeq==3) { } - KMem.WFX[1]=(RX_Buffer[4]) + (RX_Buffer[5]<<8); + KMem.WFX[1]=(KwRx_Buffer[4]) + (KwRx_Buffer[5]<<8); // KMem.WFX[1]=(RX_Buffer[4]) + (indicator3<<8); - KMem.WFX[2]=(RX_Buffer[6]) + (RX_Buffer[7]<<8); + KMem.WFX[2]=(KwRx_Buffer[6]) + (KwRx_Buffer[7]<<8); +// 鏁版嵁閫忎紶 鏁版嵁鐨勫彂閫佹垚鍔熶笌鍚︼紝闇�瑕佸湪瀵规柟鐨勫簲绛斿寘涓‘璁� + if (KwRunStat.sizesending > 0) { + // 纭姝e湪鍙戦�佺殑锛屽彂閫佹垚鍔� + 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]; @@ -662,48 +792,77 @@ int KWLMasterSendReqPkt(int nChn) { int len1=12; - pstKLPacket p1 = (pstKLPacket) TX_Buffer; + pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; p1->STSign = enReqSign; p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); p1->Func = 0x3; - p1->Stat = (p1->Stat + 1) &0x03; //0x00; + 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; -/* - TX_Buffer[0] = 'P'; - TX_Buffer[1] = 'I'; - TX_Buffer[2] = 'N'; - TX_Buffer[3] = 'G'; - TX_Buffer[4] = KMem.WFY[1]; - TX_Buffer[5] = KMem.WFY[1]>>8; - TX_Buffer[6] = KMem.WFY[2]; - TX_Buffer[7] = KMem.WFY[2]>>8; -*/ if (p1->Stat == 0) { - TX_Buffer[10] = RssiValue; - TX_Buffer[11] = SnrValue; + KwTx_Buffer[10] = RssiValue; + KwTx_Buffer[11] = SnrValue; }else if (p1->Stat == 1){ - memcpy(TX_Buffer+8,&KwRunStat.sentCount,4); + memcpy(KwTx_Buffer+8,&KwRunStat.sentCount,4); }else if (p1->Stat == 2) { - memcpy(TX_Buffer+8,&KwRunStat.recvCount,4); + memcpy(KwTx_Buffer+8,&KwRunStat.recvCount,4); }else if (p1->Stat == 3) { } - crc_value=RadioComputeCRC(TX_Buffer,len1,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� - TX_Buffer[len1]=crc_value; - TX_Buffer[len1+1]=crc_value>>8; - +// 鍙楅檺浜庣┖涓寘澶у皬鐨勯檺鍒讹紝 閫忎紶鏁版嵁鍙兘闇�瑕佸垎鍑犳鍙戦�併�� +// 鍙戦�佹柟璐熻矗鎷嗗寘锛� 鎺ユ敹鏂硅礋璐� 鍚堝寘锛� 鍙戦�佹柟鍙戦�佺涓�涓寘锛屾湁璧峰鏍囧織锛� 鍙戦�佹柟鍙戦�佹渶鍚庝竴涓寘锛屾湁缁撴潫鏍囧織銆� +// 濡傛灉鍙湁涓�涓寘鐨勬暟鎹紝鍒欏悓鏃跺叿鏈夎捣濮嬪拰缁撴潫鏍囧織銆� +// 涓棿鐨勬暟鎹寘锛屼笉鍏锋湁璧峰鏍囧織锛屼篃涓嶅叿鏈夌粨鏉熸爣蹇椼�� +// 鍒╃敤鍖呭簭鍒楀彿鏉ヤ繚璇� 涓棿 鐨勬暟鎹寘鐨� 瀹屾暣鎬� 鍜岄『搴忔纭�с�� +// 鍏堝疄鐜�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.sentCount++; KwRunStat.cycleTime = GetTick()- KwRunStat.lastSendtime ; KwRunStat.lastSendtime = GetTick(); - Radio.Send( TX_Buffer, len1+2); + Radio.Send( KwTx_Buffer, len1+2); KwRunStat.runStep=RS_SENDING; KwRunStat.lastActTime = GetTick(); @@ -713,7 +872,7 @@ int KWLSlaveSendRplyPkt(int nChn) { int len1=12; - pstKLPacket p1 = (pstKLPacket) TX_Buffer; + pstKwPacket p1 = (pstKwPacket) KwTx_Buffer; p1->STSign = enRplySign; p1->DstAddr = MixAddr(WLCfg.nChannel,WLCfg.nRadioAddr); p1->Func = 0x3; @@ -722,32 +881,60 @@ p1->Data[1]=KMem.WFY[1]>>8; p1->Data[2]=KMem.WFY[2]; p1->Data[3]=KMem.WFY[2]>>8; -/* - TX_Buffer[0] = 'P'; - TX_Buffer[1] = 'O'; - TX_Buffer[2] = 'N'; - TX_Buffer[3] = 'G'; - TX_Buffer[4] = KMem.WFY[1]; - TX_Buffer[5] = KMem.WFY[1]>>8; - TX_Buffer[6] = KMem.WFY[2]; - TX_Buffer[7] = KMem.WFY[2]>>8; -*/ + if (p1->Stat == 0) { - TX_Buffer[10] = RssiValue; - TX_Buffer[11] = SnrValue; + KwTx_Buffer[10] = RssiValue; + KwTx_Buffer[11] = SnrValue; }else if (p1->Stat == 1){ - memcpy(TX_Buffer+8,&KwRunStat.sentCount,4); + memcpy(KwTx_Buffer+8,&KwRunStat.sentCount,4); }else if (p1->Stat == 2) { - memcpy(TX_Buffer+8,&KwRunStat.recvCount,4); + memcpy(KwTx_Buffer+8,&KwRunStat.recvCount,4); }else if (p1->Stat == 3) { } - crc_value=RadioComputeCRC(TX_Buffer,len1,CRC_TYPE_IBM);//璁$畻寰楀嚭瑕佸彂閫佹暟鎹寘CRC鍊� - TX_Buffer[len1]=crc_value; - TX_Buffer[len1+1]=crc_value>>8; - Radio.Send( TX_Buffer, len1+2); +// 鍙楅檺浜庣┖涓寘澶у皬鐨勯檺鍒讹紝 閫忎紶鏁版嵁鍙兘闇�瑕佸垎鍑犳鍙戦�併�� +// 鍙戦�佹柟璐熻矗鎷嗗寘锛� 鎺ユ敹鏂硅礋璐� 鍚堝寘锛� 鍙戦�佹柟鍙戦�佺涓�涓寘锛屾湁璧峰鏍囧織锛� 鍙戦�佹柟鍙戦�佹渶鍚庝竴涓寘锛屾湁缁撴潫鏍囧織銆� +// 濡傛灉鍙湁涓�涓寘鐨勬暟鎹紝鍒欏悓鏃跺叿鏈夎捣濮嬪拰缁撴潫鏍囧織銆� +// 涓棿鐨勬暟鎹寘锛屼笉鍏锋湁璧峰鏍囧織锛屼篃涓嶅叿鏈夌粨鏉熸爣蹇椼�� +// 鍒╃敤鍖呭簭鍒楀彿鏉ヤ繚璇� 涓棿 鐨勬暟鎹寘鐨� 瀹屾暣鎬� 鍜岄『搴忔纭�с�� +// 鍏堝疄鐜�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.lastActTime = GetTick(); @@ -795,7 +982,7 @@ switch (KwRunStat.runStep){ case RS_IDLE: - if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10){ + if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10 ||KwRunStat.sizetosend > 0 ){ Radio.StartCad(); KwRunStat.runStep = RS_MASTER_CAD; KwRunStat.lastActTime = GetTick(); @@ -815,7 +1002,7 @@ case RS_SENT: break; case RS_RECVING: - if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10){ + if (GetTick() - KwRunStat.lastSendtime > (WLCfg.nCycleTime) *10 || KwRunStat.bMasterRecved){ KwRunStat.ErrStat=5000; KwRunStat.LostPackets++; KwRunStat.CtnLstPkts++; @@ -844,7 +1031,8 @@ KwRunStat.runStep = RS_IDLE; - } + } + break; case RS_RECVED: KwRunStat.runStep = RS_IDLE; diff --git a/Radio_LLCC68/Radio/KWireLess.h b/Radio_LLCC68/Radio/KWireLess.h index bdd2443..0eeae2e 100644 --- a/Radio_LLCC68/Radio/KWireLess.h +++ b/Radio_LLCC68/Radio/KWireLess.h @@ -103,9 +103,23 @@ #pragma anon_unions +typedef struct tagKwStatByte +{ + uint8_t nSeq :2; + uint8_t Err1 :1; + uint8_t Err2 :1; + uint8_t bHasData :1; + uint8_t bHeader :1; + uint8_t bTail :1; + + +}stKwStatByte; + typedef struct tagKwChnStat { uint32_t DeviceAddr; + uint8_t Stat; // 鐘舵�佸瓧鑺� + uint8_t nSeq; // 鍖呭簭鍒楀彿 uint8_t Tx_Power; uint8_t RSSI; uint8_t SNR; @@ -122,10 +136,16 @@ uint16_t CtnLstPkts; uint16_t MaxCtnLstPkts; + uchar * pTxBuffer; + uint16_t sizetosend; + uint16_t sentsize; + + uchar * pRxBuffer; // and buffer max size; +// uint16_t SizeToRecv; + uint16_t RecvedSize; + }stKwChnStat; - - typedef struct tagWLStat @@ -144,9 +164,10 @@ uint16_t ErrStat; //閿欒鐘舵�� uint32_t RF_Freq; //杩愯棰戠巼 + uint16_t nTimeOnAir; uint16_t DeviceAddr; - + uint8_t nSeq; uint8_t NetWorkAddr; uchar Tx_Power; // dBm 5 - 22 dBm @@ -200,7 +221,49 @@ uint32_t targetSentCount; //瀵规柟鍙戦�佹暟閲� uint32_t targetRecvdCount; //瀵规柟鎺ュ彈鏁伴噺 + unsigned char ttTxBuf1[256]; + uint16_t sizetosend; + uint16_t sentsize; + uint16_t sizesending; + + unsigned char ttRxBuf1[256]; + uint16_t ttRxSize; + unsigned char ttRxRecved; + + unsigned char ttAirBuf[65]; + uint16_t ttAirSize; + unsigned char bttAirHeader; + unsigned char bttAirTail; + + unsigned char bttAirData; + }stWLRunStat,*pstWLRunStat; + +enum enKwCMDs +{ + + KwcmdNone = 0x00, //Nothing + + KwcmdQuery = 0x01, //Query basic Info + KwcmdQueryRply = 0x81, //Query Info Reply + + KwcmdSetCfg = 0x02, // Set Configuration + KwcmdSetCfgRply = 0x82, // Set Configuration Response + + KwcmdToRunMode = 0x03, + KwcmdToRunModeRply = 0x83, + + KwcmdBroadCastCfg = 0x04, // + + KwcmdMuExchgData = 0x05, // + KwcmdMuExchgDataRply = 0x85, // + + KwcmdToSafeMode = 0x06, + + KwcmdHeartBeat = 0x07, // + KwcmdReHeartBeat = 0x87, // +}; + enum { enReqSign = 0x55, @@ -208,15 +271,30 @@ }; -typedef struct tagKLPacket +typedef struct tagKwPktStatByte { - uchar STSign; - uchar DstAddr; - uchar Func; - uchar Stat; - uchar Data[1]; + uchar nSeq :2 ; + uchar bErr1 :1 ; + uchar bErr2 :1 ; + uchar bHasData :1; + uchar bHead :1; + uchar bTail :1; -}stKLPacket, *pstKLPacket; + +}stKwPktStatByte; + +typedef struct tagKwPacket +{ + uchar STSign; // 鍖呭紑濮嬫爣璁� + uchar DstAddr; // 瀛愭満缁勫悎鍦板潃, 鍖呮嫭 棰戦亾 鍜� 瀛愭満鍦板潃 + uchar Func; // 鍔熻兘鐮� + union{ + uchar Stat; // 鐘舵�佸瓧 + stKwPktStatByte; + }; + uchar Data[1]; // 鏁版嵁 + +}stKwPacket, *pstKwPacket; int LoadKwConfig(void); int SaveKwConfig(void); @@ -245,9 +323,6 @@ int KWLMasterSendReqPkt(int nChn); int KWLSlaveSendRplyPkt(int nChn); - - - int KWMasterProc(void); diff --git a/Radio_LLCC68/Radio/src/radio.c b/Radio_LLCC68/Radio/src/radio.c index a35cbe0..76a1f2c 100644 --- a/Radio_LLCC68/Radio/src/radio.c +++ b/Radio_LLCC68/Radio/src/radio.c @@ -413,7 +413,7 @@ { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512, 0.256, 0.128}, // 250 KHz { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256, 0.128, 0.064}}; // 500 KHz -//*/ +// */ /* static uint16_t RadioLoRaSymbTimeUs[3][8] = {{ 32768, 16384, 8192, 4096, 2048, 1024, 512, 256}, // 125 KHz { 16384, 8192, 4096, 2048, 1024, 512, 256, 128}, // 250 KHz diff --git a/Radio_LLCC68/Src/BoardType.c b/Radio_LLCC68/Src/BoardType.c index 2070134..b803dc9 100644 --- a/Radio_LLCC68/Src/BoardType.c +++ b/Radio_LLCC68/Src/BoardType.c @@ -12,7 +12,7 @@ extern int Region$$Table$$Limit; #define MAKE_VER(x,y) ((x<<8)|y) -#define APP_VER MAKE_VER(1,15) +#define APP_VER MAKE_VER(1,16) const stAppInfoBlock AppInfoBlock __attribute__((at(APPINFOBLOCK_ADDR))) = { diff --git a/Radio_LLCC68/Src/main.c b/Radio_LLCC68/Src/main.c index b36d9df..76118a0 100644 --- a/Radio_LLCC68/Src/main.c +++ b/Radio_LLCC68/Src/main.c @@ -70,19 +70,37 @@ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ -#define RX2BUFSIZE 64 -#define TX2BUFSIZE 64 -unsigned char Uart1RxBuf[128]; -unsigned char Uart1TxBuf[260]; -unsigned char Uart2RxBuf[RX2BUFSIZE]; -unsigned char Uart2TxBuf[TX2BUFSIZE]; +unsigned char Uart1RxBuf1[Uart1RxBufSize]; +unsigned char Uart1TxBuf1[260]; + +unsigned char Uart2RxBuf1[RX2BUFSIZE]; +unsigned char Uart2TxBuf1[TX2BUFSIZE]; + +unsigned short Uart1RxBuf1DataLen = 0; +unsigned short Uart2RxBuf1DataLen = 0; unsigned char SlowFlicker=0; unsigned char FastFlicker=0; unsigned int Uart1IdelTimer = 0; +unsigned char Uart1Mode = 1; //Uart1宸ヤ綔妯″紡锛� 0 : 鏅�氾紝 1 : 閫忎紶妯″紡 + +unsigned int Uart1Baud = DefaultUart1Baud; +unsigned int Uart2Baud = DefaultUart2Baud; + +//unsigned char Uart1RecvBuf1[Uart1RecvBufSize]; +//unsigned short Uart1RecvBuf1DataLen=0; + +//unsigned char Uart2RecvBuf1[128]; +//unsigned short Uart2RecvBuf1DataLen=0; + +volatile char Uart1BaudGot=0; +volatile char Uart1BaudFirstGot=0; +volatile char Uart1DmaInts=0; + + #if (ENABLE_PLC) stBinProg1 * pProgs = (stBinProg1 *)STORE_PRG_BASE; #endif @@ -151,23 +169,45 @@ #endif if (Uart2Stat.bPacketRecved) { - KBusParsePacket(&KBus1, (pKBPacket)Uart2RecvBuf1, Uart2RecvBuf1DataLen); - Uart2RecvBuf1DataLen=0; + KBusParsePacket(&KBus1, (pKBPacket)Uart2RxBuf1, Uart2RxBuf1DataLen); + Uart2RxBuf1DataLen=0; Uart2Stat.bPacketRecved=0; - Uart2RecvDMA(Uart2RecvBuf1,sizeof(Uart2RecvBuf1)); + Uart2RecvDMA(Uart2RxBuf1,sizeof(Uart2RxBuf1)); KMem.WDT[2]++; } - if (Uart1RecvBuf1DataLen >0 && Uart1Stat.bPacketRecved) + if (Uart1RxBuf1DataLen >0 && Uart1Stat.bPacketRecved) { int res1 = -1; - res1 = ModBusSlaveParsePkg(1, Uart1RecvBuf1, Uart1RecvBuf1DataLen); - if (res1 !=0) + if (Uart1RxBuf1DataLen == 3 && Uart1RxBuf1[0]=='+' && Uart1RxBuf1[0]=='+' && Uart1RxBuf1[0]=='+') { - KLParsePacket(1, Uart1RecvBuf1, Uart1RecvBuf1DataLen); + Uart1Mode = 0; // 鍒囨崲鍒板懡浠ゆā寮� + }else if (Uart1RxBuf1DataLen == 3 && Uart1RxBuf1[0]=='-' && Uart1RxBuf1[0]=='-' && Uart1RxBuf1[0]=='-') + { + Uart1Mode = 1; // 鍒囨崲鍒伴�忎紶妯″紡 + }else if (Uart1Mode == 0) { + + res1 = ModBusSlaveParsePkg(1, Uart1RxBuf1, Uart1RxBuf1DataLen); + if (res1 !=0) + { + KLParsePacket(1, Uart1RxBuf1, Uart1RxBuf1DataLen); + } + + }else if (Uart1Mode == 1) { + // 閫忎紶妯″紡 + if (KwRunStat.sizetosend == 0) { + memcpy( KwRunStat.ttTxBuf1,Uart1RxBuf1, Uart1RxBuf1DataLen); + KwRunStat.sentsize = 0; + KwRunStat.sizesending = 0; + KwRunStat.sizetosend = Uart1RxBuf1DataLen; + }else { + return; + } + + //SendPacket(1, Uart1RecvBuf1, Uart1RecvBuf1DataLen); } - Uart1RecvBuf1DataLen=0; + Uart1RxBuf1DataLen=0; Uart1Stat.bPacketRecved=0; - Uart1IdelTimer = 0; + Uart1IdelTimer = 0; } } @@ -228,8 +268,8 @@ /* USER CODE BEGIN 1 */ KMRunStat.bLEDFlick = 1; - InitUartstat(&Uart1Stat,Uart1RxBuf,sizeof(Uart1RxBuf),Uart1TxBuf,sizeof(Uart1TxBuf)); - InitUartstat(&Uart2Stat,Uart2RxBuf,sizeof(Uart2RxBuf),Uart2TxBuf,sizeof(Uart2TxBuf)); + InitUartstat(&Uart1Stat,Uart1RxBuf1,sizeof(Uart1RxBuf1),Uart1TxBuf1,sizeof(Uart1TxBuf1)); +// InitUartstat(&Uart2Stat,Uart2RxBuf1,sizeof(Uart2RxBuf1),Uart2TxBuf1,sizeof(Uart2TxBuf1)); /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ @@ -338,7 +378,7 @@ LL_USART_EnableIT_TC(USART1); // LL_USART_EnableIT_RXNE(USART2); - Uart2RecvDMA(Uart2RecvBuf1,sizeof(Uart2RecvBuf1)); + Uart2RecvDMA(Uart2RxBuf1,sizeof(Uart2RxBuf1)); LL_USART_EnableIT_IDLE(USART2); LL_USART_EnableIT_TC(USART2); -- Gitblit v1.9.1