1. 程式人生 > >【DWM1000】 code 解密一 工程初始化代碼分析

【DWM1000】 code 解密一 工程初始化代碼分析

eof associate 回調函數 pre ack 也有 tca use fas

Draft ,以後整理

instance_init 函數追下去,絕大多數的代碼都在初始化如下結構體

typedef struct

{

INST_MODE mode; instance_init -ANCHOR //instance mode (tag or anchor)

INST_STATES testAppState ; int instance_init_s(int mode) TA_INIT

//state machine - current state

INST_STATES nextState ; //state machine - next state

INST_STATES previousState ; //state machine - previous state

int done ; //done with the current event/wait for next event to arrive

//configuration structures

dwt_config_t configData ; //DW1000 channel configuration

dwt_txconfig_t configTX ; //DW1000 TX power configuration

uint16 txantennaDelay ; //DW1000 TX antenna delay

uint16 rxantennaDelay ; //DW1000 RX antenna delay

uint8 antennaDelayChanged;

// "MAC" features

uint8 frameFilteringEnabled ; //frame filtering is enabled

// Is sleeping between frames enabled?

uint8 sleep_en; instance_init 1

//timeouts and delays

int tagSleepTime_ms; instancesettagsleepdelay 500//in milliseconds

int tagBlinkSleepTime_ms; instancesettagsleepdelay 1000

//this is the delay used for the delayed transmit (when sending the ranging init, response, and final messages)

uint64 rnginitReplyDelay ;

uint64 finalReplyDelay ;

uint64 responseReplyDelay ;

int finalReplyDelay_ms ;

// xx_sy the units are 1.0256 us

uint32 txToRxDelayAnc_sy ; // this is the delay used after sending a response and turning on the receiver to receive final

uint32 txToRxDelayTag_sy ; // this is the delay used after sending a poll and turning on the receiver to receive response

int rnginitW4Rdelay_sy ; // this is the delay used after sending a blink and turning on the receiver to receive the ranging init message

int fwtoTime_sy ; //this is final message duration (longest out of ranging messages)

int fwtoTimeB_sy ; //this is the ranging init message duration

uint32 delayedReplyTime; // delayed reply time of delayed TX message - high 32 bits

uint32 rxTimeouts ; instanceclearcounts 0

// - not used in the ARM code uint32 responseTimeouts ;

// Pre-computed frame lengths for frames involved in the ranging process,

// in microseconds.

uint32 fl_us[FRAME_TYPE_NB];

//message structures used for transmitted messages

#if (USING_64BIT_ADDR == 1)

srd_msg_dlsl rng_initmsg ; // ranging init message (destination long, source long)

srd_msg_dlsl msg ; // simple 802.15.4 frame structure (used for tx message) - using long addresses

#else

srd_msg_dlss rng_initmsg ; // ranging init message (destination long, source short)

srd_msg_dsss msg ; // simple 802.15.4 frame structure (used for tx message) - using short addresses

#endif

iso_IEEE_EUI64_blink_msg blinkmsg ; // frame structure (used for tx blink message)

//messages used in "fast" ranging ...

srd_msg_dlss rnmsg ; // ranging init message structure

srd_msg_dsss msg_f ; // ranging message with 16-bit addresses - used for "fast" ranging

//Tag function address/message configuration

uint8 eui64[8]; // devices EUI 64-bit address

uint16 tagShortAdd ; // Tag‘s short address (16-bit) used when USING_64BIT_ADDR == 0

uint16 psduLength ; // used for storing the frame length

uint8 frame_sn; instanceclearcounts 0 // modulo 256 frame sequence number - it is incremented for each new frame transmittion

uint16 panid ; instance_init 0 xdeca // panid used in the frames

uint8 relpyAddress[8] ; // address of the anchor the tag is ranging with

//64 bit timestamps

//union of TX timestamps

union {

uint64 txTimeStamp ; // last tx timestamp

uint64 tagPollTxTime ; // tag‘s poll tx timestamp

uint64 anchorRespTxTime ; // anchor‘s reponse tx timestamp

}txu;

uint64 anchorRespRxTime ; // receive time of response message

uint64 tagPollRxTime ; // receive time of poll message

//32 bit timestamps (when "fast" ranging is used)

uint32 tagPollTxTime32l ; // poll tx time - low 32 bits

uint32 tagPollRxTime32l ; // poll rx time - low 32 bits

uint32 anchorRespTxTime32l ; // response tx time - low 32 bits

uint32 anchResp1RxTime32l ; // response 1 rx time - low 32 bits

//application control parameters

uint8 wait4ack ; instance_init 0 // if this is set to DWT_RESPONSE_EXPECTED, then the receiver will turn on automatically after TX completion

uint8 instToSleep; instance_init 0 // if set the instance will go to sleep before sending the blink/poll message

uint8 stoptimer; instance_init 0 // stop/disable an active timer

uint8 instancetimer_en; instance_init 0 // enable/start a timer

uint32 instancetimer; // e.g. this timer is used to timeout Tag when in deep sleep so it can send the next poll message

uint32 instancetimer_saved;

// - not used in the ARM code

//uint8 deviceissleeping; // this disabled reading/writing to DW1000 while it is in sleep mode

// (DW1000 will wake on chip select so need to disable and chip select line activity)

uint8 gotTO; // got timeout event

uint8 responseRxNum; // response number

//diagnostic counters/data, results and logging

int32 tof32 ;

int64 tof ; instance_init 0

double clockOffset ; instance_init 0

uint32 blinkRXcount ; instcleartaglist 0

int txmsgcount; instanceclearcounts 0

int rxmsgcount; instanceclearcounts 0

int lateTX; instanceclearcounts 0

int lateRX; instanceclearcounts 0

double adist[RTD_MED_SZ] ;

double adist4[4] ;

double longTermRangeSum ; instanceclearcounts 0

int longTermRangeCount ; instanceclearcounts 0

int tofindex ; instance_init 0 instanceclearcounts 0

int tofcount ; instance_init 0 instanceclearcounts 0

int last_update ; // detect changes to status report

double idistmax; instanceclearcounts 0

double idistmin; instanceclearcounts 1000

double idistance ; // instantaneous distance

int newrange;

int norange;

int newrangeancaddress; //last 4 bytes of anchor address

int newrangetagaddress; //last 4 bytes of tag address

// - not used in the ARM code uint32 lastReportTime;

int respPSC;

//if set to 1 then it means that DW1000 is in DEEP_SLEEP

//so the ranging has finished and micro can output on USB/LCD

//if sending data to LCD during ranging this limits the speed of ranging

uint8 canprintinfo ;

//devicelogdata_t devicelogdata;

uint8 tagToRangeWith; instcleartaglist 0//it is the index of the tagList array which contains the address of the Tag we are ranging with

uint8 tagListLen ; instcleartaglist 0

uint8 anchorListIndex ; int instance_init_s(int mode) 0

uint8 tagList[TAG_LIST_SIZE][8]; instcleartaglist 0

//event queue - used to store DW1000 events as they are processed by the dw_isr/callback functions

event_data_t dwevent[MAX_EVENT_NUMBER]; instance_clearevents 0 //this holds any TX/RX events and associated message data

event_data_t saved_dwevent; //holds an RX event while the ACK is being sent

uint8 dweventIdxOut; instance_clearevents 0

uint8 dweventIdxIn; instance_clearevents 0

uint8 dweventPeek; instance_clearevents 0

uint8 monitor; instance_init 0

uint32 timeofTx ;

int dwIDLE;

} instance_data_t ;

