/*! ---------------------------------------------------------------------------- * @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 "CRC.h" #include "dw_mbx_anc.h" #include "ADC.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 //#define _UWB_4G static dwt_config_t config = { #ifdef _UWB_4G 2, /* Channel number. */ #else 5, #endif 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; 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; //²â¾àÓõĵÍͨÂ˲¨Æ÷ float range_lost_time = 0; 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 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 /* Apply default antenna delay value. See NOTE 1 below. */ dwt_setrxantennadelay(RX_ANT_DLY); //ÉèÖýÓÊÕÌìÏßÑÓ³Ù dwt_settxantennadelay(TX_ANT_DLY); //ÉèÖ÷¢ÉäÌìÏßÑÓ³Ù } 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; iBRR = SPIx_CS; delay_us(600); SPIx_CS_GPIO->BSRR = SPIx_CS; id = dwt_readdevid() ; while (0xDECA0130!=id) { u8 iderror_count = 0; id = dwt_readdevid() ; if(iderror_count++>100) { printf("UWBоƬID´íÎó"); break; } } } #include "radio.h" #include "dw_mbx_anc.h" u8 lora_start_poll_buff[4] = {LORA_MSGTYPE_RANGEPOLL,'I','N','G'}; uint16_t current_count,target_count; typedef enum{ Next_Poll_RANGE, Next_Poll_LORASYNC, }nextpoll_enum; #define UWB 0 #define LORA 1 static uint8_t lora_sendbuffer[40]; static uint16_t wg_report_id=0xffff; uint8_t seq_num; static u16 checksum; #define SEQNUM_IDX 6 //±êÇ©±¨ÎÄÐòºÅ #define BAT_IDX 7 //±êÇ©µçÁ¿ #define STATE_IDX 8 #define ANCID_IDX 30 //УÑéÔÚ4*ancnum+ANCID_IDX λÖà #define LORA5_CHANNEL_FRQ 484 #define LORA5_CHANNEL_SF 7 uint8_t poll_state; void Lora_Poll(void) { SwitchLoraSettings(LORA5_CHANNEL_FRQ,LORA5_CHANNEL_SF,22); lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_TAGMSGTOWG_GPS; lora_sendbuffer[MSG_LENGTH] = 30; memcpy(&lora_sendbuffer[SOURCE_ID_IDX],&g_com_map[DEV_ID],2); memcpy(&lora_sendbuffer[DEST_ID_IDX],&wg_report_id,2); lora_sendbuffer[SEQNUM_IDX] = seq_num++; lora_sendbuffer[BAT_IDX] = bat_percent; lora_sendbuffer[STATE_IDX] = 0; // memcpy(&lora_sendbuffer[GPS_JINGDU_IDX],&gps_jingdu,8); // memcpy(&lora_sendbuffer[GPS_WEIDU_IDX],&gps_jingdu,8); // lora_sendbuffer[GPS_STATE_IDX] = gps_state; // lora_sendbuffer[GPS_SATEL_NUM_IDX] = gps_satel_num; // lora_sendbuffer[GPS_SPOWER_IDX] = gps_signalpower; // lora_sendbuffer[GPS_CHAFENLINGQI] = gps_chafenlingqi; // lora_sendbuffer[ANCNUM_IDX] = report_ancnum; // memcpy(&lora_sendbuffer[ANCID_IDX],report_ancid,report_ancnum*2); // memcpy(&lora_sendbuffer[ANCID_IDX+report_ancnum*2],report_ancdist,report_ancnum*2); checksum = Checksum_u16(lora_sendbuffer,4*0+ANCID_IDX); memcpy(&lora_sendbuffer[ANCID_IDX+0*4],&checksum,2); Radio.Send(lora_sendbuffer,ANCID_IDX+0*4+2); } nextpoll_enum next_poll_state; extern uint8_t sync_lost_count; extern uint8_t Lorahuifu_flag; extern int16_t intheight; extern u16 uwbdistance; void Tag_App(void)//·¢ËÍģʽ(TAG±êÇ©) { // SyncStateSwitch(); if(poll_state==UWB) //¶ÁÈ¡±¾´ÎµÄ¹¤×÷״̬ ²â¾à»¹ÊÇͬ²½ { poll_state=LORA; current_count=HAL_LPTIM_ReadCounter(&hlptim1); // g_com_map[LORA_POWER]=22; // g_com_map2[LORA_POWER]=22; SwitchLoraSettings(UWB_CHANNEL_FRQ+g_com_map[GROUP_ID],5,g_com_map[LORA_POWER]); //Çл»lora½ÓÊÕÆµµã memcpy(&lora_start_poll_buff[ANC_ID_IDX],&g_com_map[DEV_ID],2); Radio.Send(lora_start_poll_buff, 4); UWB_Wkup(); delay_us(700); MBXANCPoll(); dwt_entersleep(); // next_poll_state = Next_Poll_LORASYNC; }else{ poll_state=UWB; Lora_Poll(); if(intheight!=0) printf("¸ß¶ÈÖµ:%d\r\n",intheight); if(uwbdistance!=0) printf("UWB²â¾àÖµ:%d\r\n",uwbdistance); if(Lorahuifu_flag) { Lorahuifu_flag=0; printf("ÊÕµ½Íø¹Ø»Ø¸´,LORA³É¹¦\r\n"); } // LoraSyncRecPoll(); // if(GetRangeState()) //»ñÈ¡µ±Ç°²â¾à״̬£¬ÊÇ·ñ¿ªÆô¡£Èç¹û¿ªÆôÏ´ÎΪ²â¾à£¬·ñΪͬ²½ // { // next_poll_state = Next_Poll_RANGE; // }else{ // next_poll_state = Next_Poll_LORASYNC; // } } // Radio.Sleep(); // if(next_poll_state == Next_Poll_LORASYNC) //É趨ÏÂÒ»´ÎµÄ»½ÐÑʱ¼ä // { //// if(sync_state==Sync_Lost) //// { //// target_count = GetLoraSyncCount()-(18000)/LPTIMER_LSB+sync_lost_count*1000; //// }else // { // target_count = GetLoraSyncCount()-(18000)/LPTIMER_LSB; //±ÈÉÏ´ÎÊÕµ½µÄloraÌáǰ17ms»½ÐÑ£¨lora½ÓÊÕ´ó¸Å17ms£©£¬Èç¹ûÔÚͬ²½¼ä¸ôÄÚ£¬Ôò»á¿ìËÙ½øÈëÐÝÃß¡£ // } // if(target_count<0) // target_count+=32768; // __HAL_LPTIM_COMPARE_SET(&hlptim1, target_count); // }else{ // target_count = GetUwbPollCount(); //²â¾àÌáǰ2ms»½ÐÑ // __HAL_LPTIM_COMPARE_SET(&hlptim1, target_count); // } }