From bc733eb48e920478f281a97881aeb229c4af2235 Mon Sep 17 00:00:00 2001 From: David <stierint@hotmail.com> Date: Sun, 27 Sep 2020 22:06:52 -0400 Subject: [PATCH] added TDMA subnetwork frame sync --- DecaRanging.coproj | 20 +- src/application/application_definitions.h | 11 +- src/application/instance.c | 18 +- src/application/instance_common.c | 2 +- src/application/tdma_handler.c | 240 +++++++++++++++++++--- src/application/tdma_handler.h | 4 + 6 files changed, 248 insertions(+), 47 deletions(-) diff --git a/DecaRanging.coproj b/DecaRanging.coproj index ad9877d..6c9e7cf 100644 --- a/DecaRanging.coproj +++ b/DecaRanging.coproj @@ -105,8 +105,8 @@ <File name="src/platform/deca_spi.h" path="src/platform/deca_spi.h" type="1"/> <File name="Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c" path="Libraries/STM32_USB_Device_Library/Core/src/usbd_ioreq.c" type="1"/> <File name="Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c" path="Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c" type="1"/> - <File name="src/usb/usbd_desc.h" path="src/usb/usbd_desc.h" type="1"/> <File name="Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h" path="Libraries/STM32_USB_Device_Library/Class/cdc/inc/usbd_cdc_core.h" type="1"/> + <File name="src/usb/usbd_desc.h" path="src/usb/usbd_desc.h" type="1"/> <File name="src/platform/deca_spi.c" path="src/platform/deca_spi.c" type="1"/> <File name="src/usb" path="" type="2"/> <File name="src/decadriver/deca_version.h" path="src/decadriver/deca_version.h" type="1"/> @@ -137,12 +137,12 @@ <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h" type="1"/> <File name="src/decadriver/deca_device.c" path="src/decadriver/deca_device.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_exti.c" type="1"/> - <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_adc.h" type="1"/> + <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_req.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_fsmc.c" type="1"/> - <File name="src/usb/usb_conf.h" path="src/usb/usb_conf.h" type="1"/> <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_otg.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_otg.h" type="1"/> + <File name="src/usb/usb_conf.h" path="src/usb/usb_conf.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c" type="1"/> <File name="Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c" path="Libraries/STM32_USB_Device_Library/Core/src/usbd_req.c" type="1"/> <File name="src/usb/usbd_conf.h" path="src/usb/usbd_conf.h" type="1"/> @@ -163,26 +163,26 @@ <File name="Libraries/STM32_USB_Device_Library/Core/src" path="" type="2"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_i2c.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/misc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/misc.c" type="1"/> - <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h" type="1"/> <File name="Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c" path="Libraries/STM32_USB_OTG_Driver/src/usb_hcd.c" type="1"/> + <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_cec.h" type="1"/> <File name="src/application/main.c" path="src/main.c" type="1"/> <File name="src/platform/deca_sleep.c" path="src/platform/deca_sleep.c" type="1"/> - <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_defines.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_defines.h" type="1"/> <File name="Libraries/CMSIS/CM3/CoreSupport" path="" type="2"/> - <File name="Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c" path="Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c" type="1"/> - <File name="src/compiler" path="" type="2"/> + <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_defines.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_defines.h" type="1"/> <File name="src/decadriver/deca_param_types.h" path="src/decadriver/deca_param_types.h" type="1"/> + <File name="src/compiler" path="" type="2"/> + <File name="Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c" path="Libraries/STM32_USB_OTG_Driver/src/usb_dcd_int.c" type="1"/> <File name="src/usb/deca_usb_bsp_evk1000.c" path="src/usb/deca_usb_bsp_evk1000.c" type="1"/> <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/startup_stm32f10x_cl.S" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/startup_stm32f10x_cl.S" type="1"/> - <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h" type="1"/> <File name="src/platform/stm32f10x_conf.h" path="src/platform/stm32f10x_conf.h" type="1"/> + <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h" type="1"/> <File name="Libraries/CMSIS/CM3" path="" type="2"/> <File name="Libraries" path="" type="2"/> <File name="src/decadriver/deca_types.h" path="src/decadriver/deca_types.h" type="1"/> <File name="src/usb/deca_usb.h" path="src/usb/deca_usb.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/inc" path="" type="2"/> - <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h" type="1"/> <File name="Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h" path="Libraries/STM32_USB_Device_Library/Core/inc/usbd_def.h" type="1"/> + <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_spi.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_iwdg.h" type="1"/> <File name="src/platform/stm32f10x_it.c" path="src/platform/stm32f10x_it.c" type="1"/> <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c" path="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c" type="1"/> @@ -216,8 +216,8 @@ <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup" path="" type="2"/> <File name="Libraries/STM32_USB_OTG_Driver/inc/usb_core.h" path="Libraries/STM32_USB_OTG_Driver/inc/usb_core.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_bkp.c" type="1"/> - <File name="src/application/dw_main.c" path="src/application/dw_main.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c" type="1"/> + <File name="src/application/dw_main.c" path="src/application/dw_main.c" type="1"/> <File name="src/platform" path="" type="2"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_tim.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_i2c.h" type="1"/> diff --git a/src/application/application_definitions.h b/src/application/application_definitions.h index 501a5ee..18cec85 100644 --- a/src/application/application_definitions.h +++ b/src/application/application_definitions.h @@ -172,11 +172,12 @@ enum //INF message byte offsets #define TDMA_TSFS 1+6 // offset to put time since TDMA frame start in the INF message -#define TDMA_NUMN 7+6 // offset to put the number of this UWB's neighbors in the INF message -#define TDMA_NUMH 8+6 // offset to put the number of this UWB's hidden neighbors in the INF message -#define TDMA_FRAMELENGTH 9+6 // offset to put this UWB's TDMA framelength in the INF message -#define TDMA_NUMS 10+6 // offset to put the number of this UWB's TDMA slot assignments in the INF message - +#define TDMA_TSFS_REBASE 7+6 // offset to put whether the receiving UWB needs to rebase its TDMA frame to the transmitted TSFS +#define TDMA_NUMN 8+6 // offset to put the number of this UWB's neighbors in the INF message +#define TDMA_NUMH 9+6 // offset to put the number of this UWB's hidden neighbors in the INF message +#define TDMA_FRAMELENGTH 10+6 // offset to put this UWB's TDMA framelength in the INF message +#define TDMA_NUMS 11+6 // offset to put the number of this UWB's TDMA slot assignments in the INF message +//TODO remove the +6 from above! // Final message byte offsets. #define PTXT 1 diff --git a/src/application/instance.c b/src/application/instance.c index b4abab2..c563f56 100644 --- a/src/application/instance.c +++ b/src/application/instance.c @@ -859,7 +859,6 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess //update time since frame start! tdma_handler->update_inf_tsfs(tdma_handler); - //response is not expected inst->wait4ack = 0; @@ -879,6 +878,7 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess tdma_handler->set_discovery_mode(tdma_handler, EXIT, portGetTickCnt()); inst->mode = ANCHOR; + // uint8 debug_msg[100]; // int n = sprintf((char *)&debug_msg, "TX_INF_SUG,%llX,NULL", instance_get_addr()); // send_usbmessage(&debug_msg[0], n); @@ -908,6 +908,11 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess memcpy(&inst->inf_msg.messageData[FCODE], &fcode, sizeof(uint8)); } + if(tdma_handler->rebase_pending == TRUE) + { + tdma_handler->rebase_tx = TRUE; + } + inst->timeofTx = portGetTickCnt(); inst->testAppState = TA_TX_WAIT_CONF ; //TODO should only do this if we don't have a problem with the INF send... inst->previousState = TA_TXINF_WAIT_SEND ; @@ -1526,7 +1531,7 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess if(tdma_handler->discovery_mode == WAIT_INF_REG) //treat INF_UPDATE and INF_SUG the same { - //synchronize the frames + //synchronize the frames //TODO don't need to sync frame at this point...? tdma_handler->frame_sync(tdma_handler, dw_event, messageData, srcIndex, FS_ADOPT); // //initialize collection of tdma info, clear any previously stored info tdma_handler->process_inf_msg(tdma_handler, messageData, srcIndex, CLEAR_ALL_COPY); @@ -1535,7 +1540,14 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess } else if(tdma_handler->discovery_mode == COLLECT_INF_REG) { - //TODO for some reason, it seems like the frame start time is way off with this... fix it! + //TODO handle the case where we are collecting from two different UWB networks that are not synchronized + //in case there are multiple subnetworks... only collect average frame start times for one of them... + //send out INF_SUG in that 0th frame with rebase to the other subnetwork's frame. but what if there are two other networks? + //instead send out INF fug in that 0th frame with rebase to that frame. Hopefully the other networks will get the message. + //if not, the discrepency will eventually be taken care of the ANCHOR and TAG logic, regarless of how many subnetworks there are. + //sync to the largest subnetwork... + + //TODO don't need to sync frame while collecting? //synchronize the frames tdma_handler->frame_sync(tdma_handler, dw_event, messageData, srcIndex, FS_AVERAGE); diff --git a/src/application/instance_common.c b/src/application/instance_common.c index 8734a0b..93c3308 100644 --- a/src/application/instance_common.c +++ b/src/application/instance_common.c @@ -1836,7 +1836,7 @@ int instance_run(void) //TODO could also have a timer to put into DISCOVERY if we haven't spoken to anyone in a while uint32 time_now = portGetTickCnt(); - uint32 delat_t = get_dt32(instance_data[instance].lastCommTimeStamp[i], time_now); + uint32 delta_t = get_dt32(instance_data[instance].lastCommTimeStamp[i], time_now); // if(instance_data[instance].lastCommTimeStamp[i] + UWB_COMM_TIMEOUT < portGetTickCnt()) //TODO handle number wrapping if(delta_t > UWB_COMM_TIMEOUT) //TODO handle number wrapping { diff --git a/src/application/tdma_handler.c b/src/application/tdma_handler.c index 2b4e00e..d384b5c 100644 --- a/src/application/tdma_handler.c +++ b/src/application/tdma_handler.c @@ -38,6 +38,11 @@ static bool slot_transition(struct TDMAHandler *this) // send_usbmessage(&debug_msg[0], n); // usb_run(); + //TODO think about adopting rebase AFTER all neighbors have had a chance to TX the rebase in their INF message as well. + this->rebase_pending = FALSE; + this->rebase_tx = FALSE; + this->uwbFrameStartTimes64[0] = this->rebase_frameStartTime64; + timeSinceFrameStart64 = get_dt64(this->uwbFrameStartTimes64[0], time_now_us); } while(timeSinceFrameStart64 >= frameDuration64) @@ -119,6 +124,12 @@ static bool slot_transition(struct TDMAHandler *this) //static void frame_sync(struct TDMAHandler *this, uint8 *messageData, uint16 rxLength, uint8 srcIndex, FRAME_SYNC_MODE mode) static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 *messageData, uint8 srcIndex, FRAME_SYNC_MODE mode) { + //ignore frame sync if we have a rebase pending + if(this->rebase_pending == TRUE) + { + return; + } + instance_data_t *inst = instance_get_local_structure_ptr(0); uint8 sys_time_arr[5] = {0, 0, 0, 0, 0}; @@ -128,11 +139,12 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 * uint8 framelength; uint32 timeSinceFrameStart64 = 0; + bool rebase = FALSE; - memcpy(&framelength, &messageData[TDMA_FRAMELENGTH], 1); + memcpy(&framelength, &messageData[TDMA_FRAMELENGTH], sizeof(uint8)); //timeSinceFrameStart in message - memcpy(&timeSinceFrameStart64, &messageData[TDMA_TSFS], 6); - + memcpy(&timeSinceFrameStart64, &messageData[TDMA_TSFS], sizeof(uint64)); + memcpy(&rebase, &messageData[TDMA_TSFS_REBASE], sizeof(bool)); //time from message to tx //assuming zero since we use DWT_START_TX_IMMEDIATE @@ -141,7 +153,6 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 * uint64 tx_antenna_delay = (uint64)inst->txAntennaDelay; //time for xmission (only count once, happens on both sides near simultaneously) - //TODO make sure this is correct... //easiest way to check would be to see if it is the same as the defines for other standard messages... inst->frameLengths_us[INF] = instance_getmessageduration_us(dw_event->rxLength); //TODO should maybe make sure extended framelength cannot overflow a uint32 @@ -165,11 +176,40 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 * uint8 slot = hisTimeSinceFrameStart_us/this->slotDuration_us; //integer division rounded down this->lastSlotStartTime64 = this->uwbFrameStartTimes64[0] + (uint64)((this->slotDuration_us)*slot); } +// else if(mode == FS_REBASE) +// { +// this->rebase_pending = TRUE; +// this->rebase_tx = FALSE; +// this->rebase_frameStartTime = this->uwbFrameStartTimes64[srcIndex]; +// } else if(mode == FS_AVERAGE) //TODO consider using a weighted average. perhaps use threshholds to determine if instead we should just use the ADOPT logic { +// if(this->discovery_mode == COLLECT_INF_REG) +// { +// //TODO handle the case where we are collecting from two different UWB networks that are not synchronized +// //in case there are multiple subnetworks... only collect average frame start times for one of them... +// //send out INF_SUG in that 0th frame with rebase to the other subnetwork's frame. but what if there are two other networks? +// //instead send out INF fug in that 0th frame with rebase to that frame. Hopefully the other networks will get the message. +// //if not, the discrepency will eventually be taken care of the ANCHOR and TAG logic, regarless of how many subnetworks there are. +// //sync to the largest subnetwork... +// } + + + if(rebase == TRUE) + { + this->rebase_pending = TRUE; + this->rebase_tx = FALSE; + this->rebase_frameStartTime64 = this->uwbFrameStartTimes64[srcIndex]; + return; + } + uint64 myFramelengthDuration_us = this->uwbListTDMAInfo[0].framelength*this->slotDuration_us; uint64 myTimeSinceFrameStart_us = get_dt64(this->uwbFrameStartTimes64[0], time_now_us); + uint64 diff_us = 0; + bool diff_add = FALSE; + uint64 threshold = this->slotStartDelay_us; //TODO make a permanent variable for this threshold + //TODO make sure this can't/doesn't happen //myTimeSinceFrameStart is longer than the FramelengthDuration!!! // if(myTimeSinceFrameStart > myFramelengthDuration) @@ -186,17 +226,20 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 * if(myTimeSinceFrameStart_us > hisTimeSinceFrameStartMod_us) { - uint64 diff_us = myTimeSinceFrameStart_us - hisTimeSinceFrameStartMod_us; + diff_us = myTimeSinceFrameStart_us - hisTimeSinceFrameStartMod_us; + diff_add = TRUE; - this->uwbFrameStartTimes64[0] = timestamp_add64(this->uwbFrameStartTimes64[0], diff_us/2); - this->lastSlotStartTime64 = timestamp_add64(this->lastSlotStartTime64, diff_us/2); +// uint64 diff_us = myTimeSinceFrameStart_us - hisTimeSinceFrameStartMod_us; +// this->uwbFrameStartTimes64[0] = timestamp_add64(this->uwbFrameStartTimes64[0], diff_us/2); +// this->lastSlotStartTime64 = timestamp_add64(this->lastSlotStartTime64, diff_us/2); } else { - uint64 diff_us = hisTimeSinceFrameStartMod_us - myTimeSinceFrameStart_us; - - this->uwbFrameStartTimes64[0] = timestamp_subtract64(this->uwbFrameStartTimes64[0], diff_us/2); - this->lastSlotStartTime64 = timestamp_subtract64(this->lastSlotStartTime64, diff_us/2); + diff_us = hisTimeSinceFrameStartMod_us - myTimeSinceFrameStart_us; + diff_add = FALSE; +// uint64 diff_us = hisTimeSinceFrameStartMod_us - myTimeSinceFrameStart_us; +// this->uwbFrameStartTimes64[0] = timestamp_subtract64(this->uwbFrameStartTimes64[0], diff_us/2); +// this->lastSlotStartTime64 = timestamp_subtract64(this->lastSlotStartTime64, diff_us/2); } } else @@ -215,20 +258,47 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 * if(hisTimeSinceFrameStart_us > myTimeSinceFrameStartMod_us) { - uint64 diff_us = hisTimeSinceFrameStart_us - myTimeSinceFrameStartMod_us; + diff_us = hisTimeSinceFrameStart_us - myTimeSinceFrameStartMod_us; + diff_add = FALSE; - this->uwbFrameStartTimes64[0] = timestamp_subtract64(this->uwbFrameStartTimes64[0], diff_us/2); - this->lastSlotStartTime64 = timestamp_subtract64(this->lastSlotStartTime64, diff_us/2); +// uint64 diff_us = hisTimeSinceFrameStart_us - myTimeSinceFrameStartMod_us; +// this->uwbFrameStartTimes64[0] = timestamp_subtract64(this->uwbFrameStartTimes64[0], diff_us/2); +// this->lastSlotStartTime64 = timestamp_subtract64(this->lastSlotStartTime64, diff_us/2); } else { - uint64 diff_us = myTimeSinceFrameStartMod_us - hisTimeSinceFrameStart_us; + diff_us = myTimeSinceFrameStartMod_us - hisTimeSinceFrameStart_us; + diff_add = TRUE; + +// uint64 diff_us = myTimeSinceFrameStartMod_us - hisTimeSinceFrameStart_us; +// this->uwbFrameStartTimes64[0] = timestamp_add64(this->uwbFrameStartTimes64[0], diff_us/2); +// this->lastSlotStartTime64 = timestamp_add64(this->lastSlotStartTime64, diff_us/2); + } + } + + //if the difference is too large, we need to rebase our frame start time + if(diff_us > threshold) + { + this->rebase_pending = TRUE; + this->rebase_tx = FALSE; + this->rebase_frameStartTime64 = this->uwbFrameStartTimes64[srcIndex]; + } + else + { + if(diff_add == TRUE) + { this->uwbFrameStartTimes64[0] = timestamp_add64(this->uwbFrameStartTimes64[0], diff_us/2); this->lastSlotStartTime64 = timestamp_add64(this->lastSlotStartTime64, diff_us/2); } + else + { + this->uwbFrameStartTimes64[0] = timestamp_subtract64(this->uwbFrameStartTimes64[0], diff_us/2); + this->lastSlotStartTime64 = timestamp_subtract64(this->lastSlotStartTime64, diff_us/2); + } } } + } @@ -610,6 +680,8 @@ static void update_inf_tsfs(struct TDMAHandler *this) memcpy(&inst->inf_msg.messageData[1], &tsinf, 6); this->lastINFtx = time_now_us; + //indicate whether the TSFS being transmitted is a rebase. + memcpy(&inst->inf_msg.messageData[TDMA_TSFS_REBASE], &this->rebase_pending, sizeof(bool)); // uint8 debug_msg[100]; // int n = sprintf((char *)&debug_msg, "TSFS %llu", timeSinceFrameStart64 ); @@ -2298,27 +2370,130 @@ static void set_discovery_mode(struct TDMAHandler *this, DISCOVERY_MODE discover //find common frame start time among neighbors instance_data_t *inst = instance_get_local_structure_ptr(0); + //need to modify this. + //need to discriminate between different subnetworks. + //count the number of UWBs that belong to each subnetwork + //select the subnetwork with the largest number of UWBs + //find the common frame start time among the UWBs in that network + //if subnetworks do indeed exist, set the appropriate rebase variables here and in our inf_message + + //keep track of which number each UWB belongs to + //then keep track of which was selected so we can iterate over it later in this function + uint8 num_sub_networks = 0; + uint8 sub_network_membership[UWB_LIST_SIZE] = {0}; + uint8 sub_network_selected = 0; + uint8 sub_network_members[UWB_LIST_SIZE-1] = {0}; //cannot be more subnetworks than other UWBs + uint64 sub_network_tsfs[UWB_LIST_SIZE-1] = {0}; + uint8 sub_network_base_framelength[UWB_LIST_SIZE-1] = {0}; //TODO handle number wrapping uint64 time_now_us = portGetTickCntMicro(); uint64 tcommon; uint64 shortestFrameDuration = this->maxFramelength*this->slotDuration_us; -// uint32 tcommon; -// uint32 shortestFrameDuration = this->maxFramelength*this->slotDuration_ms; - uint8 numNeighbors = instfindnumactiveneighbors(inst); -// uint32 tnext[numNeighbors]; -// uint32 latest_tnext; - uint64 tnext[numNeighbors]; + + + + for(int i=1; i < inst->uwbListLen; i++) //zero reserved for self + { + if(inst->uwbListType[i] != UWB_LIST_NEIGHBOR) + { + continue; //TODO consider a way to accoutn for hidden and twice hidden to determine which netowrk is larger + } + + struct TDMAInfo *info_i = &this->uwbListTDMAInfo[i]; + uint64 framelengthDuration_us = info_i->framelength*this->slotDuration_us; + uint64 timeSinceFrameStart_us = get_dt64(this->uwbFrameStartTimes64[i], time_now_us); + + //test the ith UWB against the jth subnetwork + for(int j=0; j < num_sub_networks; j++) + { + uint64 diff_us = 0; + + if(info_i->framelength <= sub_network_base_framelength[j]) + { + uint64 sub_network_tsfs_us_mod = sub_network_tsfs[j]%framelengthDuration_us; + + if(timeSinceFrameStart_us > sub_network_tsfs_us_mod) + { + diff_us = timeSinceFrameStart_us - sub_network_tsfs_us_mod; + } + else + { + diff_us = sub_network_tsfs_us_mod - timeSinceFrameStart_us; + } + } + else + { + uint64 sub_network_FramelengthDuration_us = sub_network_base_framelength[j]*this->slotDuration_us; + uint64 timeSinceFrameStartMod_us = timeSinceFrameStart_us%sub_network_FramelengthDuration_us; + + if(sub_network_tsfs[j] > timeSinceFrameStartMod_us) + { + diff_us = sub_network_tsfs[j] - timeSinceFrameStartMod_us; + } + else + { + diff_us = timeSinceFrameStartMod_us - sub_network_tsfs[j]; + } + } + + uint64 threshold = this->slotStartDelay_us; //TODO make a permanent variable for this threshold + //if difference is below the threshold, it belongs to this subnetwork + //if not, it may belong to another one already listed, + //if not, create a new one... + if(diff_us < threshold) + { + sub_network_members[j]++; + sub_network_membership[i] = j; + break; + } + else if(j == num_sub_networks - 1) + { + //reached the last listed sub_netowrk, list a new subnetwork. + sub_network_members[num_sub_networks] = 1; + sub_network_base_framelength[num_sub_networks] = this->uwbListTDMAInfo[i].framelength; + sub_network_tsfs[num_sub_networks] = get_dt64(this->uwbFrameStartTimes64[i], time_now_us); + sub_network_membership[num_sub_networks] = num_sub_networks; + num_sub_networks++; + break; + } + } + + //no subnetworks listed yet, set the first one. + if(num_sub_networks == 0) + { + sub_network_members[num_sub_networks] = 1; + sub_network_base_framelength[num_sub_networks] = this->uwbListTDMAInfo[i].framelength; + sub_network_tsfs[UWB_LIST_SIZE-1] = get_dt64(this->uwbFrameStartTimes64[i], time_now_us); + sub_network_membership[num_sub_networks] = num_sub_networks; + num_sub_networks++; + break; + } + } + + //now select the subnetwork with the greatest number of uwbs + uint8 max_num = 0; + for(int i=0; i < num_sub_networks; i++) + { + if(sub_network_members[i] > max_num) + { + max_num = sub_network_members[i]; + sub_network_selected = i; + } + } + + + + uint64 tnext[max_num]; + uint8 neighborIndices[max_num]; uint64 latest_tnext; - uint8 neighborIndices[numNeighbors]; uint8 nidx = 0; uint64 slotDuration_us = this->slotDuration_us; for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self { - if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR) + if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR && sub_network_membership[i] == sub_network_selected) { neighborIndices[nidx] = i; -// tnext[nidx] = this->uwbFrameStartTimes_stm32[i]; tnext[nidx] = this->uwbFrameStartTimes64[i]; while(time_now_us > tnext[nidx]) //TODO handle number wrapping... { @@ -2326,7 +2501,6 @@ static void set_discovery_mode(struct TDMAHandler *this, DISCOVERY_MODE discover } nidx++; -// if(this->uwbListTDMAInfo[i].framelength*this->slotDuration_ms < shortestFrameDuration) if(this->uwbListTDMAInfo[i].framelength*slotDuration_us < shortestFrameDuration) { shortestFrameDuration = this->uwbListTDMAInfo[i].framelength*slotDuration_us; @@ -2342,7 +2516,6 @@ static void set_discovery_mode(struct TDMAHandler *this, DISCOVERY_MODE discover converged = TRUE; for(int i = 0; i < nidx; i++) { -// uint32 frameduration = this->uwbListTDMAInfo[neighborIndices[i]].framelength*this->slotDuration_ms; uint64 frameduration = this->uwbListTDMAInfo[neighborIndices[i]].framelength*slotDuration_us; while(tnext[i] < tcommon && tcommon - tnext[i] >= frameduration) //include small buffer { @@ -2364,8 +2537,16 @@ static void set_discovery_mode(struct TDMAHandler *this, DISCOVERY_MODE discover } + if(num_sub_networks > 1) + { + //need indicate rebase in inf message so other networks will have a chance to rebase to the network selected by this UWB + this->rebase_pending = TRUE; + this->rebase_tx = FALSE; + this->rebase_frameStartTime64 = latest_tnext; + } + + //expire as the beginning of the common frame start time -// this->discovery_mode_duration = get_dt32(time_now, latest_tnext); this->discovery_mode_duration = (uint32)(get_dt64(time_now_us, latest_tnext)/1000); //TODO make duration in us? this->discovery_mode_expires = TRUE; break; @@ -2578,10 +2759,13 @@ static struct TDMAHandler new(){ ret.infPollSentThisSlot = FALSE; ret.slotStartDelay_us = 4000; ret.infMessageLength = 0; + ret.rebase_pending = FALSE; + ret.rebase_tx = FALSE; + ret.rebase_frameStartTime64 = time_now_us; ret.enter_discovery_mode(&ret); // ret.collectInfDuration = ret.maxFramelength*ret.slotDuration; - ret.collectInfDuration = 10000; + ret.collectInfDuration = 10000; //TODO change this back ret.waitInfDuration = ret.collectInfDuration; ret.lastINFtx = time_now_us; diff --git a/src/application/tdma_handler.h b/src/application/tdma_handler.h index 917ad36..867f20b 100644 --- a/src/application/tdma_handler.h +++ b/src/application/tdma_handler.h @@ -25,6 +25,7 @@ typedef enum frame_sync_mode { FS_ADOPT, FS_AVERAGE +// FS_REBASE //TODO remove } FRAME_SYNC_MODE; @@ -49,6 +50,9 @@ struct TDMAHandler uint32 slotDuration_ms; //TODO make variable in duration based on UWB_LIST_SIZE uint32 slotDuration_us; //TODO make variable in duration based on UWB_LIST_SIZE bool infPollSentThisSlot; + bool rebase_pending; + bool rebase_tx; + uint64 rebase_frameStartTime64; //TODO rename 64 to us! //TODO can probably use a smaller data type... uint64 slotStartDelay_us; //time between slot start and transmission within that slot -- GitLab