instance.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. /*! ----------------------------------------------------------------------------
  2. * @file instance.c
  3. * @brief DecaWave application level message exchange for ranging demo
  4. *
  5. * @attention
  6. *
  7. * Copyright 2015 (c) DecaWave Ltd, Dublin, Ireland.
  8. *
  9. * All rights reserved.
  10. *
  11. * @author DecaWave
  12. */
  13. #include "compiler.h"
  14. #include "port.h"
  15. #include "deca_device_api.h"
  16. #include "deca_spi.h"
  17. #include "deca_regs.h"
  18. #include "instance.h"
  19. // -------------------------------------------------------------------------------------------------------------------
  20. // -------------------------------------------------------------------------------------------------------------------
  21. // Data Definitions
  22. // -------------------------------------------------------------------------------------------------------------------
  23. extern char debugBuffer[256];
  24. extern int debugLen;
  25. extern volatile stTagFinalRecord tagFinalRecord;
  26. extern volatile uint32_t ancRespCount;
  27. extern volatile stAncRespRecord ancRespRecords[8];
  28. extern volatile stInstDebug instDebug;
  29. int ReceivedReply=5000;
  30. typedef struct _monitor_ticks_
  31. {
  32. uint32_t startTick;
  33. uint32_t pollRecvTick;
  34. uint32_t startSendTick;
  35. uint32_t temp;
  36. }stDwmMonitor;
  37. volatile stDwmMonitor monitor = {0};
  38. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  39. // NOTE: the maximum RX timeout is ~ 65ms
  40. // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  41. // -------------------------------------------------------------------------------------------------------------------
  42. // Functions
  43. // -------------------------------------------------------------------------------------------------------------------
  44. #if defined(REPORT2WIFI)
  45. extern int SendMessageWifi(uint8_t* buf,int len);
  46. #endif
  47. extern int SendMessage(uint8_t* buf,int len);
  48. extern int SendMessageDbg(uint8_t* buf,int len);
  49. // -------------------------------------------------------------------------------------------------------------------
  50. //
  51. // function to construct the message/frame header bytes
  52. //
  53. // -------------------------------------------------------------------------------------------------------------------
  54. //
  55. void instConfigFrameHeader16(instance_data_t *inst)
  56. {
  57. //set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
  58. inst->msgFrame.content.frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
  59. //source/dest addressing modes and frame version
  60. inst->msgFrame.content.frameCtrl[1] = 0x8 /*dest extended address (16bits)*/ | 0x80 /*src extended address (16bits)*/;
  61. inst->msgFrame.content.panID[0] = (inst->setting.panID) & 0xff;
  62. inst->msgFrame.content.panID[1] = inst->setting.panID >> 8;
  63. inst->msgFrame.content.seqNum = 0;
  64. }
  65. int instSendDlyPacket(instance_data_t *inst, int delayedTx)
  66. {
  67. int result = 0;
  68. dwt_writetxfctrl(inst->msgFrame.psduLength, 0);
  69. if(delayedTx == DWT_START_TX_DELAYED)
  70. {
  71. dwt_setdelayedtrxtime(inst->tmAndDelays.delayedReplyTime) ; //should be high 32-bits of delayed TX TS
  72. }
  73. //begin delayed TX of frame
  74. if (dwt_starttx(delayedTx | inst->stateMachine.wait4ack)) // delayed start was too late
  75. {
  76. result = 1; //late/error
  77. }
  78. else
  79. {
  80. //inst->stateMachine.monitor = 1;
  81. }
  82. return result; // state changes
  83. }
  84. int instance_calcranges(stTofInformation *array, uint16_t size, int reportRange, uint32_t* mask)
  85. {
  86. int i;
  87. int newRange = TOF_REPORT_NUL;
  88. int distance = 0;
  89. for(i=0; i<size; i++)
  90. {
  91. stTofInformation* tofx = array+i;
  92. if(tofx->value != INVALID_TOF) //if ToF == 0 - then no new range to report
  93. {
  94. distance = reportTOF(i, tofx);
  95. }
  96. if(distance == 1)
  97. {
  98. newRange = reportRange;
  99. }
  100. else
  101. {
  102. clearDistTable(i);
  103. }
  104. array[i].value = INVALID_TOF;
  105. array[i].address = BROADCAST_ADDR;
  106. distance = 0;
  107. }
  108. if(newRange==TOF_REPORT_NUL)
  109. {
  110. distance = 0;
  111. }
  112. return newRange;
  113. }
  114. void ReportTagStatus(uint32_t address)
  115. {
  116. stTagStatus tagStatus;
  117. GetTagStatus(address, &tagStatus);
  118. debugLen = sprintf(debugBuffer,"tag: %04x, st=%04x, pw=%d, hb=%d; ps: %06d, as: %06d ar:%06d %06d %06d %06d, fs: %06d, tof: %06d T:%d\r\n",
  119. address, tagStatus.status, tagStatus.power, tagStatus.heartRate,
  120. instDebug.ancPollCount, instDebug.andRespSentCount,
  121. instDebug.ancRespCounts[0],instDebug.ancRespCounts[1],
  122. instDebug.ancRespCounts[2],instDebug.ancRespCounts[3],
  123. instDebug.ancFinalCount, instDebug.tofSuccess,
  124. portGetTickCnt());
  125. #if defined(REPORT2COM)
  126. ReportMessage((uint8_t*)debugBuffer, debugLen);
  127. #elif defined(REPORT2WIFI)
  128. SendMessageWifi((uint8_t*)debugBuffer, debugLen);
  129. #endif
  130. SendMessage((uint8_t*)debugBuffer,debugLen);
  131. SendMessageDbg((uint8_t*)debugBuffer,debugLen);
  132. }
  133. int appState_TA_INIT(instance_data_t *inst, uint32_t* status, int message)
  134. {
  135. *status=TA_INIT;
  136. memcpy(inst->setting.eui64, &inst->setting.instanceAddress16, ADDR_BYTE_SIZE_S);
  137. dwt_seteui(inst->setting.eui64);
  138. dwt_setpanid(inst->setting.panID);
  139. //set source address
  140. inst->setting.shortAdd_idx = (inst->setting.instanceAddress16 % (ANCHOR_SHORT_MASK + 1));
  141. //inst->setting.shortAdd_idx = (inst->setting.instanceAddress16 % NUM_EXPECTED_RESPONSES);
  142. dwt_setaddress16(inst->setting.instanceAddress16);
  143. dwt_enableframefilter(DWT_FF_NOTYPE_EN); //allow data, ack frames;
  144. // First time anchor listens we don't do a delayed RX
  145. dwt_setrxaftertxdelay(0);
  146. //change to next state - wait to receive a message
  147. inst->stateMachine.testAppState = TA_RXE_WAIT ;
  148. dwt_setrxtimeout(0);
  149. dwt_setpreambledetecttimeout(0);
  150. instConfigFrameHeader16(inst);
  151. return 0;
  152. }
  153. //
  154. int appState_TA_TX_WAIT_CONF(instance_data_t *inst, uint32_t *status, int message)
  155. {
  156. *status=TA_TX_WAIT_CONF;
  157. event_data_t* dw_event = instGetEvent(11); //get and clear this event
  158. //NOTE: Can get the ACK before the TX confirm event for the frame requesting the ACK
  159. //this happens because if polling the ISR the RX event will be processed 1st and then the TX event
  160. //thus the reception of the ACK will be processed before the TX confirmation of the frame that requested it.
  161. if(dw_event->type != DWT_SIG_TX_DONE) //wait for TX done confirmation
  162. {
  163. if(dw_event->type == DWT_SIG_RX_TIMEOUT) //got RX timeout - i.e. did not get the response (e.g. ACK)
  164. {
  165. //printf("RX timeout in TA_TX_WAIT_CONF (%d)\n", inst->previousState);
  166. //we need to wait for SIG_TX_DONE and then process the timeout and re-send the frame if needed
  167. inst->stateMachine.gotTO = 1;
  168. }
  169. else
  170. {
  171. //inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT;
  172. inst->stateMachine.done = INST_NOT_DONE_YET;
  173. }
  174. uint32_t curTick = HAL_GetTick();
  175. if(monitor.startSendTick > curTick)
  176. {
  177. monitor.startSendTick = curTick;
  178. }
  179. if(curTick - monitor.startSendTick < inst->setting.slotPeriod )
  180. {
  181. return -1;
  182. }
  183. else
  184. {
  185. inst->stateMachine.gotTO = 1;
  186. }
  187. }
  188. inst->stateMachine.done = INST_NOT_DONE_YET;
  189. if (inst->stateMachine.gotTO == 1) //timeout
  190. {
  191. if(inst->stateMachine.previousState == TA_TXRESPONSE_SENT_TORX)
  192. {
  193. dwt_forcetrxoff();
  194. dwt_rxreset();
  195. }
  196. instProcessRXtimeout(inst);
  197. inst->stateMachine.gotTO = 0;
  198. inst->stateMachine.wait4ack = 0 ; //if Resp timeout, clear this
  199. #if (ANC_RESP_TEST==1)
  200. {
  201. debugLen = sprintf((char*)debugBuffer,"ANC_RESP TIMEOUT 0x%04x, src:0x%02x%02x, dst:0x%02x%02x, fctrl:0x%x, %d\r\n",
  202. inst->setting.instanceAddress16,
  203. inst->msgFrame.content.srcAddr[1],inst->msgFrame.content.srcAddr[0],
  204. inst->msgFrame.content.dstAddr[1],inst->msgFrame.content.dstAddr[0],
  205. inst->msgFrame.content.frameCtrl[0]|(inst->msgFrame.content.frameCtrl[1]<<8),
  206. portGetTickCnt());
  207. #if defined(REPORT2COM)
  208. ReportMessage((uint8_t*)debugBuffer, debugLen);
  209. #elif defined(REPORT2WIFI)
  210. SendMessageWifi((uint8_t*)debugBuffer, debugLen);
  211. #endif
  212. SendMessage((uint8_t*)debugBuffer,debugLen);
  213. SendMessageDbg((uint8_t*)debugBuffer,debugLen);
  214. }
  215. #endif
  216. return -1;
  217. }
  218. else
  219. {
  220. //inst->tmAndDelays.txu.txTimeStamp = dw_event->timeStamp;
  221. if(inst->stateMachine.previousState == TA_TXRESPONSE_SENT_TORX)
  222. { //Send resp fails
  223. inst->stateMachine.previousState = TA_TXRESPONSE_WAIT_SEND ;
  224. }
  225. inst->stateMachine.testAppState = TA_RXE_WAIT ; // After sending, tag expects response/report, anchor waits to receive a final/new poll
  226. }//fall into the next case (turn on the RX)
  227. return 0;
  228. }
  229. int appState_TA_RXE_WAIT(instance_data_t *inst, uint32_t *status, int message)
  230. {
  231. *status = TA_RXE_WAIT;
  232. if(inst->stateMachine.wait4ack == 0) //if this is set the RX will turn on automatically after TX
  233. { //turn RX on
  234. dwt_rxenable(DWT_START_RX_IMMEDIATE) ; // turn RX on, without delay
  235. trxStage = RTX_RX;
  236. }
  237. else
  238. {
  239. inst->stateMachine.wait4ack = 0 ; //clear the flag, the next time we want to turn the RX on it might not be auto
  240. }
  241. //inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT; //using RX FWTO
  242. inst->stateMachine.done = INST_NOT_DONE_YET;
  243. inst->stateMachine.testAppState = TA_RX_WAIT_DATA; // let this state handle it
  244. // end case TA_RXE_WAIT, don't break, but fall through into the TA_RX_WAIT_DATA state to process it immediately.
  245. if(message == 0)
  246. {
  247. return -1;
  248. }
  249. return 0;
  250. }
  251. int64_t CalculateTof(instance_data_t *inst, uint64_t tagPollTxTime, uint64_t anchorRespRxTime, uint64_t tagFinalTxTime)
  252. {
  253. int64_t Rb, Da, Ra, Db ;
  254. int64_t tof = INVALID_TOF;
  255. double RaRbxDaDb = 0;
  256. double RbyDb = 0;
  257. double RayDa = 0;
  258. // poll response round trip delay time is calculated as
  259. // (anchorRespRxTime - tagPollTxTime) - (anchorRespTxTime - tagPollRxTime)
  260. Ra = (int64_t)((anchorRespRxTime - tagPollTxTime) & MASK_40BIT);
  261. Db = (int64_t)((inst->tmAndDelays.txu.anchorRespTxTime - inst->tmAndDelays.tagPollRxTime) & MASK_40BIT);
  262. // response final round trip delay time is calculated as
  263. // (tagFinalRxTime - anchorRespTxTime) - (tagFinalTxTime - anchorRespRxTime)
  264. Rb = (int64_t)((inst->tmAndDelays.tagFinalRxTime - inst->tmAndDelays.txu.anchorRespTxTime) & MASK_40BIT);
  265. Da = (int64_t)((tagFinalTxTime - anchorRespRxTime) & MASK_40BIT);
  266. RaRbxDaDb = (((double)Ra))*(((double)Rb))
  267. - (((double)Da))*(((double)Db));
  268. RbyDb = ((double)Rb + (double)Db);
  269. RayDa = ((double)Ra + (double)Da);
  270. tof = (int64_t) ( RaRbxDaDb/(RbyDb + RayDa) );
  271. return tof;
  272. }
  273. int appState_TA_RX_WAIT_DATA(instance_data_t *inst, uint32_t *status, int message)
  274. {
  275. *status = TA_RX_WAIT_DATA;
  276. if(ReceivedReply>0)
  277. {
  278. ReceivedReply--;
  279. }
  280. switch (message)
  281. {
  282. //if we have received a DWT_SIG_RX_OKAY event - this means that the message is IEEE data type - need to check frame control to know which addressing mode is used
  283. case DWT_SIG_RX_OKAY :
  284. {
  285. ReceivedReply=5000;
  286. event_data_t* dw_event = instGetEvent(15); //get and clear this event
  287. uint8_t srcAddr[8] = {0,0,0,0,0,0,0,0};
  288. uint8_t dstAddr[8] = {0,0,0,0,0,0,0,0};
  289. int fcode = 0;
  290. uint8_t tof_idx = 0;
  291. uint8_t *messageData;
  292. monitor.startTick = dw_event->uTimeStamp;
  293. //short address, already checked in rxCallBack
  294. memcpy(&srcAddr[0], &(dw_event->msgUnion.rxMsg_ss.srcAddr[0]), ADDR_BYTE_SIZE_S);
  295. memcpy(&dstAddr[0], &(dw_event->msgUnion.rxMsg_ss.dstAddr[0]), ADDR_BYTE_SIZE_S);
  296. fcode = dw_event->msgUnion.rxMsg_ss.messageData[FCODE];
  297. messageData = &dw_event->msgUnion.rxMsg_ss.messageData[0];
  298. //process ranging messages
  299. switch(fcode)
  300. {
  301. case RTLS_DEMO_MSG_ANCH_POLL:
  302. break;
  303. case RTLS_DEMO_MSG_TAG_POLL:
  304. {
  305. tof_idx = srcAddr[0] | (srcAddr[1]<<8);
  306. SaveTagStatus(tof_idx, messageData);
  307. monitor.pollRecvTick = dw_event->uTimeStamp;
  308. if(DWT_SIG_TX_PENDING == dw_event->typePend)
  309. { //the response has been sent - await TX done event
  310. inst->stateMachine.testAppState = TA_TX_WAIT_CONF; // wait confirmation
  311. inst->stateMachine.previousState = TA_TXRESPONSE_SENT_POLLRX ; //wait for TX confirmation of sent response
  312. monitor.startSendTick = dw_event->uTimeStamp;
  313. }
  314. else if (DWT_SIG_RX_PENDING == dw_event->typePend)
  315. { //already re-enabled the receiver, stay in RX wait for next frame..., RX is already enabled...
  316. inst->stateMachine.testAppState = TA_RX_WAIT_DATA ; // wait for next frame
  317. }
  318. else //the DW1000 is idle (re-enable from the application level)
  319. {
  320. //stay in RX wait for next frame...
  321. inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
  322. }
  323. inst->stateMachine.done = INST_NOT_DONE_YET;
  324. } break; //RTLS_DEMO_MSG_TAG_POLL
  325. case RTLS_DEMO_MSG_ANCH_RESP2:
  326. break;
  327. case RTLS_DEMO_MSG_ANCH_RESP:
  328. {
  329. inst->stateMachine.done = INST_NOT_DONE_YET;
  330. //tof_idx = srcAddr[0] & ANCHOR_LIST_INDEX_MASK;
  331. //the response has been sent - await TX done event
  332. if( DWT_SIG_TX_PENDING == dw_event->typePend ) //anchor received response from anchor ID - 1 so is sending it's response now back to tag
  333. {
  334. inst->stateMachine.testAppState = TA_TX_WAIT_CONF; // wait confirmation
  335. inst->stateMachine.previousState = TA_TXRESPONSE_SENT_RESPRX ; //wait for TX confirmation of sent response
  336. monitor.startSendTick = dw_event->uTimeStamp;
  337. }
  338. //already re-enabled the receiver
  339. else if( DWT_SIG_RX_PENDING == dw_event->typePend )
  340. {
  341. // stay in TA_RX_WAIT_DATA - receiver is already enabled.
  342. }
  343. //DW1000 idle - send the final
  344. else //if(dw_event->type_pend == DWT_SIG_DW_IDLE)
  345. {
  346. instBack2Anchor(inst);
  347. }
  348. #if (ANC_RESP_TEST==1)
  349. {
  350. debugLen = sprintf(debugBuffer,"ANC_RESP RECVED:%d, %04x, %04x, %04x, %04x; count:%d,%d,%d,%d. T:%d\r\n",
  351. ancRespCount,ancRespRecords[0].address,ancRespRecords[1].address,
  352. ancRespRecords[2].address,ancRespRecords[3].address,
  353. instDebug.ancRespCounts[0],instDebug.ancRespCounts[1],
  354. instDebug.ancRespCounts[2],instDebug.ancRespCounts[3],
  355. portGetTickCnt());
  356. #if defined(REPORT2COM)
  357. ReportMessage((uint8_t*)debugBuffer, debugLen);
  358. #elif defined(REPORT2WIFI)
  359. SendMessageWifi((uint8_t*)debugBuffer, debugLen);
  360. #endif
  361. SendMessage((uint8_t*)debugBuffer,debugLen);
  362. SendMessageDbg((uint8_t*)debugBuffer,debugLen);
  363. }
  364. #endif
  365. } break; //RTLS_DEMO_MSG_ANCH_RESP
  366. case RTLS_DEMO_MSG_ANCH_FINAL:
  367. break;
  368. case RTLS_DEMO_MSG_TAG_FINAL:
  369. {
  370. inst->stateMachine.done = INST_NOT_DONE_YET;
  371. inst->stateMachine.wait4ack = 0; //clear the flag as the TX has failed the TRX is off
  372. tof_idx = srcAddr[0] | (srcAddr[1]<<8);//tag address
  373. if((RTLS_DEMO_MSG_TAG_FINAL == fcode) &&
  374. (instGetTagRangeNum(tof_idx) != messageData[POLL_RNUM])) //Final's range number needs to match Poll's or else discard this message
  375. {
  376. inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
  377. break;
  378. }
  379. monitor.pollRecvTick = 0;//clear
  380. monitor.startSendTick = 0;
  381. uint32_t count = 0;
  382. uint64_t tagFinalTxTime = 0;
  383. uint64_t tagPollTxTime = 0;
  384. uint64_t anchorRespRxTime = 0;
  385. uint64_t tof = INVALID_TOF;
  386. //if we got the final, maybe the tag did not get our response, so
  387. //we can use other anchors responses/ToF if there are any.. and output..
  388. //but we cannot calculate new range
  389. for(count = 0; count < NUM_EXPECTED_RESPONSES; count++)
  390. {
  391. //if(((validResp & (0x1<<(inst->setting.shortAdd_idx))) != 0))
  392. if(tagFinalRecord.ancRespTimes[count].address == inst->setting.instanceAddress16)
  393. {
  394. inst->tmAndDelays.delayedReplyTime = 0 ;
  395. // times measured at Tag extracted from the message buffer extract 40bit times
  396. memcpy(&tagPollTxTime, (void const *)tagFinalRecord.tagPollTxTime, TIMESTAME_LENGTH);
  397. memcpy(&anchorRespRxTime, (void const *)tagFinalRecord.ancRespTimes[count].ancRespRxTime, TIMESTAME_LENGTH);
  398. memcpy(&tagFinalTxTime, (void const *)tagFinalRecord.tagFinalTxTime, TIMESTAME_LENGTH);
  399. tof = (int32_t)CalculateTof(inst, tagPollTxTime, anchorRespRxTime, tagFinalTxTime);
  400. }
  401. }
  402. inst->stateMachine.newRangeTime = dw_event->uTimeStamp ;
  403. inst->stateMachine.newRangeAncAddress = inst->setting.instanceAddress16;
  404. inst->stateMachine.newRangeTagAddress = tof_idx;
  405. //time-of-flight
  406. SetTagTofResult(inst->stateMachine.newRangeTagAddress, tof);
  407. //we have our range - update the own mask entry...
  408. if(tof != INVALID_TOF) //check the last ToF entry is valid and copy into the current array
  409. {
  410. //setTagDist(tof_idx & TAG_LIST_INDEX_MASK, inst->setting.shortAdd_idx); //copy distance from this anchor to the tag into array
  411. SetTofResult(inst->setting.instanceAddress16, tof);
  412. instDebug.tofSuccess++;
  413. }
  414. //calculate all tag - anchor ranges... and report
  415. inst->stateMachine.newRange = instance_calcranges(inst->twrResult.tofArray, MAX_ANCHOR_LIST_SIZE, TOF_REPORT_T2A, status);
  416. if(inst->stateMachine.newRange == TOF_REPORT_NUL)
  417. {
  418. instDebug.calculateFails++;
  419. }
  420. //PrintDebugMessage();
  421. //ReportTagStatus(inst->stateMachine.newRangeTagAddress);
  422. instSetAntennaDelays(); //this will update the antenna delay if it has changed
  423. instSetTXPower(); // configure TX power if it has changed
  424. inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
  425. } break; //RTLS_DEMO_MSG_TAG_FINAL
  426. default:
  427. {
  428. //only enable receiver when not using double buffering
  429. inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
  430. dwt_setrxaftertxdelay(0);
  431. } break;
  432. } //end switch (fcode)
  433. if(dw_event->msgUnion.frame[0] & 0x20)
  434. {
  435. //as we only pass the received frame with the ACK request bit set after the ACK has been sent
  436. instGetEvent(16); //get and clear the ACK sent event
  437. }
  438. }
  439. break ; //end of DWT_SIG_RX_OKAY
  440. case DWT_SIG_RX_TIMEOUT :
  441. {
  442. event_data_t* dw_event = instGetEvent(17); //get and clear this event
  443. monitor.startTick = dw_event->uTimeStamp;
  444. if( DWT_SIG_TX_PENDING == dw_event->typePend )
  445. { // Sent resp in event DWT_SIG_RX_TIMEOUT of rxCallBack
  446. inst->stateMachine.testAppState = TA_TX_WAIT_CONF; // wait confirmation
  447. inst->stateMachine.previousState = TA_TXRESPONSE_SENT_TORX ; //wait for TX confirmation of sent response
  448. monitor.startSendTick = dw_event->uTimeStamp;
  449. }
  450. else if( DWT_SIG_DW_IDLE == dw_event->typePend ) //if timed out and back in receive then don't process as timeout
  451. {
  452. instProcessRXtimeout(inst);
  453. }
  454. inst->stateMachine.done = INST_NOT_DONE_YET;
  455. message = 0; //clear the message as we have processed the event
  456. }
  457. break ;
  458. case DWT_SIG_TX_AA_DONE: //ignore this event - just process the rx frame that was received before the ACK response
  459. case 0:
  460. default :
  461. {
  462. if(message) // == DWT_SIG_TX_DONE)
  463. {
  464. inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT;
  465. }
  466. if(inst->stateMachine.done == INST_NOT_DONE_YET)
  467. {
  468. inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT;
  469. }
  470. ///*status = dwt_read32bitoffsetreg(0x0F,0);//SYS_STATUS_ID
  471. ///(*status)++;
  472. uint32_t curTick = HAL_GetTick();
  473. if(monitor.pollRecvTick > 0)
  474. {
  475. if(monitor.pollRecvTick > curTick)
  476. {
  477. monitor.pollRecvTick = curTick;
  478. }
  479. if(curTick - monitor.pollRecvTick > inst->setting.sframePeriod)// * 10)
  480. {
  481. //dwt_forcetrxoff();
  482. //dwt_rxreset();
  483. monitor.startTick = curTick;
  484. monitor.pollRecvTick = 0;
  485. }
  486. }
  487. else
  488. {
  489. if(monitor.startTick > curTick)
  490. {
  491. monitor.startTick = curTick;
  492. }
  493. if(curTick - monitor.startTick > (3*1000))
  494. {
  495. dwt_forcetrxoff();
  496. dwt_rxreset();
  497. instProcessRXtimeout(inst);
  498. inst->stateMachine.gotTO = 0;
  499. inst->stateMachine.wait4ack = 0 ; //if Resp timeout, clear this
  500. monitor.startTick = curTick;
  501. //sprintf((char*)debugBuffer,"Crash DWT_SIGNAL \r\n");
  502. //DebugMessage(debugBuffer);
  503. }
  504. }
  505. }
  506. break;
  507. }
  508. return 0;
  509. }
  510. // -------------------------------------------------------------------------------------------------------------------
  511. //
  512. // the main instance state machine (all the instance modes Tag, Anchor or Listener use the same statemachine....)
  513. //
  514. // -------------------------------------------------------------------------------------------------------------------
  515. //
  516. int testAppRun(instance_data_t *inst, int message)
  517. {
  518. uint32_t status=0;
  519. int rtnCode = 0;
  520. switch (inst->stateMachine.testAppState)
  521. {
  522. case TA_INIT :
  523. rtnCode = appState_TA_INIT(inst, &status, message);
  524. break; // end case TA_INIT
  525. case TA_TX_WAIT_CONF :
  526. rtnCode = appState_TA_TX_WAIT_CONF(inst, &status, message);
  527. if (rtnCode != 0) break;
  528. message = 0;
  529. //break ; // end case TA_TX_WAIT_CONF
  530. case TA_RXE_WAIT :
  531. rtnCode = appState_TA_RXE_WAIT(inst, &status, message);
  532. if (rtnCode != 0) break;
  533. case TA_RX_WAIT_DATA : // Wait RX data
  534. rtnCode = appState_TA_RX_WAIT_DATA(inst, &status, message);
  535. break ; // end case TA_RX_WAIT_DATA
  536. default:
  537. //printf("\nERROR - invalid state %d - what is going on??\n", inst->testAppState) ;
  538. break;
  539. } // end switch on testAppState
  540. return inst->stateMachine.done;
  541. } // end testapprun()
  542. // -------------------------------------------------------------------------------------------------------------------
  543. // function to set the fixed reply delay time (in us)
  544. //
  545. // This sets delay for RX to TX - Delayed Send, and for TX to RX delayed receive (wait for response) functionality,
  546. // and the frame wait timeout value to use. This is a function of data rate, preamble length, and PRF
  547. void instSetReplyDelay(int delayus) //delay in us
  548. {
  549. int margin = 3000; //2000 symbols
  550. int respframe = 0;
  551. int respframe_sy = 0;
  552. //configure the rx delay receive delay time, it is dependent on the message length
  553. float msgdatalen = 0;
  554. float preamblelen = 0;
  555. int sfdlen = 0;
  556. int x = 0;
  557. //Set the RX timeouts based on the longest expected message - the Final message
  558. //Poll = 13, Response = 20, Final = 44 bytes
  559. //msgdatalen = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
  560. msgdatalen = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
  561. x = (int) ceil(msgdatalen*8/330.0f);
  562. msgdatalen = msgdatalen*8 + x*48;
  563. //add some margin so we don't timeout too soon
  564. margin = 0; //(TAG_FINAL_MSG_LEN - TAG_POLL_MSG_LEN);
  565. x = (int) ceil(margin*8/330.0f);
  566. margin = margin*8 + x*48;
  567. //assume PHR length is 172308ns for 110k and 21539ns for 850k/6.81M
  568. if(gInst->setting.configData.dataRate == DWT_BR_110K)
  569. {
  570. msgdatalen *= 8205.13f;
  571. msgdatalen += 172308; // PHR length in nanoseconds
  572. margin *= 8205.13f;
  573. }
  574. else if(gInst->setting.configData.dataRate == DWT_BR_850K)
  575. {
  576. msgdatalen *= 1025.64f;
  577. msgdatalen += 21539; // PHR length in nanoseconds
  578. margin *= 1025.64f;
  579. }
  580. else
  581. {
  582. msgdatalen *= 128.21f;
  583. msgdatalen += 21539; // PHR length in nanoseconds
  584. margin *= 128.21f;
  585. }
  586. //SFD length is 64 for 110k (always)
  587. //SFD length is 8 for 6.81M, and 16 for 850k, but can vary between 8 and 16 bytes
  588. sfdlen = dwnsSFDlen[gInst->setting.configData.dataRate];
  589. switch (gInst->setting.configData.txPreambLength)
  590. {
  591. case DWT_PLEN_4096 : preamblelen = 4096.0f; break;
  592. case DWT_PLEN_2048 : preamblelen = 2048.0f; break;
  593. case DWT_PLEN_1536 : preamblelen = 1536.0f; break;
  594. case DWT_PLEN_1024 : preamblelen = 1024.0f; break;
  595. case DWT_PLEN_512 : preamblelen = 512.0f; break;
  596. case DWT_PLEN_256 : preamblelen = 256.0f; break;
  597. case DWT_PLEN_128 : preamblelen = 128.0f; break;
  598. case DWT_PLEN_64 : preamblelen = 64.0f; break;
  599. }
  600. //preamble = plen * (994 or 1018) depending on 16 or 64 PRF
  601. if(gInst->setting.configData.prf == DWT_PRF_16M)
  602. {
  603. preamblelen = (sfdlen + preamblelen) * 0.99359f;
  604. }
  605. else
  606. {
  607. preamblelen = (sfdlen + preamblelen) * 1.01763f;
  608. }
  609. //respframe_sy = (16 + (int)((preamblelen + ((msgdatalen + margin)/1000.0))/ 1.0256)) ;
  610. respframe_sy = (16 + (int)ceil((preamblelen + ((msgdatalen + margin)/1000.0))/ 1.0256)) ;
  611. //this is the delay used for the delayed transmit (when sending the response, and final messages)
  612. gInst->setting.pollTx2FinalTxDelay = convertMicroSec2DeviceTime (delayus);
  613. //the anchor to anchor ranging consist of A0 ranging to A1 and A2 and A1 ranging to A2
  614. //as there are less messages the ranging time is shorter (thus divide by 2)
  615. gInst->setting.pollTx2FinalTxDelayAnc = convertMicroSec2DeviceTime (delayus/2 + 100);
  616. //this is the delay the anchors 1, 2, etc.. will send the response back at...
  617. //anchor 2 will have the delay set to 2 * fixedReplyDelayAnc
  618. //andhor 3 will have the delay set to 3 * fixedReplyDelayAnc and so on...
  619. //this delay depends on how quickly the tag can receive and process the message from previous anchor
  620. //(and also the frame length of course)
  621. //respframe = (int)(preamblelen + (msgdatalen/1000.0)); //length of response frame (micro seconds)
  622. respframe = (int)ceil(preamblelen + (msgdatalen/1000.0)); //length of response frame (micro seconds)
  623. if(gInst->setting.configData.dataRate == DWT_BR_110K)
  624. {
  625. //set the frame wait timeout time - total time the frame takes in symbols
  626. gInst->setting.fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_110K + 400; //add some margin because of the resp to resp RX turn on time
  627. //instance_data[instance].fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_110K + 400 + 2000;
  628. gInst->setting.fwtoTimeAnc_sy = respframe_sy; //add some margin so we don't timeout too soon
  629. gInst->setting.fixedReplyDelayAnc = convertMicroSec2DeviceTime (respframe + RX_RESPONSE1_TURNAROUND_110K);
  630. gInst->setting.fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertMicroSec2DeviceTime (preamblelen)) >> 8) + 16;
  631. gInst->setting.ancRespRxDelay = RX_RESPONSE1_TURNAROUND_110K ;
  632. }
  633. else
  634. {
  635. //set the frame wait timeout time - total time the frame takes in symbols
  636. gInst->setting.fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_6M81; //add some margin because of the resp to resp RX turn on time
  637. gInst->setting.fwtoTimeAnc_sy = respframe_sy;
  638. gInst->setting.fixedReplyDelayAnc = convertMicroSec2DeviceTime (respframe + RX_RESPONSE1_TURNAROUND_6M81);
  639. gInst->setting.fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertMicroSec2DeviceTime (preamblelen)) >> 8) + 16;
  640. gInst->setting.ancRespRxDelay = RX_RESPONSE1_TURNAROUND_6M81;
  641. //gInst->setting.ancRespRxDelay = RX_RESPONSE1_TURNAROUND ;
  642. }
  643. gInst->setting.pollRx2FinalRxDelay = delayus + gInst->setting.fwtoTime_sy;
  644. }
  645. // -------------------------------------------------------------------------------------------------------------------
  646. //
  647. // Set Payload parameters for the instance
  648. //
  649. // -------------------------------------------------------------------------------------------------------------------
  650. void instSetAddress(uint16_t address)
  651. {
  652. gInst->setting.instanceAddress16 = address ; // copy configurations
  653. }
  654. void instSetPanID(uint16_t id)
  655. {
  656. gInst->setting.panID = id ;
  657. }
  658. void instUpdateFramePeroid(uint16_t period)
  659. {
  660. gInst->setting.sframePeriod = period;
  661. gInst->setting.numSlots = gInst->setting.sframePeriod / (gInst->setting.slotPeriod * TA_SLOT_STEP);
  662. }