instance_common.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673
  1. /*! ----------------------------------------------------------------------------
  2. * @file instance_common.c
  3. * @brief DecaWave application level common instance functions
  4. *
  5. * @attention
  6. *
  7. * Copyright 2015 (c) DecaWave Ltd, Dublin, Ireland.
  8. *
  9. * All rights reserved.
  10. *
  11. * @author DecaWave
  12. */
  13. #include "bsp.h"
  14. #include "compiler.h"
  15. #include "port.h"
  16. #include "deca_device_api.h"
  17. #include "deca_spi.h"
  18. #include "instance.h"
  19. // -------------------------------------------------------------------------------------------------------------------
  20. // Data Definitions
  21. // -------------------------------------------------------------------------------------------------------------------
  22. #define DW_MAX_POWER 1
  23. // -------------------------------------------------------------------------------------------------------------------
  24. extern char debugBuffer[256];
  25. extern int debugLen;
  26. volatile instance_data_t instance_data[NUM_INST] ;
  27. volatile instance_data_t *gInst = &instance_data[0];
  28. volatile uint32_t ancRespCount=0;
  29. volatile stAncRespRecord ancRespRecords[8] = {0};
  30. volatile stTagFinalRecord tagFinalRecord = {0};
  31. volatile stInstDebug instDebug={0};
  32. volatile eRxTxStage trxStage = RTX_IDLE;
  33. // -------------------------------------------------------------------------------------------------------------------
  34. // Functions
  35. // -------------------------------------------------------------------------------------------------------------------
  36. extern void DebugRun(void);
  37. extern int SendMessageWifi(uint8_t* buf, int len);
  38. extern int SendMessage(uint8_t* buf,int len);
  39. extern int SendMessageDbg(uint8_t* buf,int len);
  40. void ancPrepareResponse(uint16_t sourceAddress, uint8_t srcAddr_index, uint8_t fcode_index, uint8_t *frame, uint32_t uTimeStamp);
  41. void instClearDistTableAll(void);
  42. uint8_t tagRXReEnable(uint16_t sourceAddress);
  43. uint8_t ancSendFinalorRXReEnable(uint16_t sourceAddress);
  44. void ancEnableRX(void);
  45. uint8_t ancTXorRXReEnable(uint16_t sourceAddress);
  46. void handle_error_unknownFrame(event_data_t dw_event);
  47. float calculatePower(float base, float N, uint8_t pulseFrequency)
  48. {
  49. float A, corrFac;
  50. if(DWT_PRF_16M == pulseFrequency) {
  51. A = 115.72;
  52. corrFac = 2.3334;
  53. } else {
  54. A = 121.74;
  55. corrFac = 1.1667;
  56. }
  57. float estFpPwr = 10.0 * log10(base / (N * N)) - A;
  58. if(estFpPwr <= -88) {
  59. return estFpPwr;
  60. } else {
  61. // approximation of Fig. 22 in user manual for dbm correction
  62. estFpPwr += (estFpPwr + 88) * corrFac;
  63. }
  64. return estFpPwr;
  65. }
  66. float dwGetReceivePower(void)
  67. {
  68. uint32_t D17F=pow(2,17);
  69. dwt_rxdiag_t rxdiag_t;
  70. rxdiag_t.maxGrowthCIR=0;
  71. rxdiag_t.rxPreamCount=0;
  72. dwt_readdignostics(&rxdiag_t);
  73. float C = (&(rxdiag_t.stdNoise))[3];
  74. float N = rxdiag_t.rxPreamCount;
  75. int RX_level_C=(int)rxdiag_t.maxGrowthCIR;
  76. int RX_level_N=(int)rxdiag_t.rxPreamCount;
  77. float RX_level_A = 0;
  78. if(gInst->setting.configData.prf== DWT_PRF_64M)
  79. RX_level_A = 121.74;
  80. if(gInst->setting.configData.prf== DWT_PRF_16M)
  81. RX_level_A = 113.77;
  82. float RX_level = 0;
  83. RX_level=RX_level_C*D17F;
  84. RX_level=RX_level/(RX_level_N*RX_level_N);
  85. RX_level=10*log10(RX_level);
  86. RX_level=RX_level-RX_level_A;
  87. return RX_level;
  88. }
  89. void PrintDebugMessage(void)
  90. {
  91. debugLen = 0;
  92. debugLen += sprintf(debugBuffer+debugLen,"Debug: p:%06d, a: %06d, %06d %06d %06d %06d, f:%06d s:%06d ",
  93. instDebug.ancPollCount, instDebug.andRespSentCount,
  94. instDebug.ancRespCounts[0],instDebug.ancRespCounts[1],
  95. instDebug.ancRespCounts[2],instDebug.ancRespCounts[3],
  96. instDebug.ancFinalCount,instDebug.tofSuccess);
  97. debugLen += sprintf(debugBuffer+debugLen,"arf: %06d %06d %06d %06d, asf: %6d, rt:%06d, calc:%d errFrm:%d T:%d\r\n",
  98. instDebug.ancRespFailsCounts[0],instDebug.ancRespFailsCounts[1],
  99. instDebug.ancRespFailsCounts[2],instDebug.ancRespFailsCounts[3],
  100. instDebug.ancRespLateCount,instDebug.rxTimeoutCount,
  101. instDebug.calculateFails,
  102. instDebug.errFrameCount,
  103. portGetTickCnt());
  104. #if defined(REPORT2COM)
  105. ReportMessage((uint8_t*)debugBuffer, debugLen);
  106. #elif defined(REPORT2WIFI)
  107. SendMessageWifi((uint8_t*)debugBuffer, debugLen);
  108. #endif
  109. SendMessage((uint8_t*)debugBuffer,debugLen);
  110. SendMessageDbg((uint8_t*)debugBuffer,debugLen);
  111. }
  112. // -------------------------------------------------------------------------------------------------------------------
  113. // convert microseconds to device time
  114. uint64_t convertMicroSec2DeviceTime (double microSec)
  115. {
  116. uint64_t dt;
  117. long double dTime;
  118. dTime = (microSec / (double) DWT_TIME_UNITS) / 1e6 ;
  119. dt = (uint64_t) (dTime) ;
  120. return dt;
  121. }
  122. double convertDeviceTime2Sec(int32_t dt)
  123. {
  124. double f = 0;
  125. f = dt * DWT_TIME_UNITS ; // seconds #define TIME_UNITS (1.0/499.2e6/128.0) = 15.65e-12
  126. return f ;
  127. }
  128. #ifdef __GNUC__
  129. #pragma GCC optimize ("O3")
  130. #elif defined(__ICCARM__)
  131. #pragma optimize=speed high
  132. #endif
  133. int reportTOF(int idx, stTofInformation* tofx)
  134. {
  135. double distance ;
  136. double distance_to_correct;
  137. double tof ;
  138. int32_t tofi ;
  139. // check for negative results and accept them making them proper negative integers
  140. tofi = (int32_t) tofx->value ; // make it signed
  141. if (tofi > 0x7FFFFFFF) // close up TOF may be negative
  142. {
  143. tofi -= 0x80000000 ; //
  144. }
  145. // convert to seconds (as floating point)
  146. tof = convertDeviceTime2Sec(tofi) ; //this is divided by 4 to get single time of flight
  147. //inst_idistraw[idx] = distance = tof * SPEED_OF_LIGHT;
  148. distance = tof * SPEED_OF_LIGHT;
  149. gInst->twrResult.distance[idx].distanceRaw = distance;
  150. gInst->twrResult.distance[idx].address = tofx->address;
  151. #if (CORRECT_RANGE_BIAS == 1)
  152. //for the 6.81Mb data rate we assume gating gain of 6dB is used,
  153. //thus a different range bias needs to be applied
  154. //if(inst->configData.dataRate == DWT_BR_6M8)
  155. if(gInst->setting.configData.smartPowerEn)
  156. {
  157. //1.31 for channel 2 and 1.51 for channel 5
  158. if(gInst->setting.configData.chan == 5)
  159. {
  160. distance_to_correct = distance/1.51;
  161. }
  162. else //channel 2
  163. {
  164. distance_to_correct = distance/1.31;
  165. }
  166. }
  167. else
  168. {
  169. distance_to_correct = distance;
  170. }
  171. distance = distance - dwt_getrangebias(gInst->setting.configData.chan, (float) distance_to_correct, gInst->setting.configData.prf);
  172. #endif
  173. if ((distance < 0) || (distance > 20000.000)) // discard any results less than <0 cm or >20 km
  174. {
  175. return 0;
  176. }
  177. gInst->twrResult.distance[idx].distanceBias = distance;
  178. gInst->tmAndDelays.longTermRangeCount++ ; // for computing a long term average
  179. return 1;
  180. }
  181. /*
  182. void setTagDist(int tidx, int aidx)
  183. {
  184. //inst_tdist[tidx] = inst_idist[aidx];
  185. inst_tagdist[tidx].distanceBias = inst_dist[aidx].distanceBias;
  186. inst_tagdist[tidx].distanceRaw = inst_dist[aidx].distanceRaw;
  187. }
  188. double getTagDist(int idx)
  189. {
  190. //return inst_tdist[idx];
  191. return inst_tagdist[idx].distanceBias;
  192. }*/
  193. void clearDistTable(int idx)
  194. {
  195. gInst->twrResult.distance[idx].address = BROADCAST_ADDR;
  196. gInst->twrResult.distance[idx].distanceBias = 0;
  197. gInst->twrResult.distance[idx].distanceRaw = 0;
  198. }
  199. void instClearDistTableAll(void)
  200. {
  201. int i;
  202. for(i=0; i<MAX_ANCHOR_LIST_SIZE; i++)
  203. {
  204. clearDistTable(i);
  205. }
  206. }
  207. int instNewRange(void)
  208. {
  209. int x = gInst->stateMachine.newRange;
  210. gInst->stateMachine.newRange = TOF_REPORT_NUL;
  211. return x;
  212. }
  213. int instNewRangeAncAdd(void)
  214. {
  215. return gInst->stateMachine.newRangeAncAddress;
  216. }
  217. int instNewRangeTagAdd(void)
  218. {
  219. return gInst->stateMachine.newRangeTagAddress;
  220. }
  221. uint32_t instNewRangeTim(void)
  222. {
  223. return gInst->stateMachine.newRangeTime;
  224. }
  225. // -------------------------------------------------------------------------------------------------------------------
  226. // function to clear counts/averages/range values
  227. //
  228. void ClearRangeInformation(int index)
  229. {
  230. int j;
  231. memset((void*)(gInst->rangeInform + index), 0, sizeof(stTagRangeInformation));
  232. gInst->rangeInform[index].address = BROADCAST_ADDR;
  233. gInst->rangeInform[index].tofOfTags = INVALID_TOF;
  234. /*for(j=0;j<RESP_RECORD_COUNT;j++)
  235. {
  236. gInst->rangeInform[index].rxResps[j] = -10;
  237. }*/
  238. memset((void*)gInst->rangeInform[index].rxResps, -10, RESP_RECORD_COUNT);
  239. }
  240. void instClearCounts(void)
  241. {
  242. int i= 0;
  243. dwt_configeventcounters(1); //enable and clear - NOTE: the counters are not preserved when in DEEP SLEEP
  244. gInst->msgFrame.frameSN = 0;
  245. gInst->tmAndDelays.longTermRangeCount = 0;
  246. for(i=0; i<MAX_ANCHOR_LIST_SIZE; i++)
  247. {
  248. gInst->twrResult.tofArray[i].address = BROADCAST_ADDR;
  249. gInst->twrResult.tofArray[i].value = INVALID_TOF;
  250. }
  251. for(i=0; i<MAX_TAG_LIST_SIZE; i++)
  252. {
  253. ClearRangeInformation(i);
  254. }
  255. } // end instanceclearcounts()
  256. // -------------------------------------------------------------------------------------------------------------------
  257. // function to initialise instance structures
  258. //
  259. // Returns 0 on success and -1 on error
  260. int instance_init(void)
  261. {
  262. int result;
  263. // assume listener,
  264. gInst->stateMachine.testAppState = TA_INIT ;
  265. // Reset the IC (might be needed if not getting here from POWER ON)
  266. // ARM code: Remove soft reset here as using hard reset in the inittestapplication() in the main.c file
  267. //dwt_softreset();
  268. //this initialises DW1000 and uses specified configurations from OTP/ROM
  269. result = dwt_initialise(DWT_LOADUCODE | DWT_LOADLDOTUNE | DWT_LOADTXCONFIG | DWT_LOADANTDLY| DWT_LOADXTALTRIM) ;
  270. //this is platform dependent - only program if DW EVK/EVB
  271. dwt_setleds(3) ; //configure the GPIOs which control the leds on EVBs
  272. if (DWT_SUCCESS != result)
  273. {
  274. return (-1) ; // device initialise has failed
  275. }
  276. instClearCounts() ;
  277. gInst->stateMachine.wait4ack = 0;
  278. instClearEvents();
  279. //dwt_geteui(instance_data[instance].eui64);
  280. memset((void*)gInst->setting.eui64, 0, ADDR_BYTE_SIZE_L);
  281. gInst->tmAndDelays.tagSleepCorrection = 0;
  282. dwt_setautorxreenable(0); //disable auto RX re-enable
  283. dwt_setdblrxbuffmode(0); //disable double RX buffer
  284. // if using auto CRC check (DWT_INT_RFCG and DWT_INT_RFCE) are used instead of DWT_INT_RDFR flag
  285. // other errors which need to be checked (as they disable receiver) are
  286. //dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_SFDT | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1);
  287. dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO | DWT_INT_RXPTO), 1);
  288. result = dwt_read32bitoffsetreg(0x0E,0);//SYS_MASK_ID
  289. result++;
  290. result = dwt_read32bitoffsetreg(0x0F,0);//SYS_STATUS_ID
  291. result++;
  292. dwt_setcallbacks(instTXcallback, instRXcallback);
  293. //gInst->stateMachine.monitor = 0;
  294. gInst->stateMachine.responseTO = -10; //initialise
  295. gInst->tmAndDelays.delayedReplyTime = 0;
  296. return 0 ;
  297. }
  298. // -------------------------------------------------------------------------------------------------------------------
  299. //
  300. // Return the Device ID register value, enables higher level validation of physical device presence
  301. //
  302. uint32_t instReadDeviceID(void)
  303. {
  304. return dwt_readdevid() ;
  305. }
  306. // -------------------------------------------------------------------------------------------------------------------
  307. //
  308. // function to allow application configuration be passed into instance and affect underlying device operation
  309. //
  310. void instance_config(const instanceConfig_t *config, const sfConfig_t *sfConfig)
  311. {
  312. uint32_t power = 0;
  313. uint8_t otprev ;
  314. gInst->setting.configData.chan = config->channelNumber ;
  315. gInst->setting.configData.rxCode = config->preambleCode ;
  316. gInst->setting.configData.txCode = config->preambleCode ;
  317. gInst->setting.configData.prf = config->pulseRepFreq ;
  318. gInst->setting.configData.dataRate = config->dataRate ;
  319. gInst->setting.configData.txPreambLength = config->preambleLen ;
  320. gInst->setting.configData.rxPAC = config->pacSize ;
  321. gInst->setting.configData.nsSFD = config->nsSFD ;
  322. gInst->setting.configData.phrMode = DWT_PHRMODE_STD ;
  323. gInst->setting.configData.sfdTO = config->sfdTO;
  324. //the DW1000 will automatically use gating gain for frames < 1ms duration (i.e. 6.81Mbps data rate)
  325. //smartPowerEn should be set based on the frame length, but we can also use data rate.
  326. if( DWT_BR_6M8 == gInst->setting.configData.dataRate && 0 == config->txPower)
  327. {
  328. gInst->setting.configData.smartPowerEn = 1;
  329. }
  330. else
  331. {
  332. gInst->setting.configData.smartPowerEn = 0;
  333. }
  334. //configure the channel parameters
  335. dwt_configure((dwt_config_t*)&(gInst->setting.configData), DWT_LOADXTALTRIM) ;
  336. gInst->setting.configTX.PGdly = txSpectrumConfig[config->channelNumber].PGdelay ;
  337. //firstly check if there are calibrated TX power value in the DW1000 OTP
  338. power = dwt_getotptxpower(config->pulseRepFreq, gInst->setting.configData.chan);
  339. if((power == 0x0) || (power == 0xFFFFFFFF)) //if there are no calibrated values... need to use defaults
  340. {
  341. if(1 == gInst->setting.configData.smartPowerEn)
  342. {
  343. dwt_setsmarttxpower(1);
  344. power = txSpectrumConfig[config->channelNumber].txPwr[config->pulseRepFreq - DWT_PRF_16M];
  345. }
  346. else
  347. {
  348. dwt_setsmarttxpower(0);
  349. #if DW_MAX_POWER==1
  350. power = txManualSpectrumConfig[config->channelNumber].txPwr[config->pulseRepFreq - DWT_PRF_16M];
  351. #else
  352. power = maxSpectrumConfig[config->channelNumber].txPwr[config->pulseRepFreq - DWT_PRF_16M];
  353. #endif
  354. power = (power & 0xff0000ff) | (config->txPower<<8) | (config->txPower<<16);
  355. }
  356. }
  357. //Configure TX power
  358. gInst->setting.configTX.power = power;
  359. gInst->setting.configTX.power = 0x39393939;
  360. gInst->setting.configTX.power = 0x1F1F1F1F;
  361. //configure the tx spectrum parameters (power and PG delay)
  362. dwt_configuretxrf((dwt_txconfig_t*)&gInst->setting.configTX);
  363. otprev = dwt_otprevision() ; // this revision tells us how OTP is programmed.
  364. if ((2 == otprev) || (3 == otprev)) // board is calibrated with TREK1000 with antenna delays set for each use case)
  365. {
  366. uint8_t mode = 1;
  367. uint8_t chanindex = 0;
  368. gInst->setting.txAntennaDelay = dwt_getTREKOTPantennadelay(mode,
  369. gInst->setting.configData.chan,
  370. gInst->setting.configData.dataRate) ;
  371. // if nothing was actually programmed then set a reasonable value anyway
  372. if ((gInst->setting.txAntennaDelay == 0)
  373. || (gInst->setting.txAntennaDelay == 0xffff))
  374. {
  375. if(gInst->setting.configData.chan == 5)
  376. {
  377. chanindex = 1;
  378. }
  379. gInst->setting.txAntennaDelay = rfDelaysTREK[chanindex];
  380. }
  381. }
  382. else // assume it is older EVK1000 programming.
  383. {
  384. //get the antenna delay that was read from the OTP calibration area
  385. gInst->setting.txAntennaDelay = dwt_readantennadelay(config->pulseRepFreq) >> 1;
  386. // if nothing was actually programmed then set a reasonable value anyway
  387. if ((gInst->setting.txAntennaDelay == 0)
  388. || (gInst->setting.txAntennaDelay == 0xffff))
  389. {
  390. gInst->setting.txAntennaDelay = rfDelays[config->pulseRepFreq - DWT_PRF_16M];
  391. }
  392. }
  393. // -------------------------------------------------------------------------------------------------------------------
  394. // set the antenna delay, we assume that the RX is the same as TX.
  395. dwt_setrxantennadelay(gInst->setting.txAntennaDelay);
  396. dwt_settxantennadelay(gInst->setting.txAntennaDelay);
  397. gInst->setting.rxAntennaDelay = gInst->setting.txAntennaDelay;
  398. if(config->preambleLen == DWT_PLEN_64) //if preamble length is 64
  399. {
  400. BSP_DWM_SPI_FastRate(0); //reduce SPI to < 3MHz
  401. dwt_loadopsettabfromotp(0);
  402. BSP_DWM_SPI_FastRate(1); //increase SPI to max
  403. }
  404. instSetTagSleepDelay(sfConfig->pollSleepDly); //set the Tag sleep time
  405. gInst->setting.sframePeriod = sfConfig->sfPeriod;
  406. gInst->setting.slotPeriod = sfConfig->slotPeriod;
  407. gInst->tmAndDelays.tagSleepRnd = sfConfig->slotPeriod;
  408. gInst->setting.numSlots = sfConfig->numSlots;
  409. //set the default response delays
  410. instSetReplyDelay(sfConfig->replyDly);
  411. //PA control
  412. //dwt_setGPIOforEXTPA();
  413. }
  414. // -------------------------------------------------------------------------------------------------------------------
  415. // function to set the tag sleep time (in ms)
  416. //
  417. void instSetTagSleepDelay(int sleepdelay) //sleep in ms
  418. {
  419. gInst->tmAndDelays.tagSleepTime_ms = sleepdelay; //subtract the micro system delays (time it takes to switch states etc.)
  420. }
  421. //range result of anchors
  422. void SetTofResult(uint32_t addr, uint32_t value)
  423. {
  424. int index = addr & ANCHOR_LIST_INDEX_MASK;
  425. gInst->twrResult.tofArray[index].address = addr;
  426. gInst->twrResult.tofArray[index].value = value;
  427. }
  428. uint32_t GetTofResult(uint32_t address)
  429. {
  430. int index = address & ANCHOR_LIST_INDEX_MASK;
  431. return gInst->twrResult.tofArray[index].value;
  432. }
  433. void ClearTofResult(uint32_t address)
  434. {
  435. int index ;
  436. for(index=0; index < MAX_ANCHOR_LIST_SIZE; index++)
  437. {
  438. if(address == gInst->twrResult.tofArray[index].address)
  439. {
  440. gInst->twrResult.tofArray[index].address = BROADCAST_ADDR;
  441. gInst->twrResult.tofArray[index].value = INVALID_TOF;
  442. }
  443. }
  444. }
  445. #define SLOT_COUNT_IN_GROUP (32)
  446. #define SLOT_ALL_IN_GROUP (0xffffffff)
  447. #define SLOT_FLAG_COUNT (100)
  448. volatile uint16_t slotIndex[MAX_TAG_LIST_SIZE] = {0};
  449. volatile uint16_t slotAddress[SLOT_FLAG_COUNT] = {0};
  450. volatile int8_t slotDelay[SLOT_FLAG_COUNT] = {0};
  451. volatile int slotIdx = 0;
  452. volatile int loop =0;
  453. int instRangeAllocateSlot(uint32_t address)
  454. {
  455. int i,j,find = 0;
  456. slotIdx = 2;
  457. if (slotIndex[address])
  458. {
  459. if (slotDelay[slotIndex[address]] > 0)
  460. {
  461. slotDelay[slotIndex[address]] = 10;
  462. return slotIndex[address];
  463. }
  464. }
  465. while (loop < SLOT_FLAG_COUNT)
  466. {
  467. if (slotDelay[slotIdx] <= 0)
  468. {
  469. slotIndex[address] = slotIdx;
  470. slotAddress[slotIdx] = address;
  471. slotDelay[slotIdx] = 10;
  472. return slotIndex[address];
  473. }
  474. slotIdx += 2;
  475. if (slotIdx >= 100)
  476. {
  477. slotIdx = 1;
  478. }
  479. loop++;
  480. }
  481. return address % MAX_TAG_LIST_SIZE;
  482. }
  483. int instRangeSlotUpdate()
  484. {
  485. for (int i=0;i<SLOT_FLAG_COUNT;i++)
  486. {
  487. slotDelay[i]--;
  488. if (slotDelay[i] <= 0)
  489. {
  490. slotDelay[i] = 0;
  491. slotIndex[slotAddress[i]] = 0;
  492. slotAddress[i] = 0;
  493. }
  494. }
  495. }
  496. int instGetRangeInformIndex(uint32_t address, uint32_t alloacated)
  497. {
  498. //return (address & TAG_LIST_INDEX_MASK);
  499. uint16_t find = 0;
  500. uint16_t step = 0;//initiallize
  501. int availableIndex = -1;
  502. int index = (address % MAX_TAG_LIST_SIZE);
  503. if (gInst->rangeInform[index].address == address)
  504. { //find the allocated slot
  505. find = 2;
  506. }
  507. else if (gInst->rangeInform[index].address == BROADCAST_ADDR)
  508. {
  509. if(!alloacated)
  510. {//find slot for new tag
  511. find = 1;
  512. }
  513. if(availableIndex < 0)
  514. {//record the available slot
  515. availableIndex = index;
  516. }
  517. }
  518. switch(find)
  519. {
  520. case 1:
  521. gInst->rangeInform[index].address = address;
  522. gInst->rangeInform[index].slot = instRangeAllocateSlot(address);
  523. case 2:
  524. gInst->rangeInform[index].flag = 1;
  525. gInst->rangeInform[index].slot = instRangeAllocateSlot(address);
  526. gInst->rangeInform[index].tickUpdate = HAL_GetTick();
  527. break;
  528. }
  529. return index;
  530. }
  531. //range from Tag to anc
  532. void SetTagTofResult(uint32_t address, uint32_t value )
  533. {
  534. int index = instGetRangeInformIndex(address, 0);
  535. if (index >= 0)
  536. {
  537. gInst->rangeInform[index].address = address;
  538. gInst->rangeInform[index].tofOfTags = value;
  539. }
  540. }
  541. uint32_t GetTagTofResult(uint32_t address)
  542. {
  543. int index = instGetRangeInformIndex(address, 0);
  544. if (index >=0)
  545. {
  546. return gInst->rangeInform[index].tofOfTags;
  547. }
  548. else
  549. {
  550. return INVALID_TOF;
  551. }
  552. }
  553. void ClearTagTofResult(uint32_t address)
  554. {
  555. int index ;
  556. for(index=0; index < MAX_TAG_LIST_SIZE; index++)
  557. {
  558. if(address == gInst->rangeInform[index].address)
  559. {
  560. gInst->rangeInform[index].tofOfTags = INVALID_TOF;
  561. }
  562. }
  563. }
  564. //rangeNum from tag
  565. uint32_t instGetTagRangeNum(uint32_t address)
  566. {
  567. int index = instGetRangeInformIndex(address, 0);
  568. if (index > 0)
  569. {
  570. return gInst->rangeInform[index].rangeNumA;
  571. }
  572. else
  573. {
  574. return 0xFF;
  575. }
  576. }
  577. void instSetTagRangeNum(uint32_t address, uint32_t num)
  578. {
  579. int index = instGetRangeInformIndex(address, 0);
  580. if (index > 0)
  581. {
  582. gInst->rangeInform[index].rangeNumA = num;
  583. }
  584. }
  585. //response flag for tag
  586. void instInitTagResponseFlag(uint32_t address, uint32_t rangeNum)
  587. {
  588. int index = instGetRangeInformIndex(address, 0);
  589. if (index >= 0)
  590. {
  591. int respIndex = rangeNum & RESP_RECORD_MASK;
  592. gInst->rangeInform[index].rxRespsIdx = respIndex;
  593. gInst->rangeInform[index].rxResps[respIndex] = 0;
  594. }
  595. }
  596. int32_t instGetTagResponseFlag(uint32_t address)
  597. {
  598. int index = instGetRangeInformIndex(address, 1);
  599. if (index >= 0)
  600. {
  601. int reseIndex = gInst->rangeInform[index].rxRespsIdx;
  602. return gInst->rangeInform[index].rxResps[reseIndex];
  603. }
  604. else
  605. {
  606. return -1;
  607. }
  608. }
  609. void instIncTagResponseFlag(uint32_t address)
  610. {
  611. int index = instGetRangeInformIndex(address, 0);
  612. if (index >= 0)
  613. {
  614. int reseIndex = gInst->rangeInform[index].rxRespsIdx;
  615. gInst->rangeInform[index].rxResps[reseIndex]++;
  616. }
  617. }
  618. void instClearTagResponseFlag(uint32_t address)
  619. {
  620. int index = instGetRangeInformIndex(address, 0);
  621. if (index >= 0)
  622. {
  623. int reseIndex = gInst->rangeInform[index].rxRespsIdx;
  624. if(gInst->rangeInform[index].rxResps[reseIndex] >= 0)
  625. {
  626. gInst->rangeInform[index].rxResps[reseIndex] *= -1;
  627. if(gInst->rangeInform[index].rxResps[reseIndex] == 0) //as A0 will have this as 0 when ranging to A1
  628. {
  629. gInst->rangeInform[index].rxResps[reseIndex] = -1 ;
  630. }
  631. }
  632. }
  633. }
  634. //Tag command
  635. void SaveTagCommand(uint8_t* buf, uint32_t len)
  636. {
  637. if(len < 6)return;
  638. uint32_t address = buf[0] + (buf[1]<<8);
  639. int count = instGetRangeInformIndex(address, 0);
  640. if (count >= 0)
  641. {
  642. int index = 2;
  643. gInst->rangeInform[count].address = address;
  644. gInst->rangeInform[count].tagCommand.control = buf[index++];
  645. gInst->rangeInform[count].tagCommand.command = buf[index++];
  646. gInst->rangeInform[count].tagCommand.reservered1 = buf[index++];
  647. gInst->rangeInform[count].tagCommand.reservered2 = buf[index++];
  648. gInst->rangeInform[count].tagCommand.reservered3 = buf[index++];
  649. gInst->rangeInform[count].tagCommand.reservered4 = buf[index++];
  650. }
  651. }
  652. int GetTagCommand(uint16_t sourceAddress, stTagControlCommand* cmd)
  653. {
  654. int index = 0;
  655. memset((void*)cmd, 0, sizeof(stTagControlCommand));
  656. for(;index< MAX_TAG_LIST_SIZE;index++)
  657. {
  658. if( sourceAddress == gInst->rangeInform[index].address )
  659. {
  660. memcpy((void*)cmd, (const void*)(&gInst->rangeInform[index].tagCommand), sizeof(stTagControlCommand));
  661. memset((void*)(&gInst->rangeInform[index].tagCommand), 0, sizeof(stTagControlCommand));//after cmd is used, clear it!!!
  662. break;
  663. }
  664. }
  665. if( index >= MAX_TAG_LIST_SIZE )
  666. {
  667. index = -1;
  668. }
  669. return index;
  670. }
  671. //tag status
  672. int GetTagStatus(uint32_t address, stTagStatus* status)
  673. {
  674. int index = instGetRangeInformIndex(address, 0);
  675. if (index >= 0)
  676. {
  677. memcpy((void*)status, (const void*)(&gInst->rangeInform[index].tagStatus), sizeof(stTagStatus));//clear tagStatus
  678. memset((void*)(&gInst->rangeInform[index].tagStatus), 0, sizeof(stTagStatus));//clear tagStatus
  679. }
  680. return 0;
  681. }
  682. void SaveTagStatus(uint16_t address, uint8_t* messageData)
  683. {
  684. int index = instGetRangeInformIndex(address, 0);
  685. if (index >= 0)
  686. {
  687. gInst->rangeInform[index].address = address;
  688. gInst->rangeInform[index].flag = 1;
  689. //Get status from TAG POLL message
  690. gInst->rangeInform[index].tagStatus.status = messageData[POLL_TAG_STATUS];
  691. gInst->rangeInform[index].tagStatus.power = messageData[POLL_TAG_POWER];
  692. gInst->rangeInform[index].tagStatus.heartRate = messageData[POLL_TAG_HEARTBEAT];
  693. gInst->rangeInform[index].tagStatus.reserved1 = messageData[POLL_TAG_RESV1];
  694. gInst->rangeInform[index].tagStatus.reserved2= messageData[POLL_TAG_RESV2];
  695. }
  696. }
  697. int16_t GetTagSlot(uint16_t address)
  698. {
  699. int index = instGetRangeInformIndex(address, 0);
  700. if (index >=0 )
  701. {
  702. return gInst->rangeInform[index].slot;
  703. }
  704. else
  705. {
  706. return address % 4;
  707. }
  708. }
  709. int instGetLCount(void) //get count of ranges used for calculation of lt avg
  710. {
  711. int x = gInst->tmAndDelays.longTermRangeCount;
  712. return (x);
  713. }
  714. uint16_t instGetIdistAddress(int idx) //get instantaneous range
  715. {
  716. return gInst->twrResult.distance[idx].address;
  717. }
  718. double instGetIdist(int idx) //get instantaneous range
  719. {
  720. double x ;
  721. idx &= (MAX_ANCHOR_LIST_SIZE - 1);
  722. x = gInst->twrResult.distance[idx].distanceBias;
  723. return (x);
  724. }
  725. double instGetIdistRaw(int idx) //get instantaneous range (uncorrected)
  726. {
  727. double x ;
  728. idx &= (MAX_ANCHOR_LIST_SIZE - 1);
  729. x = gInst->twrResult.distance[idx].distanceRaw;
  730. return (x);
  731. }
  732. int instGetIdist_mm(int idx) //get instantaneous range
  733. {
  734. int x ;
  735. idx &= (MAX_ANCHOR_LIST_SIZE - 1);
  736. x = (int)(gInst->twrResult.distance[idx].distanceBias * 1000);
  737. return (x);
  738. }
  739. int instGetIdistRaw_mm(int idx) //get instantaneous range (uncorrected)
  740. {
  741. int x ;
  742. idx &= (MAX_ANCHOR_LIST_SIZE - 1);
  743. x = (int)(gInst->twrResult.distance[idx].distanceRaw * 1000);
  744. return (x);
  745. }
  746. void instBack2Anchor(instance_data_t *inst)
  747. {
  748. //stay in RX and behave as anchor
  749. inst->stateMachine.testAppState = TA_RXE_WAIT ;
  750. dwt_setrxtimeout(0);
  751. dwt_setpreambledetecttimeout(0);
  752. dwt_setrxaftertxdelay(0);
  753. }
  754. #ifdef __GNUC__
  755. #pragma GCC optimize ("O3")
  756. #elif defined(__ICCARM__)
  757. #pragma optimize=speed high
  758. #endif
  759. void instProcessRXtimeout(instance_data_t *inst)
  760. {
  761. inst->stateMachine.done = INST_NOT_DONE_YET;
  762. inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
  763. dwt_setrxtimeout(0);//Close timeout
  764. //timeout - disable the radio (if using SW timeout the rx will not be off)
  765. //dwt_forcetrxoff() ;
  766. }
  767. //
  768. // NB: This function is called from the (TX) interrupt handler
  769. //
  770. #ifdef __GNUC__
  771. #pragma GCC optimize ("O3")
  772. #elif defined(__ICCARM__)
  773. #pragma optimize=speed high
  774. #endif
  775. void instTXcallback(const dwt_callback_data_t *txd)
  776. {
  777. uint8_t txTimeStamp[TIMESTAME_LENGTH] = {0, 0, 0, 0, 0};
  778. uint8_t txevent = txd->event;
  779. event_data_t dw_event;
  780. dw_event.uTimeStamp = portGetTickCnt();
  781. if(txevent == DWT_SIG_TX_DONE)
  782. {
  783. //NOTE - we can only get TX good (done) while here
  784. //dwt_readtxtimestamp((uint8_t*) &instance_data[instance].txu.txTimeStamp);
  785. dwt_readtxtimestamp(txTimeStamp) ;
  786. dw_event.timeStamp32l = (uint32_t)txTimeStamp[0] + ((uint32_t)txTimeStamp[1] << 8) + ((uint32_t)txTimeStamp[2] << 16) + ((uint32_t)txTimeStamp[3] << 24);
  787. dw_event.timeStamp = txTimeStamp[4];
  788. dw_event.timeStamp <<= 32;
  789. dw_event.timeStamp += dw_event.timeStamp32l;
  790. dw_event.timeStamp32h = ((uint32_t)txTimeStamp[4] << 24) + (dw_event.timeStamp32l >> 8);
  791. //TX timestamp
  792. gInst->tmAndDelays.txu.txTimeStamp = dw_event.timeStamp;
  793. dw_event.rxLength = gInst->msgFrame.psduLength;
  794. dw_event.type = 0;
  795. dw_event.typePend = 0;
  796. dw_event.typeSave = DWT_SIG_TX_DONE;
  797. memcpy((uint8_t *)&dw_event.msgUnion.frame[0], (uint8_t *)&gInst->msgFrame.content, gInst->msgFrame.psduLength);
  798. instPutEvent(dw_event, DWT_SIG_TX_DONE);
  799. trxStage = RTX_IDLE;
  800. }
  801. else if(txevent == DWT_SIG_TX_AA_DONE)
  802. {
  803. //auto ACK confirmation
  804. dw_event.rxLength = 0;
  805. dw_event.type = 0;
  806. dw_event.typeSave = DWT_SIG_TX_AA_DONE;
  807. instPutEvent(dw_event, DWT_SIG_TX_AA_DONE);
  808. }
  809. //gInst->stateMachine.monitor = 0;
  810. }
  811. /**
  812. * @brief this function either enables the receiver (delayed)
  813. *
  814. **/
  815. void ancEnableRX(void)
  816. {
  817. //subtract preamble length
  818. dwt_setdelayedtrxtime(gInst->tmAndDelays.delayedReplyTime - gInst->setting.fixedReplyDelayAncP) ;
  819. if(dwt_rxenable(DWT_START_RX_DELAYED)) //delayed rx
  820. {
  821. //if the delayed RX failed - time has passed - do immediate enable
  822. dwt_setrxtimeout((uint16_t)gInst->setting.fwtoTimeAnc_sy*2); //reconfigure the timeout before enable
  823. //longer timeout as we cannot do delayed receive... so receiver needs to stay on for longer
  824. dwt_rxenable(DWT_START_RX_IMMEDIATE);
  825. trxStage = RTX_RX;
  826. dwt_setrxtimeout((uint16_t)gInst->setting.fwtoTimeAnc_sy); //restore the timeout for next RX enable
  827. }
  828. }
  829. /**
  830. * @brief this function either re-enables the receiver (delayed or immediate) or transmits the response frame
  831. *
  832. * @param the sourceAddress is the address of the sender of the current received frame
  833. *
  834. */
  835. #ifdef __GNUC__
  836. #pragma GCC optimize ("O0")
  837. #elif defined(__ICCARM__)
  838. #pragma optimize=speed high
  839. #endif
  840. uint8_t ancTXorRXReEnable(uint16_t sourceAddress)
  841. {
  842. uint8_t typePend = DWT_SIG_DW_IDLE;
  843. //int sendResp = 0;
  844. if(gInst->stateMachine.responseTO == 0) //go back to RX without TO - ranging has finished. (wait for Final but no TO)
  845. {
  846. dwt_setrxtimeout(0); //reconfigure the timeout
  847. dwt_setpreambledetecttimeout(0);
  848. }
  849. //configure delayed reply time (this is incremented for each received frame) it is timed from Poll rx time
  850. gInst->tmAndDelays.delayedReplyTime += (gInst->setting.fixedReplyDelayAnc >> 8);
  851. //this checks if to send a frame
  852. if( (gInst->stateMachine.responseTO + gInst->setting.shortAdd_idx) == NUM_EXPECTED_RESPONSES)
  853. {
  854. //response is expected
  855. gInst->stateMachine.wait4ack = DWT_RESPONSE_EXPECTED; //re has/will be re-enabled
  856. dwt_setdelayedtrxtime(gInst->tmAndDelays.delayedReplyTime) ;
  857. if(dwt_starttx(DWT_START_TX_DELAYED | gInst->stateMachine.wait4ack))
  858. //if(dwt_starttx(DWT_START_TX_IMMEDIATE | gInst->stateMachine.wait4ack))
  859. {//if TX has failed - we need to re-enable RX for the next response or final reception...
  860. dwt_setrxaftertxdelay(0);
  861. gInst->stateMachine.wait4ack = 0; //clear the flag as the TX has failed the TRX is off
  862. gInst->tmAndDelays.delayedReplyTime += 2*(gInst->setting.fixedReplyDelayAnc >> 8); //to take into account W4R
  863. ancEnableRX();
  864. typePend = DWT_SIG_RX_PENDING ;
  865. instDebug.ancRespLateCount++;
  866. trxStage = RTX_RX;
  867. }
  868. else
  869. {
  870. gInst->tmAndDelays.delayedReplyTime += (gInst->setting.fixedReplyDelayAnc >> 8); //to take into account W4R
  871. typePend = DWT_SIG_TX_PENDING ; // exit this interrupt and notify the application/instance that TX is in progress.
  872. instDebug.andRespSentCount++;
  873. trxStage = RTX_TX_THEN_RX;
  874. }
  875. }
  876. else //stay in receive
  877. {
  878. if(sourceAddress == 0)
  879. { //we got here after RX error, as we don't need to TX, we just enable RX
  880. dwt_setrxtimeout(0);
  881. dwt_rxenable(DWT_START_RX_IMMEDIATE);
  882. trxStage = RTX_RX;
  883. }
  884. else
  885. {
  886. if(gInst->stateMachine.responseTO > 0) //go back to RX without TO - ranging has finished. (wait for Final but no TO)
  887. {
  888. ancEnableRX();//??
  889. }
  890. else
  891. {
  892. dwt_rxenable(DWT_START_RX_IMMEDIATE);
  893. trxStage = RTX_RX;
  894. }
  895. }
  896. typePend = DWT_SIG_RX_PENDING ;
  897. }
  898. return typePend;
  899. }
  900. /**
  901. * @brief this function handles frame error event, it will either signal TO or re-enable the receiver
  902. */
  903. void handle_error_unknownFrame(event_data_t dw_event)
  904. {
  905. //re-enable the receiver (after error frames as we are not using auto re-enable
  906. //for ranging application rx error frame is same as TO - as we are not going to get the expected frame
  907. instDebug.errFrameCount++;
  908. instDebug.toBeHandled = TRUE;
  909. instDebug.type = dw_event.typeSave;
  910. //if we are participating in the ranging (i.e. Poll was received)
  911. //and we get an rx error (in one of the responses)
  912. //need to consider this as a timeout as we could be sending our response next and
  913. //the applications needs to know to change the state
  914. //
  915. if(gInst->stateMachine.responseTO > 0)
  916. {
  917. gInst->stateMachine.responseTO--;
  918. //send a response or re-enable rx
  919. dw_event.typePend = ancTXorRXReEnable(0);
  920. dw_event.type = 0;
  921. dw_event.typeSave = 0x40 | DWT_SIG_RX_TIMEOUT;
  922. dw_event.rxLength = 0;
  923. instPutEvent(dw_event, DWT_SIG_RX_TIMEOUT);
  924. //dwt_setrxtimeout(0); //reconfigure the timeout
  925. //dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
  926. }
  927. else
  928. {
  929. dwt_setrxtimeout(0); //reconfigure the timeout
  930. dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
  931. trxStage = RTX_RX;
  932. }
  933. }
  934. /**
  935. * @brief this function prepares and writes the anchor to tag response frame into the TX buffer
  936. * it is called after anchor receives a Poll from a tag
  937. */
  938. void ancPrepareResponse(uint16_t sourceAddress, uint8_t srcAddr_index, uint8_t fcode_index, uint8_t *frame, uint32_t uTimeStamp)
  939. {
  940. uint16_t frameLength = 0;
  941. uConverterUint2Bytes time = {0};
  942. uint32_t tofvalue=0;
  943. gInst->msgFrame.psduLength = frameLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
  944. memcpy((void*)&gInst->msgFrame.content.dstAddr[0], &frame[srcAddr_index], ADDR_BYTE_SIZE_S); //remember who to send the reply to (set destination address)
  945. gInst->msgFrame.content.srcAddr[0] = gInst->setting.eui64[0];
  946. gInst->msgFrame.content.srcAddr[1] = gInst->setting.eui64[1];
  947. // Write calculated TOF into response message (get the previous ToF+range number from that tag)
  948. tofvalue = GetTagTofResult(sourceAddress);
  949. memcpy((void*)&(gInst->msgFrame.content.messageData[TOFR]), (void*)&tofvalue, 4);
  950. memcpy((void*)&gInst->msgFrame.content.messageData[TAGADDR], &frame[srcAddr_index], ADDR_BYTE_SIZE_S); //get the previous range number
  951. #if 1
  952. //TagCommand: From ANC to TAG message
  953. stTagControlCommand cmd = {0};
  954. time.u32Data = g_stTimeValue.timeValue;
  955. int index = GetTagCommand(sourceAddress, &cmd);
  956. gInst->msgFrame.content.messageData[RESP_CONTROL] = cmd.control; //Control byte
  957. if(cmd.command != 0) //Ext Cmd
  958. {//command
  959. gInst->msgFrame.content.messageData[RESP_CMD] = cmd.command; //command byte
  960. time.u8Data[0] = cmd.reservered1;
  961. time.u8Data[1] = cmd.reservered2;
  962. time.u8Data[2] = cmd.reservered3;
  963. time.u8Data[3] = cmd.reservered4;
  964. gInst->msgFrame.content.messageData[RESP_TIME1] = time.u8Data[0]; //Time1
  965. gInst->msgFrame.content.messageData[RESP_TIME2] = time.u8Data[1]; //Time2
  966. gInst->msgFrame.content.messageData[RESP_TIME3] = time.u8Data[2]; //Time3
  967. gInst->msgFrame.content.messageData[RESP_TIME4] = time.u8Data[3]; //Time4
  968. }
  969. else if (time.u32Data > 0) //Timeset
  970. {//Timeset
  971. gInst->msgFrame.content.messageData[RESP_CMD] = EXTCMD_TIMESET; //set framePeroid
  972. gInst->msgFrame.content.messageData[RESP_TIME1] = time.u8Data[0]; //Time1
  973. gInst->msgFrame.content.messageData[RESP_TIME2] = time.u8Data[1]; //Time2
  974. gInst->msgFrame.content.messageData[RESP_TIME3] = time.u8Data[2]; //Time3
  975. gInst->msgFrame.content.messageData[RESP_TIME4] = time.u8Data[3]; //Time4
  976. }
  977. else // Superframe Peroid
  978. {//Peroid
  979. gInst->msgFrame.content.messageData[RESP_CMD] = EXTCMD_ANCFRAMEPEROID; //set framePeroid
  980. time.u32Data = g_stExtandCommand.param;
  981. gInst->msgFrame.content.messageData[RESP_TIME1] = time.u8Data[0]; //Time1
  982. gInst->msgFrame.content.messageData[RESP_TIME2] = time.u8Data[1]; //Time2
  983. gInst->msgFrame.content.messageData[RESP_TIME3] = time.u8Data[2]; //Time3
  984. gInst->msgFrame.content.messageData[RESP_TIME4] = time.u8Data[3]; //Time4
  985. }
  986. #endif
  987. instSetTagRangeNum(sourceAddress, frame[POLL_RNUM + fcode_index]);
  988. gInst->msgFrame.content.messageData[TOFRN] = frame[POLL_RNUM + fcode_index]; //get the previous range number
  989. gInst->msgFrame.content.seqNum = gInst->msgFrame.frameSN++;
  990. //we have our range - update the own mask entry...
  991. if(tofvalue != INVALID_TOF) //check the last ToF entry is valid and copy into the current array
  992. {
  993. SetTofResult(gInst->setting.instanceAddress16, tofvalue);
  994. }
  995. else //reset response mask
  996. {
  997. ClearTofResult(gInst->setting.instanceAddress16);
  998. }
  999. //set the delayed rx on time (the final message will be sent after this delay)
  1000. dwt_setrxaftertxdelay(gInst->setting.ancRespRxDelay); //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
  1001. //dwt_setrxaftertxdelay(0);
  1002. //���еĻ�վ����������ʱ�䣬�ֻ�����ɽ��յ�
  1003. {
  1004. int error = 0;
  1005. int currentSlotTime = 0;
  1006. int expectedSlotTime = 0;
  1007. int slot =-1;
  1008. //find the time in the current superframe
  1009. currentSlotTime = uTimeStamp % gInst->setting.sframePeriod;
  1010. //this is the slot time the poll should be received in (Mask 0x07 for the 8 MAX tags we support in TREK)
  1011. slot = GetTagSlot(sourceAddress);
  1012. expectedSlotTime = slot * TA_SLOT_STEP * gInst->setting.slotPeriod; //
  1013. error = expectedSlotTime - currentSlotTime;
  1014. if(error < (-(gInst->setting.sframePeriod>>1)) //if error is more negative than 0.5 period, add whole period to give up to 1.5 period sleep
  1015. && error < -12)
  1016. {
  1017. gInst->tmAndDelays.tagSleepCorrection = (gInst->setting.sframePeriod + error);
  1018. }
  1019. else //the minimum Sleep time will be 0.5 period
  1020. {
  1021. gInst->tmAndDelays.tagSleepCorrection = error;
  1022. }
  1023. gInst->msgFrame.content.messageData[RES_TAG_SLP0] = gInst->tmAndDelays.tagSleepCorrection & 0xFF ;
  1024. gInst->msgFrame.content.messageData[RES_TAG_SLP1] = (gInst->tmAndDelays.tagSleepCorrection >> 8) & 0xFF;
  1025. }
  1026. gInst->msgFrame.content.messageData[FCODE] = RTLS_DEMO_MSG_ANCH_RESP; //message function code (specifies if message is a poll, response or other...)
  1027. //write the TX data
  1028. dwt_writetxfctrl(frameLength, 0);
  1029. dwt_writetxdata(frameLength, (uint8_t *) &gInst->msgFrame.content, 0); // write the frame data
  1030. }
  1031. /**
  1032. * @brief this is the receive event callback handler, the received event is processed and the instance either
  1033. * responds by sending a response frame or re-enables the receiver to await the next frame
  1034. * once the immediate action is taken care of the event is queued up for application to process
  1035. */
  1036. #ifdef __GNUC__
  1037. #pragma GCC optimize ("O3")
  1038. #elif defined(__ICCARM__)
  1039. #pragma optimize=speed high
  1040. #endif
  1041. void instRXcallback(const dwt_callback_data_t *rxd)
  1042. {
  1043. uint8_t rxTimeStamp[TIMESTAME_LENGTH] = {0, 0, 0, 0, 0};
  1044. uint8_t rxd_event = 0;
  1045. uint8_t fcode_index = 0;
  1046. uint8_t srcAddr_index = 0;
  1047. event_data_t dw_event;
  1048. //microcontroller time at which we received the frame
  1049. dw_event.uTimeStamp = portGetTickCnt();
  1050. //if we got a frame with a good CRC - RX OK
  1051. if( rxd->event == DWT_SIG_RX_OKAY
  1052. || rxd->event == DWT_SIG_RX_PHR_ERROR
  1053. )
  1054. {
  1055. dw_event.rxLength = rxd->datalength;
  1056. //need to process the frame control bytes to figure out what type of frame we have received
  1057. if( ((rxd->fctrl[0] == 0x41) || (rxd->fctrl[0] == 0x61))
  1058. && ((rxd->fctrl[1] & 0xCC) == 0x88)) //short address
  1059. {
  1060. fcode_index = FRAME_CRTL_AND_ADDRESS_S; //function code is in first byte after source address
  1061. srcAddr_index = FRAME_CTRLP + ADDR_BYTE_SIZE_S;
  1062. rxd_event = DWT_SIG_RX_OKAY;
  1063. }
  1064. else
  1065. {
  1066. rxd_event = SIG_RX_UNKNOWN; //not supported - all TREK1000 frames are short addressed
  1067. }
  1068. //read RX timestamp
  1069. dwt_readrxtimestamp(rxTimeStamp) ;
  1070. dwt_readrxdata((uint8_t *)&dw_event.msgUnion.frame[0], rxd->datalength, 0); // Read Data Frame
  1071. dw_event.timeStamp32l = (uint32_t)rxTimeStamp[0] + ((uint32_t)rxTimeStamp[1] << 8) + ((uint32_t)rxTimeStamp[2] << 16) + ((uint32_t)rxTimeStamp[3] << 24);
  1072. dw_event.timeStamp = rxTimeStamp[4];
  1073. dw_event.timeStamp <<= 32;
  1074. dw_event.timeStamp += dw_event.timeStamp32l;
  1075. dw_event.timeStamp32h = ((uint32_t)rxTimeStamp[4] << 24) + (dw_event.timeStamp32l >> 8);
  1076. dw_event.type = 0; //type will be added as part of adding to event queue
  1077. dw_event.typeSave = rxd_event;
  1078. dw_event.typePend = DWT_SIG_DW_IDLE;
  1079. //if Listener then just report the received frame to the instance (application)
  1080. if(rxd_event == DWT_SIG_RX_OKAY) //Process good/known frame types
  1081. {
  1082. uint16_t sourceAddress = (((uint16_t)dw_event.msgUnion.frame[srcAddr_index+1]) << 8) + dw_event.msgUnion.frame[srcAddr_index];
  1083. //check if this is a TWR message (and also which one)
  1084. switch(dw_event.msgUnion.frame[fcode_index])
  1085. {
  1086. //poll message from an anchor
  1087. case RTLS_DEMO_MSG_ANCH_POLL:
  1088. {
  1089. } break;
  1090. case RTLS_DEMO_MSG_TAG_POLL:
  1091. {
  1092. instInitTagResponseFlag(sourceAddress, dw_event.msgUnion.frame[POLL_RNUM + fcode_index]);
  1093. float uwb_rssi = dwGetReceivePower();
  1094. gInst->rangeInform[sourceAddress].tagStatus.txRssi = uwb_rssi;
  1095. //gInst->stateMachine.isAncResp = 0;
  1096. //prepare the response and write it to the tx buffer
  1097. ancPrepareResponse(sourceAddress, srcAddr_index, fcode_index, &dw_event.msgUnion.frame[0], dw_event.uTimeStamp);
  1098. gInst->tmAndDelays.tagPollRxTime = dw_event.timeStamp ; //save Poll's Rx time
  1099. gInst->tmAndDelays.delayedReplyTime = dw_event.timeStamp32h /*+ (instance_data[0].fixedReplyDelayAnc >> 8)*/ ;
  1100. gInst->stateMachine.responseTO = NUM_EXPECTED_RESPONSES; //set number of expected responses to 3 (from other anchors)
  1101. /*if(gInst->setting.shortAdd_idx==2)
  1102. {
  1103. gInst->tmAndDelays.delayedReplyTime += 3 * (gInst->setting.fixedReplyDelayAnc >> 8); //to take into account W4R
  1104. //dwt_setrxtimeout((uint16_t)gInst->setting.fwtoTime_sy * NUM_EXPECTED_RESPONSES); //reconfigure the timeout for response
  1105. dwt_setrxtimeout(gInst->setting.pollRx2FinalRxDelay);
  1106. }
  1107. else*/
  1108. {
  1109. dwt_setrxtimeout((uint16_t)gInst->setting.fwtoTimeAnc_sy); //reconfigure the timeout for response
  1110. }
  1111. dw_event.typePend = ancTXorRXReEnable(gInst->setting.instanceAddress16);
  1112. //clear ToF ..
  1113. ClearTagTofResult(sourceAddress);
  1114. memset((void*)&tagFinalRecord, 0, sizeof(stTagFinalRecord));
  1115. ancRespCount = 0;
  1116. memset((void*)&ancRespRecords, 0 ,sizeof(ancRespRecords));
  1117. instDebug.ancPollCount++;
  1118. //sprintf((char*)debugBuffer,"Rssi, rn=%d, tx=%f \r\n", gInst->rangeInform[sourceAddress].rangeNumA, uwb_rssi);
  1119. //DebugMessage(debugBuffer);
  1120. } break;
  1121. //we got a response from a "responder" (anchor)
  1122. case RTLS_DEMO_MSG_ANCH_RESP2:
  1123. break;
  1124. case RTLS_DEMO_MSG_ANCH_RESP:
  1125. {
  1126. uint16_t tagAddress = (uint16_t) (dw_event.msgUnion.frame[fcode_index + TAGADDR] + (dw_event.msgUnion.frame[fcode_index + TAGADDR + 1]<<8));
  1127. //got a response... (check if we got a Poll with the same range number as in this response)
  1128. if(RTLS_DEMO_MSG_ANCH_RESP == dw_event.msgUnion.frame[fcode_index])
  1129. {
  1130. //if((gInst->setting.shortAdd_idx != 2)&&
  1131. if((instGetTagResponseFlag(tagAddress) >= 0) //we got the poll else ignore this response
  1132. && (gInst->stateMachine.responseTO > 0) ) //if responseTO == 0 we have already received all of the responses - meaning should not be here => error
  1133. {
  1134. instIncTagResponseFlag(tagAddress); //increment the number of responses received
  1135. gInst->stateMachine.responseTO--;
  1136. //send a response or re-enable rx
  1137. dw_event.typePend = ancTXorRXReEnable(sourceAddress);
  1138. }
  1139. else //like a timeout (error) ...
  1140. {
  1141. //send a response or re-enable rx
  1142. dwt_setrxtimeout(0); //reconfigure the timeout
  1143. dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
  1144. trxStage = RTX_RX;
  1145. dw_event.typePend = DWT_SIG_RX_PENDING ;
  1146. }
  1147. }
  1148. int currentRangeNum = dw_event.msgUnion.frame[fcode_index + TOFRN];
  1149. if(instGetTagRangeNum(tagAddress) == currentRangeNum)
  1150. {
  1151. uint16_t src_addr = 0;
  1152. uint32_t src_tof = 0;
  1153. memcpy((void*)&src_addr, &dw_event.msgUnion.frame[srcAddr_index], 2);
  1154. memcpy((void*)&src_tof, &(dw_event.msgUnion.frame[fcode_index + TOFR]), TIMEOFFLY_LENGTH);
  1155. SetTofResult(src_addr, src_tof);
  1156. instDebug.ancRespCounts[sourceAddress & ANCHOR_LIST_INDEX_MASK]++;
  1157. ancRespRecords[ancRespCount].rangNum = dw_event.msgUnion.frame[fcode_index + TOFRN];
  1158. memcpy((void*)&ancRespRecords[ancRespCount].address, &dw_event.msgUnion.frame[srcAddr_index], 2);
  1159. memcpy((void*)&ancRespRecords[ancRespCount].tof, &dw_event.msgUnion.frame[fcode_index + TOFR], TIMEOFFLY_LENGTH);
  1160. ancRespCount++;
  1161. }
  1162. else
  1163. {
  1164. ClearTofResult(sourceAddress);
  1165. instDebug.ancRespFailsCounts[sourceAddress & ANCHOR_LIST_INDEX_MASK]++;
  1166. }
  1167. } break;
  1168. case RTLS_DEMO_MSG_TAG_FINAL:
  1169. {
  1170. int count,index;
  1171. gInst->tmAndDelays.tagFinalRxTime = dw_event.timeStamp;
  1172. //reset the response count
  1173. instClearTagResponseFlag(sourceAddress);
  1174. float uwb_rssi = dwGetReceivePower();
  1175. gInst->rangeInform[sourceAddress].tagStatus.txRssiFinal = uwb_rssi;
  1176. tagFinalRecord.tagAddress = sourceAddress;
  1177. tagFinalRecord.rangNum = dw_event.msgUnion.frame[fcode_index + POLL_RNUM];
  1178. for(count = 0; count < NUM_EXPECTED_RESPONSES; count++)
  1179. {
  1180. index = fcode_index + RRXT0ADDR + (TIMESTAME_LENGTH + ADDR_BYTE_SIZE_S) * count;
  1181. memcpy((void*)&tagFinalRecord.ancRespTimes[count].address, (void const*)&(dw_event.msgUnion.frame[index]), ADDR_BYTE_SIZE_S);
  1182. memcpy((void*)tagFinalRecord.ancRespTimes[count].ancRespRxTime, (void const*)&(dw_event.msgUnion.frame[index + ADDR_BYTE_SIZE_S]), TIMESTAME_LENGTH);
  1183. }
  1184. memcpy((void*)tagFinalRecord.tagPollTxTime, (void const*)&(dw_event.msgUnion.frame[fcode_index + PTXT]), TIMESTAME_LENGTH);
  1185. memcpy((void*)tagFinalRecord.tagFinalTxTime, (void const*)&(dw_event.msgUnion.frame[fcode_index + FTXT]), TIMESTAME_LENGTH);
  1186. dw_event.typePend = DWT_SIG_DW_IDLE;
  1187. instDebug.ancFinalCount++;
  1188. //sprintf((char*)debugBuffer,"Rssi, rn=%d, txFinal=%f\r\n", gInst->rangeInform[sourceAddress].rangeNumA, uwb_rssi);
  1189. //DebugMessage(debugBuffer);
  1190. //after final received start receiving next poll
  1191. ///instSetAntennaDelays(); //this will update the antenna delay if it has changed
  1192. //instSetTXPower(); // configure TX power if it has changed
  1193. //dwt_setrxtimeout(0); //reconfigure the timeout
  1194. //dwt_rxenable(DWT_START_RX_IMMEDIATE);
  1195. } break;
  1196. case RTLS_DEMO_MSG_ANCH_FINAL:
  1197. //if anchor fall into case below and process the frame
  1198. default: //process rx frame
  1199. {
  1200. dw_event.typePend = DWT_SIG_DW_IDLE;
  1201. } break;
  1202. }
  1203. instPutEvent(dw_event, rxd_event);
  1204. }
  1205. else //if (rxd_event == SIG_RX_UNKNOWN) //need to re-enable the rx (got unknown frame type)
  1206. {
  1207. handle_error_unknownFrame(dw_event);
  1208. }
  1209. }
  1210. else if (rxd->event == DWT_SIG_RX_TIMEOUT) //if tag and got TO, then did not get any or some responses - check if need to send final.
  1211. {
  1212. dw_event.typePend = DWT_SIG_DW_IDLE;
  1213. instDebug.rxTimeoutCount++;
  1214. //check if anchor has received all of the responses from other anchors (it could have received only 1 or 2)
  1215. //it's timed out (re-enable rx or tx response)
  1216. if(gInst->stateMachine.responseTO > 0)
  1217. {
  1218. gInst->stateMachine.responseTO--;
  1219. //send a response or re-enable rx
  1220. dw_event.typePend = ancTXorRXReEnable(gInst->setting.instanceAddress16);
  1221. }
  1222. else
  1223. {
  1224. //dwt_setrxtimeout(0); //reconfigure the timeout
  1225. //dwt_rxenable(DWT_START_RX_IMMEDIATE);
  1226. //trxStage = RTX_RX;
  1227. }
  1228. dw_event.type = 0;
  1229. dw_event.typeSave = DWT_SIG_RX_TIMEOUT;
  1230. dw_event.rxLength = 0;
  1231. dw_event.timeStamp = 0;
  1232. dw_event.timeStamp32l = 0;
  1233. dw_event.timeStamp32h = 0;
  1234. instPutEvent(dw_event, DWT_SIG_RX_TIMEOUT);
  1235. //printf("RX timeout while in %d\n", instance_data[instance].testAppState);
  1236. }
  1237. else //assume other events are errors
  1238. {
  1239. dw_event.typeSave = rxd->event;
  1240. handle_error_unknownFrame(dw_event);
  1241. }
  1242. }
  1243. /**************************************************************************************/
  1244. #ifdef __GNUC__
  1245. #pragma GCC optimize ("O3")
  1246. #elif defined(__ICCARM__)
  1247. #pragma optimize=speed high
  1248. #endif
  1249. int instPeekEvent(void)
  1250. {
  1251. return peekEvent((const event_queue*)&(gInst->evtQueue));
  1252. }
  1253. /*
  1254. #ifdef __GNUC__
  1255. #pragma GCC optimize ("O3")
  1256. #elif defined(__ICCARM__)
  1257. #pragma optimize=speed high
  1258. #endif
  1259. void instSaveEvent(event_data_t newEvent, uint8_t eType)
  1260. {
  1261. saveEvent((event_queue*)&(gInst->evtQueue), newEvent, eType);
  1262. }
  1263. #ifdef __GNUC__
  1264. #pragma GCC optimize ("O3")
  1265. #elif defined(__ICCARM__)
  1266. #pragma optimize=speed high
  1267. #endif
  1268. event_data_t instGetSavedEvent(void)
  1269. {
  1270. return getSavedEvent((event_queue*)&(gInst->evtQueue));
  1271. }
  1272. */
  1273. #ifdef __GNUC__
  1274. #pragma GCC optimize ("O3")
  1275. #elif defined(__ICCARM__)
  1276. #pragma optimize=speed high
  1277. #endif
  1278. void instPutEvent(event_data_t newEvent, uint8_t eType)
  1279. {
  1280. putEvent((event_queue*)&(gInst->evtQueue), newEvent, eType);
  1281. }
  1282. #ifdef __GNUC__
  1283. #pragma GCC optimize ("O3")
  1284. #elif defined(__ICCARM__)
  1285. #pragma optimize=speed high
  1286. #endif
  1287. event_data_t* instGetEvent(int x)
  1288. {
  1289. return getEvent((event_queue*)&(gInst->evtQueue), x);
  1290. }
  1291. void instClearEvents(void)
  1292. {
  1293. clearEvents((event_queue*)&(gInst->evtQueue));
  1294. }
  1295. // -------------------------------------------------------------------------------------------------------------------
  1296. /**************************************************************************************/
  1297. #ifdef __GNUC__
  1298. #pragma GCC optimize ("O3")
  1299. #elif defined(__ICCARM__)
  1300. #pragma optimize=speed high
  1301. #endif
  1302. int instance_run(void)
  1303. {
  1304. int done = INST_NOT_DONE_YET;
  1305. int message = 0;
  1306. #if 1
  1307. while(done == INST_NOT_DONE_YET)
  1308. {
  1309. message = instPeekEvent(); //get any of the received events from ISR
  1310. //int state = instance_data[instance].testAppState;
  1311. done = testAppRun((instance_data_t*)gInst, message) ; // run the communications application
  1312. //we've processed message
  1313. message = 0;
  1314. //DebugRun();
  1315. }
  1316. //debugLen = sprintf(debugBuffer,"ENDWILE1 state:%d, %d T:%d\r\n",gInst->stateMachine.testAppState,done,portGetTickCnt());
  1317. //ReportMessage(debugBuffer, debugLen);
  1318. #else
  1319. message = instPeekEvent(); //get any of the received events from ISR
  1320. while(done == INST_NOT_DONE_YET)
  1321. {
  1322. //int state = instance_data[instance].testAppState;
  1323. done = testAppRun(gInst, message) ; // run the communications application
  1324. //we've processed message
  1325. message = 0;
  1326. //DebugRun();
  1327. }
  1328. #endif
  1329. if(instDebug.toBeHandled == TRUE)
  1330. {
  1331. instDebug.toBeHandled=FALSE;
  1332. #if (ANC_RESP_TEST==1)
  1333. {
  1334. debugLen = sprintf(debugBuffer,"ERROR FRAME %d: %d T:%d\r\n",
  1335. instDebug.errFrameCount, instDebug.type, portGetTickCnt());
  1336. #if defined(REPORT2COM)
  1337. ReportMessage((uint8_t*)debugBuffer, debugLen);
  1338. #elif defined(REPORT2WIFI)
  1339. SendMessageWifi((uint8_t*)debugBuffer, debugLen);
  1340. #endif
  1341. SendMessage((uint8_t*)debugBuffer,debugLen);
  1342. }
  1343. #endif
  1344. }
  1345. return 0 ;
  1346. }
  1347. void instClose(void)
  1348. {
  1349. //wake up device from low power mode
  1350. //NOTE - in the ARM code just drop chip select for 200us
  1351. port_SPIx_CS_clear(); //CS low
  1352. Sleep(1); //200 us to wake up then waits 5ms for DW1000 XTAL to stabilise
  1353. port_SPIx_CS_set(); //CS high
  1354. Sleep(5);
  1355. dwt_entersleepaftertx(0); // clear the "enter deep sleep after tx" bit
  1356. dwt_setinterrupt(0xFFFFFFFF, 0); //don't allow any interrupts
  1357. }
  1358. void instConfigTXPower(uint32_t txpower)
  1359. {
  1360. gInst->setting.txPower = txpower ;
  1361. gInst->setting.txPowerChanged = 1;
  1362. }
  1363. void instSetTXPower(void)
  1364. {
  1365. if(gInst->setting.txPowerChanged == 1)
  1366. {
  1367. //Configure TX power
  1368. dwt_write32bitreg(0x1E, gInst->setting.txPower);
  1369. gInst->setting.txPowerChanged = 0;
  1370. }
  1371. }
  1372. void instConfigAntennaDelays(uint16_t tx, uint16_t rx)
  1373. {
  1374. gInst->setting.txAntennaDelay = tx ;
  1375. gInst->setting.rxAntennaDelay = rx ;
  1376. gInst->setting.antennaDelayChanged = 1;
  1377. }
  1378. void instSetAntennaDelays(void)
  1379. {
  1380. if(gInst->setting.antennaDelayChanged == 1)
  1381. {
  1382. dwt_setrxantennadelay(gInst->setting.rxAntennaDelay);
  1383. dwt_settxantennadelay(gInst->setting.txAntennaDelay);
  1384. gInst->setting.antennaDelayChanged = 0;
  1385. }
  1386. }
  1387. uint16_t instTXAntennaDly(void)
  1388. {
  1389. return gInst->setting.txAntennaDelay;
  1390. }
  1391. uint16_t instRXAntennaDly(void)
  1392. {
  1393. return gInst->setting.rxAntennaDelay;
  1394. }
  1395. uint8_t instValidRanges(void)
  1396. {
  1397. return 0;
  1398. }