【DWM1000】 code 解密8一 TAG接收blink response 信號

         在分析這個部分前,目前我看到DWM1000 的資料,data能夠分爲blink和通常無線數據,後面有內容咱們再擴充, 上面咱們已經看到接收到blink觸發的事件爲app

case SIG_RX_BLINK :函數

通常數據包應該觸發的的是ui

case DWT_SIG_RX_OKAY :this

表示接收到一個無線無線數據包,具體怎麼解析這個數據包咱們一點點分析。spa

好了,看TAG收到ANCHOR的blink response,這個數據包爲通常數據包,具體數據內容咱們前面簡單列出來了,這裏從TAG接收的角度一點點在分析。code

 

好了,仍是上代碼事件

event_data_t* dw_event = instance_getevent(15); //get and clear this eventip

uint8  srcAddr[8] = {0,0,0,0,0,0,0,0};ci

int fcode = 0;rem

int fn_code = 0;

uint8 *messageData;

 

inst->stoptimer = 0; //clear the flag, as we have received a message

首先是獲取事件getevent,這個應該是獲取到接收數據成功的事件。後面緊隨其後是一下變量的生命。後面看用到這些變量再看。

switch(dw_event->msgu.frame[1])

這個msgu.frame[1] 是啥內容,咱們須要回到ANCHOR發送端看了

#if (USING_64BIT_ADDR == 1)

                                     inst->rng_initmsg.frameCtrl[1] = 0xCC;

                                     inst->psduLength += FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;

#else

咱們接着摘錄具體的代碼

case 0xCC: //

memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ll.sourceAddr[0]), ADDR_BYTE_SIZE_L);

fn_code = dw_event->msgu.rxmsg_ll.messageData[FCODE];

messageData = &dw_event->msgu.rxmsg_ll.messageData[0];

這個決定了咱們從不一樣地方去srcAddr以及fn_code 和messageData。 後面用到這幾個變量再看具體是什麼內容

    if(inst->mode == ANCHOR)

      {

……

      }

      else // LISTENER or TAG

     {

                            fcode = fn_code;

     }

接着後面看

  switch(fcode)

    {

           case RTLS_DEMO_MSG_RNG_INIT:

          {

 

原來fcode是這些傢伙,咱們再看看ANCHOR發送的時候fcode是什麼吧

inst->rng_initmsg.messageData[FCODE] = RTLS_DEMO_MSG_RNG_INIT;

正好是第一個case,直接在拉代碼看看作了什麼,沒看代碼前,咱們根據發送時的數據(短地址以及兩個delay)能夠大概猜出來,TAG應該是保持這些數據,由於ANCHOR那邊還在等着,因此應該還會發一個數據給ANCHOR。

 

好,上代碼

先修改了兩個很是重要的變量,咱們記一下,等一會還會用到

inst->testAppState = TA_TXE_WAIT;

inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll

 

後面就是從數據包提取短地址和兩個delay

inst->tagShortAdd = messageData[RNG_INIT_TAG_SHORT_ADDR_LO]                                                        + (messageData[RNG_INIT_TAG_SHORT_ADDR_HI] << 8) ;

// Get response delays from message and update internal timings accordingly

resp_dly[RESP_DLY_ANC] =  messageData[RNG_INIT_ANC_RESP_DLY_LO]

+ (messageData[RNG_INIT_ANC_RESP_DLY_HI] << 8);

resp_dly[RESP_DLY_TAG] =  messageData[RNG_INIT_TAG_RESP_DLY_LO]

+ (messageData[RNG_INIT_TAG_RESP_DLY_HI] << 8);

 

其中短地址被保存到結構體instance中,而兩個delay目前只保存到臨時變量裏。

後面兩個delay在代碼中進行了轉換,最終計算出了兩個delay保存到instance中了

// Update delay between poll transmission and response reception.

inst->txToRxDelayTag_sy

// Update delay between poll transmission and final transmission.

inst->finalReplyDelay

inst->finalReplyDelay_ms

 

後面的inst->sleep_en = 0; 咱們姑且認爲是吧。 接着分析後面的代碼

#if (USING_64BIT_ADDR == 1)

memcpy(&inst->msg.destAddr[0], &srcAddr[0], ADDR_BYTE_SIZE_L);

//set the anchor address for the reply (set destination address)

#else

看代碼,用的是64bit 地址,前面分析srcAddr實際上是源地址

memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ll.sourceAddr[0]), ADDR_BYTE_SIZE_L);

