| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791 |
- /*! ----------------------------------------------------------------------------
- * @file instance.c
- * @brief DecaWave application level message exchange for ranging demo
- *
- * @attention
- *
- * Copyright 2015 (c) DecaWave Ltd, Dublin, Ireland.
- *
- * All rights reserved.
- *
- * @author DecaWave
- */
- #include "compiler.h"
- #include "port.h"
- #include "deca_device_api.h"
- #include "deca_spi.h"
- #include "deca_regs.h"
- #include "instance.h"
- // -------------------------------------------------------------------------------------------------------------------
- // -------------------------------------------------------------------------------------------------------------------
- // Data Definitions
- // -------------------------------------------------------------------------------------------------------------------
- extern char debugBuffer[256];
- extern int debugLen;
- extern volatile stTagFinalRecord tagFinalRecord;
- extern volatile uint32_t ancRespCount;
- extern volatile stAncRespRecord ancRespRecords[8];
- extern volatile stInstDebug instDebug;
- int ReceivedReply=5000;
- typedef struct _monitor_ticks_
- {
- uint32_t startTick;
- uint32_t pollRecvTick;
- uint32_t startSendTick;
- uint32_t temp;
- }stDwmMonitor;
- volatile stDwmMonitor monitor = {0};
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // NOTE: the maximum RX timeout is ~ 65ms
- // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // -------------------------------------------------------------------------------------------------------------------
- // Functions
- // -------------------------------------------------------------------------------------------------------------------
- #if defined(REPORT2WIFI)
- extern int SendMessageWifi(uint8_t* buf,int len);
- #endif
- extern int SendMessage(uint8_t* buf,int len);
- extern int SendMessageDbg(uint8_t* buf,int len);
- // -------------------------------------------------------------------------------------------------------------------
- //
- // function to construct the message/frame header bytes
- //
- // -------------------------------------------------------------------------------------------------------------------
- //
- void instConfigFrameHeader16(instance_data_t *inst)
- {
- //set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
- inst->msgFrame.content.frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
- //source/dest addressing modes and frame version
- inst->msgFrame.content.frameCtrl[1] = 0x8 /*dest extended address (16bits)*/ | 0x80 /*src extended address (16bits)*/;
- inst->msgFrame.content.panID[0] = (inst->setting.panID) & 0xff;
- inst->msgFrame.content.panID[1] = inst->setting.panID >> 8;
- inst->msgFrame.content.seqNum = 0;
- }
- int instSendDlyPacket(instance_data_t *inst, int delayedTx)
- {
- int result = 0;
- dwt_writetxfctrl(inst->msgFrame.psduLength, 0);
- if(delayedTx == DWT_START_TX_DELAYED)
- {
- dwt_setdelayedtrxtime(inst->tmAndDelays.delayedReplyTime) ; //should be high 32-bits of delayed TX TS
- }
- //begin delayed TX of frame
- if (dwt_starttx(delayedTx | inst->stateMachine.wait4ack)) // delayed start was too late
- {
- result = 1; //late/error
- }
- else
- {
- //inst->stateMachine.monitor = 1;
- }
- return result; // state changes
- }
- int instance_calcranges(stTofInformation *array, uint16_t size, int reportRange, uint32_t* mask)
- {
- int i;
- int newRange = TOF_REPORT_NUL;
- int distance = 0;
- for(i=0; i<size; i++)
- {
- stTofInformation* tofx = array+i;
- if(tofx->value != INVALID_TOF) //if ToF == 0 - then no new range to report
- {
- distance = reportTOF(i, tofx);
- }
- if(distance == 1)
- {
- newRange = reportRange;
- }
- else
- {
- clearDistTable(i);
- }
- array[i].value = INVALID_TOF;
- array[i].address = BROADCAST_ADDR;
- distance = 0;
- }
- if(newRange==TOF_REPORT_NUL)
- {
- distance = 0;
- }
- return newRange;
- }
- void ReportTagStatus(uint32_t address)
- {
- stTagStatus tagStatus;
- GetTagStatus(address, &tagStatus);
- 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",
- address, tagStatus.status, tagStatus.power, tagStatus.heartRate,
- instDebug.ancPollCount, instDebug.andRespSentCount,
- instDebug.ancRespCounts[0],instDebug.ancRespCounts[1],
- instDebug.ancRespCounts[2],instDebug.ancRespCounts[3],
- instDebug.ancFinalCount, instDebug.tofSuccess,
- portGetTickCnt());
- #if defined(REPORT2COM)
- ReportMessage((uint8_t*)debugBuffer, debugLen);
- #elif defined(REPORT2WIFI)
- SendMessageWifi((uint8_t*)debugBuffer, debugLen);
- #endif
- SendMessage((uint8_t*)debugBuffer,debugLen);
- SendMessageDbg((uint8_t*)debugBuffer,debugLen);
- }
- int appState_TA_INIT(instance_data_t *inst, uint32_t* status, int message)
- {
- *status=TA_INIT;
- memcpy(inst->setting.eui64, &inst->setting.instanceAddress16, ADDR_BYTE_SIZE_S);
- dwt_seteui(inst->setting.eui64);
- dwt_setpanid(inst->setting.panID);
- //set source address
- inst->setting.shortAdd_idx = (inst->setting.instanceAddress16 % (ANCHOR_SHORT_MASK + 1));
- //inst->setting.shortAdd_idx = (inst->setting.instanceAddress16 % NUM_EXPECTED_RESPONSES);
- dwt_setaddress16(inst->setting.instanceAddress16);
- dwt_enableframefilter(DWT_FF_NOTYPE_EN); //allow data, ack frames;
- // First time anchor listens we don't do a delayed RX
- dwt_setrxaftertxdelay(0);
- //change to next state - wait to receive a message
- inst->stateMachine.testAppState = TA_RXE_WAIT ;
- dwt_setrxtimeout(0);
- dwt_setpreambledetecttimeout(0);
- instConfigFrameHeader16(inst);
- return 0;
- }
- //
- int appState_TA_TX_WAIT_CONF(instance_data_t *inst, uint32_t *status, int message)
- {
- *status=TA_TX_WAIT_CONF;
- event_data_t* dw_event = instGetEvent(11); //get and clear this event
- //NOTE: Can get the ACK before the TX confirm event for the frame requesting the ACK
- //this happens because if polling the ISR the RX event will be processed 1st and then the TX event
- //thus the reception of the ACK will be processed before the TX confirmation of the frame that requested it.
- if(dw_event->type != DWT_SIG_TX_DONE) //wait for TX done confirmation
- {
- if(dw_event->type == DWT_SIG_RX_TIMEOUT) //got RX timeout - i.e. did not get the response (e.g. ACK)
- {
- //printf("RX timeout in TA_TX_WAIT_CONF (%d)\n", inst->previousState);
- //we need to wait for SIG_TX_DONE and then process the timeout and re-send the frame if needed
- inst->stateMachine.gotTO = 1;
- }
- else
- {
- //inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT;
- inst->stateMachine.done = INST_NOT_DONE_YET;
- }
- uint32_t curTick = HAL_GetTick();
- if(monitor.startSendTick > curTick)
- {
- monitor.startSendTick = curTick;
- }
- if(curTick - monitor.startSendTick < inst->setting.slotPeriod )
- {
- return -1;
- }
- else
- {
- inst->stateMachine.gotTO = 1;
- }
- }
- inst->stateMachine.done = INST_NOT_DONE_YET;
- if (inst->stateMachine.gotTO == 1) //timeout
- {
- if(inst->stateMachine.previousState == TA_TXRESPONSE_SENT_TORX)
- {
- dwt_forcetrxoff();
- dwt_rxreset();
- }
- instProcessRXtimeout(inst);
- inst->stateMachine.gotTO = 0;
- inst->stateMachine.wait4ack = 0 ; //if Resp timeout, clear this
- #if (ANC_RESP_TEST==1)
- {
- debugLen = sprintf((char*)debugBuffer,"ANC_RESP TIMEOUT 0x%04x, src:0x%02x%02x, dst:0x%02x%02x, fctrl:0x%x, %d\r\n",
- inst->setting.instanceAddress16,
- inst->msgFrame.content.srcAddr[1],inst->msgFrame.content.srcAddr[0],
- inst->msgFrame.content.dstAddr[1],inst->msgFrame.content.dstAddr[0],
- inst->msgFrame.content.frameCtrl[0]|(inst->msgFrame.content.frameCtrl[1]<<8),
- portGetTickCnt());
- #if defined(REPORT2COM)
- ReportMessage((uint8_t*)debugBuffer, debugLen);
- #elif defined(REPORT2WIFI)
- SendMessageWifi((uint8_t*)debugBuffer, debugLen);
- #endif
- SendMessage((uint8_t*)debugBuffer,debugLen);
- SendMessageDbg((uint8_t*)debugBuffer,debugLen);
- }
- #endif
- return -1;
- }
- else
- {
- //inst->tmAndDelays.txu.txTimeStamp = dw_event->timeStamp;
- if(inst->stateMachine.previousState == TA_TXRESPONSE_SENT_TORX)
- { //Send resp fails
- inst->stateMachine.previousState = TA_TXRESPONSE_WAIT_SEND ;
- }
- inst->stateMachine.testAppState = TA_RXE_WAIT ; // After sending, tag expects response/report, anchor waits to receive a final/new poll
- }//fall into the next case (turn on the RX)
- return 0;
- }
- int appState_TA_RXE_WAIT(instance_data_t *inst, uint32_t *status, int message)
- {
- *status = TA_RXE_WAIT;
- if(inst->stateMachine.wait4ack == 0) //if this is set the RX will turn on automatically after TX
- { //turn RX on
- dwt_rxenable(DWT_START_RX_IMMEDIATE) ; // turn RX on, without delay
- trxStage = RTX_RX;
- }
- else
- {
- inst->stateMachine.wait4ack = 0 ; //clear the flag, the next time we want to turn the RX on it might not be auto
- }
- //inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT; //using RX FWTO
- inst->stateMachine.done = INST_NOT_DONE_YET;
- inst->stateMachine.testAppState = TA_RX_WAIT_DATA; // let this state handle it
- // end case TA_RXE_WAIT, don't break, but fall through into the TA_RX_WAIT_DATA state to process it immediately.
- if(message == 0)
- {
- return -1;
- }
- return 0;
- }
- int64_t CalculateTof(instance_data_t *inst, uint64_t tagPollTxTime, uint64_t anchorRespRxTime, uint64_t tagFinalTxTime)
- {
- int64_t Rb, Da, Ra, Db ;
- int64_t tof = INVALID_TOF;
- double RaRbxDaDb = 0;
- double RbyDb = 0;
- double RayDa = 0;
- // poll response round trip delay time is calculated as
- // (anchorRespRxTime - tagPollTxTime) - (anchorRespTxTime - tagPollRxTime)
- Ra = (int64_t)((anchorRespRxTime - tagPollTxTime) & MASK_40BIT);
- Db = (int64_t)((inst->tmAndDelays.txu.anchorRespTxTime - inst->tmAndDelays.tagPollRxTime) & MASK_40BIT);
- // response final round trip delay time is calculated as
- // (tagFinalRxTime - anchorRespTxTime) - (tagFinalTxTime - anchorRespRxTime)
- Rb = (int64_t)((inst->tmAndDelays.tagFinalRxTime - inst->tmAndDelays.txu.anchorRespTxTime) & MASK_40BIT);
- Da = (int64_t)((tagFinalTxTime - anchorRespRxTime) & MASK_40BIT);
- RaRbxDaDb = (((double)Ra))*(((double)Rb))
- - (((double)Da))*(((double)Db));
- RbyDb = ((double)Rb + (double)Db);
- RayDa = ((double)Ra + (double)Da);
- tof = (int64_t) ( RaRbxDaDb/(RbyDb + RayDa) );
- return tof;
- }
- int appState_TA_RX_WAIT_DATA(instance_data_t *inst, uint32_t *status, int message)
- {
- *status = TA_RX_WAIT_DATA;
- if(ReceivedReply>0)
- {
- ReceivedReply--;
- }
- switch (message)
- {
- //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
- case DWT_SIG_RX_OKAY :
- {
-
- ReceivedReply=5000;
- event_data_t* dw_event = instGetEvent(15); //get and clear this event
- uint8_t srcAddr[8] = {0,0,0,0,0,0,0,0};
- uint8_t dstAddr[8] = {0,0,0,0,0,0,0,0};
- int fcode = 0;
- uint8_t tof_idx = 0;
- uint8_t *messageData;
- monitor.startTick = dw_event->uTimeStamp;
- //short address, already checked in rxCallBack
- memcpy(&srcAddr[0], &(dw_event->msgUnion.rxMsg_ss.srcAddr[0]), ADDR_BYTE_SIZE_S);
- memcpy(&dstAddr[0], &(dw_event->msgUnion.rxMsg_ss.dstAddr[0]), ADDR_BYTE_SIZE_S);
- fcode = dw_event->msgUnion.rxMsg_ss.messageData[FCODE];
- messageData = &dw_event->msgUnion.rxMsg_ss.messageData[0];
- //process ranging messages
- switch(fcode)
- {
- case RTLS_DEMO_MSG_ANCH_POLL:
- break;
- case RTLS_DEMO_MSG_TAG_POLL:
- {
- tof_idx = srcAddr[0] | (srcAddr[1]<<8);
- SaveTagStatus(tof_idx, messageData);
- monitor.pollRecvTick = dw_event->uTimeStamp;
- if(DWT_SIG_TX_PENDING == dw_event->typePend)
- { //the response has been sent - await TX done event
- inst->stateMachine.testAppState = TA_TX_WAIT_CONF; // wait confirmation
- inst->stateMachine.previousState = TA_TXRESPONSE_SENT_POLLRX ; //wait for TX confirmation of sent response
- monitor.startSendTick = dw_event->uTimeStamp;
- }
- else if (DWT_SIG_RX_PENDING == dw_event->typePend)
- { //already re-enabled the receiver, stay in RX wait for next frame..., RX is already enabled...
- inst->stateMachine.testAppState = TA_RX_WAIT_DATA ; // wait for next frame
- }
- else //the DW1000 is idle (re-enable from the application level)
- {
- //stay in RX wait for next frame...
- inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
- }
- inst->stateMachine.done = INST_NOT_DONE_YET;
- } break; //RTLS_DEMO_MSG_TAG_POLL
- case RTLS_DEMO_MSG_ANCH_RESP2:
- break;
- case RTLS_DEMO_MSG_ANCH_RESP:
- {
- inst->stateMachine.done = INST_NOT_DONE_YET;
- //tof_idx = srcAddr[0] & ANCHOR_LIST_INDEX_MASK;
- //the response has been sent - await TX done event
- 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
- {
- inst->stateMachine.testAppState = TA_TX_WAIT_CONF; // wait confirmation
- inst->stateMachine.previousState = TA_TXRESPONSE_SENT_RESPRX ; //wait for TX confirmation of sent response
- monitor.startSendTick = dw_event->uTimeStamp;
- }
- //already re-enabled the receiver
- else if( DWT_SIG_RX_PENDING == dw_event->typePend )
- {
- // stay in TA_RX_WAIT_DATA - receiver is already enabled.
- }
- //DW1000 idle - send the final
- else //if(dw_event->type_pend == DWT_SIG_DW_IDLE)
- {
- instBack2Anchor(inst);
- }
- #if (ANC_RESP_TEST==1)
- {
- debugLen = sprintf(debugBuffer,"ANC_RESP RECVED:%d, %04x, %04x, %04x, %04x; count:%d,%d,%d,%d. T:%d\r\n",
- ancRespCount,ancRespRecords[0].address,ancRespRecords[1].address,
- ancRespRecords[2].address,ancRespRecords[3].address,
- instDebug.ancRespCounts[0],instDebug.ancRespCounts[1],
- instDebug.ancRespCounts[2],instDebug.ancRespCounts[3],
- portGetTickCnt());
- #if defined(REPORT2COM)
- ReportMessage((uint8_t*)debugBuffer, debugLen);
- #elif defined(REPORT2WIFI)
- SendMessageWifi((uint8_t*)debugBuffer, debugLen);
- #endif
- SendMessage((uint8_t*)debugBuffer,debugLen);
- SendMessageDbg((uint8_t*)debugBuffer,debugLen);
- }
- #endif
- } break; //RTLS_DEMO_MSG_ANCH_RESP
- case RTLS_DEMO_MSG_ANCH_FINAL:
- break;
- case RTLS_DEMO_MSG_TAG_FINAL:
- {
- inst->stateMachine.done = INST_NOT_DONE_YET;
- inst->stateMachine.wait4ack = 0; //clear the flag as the TX has failed the TRX is off
- tof_idx = srcAddr[0] | (srcAddr[1]<<8);//tag address
- if((RTLS_DEMO_MSG_TAG_FINAL == fcode) &&
- (instGetTagRangeNum(tof_idx) != messageData[POLL_RNUM])) //Final's range number needs to match Poll's or else discard this message
- {
- inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
- break;
- }
- monitor.pollRecvTick = 0;//clear
- monitor.startSendTick = 0;
- uint32_t count = 0;
- uint64_t tagFinalTxTime = 0;
- uint64_t tagPollTxTime = 0;
- uint64_t anchorRespRxTime = 0;
- uint64_t tof = INVALID_TOF;
- //if we got the final, maybe the tag did not get our response, so
- //we can use other anchors responses/ToF if there are any.. and output..
- //but we cannot calculate new range
- for(count = 0; count < NUM_EXPECTED_RESPONSES; count++)
- {
- //if(((validResp & (0x1<<(inst->setting.shortAdd_idx))) != 0))
- if(tagFinalRecord.ancRespTimes[count].address == inst->setting.instanceAddress16)
- {
- inst->tmAndDelays.delayedReplyTime = 0 ;
- // times measured at Tag extracted from the message buffer extract 40bit times
- memcpy(&tagPollTxTime, (void const *)tagFinalRecord.tagPollTxTime, TIMESTAME_LENGTH);
- memcpy(&anchorRespRxTime, (void const *)tagFinalRecord.ancRespTimes[count].ancRespRxTime, TIMESTAME_LENGTH);
- memcpy(&tagFinalTxTime, (void const *)tagFinalRecord.tagFinalTxTime, TIMESTAME_LENGTH);
- tof = (int32_t)CalculateTof(inst, tagPollTxTime, anchorRespRxTime, tagFinalTxTime);
- }
- }
- inst->stateMachine.newRangeTime = dw_event->uTimeStamp ;
- inst->stateMachine.newRangeAncAddress = inst->setting.instanceAddress16;
- inst->stateMachine.newRangeTagAddress = tof_idx;
- //time-of-flight
- SetTagTofResult(inst->stateMachine.newRangeTagAddress, tof);
- //we have our range - update the own mask entry...
- if(tof != INVALID_TOF) //check the last ToF entry is valid and copy into the current array
- {
- //setTagDist(tof_idx & TAG_LIST_INDEX_MASK, inst->setting.shortAdd_idx); //copy distance from this anchor to the tag into array
- SetTofResult(inst->setting.instanceAddress16, tof);
- instDebug.tofSuccess++;
- }
- //calculate all tag - anchor ranges... and report
- inst->stateMachine.newRange = instance_calcranges(inst->twrResult.tofArray, MAX_ANCHOR_LIST_SIZE, TOF_REPORT_T2A, status);
- if(inst->stateMachine.newRange == TOF_REPORT_NUL)
- {
- instDebug.calculateFails++;
- }
- //PrintDebugMessage();
- //ReportTagStatus(inst->stateMachine.newRangeTagAddress);
- instSetAntennaDelays(); //this will update the antenna delay if it has changed
- instSetTXPower(); // configure TX power if it has changed
- inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
- } break; //RTLS_DEMO_MSG_TAG_FINAL
- default:
- {
- //only enable receiver when not using double buffering
- inst->stateMachine.testAppState = TA_RXE_WAIT ; // wait for next frame
- dwt_setrxaftertxdelay(0);
- } break;
- } //end switch (fcode)
- if(dw_event->msgUnion.frame[0] & 0x20)
- {
- //as we only pass the received frame with the ACK request bit set after the ACK has been sent
- instGetEvent(16); //get and clear the ACK sent event
- }
- }
- break ; //end of DWT_SIG_RX_OKAY
- case DWT_SIG_RX_TIMEOUT :
- {
- event_data_t* dw_event = instGetEvent(17); //get and clear this event
- monitor.startTick = dw_event->uTimeStamp;
- if( DWT_SIG_TX_PENDING == dw_event->typePend )
- { // Sent resp in event DWT_SIG_RX_TIMEOUT of rxCallBack
- inst->stateMachine.testAppState = TA_TX_WAIT_CONF; // wait confirmation
- inst->stateMachine.previousState = TA_TXRESPONSE_SENT_TORX ; //wait for TX confirmation of sent response
- monitor.startSendTick = dw_event->uTimeStamp;
- }
- else if( DWT_SIG_DW_IDLE == dw_event->typePend ) //if timed out and back in receive then don't process as timeout
- {
- instProcessRXtimeout(inst);
- }
- inst->stateMachine.done = INST_NOT_DONE_YET;
- message = 0; //clear the message as we have processed the event
- }
- break ;
- case DWT_SIG_TX_AA_DONE: //ignore this event - just process the rx frame that was received before the ACK response
- case 0:
- default :
- {
- if(message) // == DWT_SIG_TX_DONE)
- {
- inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT;
- }
- if(inst->stateMachine.done == INST_NOT_DONE_YET)
- {
- inst->stateMachine.done = INST_DONE_WAIT_FOR_NEXT_EVENT;
- }
- ///*status = dwt_read32bitoffsetreg(0x0F,0);//SYS_STATUS_ID
- ///(*status)++;
- uint32_t curTick = HAL_GetTick();
- if(monitor.pollRecvTick > 0)
- {
- if(monitor.pollRecvTick > curTick)
- {
- monitor.pollRecvTick = curTick;
- }
- if(curTick - monitor.pollRecvTick > inst->setting.sframePeriod)// * 10)
- {
- //dwt_forcetrxoff();
- //dwt_rxreset();
- monitor.startTick = curTick;
- monitor.pollRecvTick = 0;
- }
- }
- else
- {
- if(monitor.startTick > curTick)
- {
- monitor.startTick = curTick;
- }
- if(curTick - monitor.startTick > (3*1000))
- {
- dwt_forcetrxoff();
- dwt_rxreset();
- instProcessRXtimeout(inst);
- inst->stateMachine.gotTO = 0;
- inst->stateMachine.wait4ack = 0 ; //if Resp timeout, clear this
- monitor.startTick = curTick;
- //sprintf((char*)debugBuffer,"Crash DWT_SIGNAL \r\n");
- //DebugMessage(debugBuffer);
- }
- }
- }
- break;
- }
- return 0;
- }
- // -------------------------------------------------------------------------------------------------------------------
- //
- // the main instance state machine (all the instance modes Tag, Anchor or Listener use the same statemachine....)
- //
- // -------------------------------------------------------------------------------------------------------------------
- //
- int testAppRun(instance_data_t *inst, int message)
- {
- uint32_t status=0;
- int rtnCode = 0;
- switch (inst->stateMachine.testAppState)
- {
- case TA_INIT :
- rtnCode = appState_TA_INIT(inst, &status, message);
- break; // end case TA_INIT
- case TA_TX_WAIT_CONF :
- rtnCode = appState_TA_TX_WAIT_CONF(inst, &status, message);
- if (rtnCode != 0) break;
- message = 0;
- //break ; // end case TA_TX_WAIT_CONF
- case TA_RXE_WAIT :
- rtnCode = appState_TA_RXE_WAIT(inst, &status, message);
- if (rtnCode != 0) break;
- case TA_RX_WAIT_DATA : // Wait RX data
- rtnCode = appState_TA_RX_WAIT_DATA(inst, &status, message);
- break ; // end case TA_RX_WAIT_DATA
- default:
- //printf("\nERROR - invalid state %d - what is going on??\n", inst->testAppState) ;
- break;
- } // end switch on testAppState
- return inst->stateMachine.done;
- } // end testapprun()
- // -------------------------------------------------------------------------------------------------------------------
- // function to set the fixed reply delay time (in us)
- //
- // This sets delay for RX to TX - Delayed Send, and for TX to RX delayed receive (wait for response) functionality,
- // and the frame wait timeout value to use. This is a function of data rate, preamble length, and PRF
- void instSetReplyDelay(int delayus) //delay in us
- {
- int margin = 3000; //2000 symbols
- int respframe = 0;
- int respframe_sy = 0;
- //configure the rx delay receive delay time, it is dependent on the message length
- float msgdatalen = 0;
- float preamblelen = 0;
- int sfdlen = 0;
- int x = 0;
- //Set the RX timeouts based on the longest expected message - the Final message
- //Poll = 13, Response = 20, Final = 44 bytes
- //msgdatalen = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
- msgdatalen = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
- x = (int) ceil(msgdatalen*8/330.0f);
- msgdatalen = msgdatalen*8 + x*48;
- //add some margin so we don't timeout too soon
- margin = 0; //(TAG_FINAL_MSG_LEN - TAG_POLL_MSG_LEN);
- x = (int) ceil(margin*8/330.0f);
- margin = margin*8 + x*48;
- //assume PHR length is 172308ns for 110k and 21539ns for 850k/6.81M
- if(gInst->setting.configData.dataRate == DWT_BR_110K)
- {
- msgdatalen *= 8205.13f;
- msgdatalen += 172308; // PHR length in nanoseconds
- margin *= 8205.13f;
- }
- else if(gInst->setting.configData.dataRate == DWT_BR_850K)
- {
- msgdatalen *= 1025.64f;
- msgdatalen += 21539; // PHR length in nanoseconds
- margin *= 1025.64f;
- }
- else
- {
- msgdatalen *= 128.21f;
- msgdatalen += 21539; // PHR length in nanoseconds
- margin *= 128.21f;
- }
- //SFD length is 64 for 110k (always)
- //SFD length is 8 for 6.81M, and 16 for 850k, but can vary between 8 and 16 bytes
- sfdlen = dwnsSFDlen[gInst->setting.configData.dataRate];
- switch (gInst->setting.configData.txPreambLength)
- {
- case DWT_PLEN_4096 : preamblelen = 4096.0f; break;
- case DWT_PLEN_2048 : preamblelen = 2048.0f; break;
- case DWT_PLEN_1536 : preamblelen = 1536.0f; break;
- case DWT_PLEN_1024 : preamblelen = 1024.0f; break;
- case DWT_PLEN_512 : preamblelen = 512.0f; break;
- case DWT_PLEN_256 : preamblelen = 256.0f; break;
- case DWT_PLEN_128 : preamblelen = 128.0f; break;
- case DWT_PLEN_64 : preamblelen = 64.0f; break;
- }
- //preamble = plen * (994 or 1018) depending on 16 or 64 PRF
- if(gInst->setting.configData.prf == DWT_PRF_16M)
- {
- preamblelen = (sfdlen + preamblelen) * 0.99359f;
- }
- else
- {
- preamblelen = (sfdlen + preamblelen) * 1.01763f;
- }
- //respframe_sy = (16 + (int)((preamblelen + ((msgdatalen + margin)/1000.0))/ 1.0256)) ;
- respframe_sy = (16 + (int)ceil((preamblelen + ((msgdatalen + margin)/1000.0))/ 1.0256)) ;
- //this is the delay used for the delayed transmit (when sending the response, and final messages)
- gInst->setting.pollTx2FinalTxDelay = convertMicroSec2DeviceTime (delayus);
- //the anchor to anchor ranging consist of A0 ranging to A1 and A2 and A1 ranging to A2
- //as there are less messages the ranging time is shorter (thus divide by 2)
- gInst->setting.pollTx2FinalTxDelayAnc = convertMicroSec2DeviceTime (delayus/2 + 100);
- //this is the delay the anchors 1, 2, etc.. will send the response back at...
- //anchor 2 will have the delay set to 2 * fixedReplyDelayAnc
- //andhor 3 will have the delay set to 3 * fixedReplyDelayAnc and so on...
- //this delay depends on how quickly the tag can receive and process the message from previous anchor
- //(and also the frame length of course)
- //respframe = (int)(preamblelen + (msgdatalen/1000.0)); //length of response frame (micro seconds)
- respframe = (int)ceil(preamblelen + (msgdatalen/1000.0)); //length of response frame (micro seconds)
- if(gInst->setting.configData.dataRate == DWT_BR_110K)
- {
- //set the frame wait timeout time - total time the frame takes in symbols
- gInst->setting.fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_110K + 400; //add some margin because of the resp to resp RX turn on time
- //instance_data[instance].fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_110K + 400 + 2000;
- gInst->setting.fwtoTimeAnc_sy = respframe_sy; //add some margin so we don't timeout too soon
- gInst->setting.fixedReplyDelayAnc = convertMicroSec2DeviceTime (respframe + RX_RESPONSE1_TURNAROUND_110K);
- gInst->setting.fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertMicroSec2DeviceTime (preamblelen)) >> 8) + 16;
- gInst->setting.ancRespRxDelay = RX_RESPONSE1_TURNAROUND_110K ;
- }
- else
- {
- //set the frame wait timeout time - total time the frame takes in symbols
- gInst->setting.fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_6M81; //add some margin because of the resp to resp RX turn on time
- gInst->setting.fwtoTimeAnc_sy = respframe_sy;
- gInst->setting.fixedReplyDelayAnc = convertMicroSec2DeviceTime (respframe + RX_RESPONSE1_TURNAROUND_6M81);
- gInst->setting.fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertMicroSec2DeviceTime (preamblelen)) >> 8) + 16;
- gInst->setting.ancRespRxDelay = RX_RESPONSE1_TURNAROUND_6M81;
- //gInst->setting.ancRespRxDelay = RX_RESPONSE1_TURNAROUND ;
- }
- gInst->setting.pollRx2FinalRxDelay = delayus + gInst->setting.fwtoTime_sy;
- }
- // -------------------------------------------------------------------------------------------------------------------
- //
- // Set Payload parameters for the instance
- //
- // -------------------------------------------------------------------------------------------------------------------
- void instSetAddress(uint16_t address)
- {
- gInst->setting.instanceAddress16 = address ; // copy configurations
- }
- void instSetPanID(uint16_t id)
- {
- gInst->setting.panID = id ;
- }
- void instUpdateFramePeroid(uint16_t period)
- {
- gInst->setting.sframePeriod = period;
- gInst->setting.numSlots = gInst->setting.sframePeriod / (gInst->setting.slotPeriod * TA_SLOT_STEP);
- }
|