/*! ---------------------------------------------------------------------------- * @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" #include "Module.h" #include "Power.h" #include "DBG.h" #include "Uart.h" /*------------------------------------ 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 10 /* 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 910 /* Receive response timeout. See NOTE 5 below. */ #define RESP_RX_TIMEOUT_UUS 1000 #define DELAY_BETWEEN_TWO_FRAME_UUS 240 #define POLL_RX_TO_RESP_TX_DLY_UUS 770 /* 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 #define STARTPOLL REGPOLL #define SWITCHBASE_DIST #define SWITCHBASE_ZHUANDIAN enum enumtagstate { REGPOLL=1, DISCPOLL, GETNEARMSG, NEARPOLL, SINGLEPOLL, }tag_state=STARTPOLL; dwt_config_t config = { 5, /* Channel number. */ DWT_PRF_64M, /* Pulse repetition frequency. */ DWT_PLEN_128, /* 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. */ (129 + 8 - 8) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */ }; dwt_config_t config2 = { 5, /* Channel number. */ DWT_PRF_64M, /* Pulse repetition frequency. */ DWT_PLEN_128, /* 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. */ (129 + 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; //²â¾àÓõĵÍͨÂ˲¨Æ÷ u32 id; 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); } } extern u8 flag_ancupd_start; 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); //ÉèÖÃΪ¿ìËÙģʽ id = dwt_readdevid() ; /* Configure DW1000. See NOTE 6 below. */ if(flag_ancupd_start) { dwt_configure(&config2);//ÅäÖÃDW1000 }else{ dwt_configure(&config);//ÅäÖÃDW1000 } dwt_setinterrupt( 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); /* Apply default antenna delay value. See NOTE 1 below. */ dwt_setrxantennadelay(RX_ANT_DLY); //ÉèÖýÓÊÕÌìÏßÑÓ³Ù dwt_settxantennadelay(TX_ANT_DLY); //ÉèÖ÷¢ÉäÌìÏßÑÓ³Ù dwt_setrxtimeout(1000);//É趨½ÓÊÕ³¬Ê±Ê±¼ä£¬0λûÓг¬Ê±Ê±¼ä dwt_rxenable(0);//´ò¿ª½ÓÊÕ /* 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[GROUP_ID_IDX], &group_id, 1); memcpy(&tx_final_msg[GROUP_ID_IDX], &group_id, 1); memcpy(&tx_resp_msg[GROUP_ID_IDX], &group_id, 1); 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; iBSRR = SPIx_CS<<16; delay_us(2700); SPIx_CS_GPIO->BSRR = SPIx_CS; id = dwt_readdevid() ; while (DWT_DEVICE_ID != id) { // Dw1000_Init(); id = dwt_readdevid() ; IdleTask(); if(error_times++>20) { printf("DW ID ERROR.\r\n"); // SCB->AIRCR = 0X05FA0000|(unsigned int)0x04; //Èí¸´Î»»Øµ½bootloader } }} int32_t mainbase_dist,nearbase_switchdistlist[MAX_NEARBASE_NUM],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; extern u16 bigslot_num; u8 nearbase_num=0,last_nearbase_num,next_nearbase_num,last_slotnum, para_update,para_len; u32 rec_tagpos_binary; int16_t offset=4700,temptimer; u8 rec_remotepara_state,rec_remotepara[80]; #define SINGLEPOLL_BASENUM 3 uint16_t singlepoll_baseid[ANCHORTYPE_NUM]; int32_t singlepoll_basedist[ANCHORTYPE_NUM]; extern u8 userkey_state,stationary_flag,motor_state; extern float motor_keeptime; uint8_t changemainbase_count=0,gotosleep_flag,singlepoll_i,mindist_concount; uint32_t frame_len,mindist_ancid,last_mindist_ancid; int32_t salvebase_mindist; int16_t intheight; u32 minddist = 0x1ffff; void Poll(void) { uint32_t frame_len; uint32_t final_tx_time; u32 start_poll; int32_t mindist=999999,minid=-1,temp_dist; u8 i,j,getsync_flag=0; dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS); //ÉèÖ÷¢ËÍºó¿ªÆô½ÓÊÕ£¬²¢É趨ÑÓ³Ùʱ¼ä dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS); tag_succ_times = 0; minddist = 0x1ffff; frame_seq_nb++; for(singlepoll_i=0;singlepoll_i>8; tx_near_msg[NEARBASENUM_INDEX] = nearbase_num; memcpy(&tx_near_msg[NEARBASEID_INDEX],&singlepoll_baseid,nearbase_num*2); memcpy(&tx_near_msg[NEARBASEID_INDEX+nearbase_num*2],&singlepoll_basedist,nearbase_num*4+4); // intheight+=g_com_map[HEIGHTOFFEST_INDEX]; memcpy(&tx_near_msg[NEARBASEID_INDEX+nearbase_num*6],&intheight,2); tx_near_msg[MESSAGE_TYPE_IDX] = DISCOVERPOLL; singlepoll_basedist[singlepoll_i]= 0x1ffff; tx_near_msg[NEARP_TAGFREQ_INDEX] = tag_frequency; tx_near_msg[NEARP_TAGSLOTPOS_INDEX] = tagslotpos; tx_near_msg[ANCHOR_ID_IDX] = singlepoll_i; //memcpy(&tx_near_msg[ANCHOR_ID_IDX],&singlepoll_baseid[singlepoll_i],2); dwt_writetxdata(28+6*nearbase_num, tx_near_msg, 0);//½«Poll°üÊý¾Ý´«¸øDW1000£¬½«ÔÚ¿ªÆô·¢ËÍʱ´«³öÈ¥ dwt_writetxfctrl(28+6*nearbase_num, 0);//ÉèÖó¬¿í´ø·¢ËÍÊý¾Ý³¤¶È dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);//¿ªÆô·¢ËÍ£¬·¢ËÍÍê³ÉºóµÈ´ýÒ»¶Îʱ¼ä¿ªÆô½ÓÊÕ£¬µÈ´ýʱ¼äÔÚdwt_setrxaftertxdelayÖÐÉèÖà /* We assume that the transmission is achieved correctly, poll for reception of a frame or error/timeout. See NOTE 8 below. */ while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))//²»¶Ï²éѯоƬ״ֱ̬µ½³É¹¦½ÓÊÕ»òÕß·¢Éú´íÎó { }; if(status_reg==0xffffffff) { // NVIC_SystemReset(); } if (status_reg & SYS_STATUS_RXFCG)//Èç¹û³É¹¦½ÓÊÕ { dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);//Çå³þ¼Ä´æÆ÷±ê־λ frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK; //»ñµÃ½ÓÊÕµ½µÄÊý¾Ý³¤¶È dwt_readrxdata(rx_buffer, frame_len, 0); //¶ÁÈ¡½ÓÊÕÊý¾Ý if (rx_buffer[MESSAGE_TYPE_IDX] == RESPONSE&&!memcmp(&rx_buffer[TAG_ID_IDX],&dev_id,2)) //ÅжϽÓÊÕµ½µÄÊý¾ÝÊÇ·ñÊÇresponseÊý¾Ý { poll_tx_ts = get_tx_timestamp_u64(); //»ñµÃPOLL·¢ËÍʱ¼äT1 resp_rx_ts = get_rx_timestamp_u64(); //»ñµÃRESPONSE½ÓÊÕʱ¼äT4 if(getsync_flag==0) { getsync_flag=1; memcpy(&sync_timer,&rx_buffer[ANCTIMEMS],2); memcpy(&tmp_time,&rx_buffer[ANCTIMEUS],2); // current_count=HAL_LPTIM_ReadCounter(&hlptim1); // memcpy(&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); last_slotnum=current_slotnum; temptimer = sync_timer-10; if(temptimer<0) {temptimer+=1000;} //current_slotnum=((float)temptimer/(SLOTTIME_MS*bigslot_num))+1; if(current_slotnum==last_slotnum-1) {flag_getresponse=1;} lastsync_timer=sync_timer; //offsettimeus=ancsync_time-current_count*LPTIMER_LSB+offset; // SetNextPollTime(tagslotpos); } memcpy(&tx_near_msg[NEARBASEID_INDEX+singlepoll_i*2],&rx_buffer[ANCHOR_ID_IDX],2); memcpy(&temp_dist, &rx_buffer[DIST_IDX], 4); memcpy(&tx_near_msg[ANCHOR_ID_IDX], &rx_buffer[ANCHOR_ID_IDX], 4); singlepoll_basedist[singlepoll_i] = temp_dist; memcpy(&singlepoll_baseid[singlepoll_i], &rx_buffer[ANCHOR_ID_IDX], 2); if(temp_dist> 8;//????final?????????T5=T4+Treply2 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_TS_IDX], resp_rx_ts); final_msg_set_ts(&tx_near_msg[FINAL_MSG_FINAL_TX_TS_IDX], final_tx_ts); dwt_writetxdata(25, tx_near_msg, 0);//??????????§Õ??DW1000 dwt_writetxfctrl(25, 0);//?څ??????????? result=dwt_starttx(DWT_START_TX_DELAYED);//?څ??????? tag_succ_times++; if(result==0) {while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))//²»¶Ï²éѯоƬ״ֱ̬µ½·¢ËÍÍê³É { }; } /* Clear TXFRS event. */ dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);//Çå³ý±ê־λ random_delay_tim = 0; } else { // singlepoll_basedist[singlepoll_i] = 0x1ffff; random_delay_tim = DFT_RAND_DLY_TIM_MS; //Èç¹ûͨѶʧ°Ü£¬½«¼ä¸ôʱ¼äÔö¼Ó5ms£¬±Ü¿ªÒòΪ¶à±êǩͬʱ·¢ËÍÒýÆðµÄ³åÍ»¡£ } } else { // singlepoll_basedist[singlepoll_i] = 0x1ffff; dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR); random_delay_tim = DFT_RAND_DLY_TIM_MS; } delay_ms(1); } if(minddist!=0x1ffff) { trygetnearmsg_times = 0; tag_state = GETNEARMSG; mainbase_id = mindist_ancid; } if(getsync_flag==0) { // tagslotpos--; if(tagslotpos==0||tagslotpos>max_slotpos) { tagslotpos=max_slotpos; } tyncpoll_time=(tagslotpos-1)*slottime; } // mainbase_id=minid; // mainbase_id = 0x4; } u8 nearmsg_mainbase=0,rec_tagpos_emptylist[32],mainbase_type,outrange_times; void GetNearMsg(void) { u32 start_poll,frame_len; u8 nearmsg_i=0; for(nearmsg_i=0;nearmsg_i<20;nearmsg_i++) { nearbase_distlist[nearmsg_i] = 0x1ffff; } memcpy(&tx_near_msg[ANCHOR_ID_IDX],&mainbase_id,2); memcpy(&tx_near_msg[TAG_ID_IDX],&dev_id,2); tx_near_msg[MESSAGE_TYPE_IDX] = NEAR_MSG; dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS); //ÉèÖ÷¢ËÍºó¿ªÆô½ÓÊÕ£¬²¢É趨ÑÓ³Ùʱ¼ä dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS); dwt_writetxdata(12, tx_near_msg, 0);//½«Poll°üÊý¾Ý´«¸øDW1000£¬½«ÔÚ¿ªÆô·¢ËÍʱ´«³öÈ¥ dwt_writetxfctrl(12, 0);//ÉèÖó¬¿í´ø·¢ËÍÊý¾Ý³¤¶È dwt_starttx(DWT_START_TX_IMMEDIATE| DWT_RESPONSE_EXPECTED); /* We assume that the transmission is achieved correctly, poll for reception of a frame or error/timeout. See NOTE 8 below. */ while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))//²»¶Ï²éѯоƬ״ֱ̬µ½³É¹¦½ÓÊÕ»òÕß·¢Éú´íÎó { }; if(status_reg==0xffffffff) { // NVIC_SystemReset(); } if (status_reg & SYS_STATUS_RXFCG)//Èç¹û³É¹¦½ÓÊÕ { dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);//Çå³þ¼Ä´æÆ÷±ê־λ frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK; //»ñµÃ½ÓÊÕµ½µÄÊý¾Ý³¤¶È dwt_readrxdata(rx_buffer, frame_len, 0); //¶ÁÈ¡½ÓÊÕÊý¾Ý if (rx_buffer[MESSAGE_TYPE_IDX] == NEAR_MSG&&!memcmp(&rx_buffer[TAG_ID_IDX],&dev_id,2)) //ÅжϽÓÊÕµ½µÄÊý¾ÝÊÇ·ñÊÇresponseÊý¾Ý { nearbase_num=rx_buffer[NEARBASENUM_INDEX]; memcpy(&rec_tagpos_binary,&rx_buffer[NEARMSG_EMPTYSLOTPOS_INDEX],4); // tagslotpos=GetRandomSlotPos(rec_tagpos_binary); //tagslotpos=rx_buffer[TAGSLOTPOS]; memcpy(nearbaseid_list,&rx_buffer[NEARBASEID_INDEX],nearbase_num*2); memcpy(nearbaseid_list2,&rx_buffer[NEARBASEID_INDEX],nearbase_num*2); //slottime=ceil((nearbase_num+2)*0.3)+1; //tyncpoll_time=tagslotpos*slottime; //tyncpoll_time=(g_com_map[DEV_ID]%max_slotpos)*slottime; tag_state=NEARPOLL; outrange_times = 0; changemainbase_count = 0; mainbase_lost_count = 0; } }else{ // tyncpoll_time = (tagslotpos--%max_slotpos)*slottime; } } extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart2; extern UART_HandleTypeDef huart3; extern u32 basesystimer; u32 target_time=100; u8 pd_i; u32 temptime,delaytime; u16 delaycount; extern u16 slotpos_intoatl, slotpos; void NextPollDelay(u32 anchor_time) { // for(pd_i=0;pd_i<=tag_frequency;pd_i++) // { // slotpos_intoatl = pd_i*bigslot_num+tagslotpos; // temptime = (slotpos_intoatl*SLOTTIME_MS+100)*100; // if(anchor_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;} } extern float motor_keeptime; uint8_t changemainbase_count,gotosleep_flag; uint32_t frame_len; int32_t salvebase_mindist; int16_t intheight; u32 l_u32QuwbTick = 0; u32 response_timeout = 1000; extern u16 beepontime; u16 rec_maxrangelen; u16 rec_anc_signalpower[MAX_NEARBASE_ANCNUM]; extern u8 bat_percent2; char senddata[2048]; void HexToAsciiSendUDP(uint8_t* data,u8 len) { u8 i,temp; for(i=0;i>4); sprintf(&senddata[2*i+1],"%x",temp&0xf); } senddata[2*len] = 0x0d; senddata[2*len+1] = 0x0a; if(DBG_GetMode() == DBG_MODE_CFG) Uart_Send(0, (HIDO_UINT8 *) senddata, 2*len+2); //UDPClient_Uploadhex(senddata,2*len+2); } void SendHuiZongData(void) { usart_send[2] = 0x0c;//Õý³£Ä£Ê½ usart_send[3] = 15+8*(nearbase_num+1);//Êý¾Ý¶Î³¤¶È memcpy(&usart_send[4],&dev_id,2); usart_send[6] = frame_seq_nb; usart_send[7] = frame_seq_nb>>8; usart_send[8] = bat_percent2; usart_send[9] = tx_near_msg[BUTTON_IDX]; memcpy(&usart_send[10],&intheight,2); usart_send[12] = tag_frequency; usart_send[13] = tagslotpos; usart_send[14] = 0; usart_send[15] = 0; usart_send[16] = nearbase_num+1; memcpy(&usart_send[17],&mainbase_id,2); memcpy(&usart_send[19],&nearbaseid_list,2*nearbase_num); memcpy(&usart_send[19+nearbase_num*2],&nearbase_distlist,4*nearbase_num+4); memcpy(&usart_send[19+nearbase_num*6+4],&rec_anc_signalpower,2*nearbase_num+2); checksum = Checksum_u16(&usart_send[2],23+8*nearbase_num); memcpy(&usart_send[25+8*nearbase_num],&checksum,2); //USART_puts(usart_send,27+8*nearbase_num); HexToAsciiSendUDP(usart_send,27+8*nearbase_num); } struct tagpos_structure rectagpos; void NearPoll(void) { static u8 insideUWB_count = 0,outsideUWB_count = 0; uint32_t temp1,temp2,dw_systime,mindist_slavebaseid; uint32_t final_tx_time; u32 start_poll; u8 i,j,getsync_flag=0,timeout,recusrdata_flag=0; // USART_putc(current_slotnum); dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS); //ÉèÖ÷¢ËÍºó¿ªÆô½ÓÊÕ£¬²¢É趨ÑÓ³Ùʱ¼ä dwt_setrxtimeout(4000); tag_succ_times = 0; salvebase_mindist=999999; if(next_nearbase_num>=MAX_NEARBASE_NUM) { next_nearbase_num = MAX_NEARBASE_NUM-1; } // if(outsideUWB_count++>RTK_SWOPENTIME*tag_frequency&&rtk_state==0) // { // SCB->AIRCR = 0X05FA0000|(unsigned int)0x04; // } // HAL_GPIO_WritePin(LED0_GPIO, GPIO_PIN_9, GPIO_PIN_SET); recbase_num=0; tx_near_msg[BATTARY_IDX] = bat_percent2; tx_near_msg[BUTTON_IDX] = userkey_state|stationary_flag<<1|gotosleep_flag<<2; tx_near_msg[SEQUENCE_IDX] = frame_seq_nb; tx_near_msg[SEQUENCEH_IDX] = (frame_seq_nb++)>>8; tx_near_msg[NEARBASENUM_INDEX] = nearbase_num; memcpy(&tx_near_msg[NEARBASEID_INDEX],&nearbaseid_list,nearbase_num*2); memcpy(&tx_near_msg[NEARBASEID_INDEX+nearbase_num*2],&nearbase_distlist,nearbase_num*4+4); memcpy(&tx_near_msg[NEARBASEID_INDEX+nearbase_num*6+4],&rec_anc_signalpower,nearbase_num*2+2); if(intheight!=0) // intheight+=g_com_map[HEIGHTOFFEST_INDEX]; memcpy(&tx_near_msg[NEARBASEID_INDEX+nearbase_num*8+6],&intheight,2); tx_near_msg[NEARBASENUM_INDEX] = nearbase_num; memcpy(&tx_near_msg[NEARBASEID_INDEX],&nearbaseid_list,nearbase_num*2); tx_near_msg[MESSAGE_TYPE_IDX] = MBX_POLL; tx_near_msg[NEARP_TAGFREQ_INDEX] = tag_frequency; tx_near_msg[NEARP_TAGSLOTPOS_INDEX] = tagslotpos; memcpy(&tx_near_msg[ANCHOR_ID_IDX],&mainbase_id,2); dwt_writetxdata(28+8*nearbase_num, tx_near_msg, 0);//½«Poll°üÊý¾Ý´«¸øDW1000£¬½«ÔÚ¿ªÆô·¢ËÍʱ´«³öÈ¥ dwt_writetxfctrl(28+8*nearbase_num, 0);//ÉèÖó¬¿í´ø·¢ËÍÊý¾Ý³¤¶È dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED);//¿ªÆô·¢ËÍ£¬·¢ËÍÍê³ÉºóµÈ´ýÒ»¶Îʱ¼ä¿ªÆô½ÓÊÕ£¬µÈ´ýʱ¼äÔÚdwt_setrxaftertxdelayÖÐÉèÖà tx_near_msg[TAGCONFIGSUCCESS_INDEX] =0; para_update = 0; flag_finalsend=0; flag_rxon=1; flag_getresponse=0; // start_count=HAL_LPTIM_ReadCounter(&hlptim1); recbase_num=0; timeout=ceil((float)nearbase_num*SLOT_SCALE)+2; end_count=start_count+(timeout<<5); if(end_count>=32768) {end_count-=32768;} mainbase_dist=100000; mainbase_lost_count++; // current_count=HAL_LPTIM_ReadCounter(&hlptim1); l_u32QuwbTick = HIDO_TimerGetTick(); while(HIDO_TimerGetTick()-l_u32QuwbTick<5) { while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR)))//²»¶Ï²éѯоƬ״ֱ̬µ½³É¹¦½ÓÊÕ»òÕß·¢Éú´íÎó { if(HIDO_TimerGetTick()-l_u32QuwbTick>5) break; }; if(status_reg==0xffffffff) { // NVIC_SystemReset(); } if (status_reg & SYS_STATUS_RXFCG)//Èç¹û³É¹¦½ÓÊÕ { dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG | SYS_STATUS_TXFRS);//Çå³þ¼Ä´æÆ÷±ê־λ frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFLEN_MASK; //»ñµÃ½ÓÊÕµ½µÄÊý¾Ý³¤¶È dwt_readrxdata(rx_buffer, frame_len, 0); //¶ÁÈ¡½ÓÊÕÊý¾Ý dwt_setrxtimeout(0);//É趨½ÓÊÕ³¬Ê±Ê±¼ä£¬0λûÓг¬Ê±Ê±¼ä dwt_rxenable(0);//´ò¿ª½ÓÊÕ if (rx_buffer[MESSAGE_TYPE_IDX] == NEAR_RESPONSE&&!memcmp(&rx_buffer[TAG_ID_IDX],&dev_id,2)) //ÅжϽÓÊÕµ½µÄÊý¾ÝÊÇ·ñÊÇresponseÊý¾Ý { u16 rec_nearbaseid,rec_nearbasepos; poll_tx_ts = get_tx_timestamp_u64(); //»ñµÃPOLL·¢ËÍʱ¼äT1 resp_rx_ts = get_rx_timestamp_u64(); //»ñµÃRESPONSE½ÓÊÕʱ¼äT4 recbase_num++; memcpy(&rec_nearbaseid,&rx_buffer[ANCHOR_ID_IDX],2); if(rec_nearbaseid==mainbase_id) { //////////////////////////////////ʱ¼äͬ²½ memcpy(&sync_timer,&rx_buffer[ANCTIMEMS],2); memcpy(&tmp_time,&rx_buffer[ANCTIMEUS],2); // current_count=HAL_LPTIM_ReadCounter(&hlptim1); dwt_forcetrxoff(); final_tx_time = (resp_rx_ts + ((RESP_RX_TO_FINAL_TX_DLY_UUS) * UUS_TO_DWT_TIME)) >> 8; 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+nearbase_num*4], 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; rec_remotepara_state=rx_buffer[MOTORSTATE_INDEX]>>4; if(rec_remotepara_state&&!memcmp(&rx_buffer[TAG_ID_IDX],&dev_id,2)) { para_update = 1; tx_near_msg[TAGCONFIGSUCCESS_INDEX] = 1; para_len = frame_len-22; memcpy(rec_remotepara,&rx_buffer[REMOTEPARA_INDEX],para_len); } 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);//É趨ΪÑÓ³Ù·¢ËÍ userkey_state = !GET_USERKEY; memcpy(&temp_dist,&rx_buffer[DIST_IDX],4); temp_dist+=(int16_t)g_com_map[DIST_OFFSET]; mainbase_dist=temp_dist; nearbase_distlist[0] = temp_dist; if((rx_buffer[MOTORSTATE_INDEX]&0xf)!=3) motor_state=rx_buffer[MOTORSTATE_INDEX]&0xf; if(frame_len==28) { memcpy(&rec_maxrangelen,&rx_buffer[MAXRANGE_DISTANCE],2); memcpy(&rec_anc_signalpower[0],&rx_buffer[ANC_SIGNALPOWER],2); if(mainbase_dist>rec_maxrangelen&&mainbase_dist>0&&rec_maxrangelen!=0) { if(outrange_times++>OUTRANGE_RESTARTTIMES) { tag_state = DISCPOLL; } }else{ outrange_times = 0; } } if(frame_len>28) { if(rx_buffer[TAGPOS_LEN_INDEX]<=55) { memcpy(&rectagpos,&rx_buffer[TAGPOS_INDEX],rx_buffer[TAGPOS_LEN_INDEX]+3); recusrdata_flag = 1; } } if(temp_dist!=0x1ffff) mainbase_lost_count=0; flag_finalsend=1; memcpy(&mainbase_dist,&rx_buffer[DIST_IDX],4); flag_getresponse=1; //ʱ¼äͬ²½ //ancsync_time=((sync_timer)*1000+tmp_time); // basesystimer = sync_timer; // tmp_time=tmp_time+650; // if(tmp_time>999) // { // tmp_time-=999; // basesystimer++; // if(basesystimer>=1000) // {basesystimer=0;} // } // TIM3->CNT=tmp_time; // current_slotnum=(sync_timer-0)/g_com_map[COM_INTERVAL]; // NextPollDelay(ancsync_time); if(result==0) {while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))//²»¶Ï²éѯоƬ״ֱ̬µ½·¢ËÍÍê³É {if(HIDO_TimerGetTick()-l_u32QuwbTick>5) break; };} break; }else{ rec_nearbasepos=FindNearBasePos(rec_nearbaseid); exsistbase_list[rec_nearbasepos]=KEEP_TIMES; memcpy(&temp_dist,&rx_buffer[DIST_IDX],4); temp_dist+=(int16_t)g_com_map[DIST_OFFSET]; if(frame_len==28) memcpy(&rec_anc_signalpower[rec_nearbasepos+1],&rx_buffer[ANC_SIGNALPOWER],2); memcpy(&nearbase_switchdistlist[rec_nearbasepos],&rx_buffer[NR_NEARSWITCH_DISTANCE],2); nearbase_distlist[rec_nearbasepos+1]=temp_dist; final_msg_set_ts(&tx_near_msg[FINAL_MSG_RESP_RX_NEARBASE_IDX+(rec_nearbasepos)*4], resp_rx_ts); if(temp_distRTK_SWCLOSETIME*tag_frequency) { // CloseRTK4G(); } }else{ insideUWB_count = 0; } } #ifdef SWITCHBASE_ZHUANDIAN if(temp_dist1&&temp_dist>0) { changemainbase_count = 0; mainbase_id = rec_nearbaseid; trygetnearmsg_times = 0; tag_state = GETNEARMSG; } #endif } } }else{ dwt_write32bitreg(SYS_STATUS_ID,SYS_STATUS_RXFCG| SYS_STATUS_ALL_RX_ERR); if(recbase_num!=nearbase_num+1) {dwt_rxenable(0); } // if(flag_rxon) // { // dwt_rxenable(0); // } } // dwt_write32bitreg(SYS_STATUS_ID,SYS_STATUS_RXFCG| SYS_STATUS_ALL_RX_ERR); } if(flag_finalsend!=1) {flag_finalsend = 2;} dwt_forcetrxoff(); dwt_write32bitreg(SYS_STATUS_ID,SYS_STATUS_RXFCG| SYS_STATUS_ALL_RX_ERR); if(mainbase_lost_count==0) { #ifdef SWITCHBASE_DIST if(salvebase_mindist2) { mainbase_id = mindist_slavebaseid; trygetnearmsg_times = 0; tag_state = GETNEARMSG; } }else{ changemainbase_count = 0; } #endif }else if(mainbase_lost_count>5) { tag_state = DISCPOLL; } if(para_update) { uint8_t pack_length = 0,pack_index = 0,pack_msgtype = 0; pack_msgtype = rec_remotepara[0]; pack_index = rec_remotepara[1]; pack_length = rec_remotepara[2]; if(pack_msgtype==2) { if( pack_index == RTKCTRL_INDEX) { if(rec_remotepara[3]==1&&rtk_state == 0) { OpenRTK4G(); } if(rec_remotepara[3]==0&&rtk_state == 1) { CloseRTK4G(); } }else if( pack_index == MOTOR_ONTIME_INDEX) { // if(motor_keeptime==0) // motor_keeptime = rec_remotepara[3]; if(beepontime==0) beepontime = rec_remotepara[3]; }else{ if(pack_index<200) { if(pack_index==0x60) { tag_state = REGPOLL; }else{ memcpy((uint8_t*)&g_com_map + pack_index, &rec_remotepara[3], pack_length); //·µ»ØÒ»¸öerror״̬ //SendComMap(pack_datalen,pack_index); save_com_map_to_flash(); printf("%s URTRestart",__debug_info__); URTRestart(); } } } } } for(i=0;i999) { tmp_time-=999; basesystimer++; if(basesystimer>=1000) {basesystimer=0;} } TIM3->CNT=tmp_time; //tag_frequency = 1000 / g_com_map[COM_INTERVAL]; bigslot_num = TOTAL_SLOTNUM/tag_frequency; // NextPollDelay(ancsync_time); // SetNextPollTime(tagslotpos); mainbase_id=rec_nearbaseid; nearbase_num=rx_buffer[NEARBASENUM_INDEX]; memcpy(nearbaseid_list,&rx_buffer[NEARBASEID_INDEX],nearbase_num*2); memcpy(nearbaseid_list2,&rx_buffer[NEARBASEID_INDEX],nearbase_num*2); if(tagslotpos==255) { tagslotpos = basesystimer%bigslot_num; } tyncpoll_time=tagslotpos*slottime; //ʱ϶ϵÄʱ¼ä tag_state = DISCPOLL; } }else{ tyncpoll_time=(tagslotpos--%max_slotpos)*slottime; dwt_write32bitreg(SYS_STATUS_ID,SYS_STATUS_RXFCG| SYS_STATUS_ALL_RX_ERR); } } u32 id,error_times=0,uwbstatus_reg; u8 test3; void UWB_Wkup(void) { SPIx_CS_GPIO->BSRR = SPIx_CS<<16; delay_us(1000); SPIx_CS_GPIO->BSRR = SPIx_CS; id = dwt_readdevid() ; while (DWT_DEVICE_ID != id) { id = dwt_readdevid() ; } uwbstatus_reg = dwt_read32bitreg(CHAN_CTRL_ID) ; if(uwbstatus_reg != 0x4A7A0022) { Dw1000_Init(); } } void Tag_App(void)//·¢ËÍģʽ(TAG±êÇ©) { //LED0_ON; UWB_Wkup(); switch(tag_state) { case REGPOLL: // LED_LG_ON; Registor_Poll(); // LED_LG_OFF;s break; case DISCPOLL: // LED_LG_ON; Poll(); // LED_LG_OFF; break; case GETNEARMSG: trygetnearmsg_times++; // LED_LG_ON; GetNearMsg(); // LED_LG_OFF; if(trygetnearmsg_times>5) { tag_state = DISCPOLL; } break; case NEARPOLL: NearPoll(); break; case SINGLEPOLL: Poll(); break; } SetNextPollTime(tyncpoll_time); dwt_entersleep(); // UWBLED_BLINK; userkey_state = 0; // if(test3) // { // test3 = 0; // CloseRTK4G(); // } }