/*! ---------------------------------------------------------------------------- * @file main.c * @brief Double-sided two-way ranging (DS TWR) initiator example code * * * * @attention * * Copyright 2015 (c) Decawave Ltd, Dublin, Ireland. * * All rights reserved. * * @author Decawave */ #include #include #include "dw_app.h" #include "deca_device_api.h" #include "deca_regs.h" #include "dw_driver.h" #include "Spi.h" #include "led.h" #include "serial_at_cmd_app.h" #include "Usart.h" #include "global_param.h" #include "filters.h" #include #include "beep.h" #include "modbus.h" #define USART_INTEGRATE_OUTPUT /*------------------------------------ Marcos ------------------------------------------*/ /* Inter-ranging delay period, in milliseconds. */ #define RNG_DELAY_MS 100 /* Default antenna delay values for 64 MHz PRF. See NOTE 1 below. */ #define TX_ANT_DLY 0 #define RX_ANT_DLY 32899 /* UWB microsecond (uus) to device time unit (dtu, around 15.65 ps) conversion factor. * 1 uus = 512 / 499.2 µs and 1 µs = 499.2 * 128 dtu. */ #define UUS_TO_DWT_TIME 65536 /* Delay between frames, in UWB microseconds. See NOTE 4 below. */ /* This is the delay from the end of the frame transmission to the enable of the receiver, as programmed for the DW1000's wait for response feature. */ #define POLL_TX_TO_RESP_RX_DLY_UUS 150 /* This is the delay from Frame RX timestamp to TX reply timestamp used for calculating/setting the DW1000's delayed TX function. This includes the * frame length of approximately 2.66 ms with above configuration. */ #define RESP_RX_TO_FINAL_TX_DLY_UUS 410 /* Receive response timeout. See NOTE 5 below. */ #define RESP_RX_TIMEOUT_UUS 600 #define DELAY_BETWEEN_TWO_FRAME_UUS 400 #define POLL_RX_TO_RESP_TX_DLY_UUS 470 /* This is the delay from the end of the frame transmission to the enable of the receiver, as programmed for the DW1000's wait for response feature. */ #define RESP_TX_TO_FINAL_RX_DLY_UUS 200 /* Receive final timeout. See NOTE 5 below. */ #define FINAL_RX_TIMEOUT_UUS 4300 #define SPEED_OF_LIGHT 299702547 /* Indexes to access some of the fields in the frames defined above. */ #define FINAL_MSG_POLL_TX_TS_IDX 10 #define FINAL_MSG_RESP_RX_TS_IDX 14 #define FINAL_MSG_FINAL_TX_TS_IDX 18 #define FINAL_MSG_TS_LEN 4 enum enumtagstate { DISCPOLL, GETNEARMSG, NEARPOLL, } tag_state=NEARPOLL; dwt_config_t config = { 2, /* Channel number. */ DWT_PRF_64M, /* Pulse repetition frequency. */ DWT_PLEN_1024, /* Preamble length. */ DWT_PAC8, /* Preamble acquisition chunk size. Used in RX only. */ 9, /* TX preamble code. Used in TX only. */ 9, /* RX preamble code. Used in RX only. */ 1, /* Use non-standard SFD (Boolean) */ DWT_BR_6M8, /* Data rate. */ DWT_PHRMODE_STD, /* PHY header mode. */ (1025 + 8 - 8) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */ }; static uint8_t tx_poll_msg[20] = {0}; static uint8_t tx_sync_msg[14] = {0}; static uint8_t tx_final_msg[60] = {0}; static uint8_t tx_resp_msg[22] = {0}; uint8_t tx_near_msg[80] = {0}; static uint32_t frame_seq_nb = 0; static uint32_t status_reg = 0; static uint8_t rx_buffer[100]; static uint64_t poll_tx_ts; static uint64_t resp_rx_ts; static uint64_t final_tx_ts; static uint64_t poll_rx_ts; static uint64_t resp_tx_ts; static uint64_t final_rx_ts; static double tof; int32_t anchor_dist_last_frm[TAG_NUM_IN_SYS],his_dist[TAG_NUM_IN_SYS]; ; uint32_t tag_id = 0; uint32_t tag_id_recv = 0; uint32_t anc_id_recv = 0; uint8_t random_delay_tim = 0; double distance, dist_no_bias, dist_cm; uint32_t g_UWB_com_interval = 0; float dis_after_filter; //µ±Ç°¾àÀëÖµ LPFilter_Frac* p_Dis_Filter; //²â¾àÓõĵÍͨÂ˲¨Æ÷ static uint64_t get_tx_timestamp_u64(void) { uint8_t ts_tab[5]; uint64_t ts = 0; int i; dwt_readtxtimestamp(ts_tab); for (i = 4; i >= 0; i--) { ts <<= 8; ts |= ts_tab[i]; } return ts; } static uint64_t get_rx_timestamp_u64(void) { uint8_t ts_tab[5]; uint64_t ts = 0; int i; dwt_readrxtimestamp(ts_tab); for (i = 4; i >= 0; i--) { ts <<= 8; ts |= ts_tab[i]; } return ts; } static void final_msg_set_ts(uint8_t *ts_field, uint64_t ts) { int i; for (i = 0; i < FINAL_MSG_TS_LEN; i++) { ts_field[i] = (uint8_t) ts; ts >>= 8; } } static void final_msg_get_ts(const uint8_t *ts_field, uint32_t *ts) { int i; *ts = 0; for (i = 0; i < FINAL_MSG_TS_LEN; i++) { *ts += ts_field[i] << (i * 8); } } void SetNLOSNTMSettings(void) { uint8_t temp; temp = 7; dwt_writetodevice(LDE_IF_ID,LDE_CFG1_OFFSET,1,&temp); dwt_write16bitoffsetreg(LDE_IF_ID,LDE_CFG2_OFFSET,3); // NTM = dwt_read32bitoffsetreg(LDE_IF_ID,LDE_CFG1_OFFSET) & LDE_CFG1_NSTDEV_MASK; } void Dw1000_Init(void) { /* Reset and initialise DW1000. * For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum * performance. */ Reset_DW1000();//ÖØÆôDW1000 /* Target specific drive of RSTn line into DW1000 low for a period. */ Spi_ChangePrescaler(SPIx_PRESCALER_SLOW); //ÉèÖÃΪ¿ìËÙģʽ dwt_initialise(DWT_LOADUCODE);//³õʼ»¯DW1000 Spi_ChangePrescaler(SPIx_PRESCALER_FAST); //ÉèÖÃΪ¿ìËÙģʽ /* Configure DW1000. See NOTE 6 below. */ dwt_configure(&config);//ÅäÖÃDW1000 SetNLOSNTMSettings(); /* Apply default antenna delay value. See NOTE 1 below. */ dwt_setrxantennadelay(RX_ANT_DLY); //ÉèÖýÓÊÕÌìÏßÑÓ³Ù dwt_settxantennadelay(TX_ANT_DLY); //ÉèÖ÷¢ÉäÌìÏßÑÓ³Ù /* Set expected response's delay and timeout. See NOTE 4 and 5 below. * As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */ //ÉèÖýÓÊÕ³¬Ê±Ê±¼ä } void Dw1000_App_Init(void) { //g_com_map[DEV_ID] = 0x0b; //tag_state=DISCPOLL; tx_poll_msg[MESSAGE_TYPE_IDX]=POLL; tx_resp_msg[MESSAGE_TYPE_IDX]=RESPONSE; tx_final_msg[MESSAGE_TYPE_IDX]=FINAL; tx_sync_msg[MESSAGE_TYPE_IDX]=SYNC; memcpy(&tx_poll_msg[TAG_ID_IDX], &dev_id, 2); memcpy(&tx_final_msg[TAG_ID_IDX], &dev_id, 2); memcpy(&tx_resp_msg[ANCHOR_ID_IDX], &dev_id, 2); memcpy(&tx_sync_msg[ANCHOR_ID_IDX], &dev_id, 2); memcpy(&tx_near_msg[ANCHOR_ID_IDX], &dev_id, 2); memcpy(&tx_near_msg[TAG_ID_IDX], &dev_id, 2); } uint16_t Checksum_u16(uint8_t* pdata, uint32_t len) { uint16_t sum = 0; uint32_t i; for(i=0; i>i)&0x1)==0) { return i; } } for(i=1; i>i)&0x1)==0) { return i; } } return max_slotpos-1; } uint32_t rec_tagpos_binary; extern uint16_t current_slotnum,total_slotnum; uint16_t target_time,last_time; uint32_t tagpos_binary; void SetNextPollTime(uint16_t time) { current_slotnum++; if(current_slotnum==total_slotnum) current_slotnum-=total_slotnum; //time=5; target_time=((current_slotnum*g_com_map[COM_INTERVAL])+time); last_time=target_time; if(target_time>=990&&target_time<992) { current_slotnum++; target_time+=g_com_map[COM_INTERVAL]; tagslotpos=GetRandomSlotPos(rec_tagpos_binary|tagpos_binary); tyncpoll_time = (tagslotpos--%max_slotpos)*slottime; } if(target_time>=1000) {target_time-=1000;} if(target_time<0) {target_time+=1000;} } int32_t mainbase_dist,nearbase_distlist[MAX_NEARBASE_NUM],true_nearbase_distlist[MAX_NEARBASE_NUM],true_exsistbase_list[MAX_NEARBASE_NUM],ancsync_time,nextpoll_delaytime,offsettimeus; u8 anclost_times=0 , mainbase_lost_count=0; u8 exsistbase_list[MAX_NEARBASE_NUM],report_num,get_newbase=0; u8 flag_finalsend,flag_getresponse,flag_rxon; uint16_t current_count,start_count,end_count,lastsync_timer; int16_t target_offsettime = 850; //u32 target_time=100; u8 pd_i; u32 temptime,delaytime,expect_anctime; int32_t error_time; u16 delaycount,slotpos_intoatl; int16_t poll_offsettime=-6900,clockoffset; extern u16 slotpos,bigslot_num; void NextPollDelay(u32 anchor_time) { //tagslotpos = 0; error_time = anchor_time-expect_anctime; if(error_time<2000&&error_time>0) clockoffset += (target_offsettime-error_time)*0.1; for(pd_i=0; pd_i=32768) { poll_startcount -=32768; } if(lpcount>=32768) { lpcount -=32768; } __HAL_LPTIM_COMPARE_SET(&hlptim1, lpcount); last_lpcount = lpcount; } void NextSlotDelayMs(int16_t delayms) { current_slotnum++; if(current_slotnum>=tag_frequency) { current_slotnum = 0; lpcount = last_lpcount+31457/tag_frequency+1311+32.767*delayms;//(float)(delayms+40)*32.767 ;//(200/tag_frequency+delayms)*4.8*1000/LPTIMER_LSB } else { lpcount = last_lpcount+31457/tag_frequency+32.767*delayms;//(float)(200/tag_frequency*48+delayms*10)*3.3 ; } if(lpcount>=32768) { lpcount -=32768; } poll_startcount = lpcount+(waketopolltimeus)/LPTIMER_LSB; if(poll_startcount>=32768) { poll_startcount -=32768; } __HAL_LPTIM_COMPARE_SET(&hlptim1, lpcount); last_lpcount = lpcount; } u8 nearbase_num=0,last_nearbase_num,next_nearbase_num,last_slotnum, para_update,para_len; u32 rec_tagpos_binary; int16_t offset=2700; extern int16_t g_commap_antdelay; //u8 motor_state,rec_remotepara_state,rec_remotepara[80]; u16 sync_anc_id = 0xffff,sync_anc_losttime = 0; int32_t ancsync_time,tpos; void SyncAncUpdate(u16 ancid,int32_t anctime,u16 slotpos) { if(ancid<=sync_anc_id) { SetLPTimer(ancsync_time); tagslotpos = slotpos; sync_anc_losttime = 0; sync_anc_id = ancid; } } //void NearPoll(void) //{ // uint32_t temp1,temp2,dw_systime; // uint32_t frame_len; // uint32_t final_tx_time; // u32 start_poll; // u8 i,j,getsync_flag=0,timeout; // dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS); //ÉèÖ÷¢ËÍºó¿ªÆô½ÓÊÕ£¬²¢É趨ÑÓ³Ùʱ¼ä // dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS); // tag_succ_times = 0; // // // if(next_nearbase_num>=MAX_NEARBASE_NUM) // { // next_nearbase_num = MAX_NEARBASE_NUM-1; // } // HAL_GPIO_WritePin(LED0_GPIO, GPIO_PIN_9, GPIO_PIN_SET); // last_nearbase_num=next_nearbase_num; // nearbase_num=next_nearbase_num; // recbase_num=0; // if(sync_anc_losttime++>10) // { // sync_anc_id = 0xffff; // } //// motor_state=0; // tx_near_msg[GROUP_ID_IDX] = group_id; // tx_near_msg[BATTARY_IDX] = bat_percent; // tx_near_msg[BUTTON_IDX] = !GET_USERKEY|stationary_flag<<1; // tx_near_msg[SEQUENCE_IDX] = frame_seq_nb++; // tx_near_msg[NEARBASENUM_INDEX] = nearbase_num; // memcpy(&tx_near_msg[NEARBASEID_INDEX],&nearbaseid_list,nearbase_num*2); // tx_near_msg[MESSAGE_TYPE_IDX] = NEAR_POLL; // memcpy(&tx_near_msg[NEARBASEID_INDEX+nearbase_num*4],&g_commap_antdelay,2); // memcpy(&tx_near_msg[ANCHOR_ID_IDX],&mainbase_id,2); // dwt_writetxdata(15+4*nearbase_num, tx_near_msg, 0);//½«Poll°üÊý¾Ý´«¸øDW1000£¬½«ÔÚ¿ªÆô·¢ËÍʱ´«³öÈ¥ // dwt_writetxfctrl(15+4*nearbase_num, 0);//ÉèÖó¬¿í´ø·¢ËÍÊý¾Ý³¤¶È // // current_count=HAL_LPTIM_ReadCounter(&hlptim1); // while(current_countpoll_startcount+16384) // { // current_count=HAL_LPTIM_ReadCounter(&hlptim1); // if(current_count=32768) // { // end_count-=32768; // } // mainbase_dist=100000; // mainbase_lost_count++; // current_count=HAL_LPTIM_ReadCounter(&hlptim1); // while(current_countend_count+15000) // { // current_count=HAL_LPTIM_ReadCounter(&hlptim1); // while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))//²»¶Ï²éѯоƬ״ֱ̬µ½³É¹¦½ÓÊÕ»òÕß·¢Éú´íÎó // { // if(flag_finalsend) // { // dw_systime=dwt_readsystimestamphi32(); // if(dw_systime>temp1&&dw_systime=end_count&¤t_count999) // { // tmp_time-=999; // sync_timer++; // if(sync_timer>=1010) // {sync_timer=0;} // } // ancsync_time=((sync_timer)*1000+tmp_time); // SyncAncUpdate(rec_nearbaseid,ancsync_time,rec_tagslotpos); // // TIM3->CNT=tmp_time; //// if(tagslotpos>max_slotpos) //// tagslotpos=tagslotpos%(max_slotpos+1); //// tyncpoll_time=(tagslotpos-1)*slottime; // //////////////////////////// // rec_nearbasepos=0; // exsistbase_list[rec_nearbasepos]=KEEP_TIMES; // memcpy(&temp_dist,&rx_buffer[DIST_IDX],4); // nearbase_distlist[rec_nearbasepos]=temp_dist; // if((rx_buffer[MOTORSTATE_INDEX]&0xf)!=3) // motor_state=rx_buffer[MOTORSTATE_INDEX]&0xf; // rec_remotepara_state=rx_buffer[MOTORSTATE_INDEX]>>4; // mainbase_lost_count=0; // flag_finalsend=1; // memcpy(&mainbase_dist,&rx_buffer[DIST_IDX],4); // final_tx_time = (resp_rx_ts + ((RESP_RX_TO_FINAL_TX_DLY_UUS+DELAY_BETWEEN_TWO_FRAME_UUS*nearbase_num+500) * UUS_TO_DWT_TIME)) >> 8; // temp1=final_tx_time-((850*UUS_TO_DWT_TIME)>>8); // temp2=final_tx_time+((100*UUS_TO_DWT_TIME)>>8); // // dwt_setdelayedtrxtime(final_tx_time);//ÉèÖÃfinal°ü·¢ËÍʱ¼äT5 // final_tx_ts = (((uint64_t)(final_tx_time & 0xFFFFFFFE)) << 8) + TX_ANT_DLY;//final°üʵ¼Ê·¢ËÍʱ¼äÊǼÆËãʱ¼ä¼ÓÉÏ·¢ËÍÌìÏßdelay // final_msg_set_ts(&tx_near_msg[FINAL_MSG_POLL_TX_TS_IDX], poll_tx_ts);//½«T1£¬T4£¬T5дÈë·¢ËÍÊý¾Ý // final_msg_set_ts(&tx_near_msg[FINAL_MSG_RESP_RX_NEARBASE_IDX], resp_rx_ts); // final_msg_set_ts(&tx_near_msg[FINAL_MSG_FINAL_TX_TS_IDX], final_tx_ts); // tx_near_msg[MESSAGE_TYPE_IDX]=NEAR_FINAL; // tx_near_msg[GROUP_ID_IDX] = group_id; // dwt_writetxdata(28+nearbase_num*4, tx_near_msg, 0);//½«·¢ËÍÊý¾ÝдÈëDW1000 // dwt_writetxfctrl(28+nearbase_num*4, 0);//É趨·¢ËÍÊý¾Ý³¤¶È // flag_getresponse=1; // memcpy(&rec_tagpos_binary,&rx_buffer[NEARMSG_EMPTYSLOTPOS_INDEX],4); // //ʱ¼äͬ²½ // ancsync_time=((sync_timer)*1000+tmp_time); // last_slotnum=current_slotnum; // current_slotnum=((float)sync_timer/g_com_map[COM_INTERVAL])+1; // if(current_slotnum==last_slotnum-1) // { // flag_getresponse=1; // } // lastsync_timer=sync_timer; // offsettimeus=ancsync_time-current_count*LPTIMER_LSB+offset; //// SetNextPollTime(tyncpoll_time); // if(rec_remotepara_state==1) // { // memcpy(rec_remotepara,&rx_buffer[REMOTEPARA_INDEX],REMOTEPARA_LEN); // memcpy(&g_com_map[COM_INTERVAL],&rec_remotepara[0],8); // memcpy(&g_com_map[POWER],&rec_remotepara[8],10); // if(g_com_map[COM_INTERVAL]>0&&g_com_map[COM_INTERVAL]<1000&&g_com_map[POWER]<67&&g_com_map[POWER]>0) // { save_com_map_to_flash(); // delay_ms(100); // } // NVIC_SystemReset(); // } // } else { // memcpy(&sync_timer,&rx_buffer[ANCTIMEMS],2); // memcpy(&tmp_time,&rx_buffer[ANCTIMEUS],2); // current_count=HAL_LPTIM_ReadCounter(&hlptim1); // memcpy(&rec_tagslotpos,&rx_buffer[TAGSLOTPOS],2); // tmp_time=tmp_time+450; // if(tmp_time>999) // { // tmp_time-=999; // sync_timer++; // if(sync_timer>=1010) // {sync_timer=0;} // } // ancsync_time=((sync_timer)*1000+tmp_time); // SyncAncUpdate(rec_nearbaseid,ancsync_time,rec_tagslotpos); // // rec_nearbasepos=FindNearBasePos(rec_nearbaseid); // if(rec_nearbasepos>=last_nearbase_num) //·¢ÏÖеĻùÕ¾ // { // get_newbase=1; // nearbase_num++; // nearbaseid_list[rec_nearbasepos] = rec_nearbaseid; // memcpy(&tx_near_msg[ANCHOR_ID_IDX],&rec_nearbaseid,2); // } // // exsistbase_list[rec_nearbasepos]=KEEP_TIMES; // memcpy(&temp_dist,&rx_buffer[DIST_IDX],4); // nearbase_distlist[rec_nearbasepos]=temp_dist; // if(motor_state<(rx_buffer[MOTORSTATE_INDEX]&0xf)&&(rx_buffer[MOTORSTATE_INDEX]&0xf)!=3) // { // motor_state=rx_buffer[MOTORSTATE_INDEX]; // } // final_msg_set_ts(&tx_near_msg[FINAL_MSG_RESP_RX_NEARBASE_IDX+(rec_nearbasepos)*4], resp_rx_ts); // dwt_writetxdata(28+nearbase_num*4, tx_near_msg, 0);//½«·¢ËÍÊý¾ÝдÈëDW1000 // dwt_writetxfctrl(28+nearbase_num*4, 0);//É趨·¢ËÍÊý¾Ý³¤¶È // //dwt_setdelayedtrxtime(final_tx_time);//ÉèÖÃfinal°ü·¢ËÍʱ¼äT5 // // result=dwt_starttx(DWT_START_TX_DELAYED);//É趨ΪÑÓ³Ù·¢ËÍ // //dwt_writetxdata(4,&tx_near_msg[FINAL_MSG_RESP_RX_NEARBASE_IDX+(rec_nearbasepos+1)*4], FINAL_MSG_RESP_RX_NEARBASE_IDX+(rec_nearbasepos+1)*4);//½«·¢ËÍÊý¾ÝдÈëDW1000 // } // } // } else { // dwt_write32bitreg(SYS_STATUS_ID,SYS_STATUS_RXFCG| SYS_STATUS_ALL_RX_ERR); // if(flag_rxon) // { dwt_rxenable(0); // } // } // // dwt_write32bitreg(SYS_STATUS_ID,SYS_STATUS_RXFCG| SYS_STATUS_ALL_RX_ERR); // } // if(mainbase_lost_count>tag_frequency*BASELOST_STOPMOTOR_TIME) // { // motor_state=0; // } // dwt_write32bitreg(SYS_STATUS_ID,SYS_STATUS_RXFCG| SYS_STATUS_ALL_RX_ERR); // nearbase_num=recbase_num; // j=0; // if(sync_anc_losttime!=0) // { // NextSlotDelayMs(0); // } // // tyncpoll_time=0; // next_nearbase_num=0; // for(i=0; i0) // { // next_nearbase_num++; // true_exsistbase_list[j]=exsistbase_list[i]; // true_nearbase_idlist[j]=nearbaseid_list[i]; // true_nearbase_distlist[j++]=nearbase_distlist[i]; // exsistbase_list[i]--; // } // } // if(recbase_num<3) // { // next_nearbase_num=next_nearbase_num; // } // last_nearbase_num = next_nearbase_num; // for(i=0; itrue_nearbase_distlist[j+1]) // { // u32 temp_dist,temp_id,temp_exsis; // temp_dist=true_nearbase_distlist[j]; // temp_id = true_nearbase_idlist[j]; // temp_exsis=true_exsistbase_list[i]; // true_nearbase_distlist[j]=true_nearbase_distlist[j+1]; // true_nearbase_idlist[j]=true_nearbase_idlist[j+1]; // true_exsistbase_list[j]=true_exsistbase_list[j+1]; // true_nearbase_distlist[j+1]=temp_dist; // true_nearbase_idlist[j+1]=temp_id; // true_exsistbase_list[j+1]=temp_exsis; // } // } // } // report_num=0; // for (i=0; i15) { LED_TB_ON; } else { LED_TR_ON; } // tag_state=DISCPOLL; switch(tag_state) { case DISCPOLL: // Poll(); break; case GETNEARMSG: // GetNearMsg(); break; case NEARPOLL: //GPIO_WriteBit(EU_TX_GPIO, EU_RX_PIN, Bit_SET); NearPoll(); //GPIO_WriteBit(EU_TX_GPIO, EU_RX_PIN, Bit_RESET); break; } dwt_entersleep(); LED_TB_OFF; LED_TR_OFF; }