也就是ANCHOR的地址,咱們能夠看到執行

memcpy(&inst->msg.destAddr[0], &srcAddr[0], ADDR_BYTE_SIZE_L);

也就是destAddr[0]裏面存放的ANCHOR的地址

接着看後面依然有個地址複製,咱們先記錄先來看看是否有用。

memcpy(&inst->relpyAddress[0], &srcAddr[0], ADDR_BYTE_SIZE_L);

 //remember who to send the reply to (set destination address)

後面的代碼就是幾個變量的賦值了

inst->mode = TAG ;

inst->instToSleep = 0;

inst->instancetimer_saved = inst->instancetimer = portGetTickCount(); //set timer base

 

而後退出testapprun_s,來回分析ANCHOR 和TAG已經忘記done的狀態了,咱們暫且認爲不須要定時器,因此回很快再次進去testapprun_s。首先列一下重要變量

inst->testAppState = TA_TXE_WAIT;

inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll

inst->mode = TAG ;

而後在testapprun_s找案發現場

case TA_TXE_WAIT : //either go to sleep or proceed to TX a message

       //if we are scheduled to go to sleep before next sending then sleep first.

       if(((inst->nextState == TA_TXPOLL_WAIT_SEND)

         || (inst->nextState == TA_TXBLINK_WAIT_SEND))

         && (inst->instToSleep)  //go to sleep before sending the next poll

                    )

         {

根據綠色標出的地方,能夠看出,知足if判斷

//the app should put chip into low power state and wake up in tagSleepTime_ms time...

//the app could go to *_IDLE state and wait for uP to wake it up...

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT_TO;

 //don't sleep here but kick off the TagTimeoutTimer (instancetimer)

inst->testAppState = TA_SLEEP_DONE;

 

 if(inst->mode == TAG_TDOA) //once we start ranging we want to display the new range

         {

                            ……不知足條件

         }

 

#if (DEEP_SLEEP == 1) 宏定義確實爲1

     if (inst->sleep_en) 上面咱們假定這個參數爲0

      {

             ……不知足條件

       }

#endif

                   //DW1000 gone to sleep - report the received range

                   if(inst->tof > 0) //if ToF == 0 - then no new range to report

                   {

                    ……

                   }

後面的tof咱們以前也沒有遇到過,假定爲0,也不知足。繞了一圈,發現其實此次進入到testapprun_s只設置兩個兩個重要變量

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT_TO;

inst->testAppState = TA_SLEEP_DONE;

根據以前分析,因爲是INST_DONE_WAIT_FOR_NEXT_EVENT_TO,在instance_run 會開個定時器。咱們認爲溢出前會先進入testapprun_s,看看在TA_SLEEP_DONE 作了什麼吧。接着找做案現場

case TA_SLEEP_DONE :

{

    event_data_t* dw_event = instance_getevent(10); //clear the event from the queue

                            // waiting for timout from application to wakup IC

         if (dw_event->type != DWT_SIG_RX_TIMEOUT)

         {

                   // if no pause and no wake-up timeout continu waiting for the sleep to be done.

         inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //wait here for sleep timeout

           break;

    }

能夠看出若是進來發現不是TIMEOUT,一直break,因此定時器一直須要等待溢出才執行後面的代碼。

……等待定時器,等待定時器……溢出。好了,咱們看後面的代碼

inst->done = INST_NOT_DONE_YET;

inst->instToSleep = 0;

inst->testAppState = inst->nextState;

inst->nextState = 0; //clear

inst->instancetimer_saved = inst->instancetimer = portGetTickCount(); //set timer base

有點尷尬nextState好像很久沒用到,沒事回頭找代碼

case RTLS_DEMO_MSG_RNG_INIT:

{

      if(inst->mode == TAG_TDOA) //only start ranging with someone if not ranging already

         {

             uint32 final_reply_delay_us;

             uint32 resp_dly[RESP_DLY_NB];

             int i;

             inst->testAppState = TA_TXE_WAIT;

             inst->nextState = TA_TXPOLL_WAIT_SEND ; // send next poll

 

根據done = INST_NOT_DONE_YET;退出不加載定時器,根據TA_TXPOLL_WAIT_SEND 咱們再找做案現場

  case TA_TXPOLL_WAIT_SEND :  //TAG:send poll message

            {

這裏主要是發送poll message給ANCHOR

與發送相關的代碼

inst->msg.seqNum = inst->frame_sn++;

setupmacframedata(inst, RTLS_DEMO_MSG_TAG_POLL);

#if (USING_64BIT_ADDR==1)

         inst->psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC;

#else

 

dwt_writetxdata(inst->psduLength, (uint8 *)  &inst->msg, 0) ;  // write the frame data

dwt_writetxfctrl(inst->psduLength, 0);

dwt_starttx(DWT_START_TX_IMMEDIATE | inst->wait4ack);

發送具體數據包在meg中了,咱們如今具體不看,ANCHOR用到在看,反正是發送了,並且仍是個DWT_RESPONSE_EXPECTED

inst->wait4ack = DWT_RESPONSE_EXPECTED;

 

還設置了兩個延時,tx後多久打開接收器等待應答,以及rx 的timeout

//set the delayed rx on time (the response message will be sent after this delay)

dwt_setrxaftertxdelay(inst->txToRxDelayTag_sy);

dwt_setrxtimeout((uint16)inst->fwtoTime_sy);

 

發送完poll message等待應答須要轉狀態,保存重要變量

inst->testAppState = TA_TX_WAIT_CONF ;   // wait confirmation

inst->previousState = TA_TXPOLL_WAIT_SEND ;

inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below)

根據done,知道退出後不須要啓動定時器。

以前咱們就分析過TA_TX_WAIT_CONF,不過這個函數會根據previousState有不少岔路,咱們接着分析它

if(dw_event->type != DWT_SIG_TX_DONE) //wait for TX done confirmation

{

         if(dw_event->type == DWT_SIG_RX_TIMEOUT)

         {

         ……沒有啓動定時器,因此不會執行到這裏

         }    

    inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;

    break;

}

由這段代碼能夠看出,TAG一直不停的循環,直到等待DWT_SIG_TX_DONE,也就是DWM1000把數據包發送出去。

inst->done = INST_NOT_DONE_YET;

 

else

 {

         inst->txu.txTimeStamp = dw_event->timeStamp;

if(inst->previousState == TA_TXPOLL_WAIT_SEND)

          {

能夠看出,知足if 判斷會接着執行後面的代碼,後面不少代碼都是計算poll message 發送時間的。

uint64 tagCalculatedFinalTxTime ;

// Embed into Final message: 40-bit pollTXTime,  40-bit respRxTime,  40-bit finalTxTime

tagCalculatedFinalTxTime = (inst->txu.txTimeStamp + inst->finalReplyDelay) & MASK_TXDTS;

 // time we should send the response

inst->delayedReplyTime = tagCalculatedFinalTxTime >> 8;

 

// Calculate Time Final message will be sent and write this field of Final message

// Sending time will be delayedReplyTime, snapped to ~125MHz or ~250MHz boundary by

// zeroing its low 9 bits, and then having the TX antenna delay added

// getting antenna delay from the device and add it to the Calculated TX Time

tagCalculatedFinalTxTime = tagCalculatedFinalTxTime + inst->txantennaDelay;

tagCalculatedFinalTxTime &= MASK_40BIT;

 

// Write Calculated TX time field of Final message

memcpy(&(inst->msg.messageData[FTXT]), (uint8 *)&tagCalculatedFinalTxTime, 5);

// Write Poll TX time field of Final message

memcpy(&(inst->msg.messageData[PTXT]), (uint8 *)&inst->txu.tagPollTxTime, 5);

 

這幾個時間咱們後面在分析,咱們先看代碼

inst->testAppState = TA_RXE_WAIT ;  

message = 0;

//break ; // end case TA_TX_WAIT_CONF

case TA_RXE_WAIT :  //enable rx,and  wait to recive a message

接着會執行TA_RXE_WAIT ,根據以前的分析結果,這裏只是打開接收器等到數據,因此到此爲止,TAG又開始等待了,等待ANCHOR回覆。

 

總結一下該小段: TAG發送poll message給ANCHOR後進入等待狀態,ANCHOR應該此時接收數據並回復TAG。

相關文章
相關標籤/搜索