1. 程式人生 > >【DWM1000】 code 解密8一 TAG接收blink response 信號

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

int 定時器 som alt calc dem mbed amp 提取

在分析這個部分前,目前我看到DWM1000 的資料,data可以分為blink和一般無線數據,後面有內容我們再擴充, 上面我們已經看到接收到blink觸發的事件為

case SIG_RX_BLINK :

一般數據包應該觸發的的是

case DWT_SIG_RX_OKAY :

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

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

好了,還是上代碼

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

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

int fcode = 0;

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。

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