上述默認初始化設別為,但是後面接著會根據撥碼開關再次決定設備類型

if(s1switch & SWS1_ANC_MODE)

{

instance_mode = ANCHOR;

led_on(LED_PC6);

}

else

{

instance_mode = TAG;

led_on(LED_PC7);

}

並再次調用函數設置設備類型

// Set this instance role as the Tag, Anchor or Listener

void instancesetrole(int inst_mode)

{

// assume instance 0, for this

instance_data[0].mode = inst_mode; // set the role

}

註意:設置全部都保存在結果體instance_data中,如果我們想擴充設備,那就需要修改這個家夥的數組了。

後面是初始化init 結構體

int instance_init_s(int mode)

{

int instance = 0 ;

instance_data[instance].mode = mode; //上面已經設定過了 // assume anchor,

instance_data[instance].testAppState = TA_INIT ; //後面狀態機會用到這個。

// if using auto CRC check (DWT_INT_RFCG and DWT_INT_RFCE) are used instead of DWT_INT_RDFR flag

// other errors which need to be checked (as they disable receiver) are

//dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_SFDT | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1);

//暫時不看具體寄存器設定

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);

//this is platform dependent - only program if DW EVK/EVB

dwt_setleds(3) ; //configure the GPIOs which control the LEDs on EVBs

//非常重要,這個是兩個回調函數

dwt_setcallbacks(instance_txcallback, instance_rxcallback);

//非常重要,這個應用層主要函數

instance_setapprun(testapprun_s);

instance_data[instance].anchorListIndex = 0 ;

//sample test calibration functions

//xtalcalibration();

//powertest();

return 0 ;

}

//回調函數設定

void dwt_setcallbacks(void (*txcallback)(const dwt_callback_data_t *), void (*rxcallback)(const dwt_callback_data_t *))

{

dw1000local.dwt_txcallback = txcallback;

dw1000local.dwt_rxcallback = rxcallback;

}

//應用層函數設定

void instance_setapprun(int (*apprun_fn)(instance_data_t *inst, int message))

{

int instance = 0 ;

instance_localdata[instance].testapprun_fn = apprun_fn;

}

設定這些函數,只是提供入口,此時還不會執行。但是RX TX 回調函數是通過中斷觸發的,設定後可能會立馬執行,這個我們後續看代碼分析。

接著返回函數上層追蹤

instance_init_s(instance_mode);

dr_mode = decarangingmode(s1switch);

//NOTE: Channel 5 is not supported for the non-discovery mode

int decarangingmode(uint8 s1switch)

{

int mode = 0;

if(s1switch & SWS1_SHF_MODE)

{

mode = 1;

}

if(s1switch & SWS1_64M_MODE)

{

mode = mode + 2;

}

if(s1switch & SWS1_CH5_MODE)

{

mode = mode + 4;

}

return mode;

}

我們暫時還不確定目前sw組合,看代碼不難理解,後續我們再分析這一塊。

instConfig.channelNumber = chConfig[dr_mode].channel ;

instConfig.preambleCode = chConfig[dr_mode].preambleCode ;

instConfig.pulseRepFreq = chConfig[dr_mode].prf ;

instConfig.pacSize = chConfig[dr_mode].pacSize ;

instConfig.nsSFD = chConfig[dr_mode].nsSFD ;

instConfig.sfdTO = chConfig[dr_mode].sfdTO ;

instConfig.dataRate = chConfig[dr_mode].datarate ;

instConfig.preambleLen = chConfig[dr_mode].preambleLength ;

instance_config(&instConfig) ; // Set operating channel etc

根據上面按鍵sw 確定某一種模式,然後將chConfig 全局變量的一部分提取出來,放到instConfig中,然後調用instance_config配置,這些都是DWM1000 工作必須配置,需要配合datasheet 查看,具體我們這裏就不解釋了,我們註重的邏輯

調用instance_config我們就認為RF 相關的參數已經正確配置到DWM1000了。

instancesettagsleepdelay(POLL_SLEEP_DELAY, BLINK_SLEEP_DELAY); //set the Tag sleep time

(500,1000)

其實從函數內容來看,還是在初始化結構體instace_data。

// -------------------------------------------------------------------------------------------------------------------

// function to set the tag sleep time (in ms)

//

void instancesettagsleepdelay(int sleepdelay, int blinksleepdelay) //sleep in ms

{

int instance = 0 ;

instance_data[instance].tagSleepTime_ms = sleepdelay ;

instance_data[instance].tagBlinkSleepTime_ms = blinksleepdelay ;

}

Inittestapplication 最後一個函數instance_init_timings

從下面的解釋可以看出還是初始化相關,這個函數稍微復雜點,我們暫時先不看。

// Pre-compute frame lengths, timeouts and delays needed in ranging process.

// /!\ This function assumes that there is no user payload in the frame.

void instance_init_timings(void)

現在我們就基本分析完了inittestapplication, 正如它的名字一樣,這個主要是init, 一些關鍵參數的值我們在上面的結構體中也有標註

【DWM1000】 code 解密一 工程初始化代碼分析