diff --git a/DecaRanging.coproj b/DecaRanging.coproj index ee9a591070d6cdb434f065921e7160367538f814..78185e5a0d9ea31e8a84e094e10ab90f6cd76173 100644 --- a/DecaRanging.coproj +++ b/DecaRanging.coproj @@ -104,22 +104,22 @@ <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="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="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/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"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_flash.c" type="1"/> - <File name="src/application/instance.c" path="src/application/instance.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_wwdg.c" type="1"/> + <File name="src/application/instance.c" path="src/application/instance.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_dbgmcu.h" type="1"/> - <File name="src/decadriver/deca_device_api.h" path="src/decadriver/deca_device_api.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_sdio.c" type="1"/> + <File name="src/decadriver/deca_device_api.h" path="src/decadriver/deca_device_api.h" type="1"/> <File name="Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x" path="" type="2"/> - <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_iwdg.c" type="1"/> - <File name="src/compiler/compiler.h" path="src/compiler/compiler.h" type="1"/> + <File name="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_bkp.h" type="1"/> <File name="src/application/tdma_handler.h" path="src/application/tdma_handler.h" type="1"/> + <File name="src/compiler/compiler.h" path="src/compiler/compiler.h" type="1"/> <File name="Libraries/STM32_USB_OTG_Driver" path="" type="2"/> <File name="src/platform/deca_mutex.c" path="src/platform/deca_mutex.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_crc.c" type="1"/> @@ -132,23 +132,23 @@ <File name="src/application/tdma_handler.c" path="src/application/tdma_handler.c" type="1"/> <File name="Libraries/STM32_USB_OTG_Driver/src/usb_hcd_int.c" path="Libraries/STM32_USB_OTG_Driver/src/usb_hcd_int.c" type="1"/> <File name="src/platform/port.c" path="src/platform/port.c" type="1"/> - <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="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h" path="Libraries/STM32F10x_StdPeriph_Driver/inc/stm32f10x_wwdg.h" type="1"/> + <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/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rtc.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/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="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"/> - <File name="src/usb/deca_usb.c" path="src/usb/deca_usb.c" type="1"/> <File name="src/application/application_definitions.h" path="src/application/application_definitions.h" type="1"/> - <File name="src/application/lib.h" path="src/application/lib.h" type="1"/> + <File name="src/usb/deca_usb.c" path="src/usb/deca_usb.c" type="1"/> <File name="src/platform/deca_range_tables.c" path="src/platform/deca_range_tables.c" type="1"/> + <File name="src/application/lib.h" path="src/application/lib.h" type="1"/> <File name="Libraries/STM32_USB_OTG_Driver/src" path="" type="2"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_dma.c" type="1"/> <File name="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_pwr.c" type="1"/> @@ -165,22 +165,22 @@ <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="src/platform/deca_sleep.c" path="src/platform/deca_sleep.c" type="1"/> - <File name="Libraries/CMSIS/CM3/CoreSupport" 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/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="src/decadriver/deca_param_types.h" path="src/decadriver/deca_param_types.h" 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="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="src/platform/stm32f10x_conf.h" path="src/platform/stm32f10x_conf.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/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/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_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"/> @@ -214,8 +214,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="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="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c" path="Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.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 5ecc7c18296f67077269b7e85139c4e32314c9b2..8757da627d63a956bc1cb1115360708c29b42373 100644 --- a/src/application/application_definitions.h +++ b/src/application/application_definitions.h @@ -6,31 +6,37 @@ #include "deca_device_api.h" /****************************************************************************************************************** -********************* NOTES on Decaranging EVK1000 application features/options *********************************************************** +********************* Definitions expected to be modified by end-user ********************************************* *******************************************************************************************************************/ -#define DEEP_SLEEP (0) //To enable deep-sleep set this to 1 -//DEEP_SLEEP mode can be used, for example, by a Tag instance to put the DW1000 into low-power deep-sleep mode -#define CORRECT_RANGE_BIAS (1) // Compensate for small bias due to uneven accumulator growth at close up high power +#define UWB_LIST_SIZE 10 //the maximum size of the UWB network + //do not use a number larger than 80 if USING_64BIT_ADDR==1 + //do not use a number larger than 127 if USING_64BIT_ADDR==0 + //these are the largest UWB network sizes that the firmware will support. + //USING_64BIT_ADDR==1: Limiting factor is the max length of the INF messages + //USING_64BIT_ADDR==0: Limiting factor is the max power of 2 that fits in a uint8 (TDMA framelength is stored as uint8) + +#define SET_TXRX_DELAY 0 //when set to 1 - the DW1000 RX and TX delays are set to the TX_DELAY and RX_DELAY defines +#define TX_ANT_DELAY 0 +#define RX_ANT_DELAY 0 //TODO put reasonable initial value? add explanation +#define USING_64BIT_ADDR 0//TODO //when set to 0 - the DecaRanging application will use 16-bit addresses + +#define SPEED_OF_LIGHT (299704644.54) //(299702547.0) // in m/s in air //TODO add explanation! /****************************************************************************************************************** ******************************************************************************************************************* *******************************************************************************************************************/ +#define CORRECT_RANGE_BIAS (1) // Compensate for small bias due to uneven accumulator growth at close up high power + #define NUM_INST 1 -#define SPEED_OF_LIGHT (299704644.54) //(299702547.0) // in m/s in air #define MASK_40BIT (0x00FFFFFFFFFF) // DW1000 counter is 40 bits #define MASK_42BIT (0x000003FFFFFFFFFF) //stm32 microsecond timestamps are 42 bits #define MASK_TXDTS (0x00FFFFFFFE00) //The TX timestamp will snap to 8 ns resolution - mask lower 9 bits. #define DELAY_CALIB (0) // when set to 1 - the LCD display will show information used for TX/RX delay calibration -#define SET_TXRX_DELAY (0) //when set to 1 - the DW1000 RX and TX delays are set to the TX_DELAY and RX_DELAY defines -#define TX_ANT_DELAY 0 -#define RX_ANT_DELAY 0 - -#define USING_64BIT_ADDR (0)//TODO (0) //when set to 0 - the DecaRanging application will use 16-bit addresses //! callback events #define DWT_SIG_RX_NOERR 0 @@ -62,6 +68,7 @@ enum FINAL, REPORT, SYNC, + INF_MAX, FRAME_TYPE_NB }; @@ -79,9 +86,9 @@ enum //lengths including the Decaranging Message Function Code byte #define TAG_POLL_MSG_LEN 1 // FunctionCode(1) -#define ANCH_RESPONSE_MSG_LEN 9//TODO 1 // FunctionCode(1) +#define ANCH_RESPONSE_MSG_LEN 1 // FunctionCode(1) #define TAG_FINAL_MSG_LEN 16 // FunctionCode(1), Poll_TxTime(5), Resp_RxTime(5), Final_TxTime(5) -#define RNG_INIT_MSG_LEN 7//TODO 1 // FunctionCode(1) +#define RNG_INIT_MSG_LEN 1 // FunctionCode(1) #define RNG_REPORT_MSG_LEN_SHORT 9 // FunctionCode(1), time of flight (6), short address (2) #define RNG_REPORT_MSG_LEN_LONG 15 // FunctionCode(1), time of flight (6), long address (8) #define SYNC_MSG_LEN 8 // FunctionCode(1), framelength (1), time since frame start (6) @@ -120,12 +127,13 @@ enum // Total frame lengths. #if (USING_64BIT_ADDR == 1) - #define RNG_INIT_FRAME_LEN_BYTES (RANGINGINIT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC) + #define RNG_INIT_FRAME_LEN_BYTES (RNG_INIT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC) #define POLL_FRAME_LEN_BYTES (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC) #define RESP_FRAME_LEN_BYTES (ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC) #define FINAL_FRAME_LEN_BYTES (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC) - #define REPORT_FRAME_LEN_BYTES (RNG_REPORT_MSG_LEN_LONG + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC) - #define SYNC_FRAME_LEN_BYTES (SYNC_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC) + #define REPORT_FRAME_LEN_BYTES (RNG_REPORT_MSG_LEN_LONG + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC) + #define SYNC_FRAME_LEN_BYTES (SYNC_MSG_LEN + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC) + #define INF_FRAME_LEN_BYTES_MAX (11.5 + (ADDR_BYTE_SIZE_L + 3.5)*UWB_LIST_SIZE + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC) #else #define RNG_INIT_FRAME_LEN_BYTES (RNG_INIT_MSG_LEN + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC) #define POLL_FRAME_LEN_BYTES (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC) @@ -133,6 +141,7 @@ enum #define FINAL_FRAME_LEN_BYTES (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC) #define REPORT_FRAME_LEN_BYTES (RNG_REPORT_MSG_LEN_SHORT + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC) #define SYNC_FRAME_LEN_BYTES (SYNC_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC) + #define INF_FRAME_LEN_BYTES_MAX (11.5 + (ADDR_BYTE_SIZE_S + 3.5)*UWB_LIST_SIZE + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC) #endif #define BLINK_FRAME_CONTROL_BYTES (1) @@ -143,13 +152,6 @@ enum #define BLINK_FRAME_CRTL_AND_ADDRESS (BLINK_FRAME_SOURCE_ADDRESS + BLINK_FRAME_CTRLP) //10 bytes #define BLINK_FRAME_LEN_BYTES (BLINK_FRAME_CRTL_AND_ADDRESS + BLINK_FRAME_CRC) -#define UWB_LIST_SIZE 10 //the maximum size of the UWB network - //do not use a number larger than 80 if USING_64BIT_ADDR==1 and 127 if USING_64BIT_ADDR==0 - //these are the largest UWB network sizes that the firmware will support. - //USING_64BIT_ADDR==1: Limiting factor is the max length of the INF messages - //USING_64BIT_ADDR==0: Limiting factor is the max power of 2 that fits in a uint8 (framelength is stored as uint8) -#define UWB_COMM_TIMEOUT 3000 //ms //TODO make this a function of UWB_LIST_SIZE, twice the max framelengt? maybe this shouldn't be a define? - //UWB_LIST types #define UWB_LIST_SELF 0 //entry for self in list #define UWB_LIST_NEIGHBOR 1 //uwb in list that is active, in range, and are slotted to range with @@ -170,11 +172,10 @@ enum //INF message byte offsets #define TDMA_TSFS 1 // offset to put time since TDMA frame start in the INF message -#define TDMA_TSFS_REBASE 7 // offset to put whether the receiving UWB needs to rebase its TDMA frame to the transmitted TSFS -#define TDMA_NUMN 8 // offset to put the number of this UWB's neighbors in the INF message -#define TDMA_NUMH 9 // offset to put the number of this UWB's hidden neighbors in the INF message -#define TDMA_FRAMELENGTH 10 // offset to put this UWB's TDMA framelength in the INF message -#define TDMA_NUMS 11 // offset to put the number of this UWB's TDMA slot assignments in the INF message +#define TDMA_NUMN 7 // offset to put the number of this UWB's neighbors in the INF message +#define TDMA_NUMH 8 // offset to put the number of this UWB's hidden neighbors in the INF message +#define TDMA_FRAMELENGTH 9 // offset to put this UWB's TDMA framelength in the INF message +#define TDMA_NUMS 10 // offset to put the number of this UWB's TDMA slot assignments in the INF message // Final message byte offsets. #define PTXT 1 @@ -190,19 +191,6 @@ enum #define SYNC_FRAMELENGTH 1 // offset to put the framelength in the sync message #define SYNC_TSFS 2 // offset to put the time since TDMA frame start in the sync message -// Response delay values coded in ranging init message. -// This is a bitfield composed of: -// - bits 0 to 14: value -// - bit 15: unit -//#define RESP_DLY_VAL_SHIFT 0 -//#define RESP_DLY_VAL_MASK 0x7FFF -//#define RESP_DLY_UNIT_SHIFT 15 //TODO remove -//#define RESP_DLY_UNIT_MASK 0x8000 - -// Response time possible units: microseconds or milliseconds. -//#define RESP_DLY_UNIT_US 0 //TODO remove -//#define RESP_DLY_UNIT_MS 1 - // Response delays types present in ranging init message. enum { @@ -211,12 +199,6 @@ enum RESP_DLY_FINAL, RESP_DLY_NB }; -//enum -//{ -// RESP_DLY_ANC = 0, //TODO remove -// RESP_DLY_TAG, -// RESP_DLY_NB -//}; // Convert microseconds to symbols, float version. // param x value in microseconds @@ -236,9 +218,15 @@ enum #define TX_CMD_TO_TX_CB_DLY_US 90 //doesn't include preamble, sfd, phr, and data. saw 81 to 87 #define MIN_DELAYED_TX_DLY_US 90 //doesn't include preamble and sfd. //80 is the minimum delay for delayed tx. anything shorter will cause failure -// Delay between blink reception and ranging init message. This is the same for -// all modes. -#define RNG_INIT_REPLY_DLY_US 10000 //TODO tune! + +#define SLOT_START_BUFFER_US 4000 //set based on experimentally observed frame sync errors +#define SLOT_BUFFER_EXP_TO_POLL_CMD_US 3*UWB_LIST_SIZE + 108 //found experimentally +#define MEASURED_SLOT_DURATIONS_US 1.7814*UWB_LIST_SIZE*UWB_LIST_SIZE + 29.39*UWB_LIST_SIZE + 1848.5 //found experimentally +#define LCD_ENABLE_BUFFER_US 5000 +#define SLOT_END_BUFFER_US 0 //increase if all messages do not fit into a slot +#define BLINK_RX_CB_TO_RESP_TX_CMD_DLY_US 1450 //found experimentally + + #define MAX(a,b) \ ({ __typeof__ (a) _a = (a); \ @@ -250,7 +238,7 @@ enum #define BLINK_PERIOD_RAND_MS 200 -#define RANGE_INIT_RAND_US 20 //TODO tune this number +#define RANGE_INIT_RAND_US 1000 #define RX_CHECK_ON_PERIOD_MS 200 //TODO modify @@ -287,20 +275,19 @@ DISCOVERY_MODE; typedef enum inst_states { TA_INIT, //0 - TA_TXE_WAIT, //1 - TA_TXINF_WAIT_SEND, //2 - TA_TXPOLL_WAIT_SEND, //3 - TA_TXFINAL_WAIT_SEND, //4 - TA_TXRESPONSE_WAIT_SEND, //5 - TA_TX_WAIT_CONF, //6 - TA_RXE_WAIT, //7 - TA_RX_WAIT_DATA, //8 - TA_SLEEP_DONE, //9 - TA_TXBLINK_WAIT_SEND, //10 - TA_TXRANGINGINIT_WAIT_SEND, //11 - TA_TX_SELECT, //12 - TA_TXREPORT_WAIT_SEND, //13 - TA_TXSUG_WAIT_SEND //14 + TA_TXINF_WAIT_SEND, //1 + TA_TXPOLL_WAIT_SEND, //2 + TA_TXFINAL_WAIT_SEND, //3 + TA_TXRESPONSE_WAIT_SEND, + TA_TX_WAIT_CONF, + TA_RXE_WAIT, + TA_RX_WAIT_DATA, + TA_SLEEP_DONE, + TA_TXBLINK_WAIT_SEND, + TA_TXRANGINGINIT_WAIT_SEND, + TA_TX_SELECT, + TA_TXREPORT_WAIT_SEND, + TA_TXSUG_WAIT_SEND } INST_STATES; diff --git a/src/application/dw_main.c b/src/application/dw_main.c index 5183778a9b669657fdede05e3d0de360053ceb2d..f06c98814e575fdbed69738b69d766bc6d22ea92 100644 --- a/src/application/dw_main.c +++ b/src/application/dw_main.c @@ -187,7 +187,7 @@ uint32 inittestapplication(uint8 mode_switch) result = instance_init() ; if (0 > result) return(-1) ; // Some failure has occurred - result = tdma_init_s(); + port_set_dw1000_fastrate(); devID = instancereaddeviceid() ; @@ -220,6 +220,9 @@ uint32 inittestapplication(uint8 mode_switch) instance_init_timings(); + instance_data_t* inst = instance_get_local_structure_ptr(0); + result = tdma_init_s(inst->durationSlotMax_us); //call after instance_init_timings() to get slot duration + return devID; } @@ -512,12 +515,12 @@ int dw_main(void) if(instance_mode == TAG && inst->canPrintInfo == TRUE) { - uint64 aaddr = instancenewrangeancadd(); - uint64 taddr = instancenewrangetagadd(); -// int n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr); - int n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%04llX,%04llX", taddr, aaddr); - send_usbmessage(&dataseq[0], n); - usb_run(); +// uint64 aaddr = instancenewrangeancadd(); +// uint64 taddr = instancenewrangetagadd(); +//// int n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%llX,%llX", taddr, aaddr); +// int n = sprintf((char*)&dataseq[0], "RANGE_COMPLETE,%04llX,%04llX", taddr, aaddr); +// send_usbmessage(&dataseq[0], n); +// usb_run(); } else @@ -546,8 +549,8 @@ int dw_main(void) } - //TODO only write to LCD if we aren't in the middle of ranging messages - //the random sleep messages embedded in the LCD calls makes things slow... + //only write to LCD if we aren't in the middle of ranging messages + //the random sleep messages embedded in the LCD calls messes up the timing if(enableLCD == TRUE && inst->canPrintInfo == TRUE) { toggle_step = 750; @@ -640,7 +643,7 @@ int dw_main(void) // usb_run(); #endif - if(canSleep)__WFI(); +// if(canSleep)__WFI(); } diff --git a/src/application/instance.c b/src/application/instance.c index 4a346dc8e01a6fd2c9ac4157e71548138193586c..e6de20211a62cda227aeb4938748d7463618520e 100644 --- a/src/application/instance.c +++ b/src/application/instance.c @@ -231,7 +231,6 @@ const char* get_inst_states_string(enum inst_states state) switch (state) { case TA_INIT : return "TA_INIT"; - case TA_TXE_WAIT : return "TA_TXE_WAIT"; case TA_TXPOLL_WAIT_SEND : return "TA_TXPOLL_WAIT_SEND"; case TA_TXFINAL_WAIT_SEND : return "TA_TXFINAL_WAIT_SEND"; case TA_TXRESPONSE_WAIT_SEND : return "TA_TXRESPONSE_WAIT_SEND"; @@ -366,15 +365,16 @@ void send_txmsgtousb(char *data) // int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int message) { + +// send_statetousb(inst, tdma_handler); //TODO remove + int done = INST_NOT_DONE_YET; - if(tdma_handler->slot_transition(tdma_handler))//TODO move these types of things to the end???? + if(tdma_handler->slot_transition(tdma_handler)) { message = 0; } -// send_statetousb(inst, tdma_handler); //TODO remove - tdma_handler->check_discovery_mode_expiration(tdma_handler); @@ -416,7 +416,7 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess srand(seed); - inst->uwbShortAdd = inst->eui64[0] + (inst->eui64[1] << 8);//TODO use a hashing algorithm + inst->uwbShortAdd = inst->eui64[0] + (inst->eui64[1] << 8);//NOTE a hashing algorithm could be used instead #if (USING_64BIT_ADDR==0) dwt_setaddress16(inst->uwbShortAdd); @@ -433,16 +433,12 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess { mode |= DWT_LOADOPSET; } -#if (DEEP_SLEEP == 1) - if (inst->sleepingEabled) - dwt_configuresleep(mode, DWT_WAKE_WK|DWT_WAKE_CS|DWT_SLP_EN); //configure the on wake parameters (upload the IC config settings) -#endif instanceconfigframeheader(inst); instanceconfigmessages(inst); // First time listening, do not delay RX - dwt_setrxaftertxdelay(0); + dwt_setrxaftertxdelay(0); //units are 1.0256us //change to next state - wait to receive a message tdma_handler->discoveryStartTime = portGetTickCnt(); @@ -452,15 +448,6 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess dwt_setrxtimeout(0); inst->wait4ack = 0; inst->canPrintInfo = TRUE; - - //TODO revisit - // If we are using long response delays, disable sleep. -// if (inst->resp_dly_us[RESP_DLY_POLL] >= LONG_RESP_DLY_LIMIT_US -// || inst->resp_dly_us[RESP_DLY_ANCH_RESP] >= LONG_RESP_DLY_LIMIT_US) -// { -// inst->sleepingEabled = 0; -// } - } break; default: @@ -495,71 +482,11 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess } done = INST_NOT_DONE_YET; - inst->goToSleep = 0; inst->testAppState = inst->nextState; inst->nextState = TA_INIT; //clear - inst->instanceTimerTimeSaved = inst->instanceTimerTime = portGetTickCnt(); //set timer base -#if (DEEP_SLEEP == 1) - if (inst->sleepingEabled) - { - //wake up device from low power mode - led_on(LED_PC9); - - port_wakeup_dw1000_fast(); - - led_off(LED_PC9); - - //this is platform dependent - only program if DW EVK/EVB - dwt_setleds(1); - - //MP bug - TX antenna delay needs reprogramming as it is not preserved after DEEP SLEEP - dwt_settxantennadelay(inst->txAntennaDelay) ; - } - instancesetantennadelays(); -#endif - //TODO should this be here? or only if DEEP_SLEEP is enabled (above) putting only above for now break; } - case TA_TXE_WAIT : //either go to sleep or proceed to TX a message - { - //TODO rework sleep functionality - //should sleep between blinks? - //should blink when not own slot? - //should sleep after everything is done in own slot? - //does sleep still allow RX? - - //if we are scheduled to go to sleep before next sending then sleep first. -// if(((inst->nextState == TA_TXPOLL_WAIT_SEND) -// || (inst->nextState == TA_TXBLINK_WAIT_SEND) || (inst->nextState == TA_TX_SELECT)) - if(inst->nextState == TA_TX_SELECT - && (inst->goToSleep) //go to sleep before sending the next poll - ) - { - //the app should put chip into low power state and wake up in tagSleepTime_ms time... - //the app could go to *_IDLE state and wait for uP to wake it up... - done = INST_DONE_WAIT_FOR_NEXT_EVENT_TO; //don't sleep here but kick off the TagTimeoutTimer (instancetimer) - inst->testAppState = TA_SLEEP_DONE; - -// inst->canPrintInfo = 1; - -#if (DEEP_SLEEP == 1) - if (inst->sleepingEabled) - { - //put device into low power mode - dwt_entersleep(); //go to sleep - } -#endif - - //inst->deviceissleeping = 1; //this is to stop polling device status register (as it will wake it up) - } - else //proceed to configuration and transmission of a frame - { - inst->testAppState = inst->nextState; - inst->nextState = TA_INIT; //clear - } - break ; - }// end case TA_TXE_WAIT case TA_TXBLINK_WAIT_SEND : { int psduLength = BLINK_FRAME_LEN_BYTES; @@ -568,8 +495,8 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess inst->blinkmsg.seqNum = inst->frameSN++; - dwt_setrxtimeout(0); - dwt_setrxaftertxdelay(0); + dwt_setrxtimeout(0); //units are 1.0256us + dwt_setrxaftertxdelay(0); //units are 1.0256us inst->wait4ack = DWT_RESPONSE_EXPECTED; dwt_writetxdata(psduLength, (uint8 *) (&inst->blinkmsg), 0) ; // write the frame data @@ -588,14 +515,12 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess send_usbmessage(&debug_msg[0], n); usb_run(); - inst->goToSleep = 1; //go to Sleep after this blink inst->testAppState = TA_TX_WAIT_CONF ; // wait confirmation inst->previousState = TA_TXBLINK_WAIT_SEND ; done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below) - inst->blink_start = portGetTickCnt(); //TODO remove inst->timeofTx = portGetTickCnt(); - //TODO check this duration! + inst->txDoneTimeoutDuration = inst->durationBlinkTxDoneTimeout_ms; tdma_handler->last_blink_time = portGetTickCnt(); tdma_handler->blinkPeriodRand = (uint32)rand()%BLINK_PERIOD_RAND_MS; @@ -606,22 +531,29 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess case TA_TXRANGINGINIT_WAIT_SEND : { int psduLength = RNG_INIT_FRAME_LEN_BYTES; -// int psduLength = RNG_INIT_MSG_LEN; //TODO remove -//#if (USING_64BIT_ADDR == 1) -// psduLength += FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC; -//#else -// psduLength += FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC; -//#endif inst->rng_initmsg.seqNum = inst->frameSN++; - dwt_setrxaftertxdelay(0); - dwt_setrxtimeout((uint16)0); + dwt_setrxaftertxdelay(0); //units are 1.0256us + dwt_setrxtimeout(0); //units are 1.0256us inst->wait4ack = DWT_RESPONSE_EXPECTED; + //add a small random number to this to reduce chance of collisions + uint8 sys_time_arr[5] = {0, 0, 0, 0, 0}; + dwt_readsystime(sys_time_arr); + uint64 dwt_time_now = 0; + dwt_time_now = (uint64)sys_time_arr[0] + ((uint64)sys_time_arr[1] << 8) + ((uint64)sys_time_arr[2] << 16) + ((uint64)sys_time_arr[3] << 24) + ((uint64)sys_time_arr[4] << 32); + inst->delayedReplyTime = (dwt_time_now + inst->rnginitReplyDelay + convertmicrosectodevicetimeu(rand()%RANGE_INIT_RAND_US)) >> 8 ; // time we should send the blink response + + dwt_writetxdata(psduLength, (uint8 *) &inst->rng_initmsg, 0) ; // write the frame data if(instancesendpacket(psduLength, DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED, inst->delayedReplyTime)) { + uint8 debug_msg[100]; + int n = sprintf((char*)&debug_msg[0], "RNG_INIT late tx!"); + send_usbmessage(&debug_msg[0], n); + usb_run(); + inst->previousState = TA_INIT; inst->nextState = TA_INIT; inst->testAppState = TA_RXE_WAIT ; // wait to receive a new blink or poll message @@ -636,7 +568,7 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess uint32 time_now = portGetTickCnt(); inst->timeofTx = time_now; - //TODO check below + inst->txDoneTimeoutDuration = inst->durationRngInitTxDoneTimeout_ms; tdma_handler->set_discovery_mode(tdma_handler, WAIT_INF_INIT, time_now); } @@ -652,7 +584,8 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess //update time since frame start! tdma_handler->update_inf_tsfs(tdma_handler); - dwt_setrxtimeout((uint16)0);//no timeout (keep RX on until instructed otherwise) + dwt_setrxaftertxdelay(0); //units are 1.0256us + dwt_setrxtimeout(0); //units are 1.0256us //no timeout (keep RX on until instructed otherwise) inst->wait4ack = 0; dwt_writetxdata(psduLength, (uint8 *) &inst->inf_msg, 0) ; // write the frame data @@ -673,12 +606,12 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess } else { - inst->testAppState = TA_TX_WAIT_CONF ; //TODO should only do this if we don't have a problem with the INF send... + inst->testAppState = TA_TX_WAIT_CONF ; inst->previousState = TA_TXINF_WAIT_SEND ; done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below) inst->timeofTx = portGetTickCnt(); - //TODO check below (INF message changes size, recalculate every time!) + uint64 margin_us = 1000; uint64 framelength_us = instance_getmessageduration_us(psduLength); inst->txDoneTimeoutDuration = CEIL_DIV(TX_CMD_TO_TX_CB_DLY_US + framelength_us + margin_us, 1000); //tx cmd to tx cb @@ -689,29 +622,24 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess case TA_TXPOLL_WAIT_SEND : { int psduLength = POLL_FRAME_LEN_BYTES; -// int psduLength = 0;//TODO remove -//#if (USING_64BIT_ADDR==1) -// psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC; -//#else -// psduLength = TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC; -//#endif inst->msg.seqNum = inst->frameSN++; inst->msg.messageData[FCODE] = RTLS_DEMO_MSG_TAG_POLL; //message function code (specifies if message is a poll, response or other...) memcpy(&inst->msg.destAddr[0], &inst->uwbList[inst->uwbToRangeWith], inst->addrByteSize); + tdma_handler->nthOldest++; + //enable rx on after tx - dwt_setrxaftertxdelay(0); - dwt_setrxtimeout(inst->durationPollTimeout); + dwt_setrxaftertxdelay(0); //units are 1.0256us + dwt_setrxtimeout(inst->durationPollTimeout_nus); //units are 1.0256us inst->wait4ack = DWT_RESPONSE_EXPECTED; - inst->cmd_poll_us = portGetTickCntMicro();//TODO remove - dwt_writetxdata(psduLength, (uint8 *) &inst->msg, 0) ; // write the frame data if(instancesendpacket(psduLength, DWT_START_TX_IMMEDIATE | inst->wait4ack, 0)) { - inst->tx_poll = FALSE; //failed + inst->tx_poll = FALSE; + inst->previousState = TA_INIT; inst->nextState = TA_INIT; inst->testAppState = TA_RXE_WAIT; @@ -721,22 +649,20 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess else { //succeded - uint8 debug_msg[100]; -// int n = sprintf((char *)&debug_msg, "TX_POLL,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); - int n = sprintf((char *)&debug_msg, "TX_POLL,%04llX,%04llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); - send_usbmessage(&debug_msg[0], n); - usb_run(); +// uint8 debug_msg[100]; //TODO remove +//// int n = sprintf((char *)&debug_msg, "TX_POLL,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); +// int n = sprintf((char *)&debug_msg, "TX_POLL,%04llX,%04llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); inst->tx_poll = TRUE; inst->testAppState = TA_TX_WAIT_CONF ; inst->previousState = TA_TXPOLL_WAIT_SEND ; done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below) + inst->canPrintInfo = FALSE; //don't print to LCD or USB while ranging - inst->range_start = portGetTickCnt(); //TODO remove inst->timeofTx = portGetTickCnt(); - //TODO check below inst->txDoneTimeoutDuration = inst->durationPollTxDoneTimeout_ms; - inst->canPrintInfo = FALSE; //don't print to LCD or USB while ranging } break; @@ -744,20 +670,14 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess case TA_TXREPORT_WAIT_SEND : { int psduLength = REPORT_FRAME_LEN_BYTES; -// int psduLength = 0; -//#if (USING_64BIT_ADDR==1) -// psduLength = RNG_REPORT_MSG_LEN_LONG + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC; -//#else -// psduLength = RNG_REPORT_MSG_LEN_SHORT + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC; -//#endif // Write calculated TOF into response message memcpy(&inst->report_msg.messageData[REPORT_TOF], &inst->tof[inst->uwbToRangeWith], 6); memcpy(&inst->report_msg.messageData[REPORT_ADDR], &inst->uwbList[inst->uwbToRangeWith], inst->addrByteSize); inst->report_msg.seqNum = inst->frameSN++; - dwt_setrxaftertxdelay(0); - dwt_setrxtimeout(0); + dwt_setrxaftertxdelay(0); //units are 1.0256us + dwt_setrxtimeout(0); //units are 1.0256us inst->wait4ack = 0; dwt_writetxdata(psduLength, (uint8 *) &inst->report_msg, 0) ; // write the frame data @@ -775,12 +695,11 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set below) inst->timeofTx = portGetTickCnt(); - //TODO check below + inst->txDoneTimeoutDuration = inst->durationReportTxDoneTimeout_ms; + inst->canPrintInfo = TRUE; //ranging complete, allow print to USB and LCD } - inst->canPrintInfo = TRUE; //ranging exchange complete, allow print to USB and LCD - break; } case TA_TX_WAIT_CONF : @@ -890,15 +809,10 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess if(inst->mode == DISCOVERY) { - //add a small random number to this to reduce chance of collisions - inst->delayedReplyTime = (dw_event->timeStamp + inst->rnginitReplyDelay + convertmicrosectodevicetimeu(rand()%RANGE_INIT_RAND_US)) >> 8 ; // time we should send the blink response - //set destination address memcpy(&inst->rng_initmsg.destAddr[0], &(dw_event->msgu.rxblinkmsg.tagID[0]), BLINK_FRAME_SOURCE_ADDRESS); //remember who to send the reply to - inst->testAppState = TA_TXE_WAIT; - inst->nextState = TA_TXRANGINGINIT_WAIT_SEND ; - + inst->testAppState = TA_TXRANGINGINIT_WAIT_SEND; } else //not initiating ranging - continue to receive { @@ -963,9 +877,7 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess inst->testAppState = TA_TX_SELECT; inst->mode = TAG; - inst->goToSleep = 0; //don't go to sleep - start ranging instead and then sleep after 1 range is done or poll times out - inst->instanceTimerTimeSaved = inst->instanceTimerTime = portGetTickCnt(); //set timer base - + break; } //RTLS_DEMO_MSG_RNG_INIT case RTLS_DEMO_MSG_SYNC : @@ -989,7 +901,7 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess case RTLS_DEMO_MSG_INF_SUG : //fall through case RTLS_DEMO_MSG_INF_REG : { - uint32 time_now = portGetTickCnt(); + uint32 time_now = portGetTickCnt(); uint8 srcIndex = instgetuwblistindex(inst, &srcAddr[0], inst->addrByteSize); uint8 framelength; @@ -1062,9 +974,25 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess } } + + inst->canPrintInfo = TRUE; //INF is last message in slot, we can print after processing + //wait for next RX inst->testAppState = TA_RXE_WAIT ; +// uint32 diff = get_dt32(time_now, portGetTickCnt()); +// uint8 debug_msg[100]; //TODO remove +// int n = sprintf((char *)&debug_msg, "process inf duration, %lu", diff); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); + +// uint64 diff = get_dt64(inst->slot_start_us, portGetTickCntMicro()); +// uint8 debug_msg[100]; //TODO remove +// int n = sprintf((char *)&debug_msg, "slot done, duration, %llu", diff); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); + + break; } case RTLS_DEMO_MSG_INF_INIT : @@ -1213,11 +1141,11 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess tdma_handler->uwbListTDMAInfo[inst->uwbToRangeWith].lastRange = portGetTickCnt(); - uint8 debug_msg[100]; -// int n = sprintf((char *)&debug_msg, "POLL_COMPLETE,%llX,%llX", inst->newRangeTagAddress, inst->newRangeAncAddress); - int n = sprintf((char *)&debug_msg, "POLL_COMPLETE,%04llX,%04llX", inst->newRangeTagAddress, inst->newRangeAncAddress); - send_usbmessage(&debug_msg[0], n); - usb_run(); +// uint8 debug_msg[100];//TODO remove +//// int n = sprintf((char *)&debug_msg, "POLL_COMPLETE,%llX,%llX", inst->newRangeTagAddress, inst->newRangeAncAddress); +// int n = sprintf((char *)&debug_msg, "POLL_COMPLETE,%04llX,%04llX", inst->newRangeTagAddress, inst->newRangeAncAddress); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); tdma_handler->firstPollComplete = TRUE; inst->testAppState = TA_TX_SELECT; @@ -1233,19 +1161,16 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess inst->uwbToRangeWith = 255; } - dwt_setrxaftertxdelay(0); - instancesetantennadelays(); //this will update the antenna delay if it has changed, TODO remove? + inst->canPrintInfo = TRUE; //ranging complete, allow print to USB and LCD + dwt_setrxaftertxdelay(0); //units are 1.0256us done = INST_DONE_WAIT_FOR_NEXT_EVENT; - - inst->canPrintInfo = TRUE; //ranging exchange complete, allow print to USB and LCD - break; } //RTLS_DEMO_MSG_RNG_REPORT default: { inst->testAppState = TA_RXE_WAIT ; // wait for next frame - dwt_setrxaftertxdelay(0); + dwt_setrxaftertxdelay(0); //units are 1.0256us break; } @@ -1279,19 +1204,19 @@ int testapprun(instance_data_t *inst, struct TDMAHandler *tdma_handler, int mess } else if(inst->previousState == TA_TXFINAL_WAIT_SEND) { - uint8 debug_msg[100]; -// n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); - n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%04llX,%04llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); - send_usbmessage(&debug_msg[0], n); - usb_run(); +// uint8 debug_msg[100]; +//// n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); +// n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%04llX,%04llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); } else if(inst->previousState == TA_TXPOLL_WAIT_SEND) { - uint8 debug_msg[100]; -// n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); - n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%04llX,%04llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); - send_usbmessage(&debug_msg[0], n); - usb_run(); +// uint8 debug_msg[100]; +//// n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%llX,%llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); +// n = sprintf((char *)&debug_msg, "TX_POLL_TIMEOUT,%04llX,%04llX", instance_get_addr(), instance_get_uwbaddr(inst->uwbToRangeWith)); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); } instance_getevent(17); //get and clear this event @@ -1397,11 +1322,10 @@ void instance_init_timings(void) static const int data_len_bytes[FRAME_TYPE_NB] = { BLINK_FRAME_LEN_BYTES, RNG_INIT_FRAME_LEN_BYTES, POLL_FRAME_LEN_BYTES, - RESP_FRAME_LEN_BYTES, FINAL_FRAME_LEN_BYTES, REPORT_FRAME_LEN_BYTES, SYNC_FRAME_LEN_BYTES}; + RESP_FRAME_LEN_BYTES, FINAL_FRAME_LEN_BYTES, REPORT_FRAME_LEN_BYTES, SYNC_FRAME_LEN_BYTES, INF_FRAME_LEN_BYTES_MAX}; // Margin used for timeouts computation. -// const int margin_sy = 50; uint64 margin_us = 200; // All internal computations are done in tens of picoseconds before @@ -1456,76 +1380,44 @@ void instance_init_timings(void) inst->frameLengths_us[i] = instance_getmessageduration_us(data_len_bytes[i]); } + //rx timeout durations (units are 1.0256us) uint64 duration = 0; duration += inst->frameLengths_us[POLL] - inst->storedPreLen_us; //poll tx ts to poll tx cb duration += RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US; //poll tx cb to resp tx cmd duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[RESP] + RX_TO_CB_DLY_US; //resp tx cmd to resp rx cb duration += margin_us; - inst->durationPollTimeout = (uint16)convertmicrosectodevicetimeu(duration); + inst->durationPollTimeout_nus = (uint16)(duration/1.0256) + 1; + duration = 0; duration += inst->frameLengths_us[RESP] - inst->storedPreLen_us; //resp tx ts to resp tx cb duration += RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US; //resp tx cb to final tx cmd duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[FINAL] + RX_TO_CB_DLY_US; //final tx cmd to final rx cb duration += margin_us; - inst->durationRespTimeout = (uint16)convertmicrosectodevicetimeu(duration); + inst->durationRespTimeout_nus = (uint16)(duration/1.0256) + 1; duration = 0; duration += inst->frameLengths_us[FINAL] - inst->storedPreLen_us; //final tx ts to final tx cb duration += RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US; //final tx cb to report tx cmd duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[REPORT] + RX_TO_CB_DLY_US;//report tx cmd to report rx cb duration += margin_us; - inst->durationFinalTimeout = (uint16)convertmicrosectodevicetimeu(duration); - -// // Update delay between poll transmission and final transmission. -// uint64 final_delay_us = 0; -// //poll tx ts to poll tx cb -// final_delay_us += inst->frameLengths_us[POLL] - inst->storedPreLen_us; -// //poll tx cb to resp tx cmd -// final_delay_us += RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US; -// //resp tx cmd to final rx cb -// final_delay_us += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[RESP] + RX_TO_CB_DLY_US; - - //TODO fix TO values below - // Final frame wait timeout time. -// inst->durationFwToFinal_sy = US_TO_SY_INT(inst->frameLengths_us[FINAL]) -// + RX_START_UP_SY + margin_sy; -// // Ranging init frame wait timeout time. -// inst->durationFwToRngInit_sy = US_TO_SY_INT(inst->frameLengths_us[RNG_INIT]) -// + RX_START_UP_SY + margin_sy; - - // Delay between blink transmission and ranging init reception. -// inst->durationTxBlink2RxRngInit_sy = -// US_TO_SY_INT((RNG_INIT_REPLY_DLY_US) - inst->frameLengths_us[BLINK]) -// - RX_START_UP_SY; - // Delay between anchor's response transmission and final reception. -// inst->durationTxAnchResp2RxFinal_sy = US_TO_SY_INT(TAG_TURN_AROUND_TIME_US) - RX_START_UP_SY; //TODO remove? - - - // POLL response delay. //TODO remove -// inst->resp_dly_us[RESP_DLY_POLL] = (ANC_TURN_AROUND_TIME_US + inst->frameLengths_us[POLL]) & 0xFFFF; -// -// // ANCH_RESP response delay. -// inst->resp_dly_us[RESP_DLY_ANCH_RESP] = (TAG_TURN_AROUND_TIME_US + inst->frameLengths_us[RESP]) & 0xFFFF; - -// // FINAL response delay. //TODO different turnaround time? -// inst->resp_dly_us[RESP_DLY_FINAL] = (ANCH_TURN_AROUND_TIME_US + inst->frameLengths_us[FINAL]) & 0xFFFF; + inst->durationFinalTimeout_nus = (uint16)(duration/1.0256) + 1; -// // Update delay between poll transmission and rx enable -// inst->txToRxDelayPoll_sy = US_TO_SY_INT((uint64)inst->resp_dly_us[RESP_DLY_POLL] - inst->frameLengths_us[POLL]) - RX_START_UP_SY; + //delayed tx durations duration = 0; duration += inst->frameLengths_us[POLL] - inst->storedPreLen_us; //poll tx ts to poll tx cb duration += RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US; //poll tx cb to resp tx cmd duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[RESP] + RX_TO_CB_DLY_US; //resp tx cmd to resp rx cb duration += RX_CB_TO_TX_CMD_DLY_US + MIN_DELAYED_TX_DLY_US + inst->storedPreLen_us; //resp rx cb to final tx timestamp + inst->finalReplyDelay_us = duration; inst->finalReplyDelay = convertmicrosectodevicetimeu(duration); // Delay between blink reception and ranging init message transmission. - inst->rnginitReplyDelay = convertmicrosectodevicetimeu(RNG_INIT_REPLY_DLY_US); + inst->rnginitReplyDelay = convertmicrosectodevicetimeu(MIN_DELAYED_TX_DLY_US + inst->storedPreLen_us); //rng_init tx cmd to rng_init tx ts - - margin_us = 1000; + margin_us = 1000; + //tx conf timeout durations inst->durationBlinkTxDoneTimeout_ms = CEIL_DIV(TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[BLINK] + margin_us, 1000); //tx cmd to tx cb inst->durationRngInitTxDoneTimeout_ms = CEIL_DIV(TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[RNG_INIT] + margin_us, 1000); //tx cmd to tx cb inst->durationPollTxDoneTimeout_ms = CEIL_DIV(TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[POLL] + margin_us, 1000); //tx cmd to tx cb @@ -1535,6 +1427,65 @@ void instance_init_timings(void) inst->durationSyncTxDoneTimeout_ms = CEIL_DIV(TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[SYNC] + margin_us, 1000); //tx cmd to tx cb + //figure maximum duration of a TDMA slot in microseconds + duration = 0; + duration += SLOT_START_BUFFER_US; //frame start buffer + duration += SLOT_BUFFER_EXP_TO_POLL_CMD_US; //buffer expiration to cmd poll + duration += TX_CMD_TO_TX_CB_DLY_US + inst->finalReplyDelay_us + inst->frameLengths_us[FINAL] + RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US;//poll cmd to place final + //duration += B //place final to cmd report + duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[REPORT] + RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US; //cmd report to place report + //duration += C //place report to cmd inf + duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[INF_MAX] + RX_TO_CB_DLY_US + RX_CB_TO_TX_CMD_DLY_US; //cmd INF to place INF + //duration += D place inf to process inf + + //MEASURED_SLOT_DURATIONS_US is experimentally found value found for B+C+D described above + duration += (uint64)MEASURED_SLOT_DURATIONS_US; + + //add some time to account for possibly timing out on first poll + duration += SLOT_BUFFER_EXP_TO_POLL_CMD_US; //assume this is the same amount of time go get from timeout to poll command + duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[POLL] - inst->storedPreLen_us + (uint64)(inst->durationPollTimeout_nus*1.0256) + 200; //add small margin of 200 + + + //if LCD is on, add time to allow for Sleep calls in the LCD display logic + bool enableLCD = FALSE; + if(port_is_switch_on(TA_SW1_4) == S1_SWITCH_ON) + { + enableLCD = TRUE; + duration += LCD_ENABLE_BUFFER_US; + } + + duration += SLOT_END_BUFFER_US; + + inst->durationSlotMax_us = duration; + + duration = 0; + //from set discovery to cmd tx blink, to rx blink cb to cmd resp to rx resp ts + duration += TX_CMD_TO_TX_CB_DLY_US + inst->frameLengths_us[BLINK] + RX_TO_CB_DLY_US + BLINK_RX_CB_TO_RESP_TX_CMD_DLY_US + (uint64)(convertdevicetimetosec(inst->rnginitReplyDelay)*1000000.0) + RANGE_INIT_RAND_US + margin_us; + if(enableLCD == TRUE) + { + duration += LCD_ENABLE_BUFFER_US*2; + } + inst->durationWaitRangeInit_ms = CEIL_DIV(duration, 1000); + + + duration = 0; + //get max FL + uint8 maxFramelength = (uint8)MIN_FRAMELENGTH; + while(maxFramelength < (int)UWB_LIST_SIZE + 1) + { + maxFramelength *= 2; + } + + uint8 numExchanges = 0; + for(int i = 1; i < UWB_LIST_SIZE; i++) + { + numExchanges += i; + } + + uint8 numZero = numExchanges/(maxFramelength-1); + + inst->durationUwbCommTimeout_ms = (numExchanges + numZero)*CEIL_DIV(inst->durationSlotMax_us,1000)*2; + inst->smartPowerEn = 0; } @@ -1695,7 +1646,7 @@ uint64 timestamp_subtract64(uint64 timestamp, uint64 duration) } } -//TODO implement a hashing function to reduce chance of collisions +//NOTE could implement a hashing function to reduce chance of collisions among UWB addresses in network //https://stackoverflow.com/questions/31710074/how-to-generate-smaller-unique-number-from-larger-11-bytes-unique-number-gene //https://en.m.wikipedia.org/wiki/Pearson_hashing uint16 address64to16(uint8 *address) diff --git a/src/application/instance.h b/src/application/instance.h index a09d509e2739f3a2c51c364bfc993e9c16ad4731..f8dee0dcfe2480b415cca99a7dcfec221b6dd54b 100644 --- a/src/application/instance.h +++ b/src/application/instance.h @@ -42,27 +42,25 @@ typedef struct // "MAC" features uint8 frameFilteringEnabled ; //frame filtering is enabled - // Is sleeping between frames enabled? - uint8 sleepingEabled; //Ranging Init message can tell tag to stay in IDLE between ranging exchanges + bool lcdEnabled; bool canPrintInfo; //only print to usb and/or LCD display when TRUE //timeouts and delays int tagSleepTime_ms; //in milliseconds int tagBlinkSleepTime_ms; //this is the delay used for the delayed transmit (when sending the ranging init, response, and final messages) - uint64 rnginitReplyDelay ; - uint64 finalReplyDelay ; -// int finalReplyDelay_ms ; //TODO remove - uint64 cmd_poll_us ;//TODO remove + uint64 rnginitReplyDelay; + uint64 finalReplyDelay; + uint64 finalReplyDelay_us; - // xx_sy the units are 1.0256 us -// uint32 durationTxAnchResp2RxFinal_sy ; // this is the delay used after sending a response and turning on the receiver to receive final - uint32 txToRxDelayPoll_sy ; // this is the delay used after sending a poll and turning on the receiver to receive response -// int durationTxBlink2RxRngInit_sy ; // this is the delay used after sending a blink and turning on the receiver to receive the ranging init message - uint16 durationPollTimeout; //rx timeout duration after tx poll - uint16 durationRespTimeout; //rx timeout duration after tx resp - uint16 durationFinalTimeout; //rx timeout duration after tx final + //TODO remove below +// uint64 slot_start_us; + + //Receive Frame Wait Timeout Periods, units are 1.0256us (aus stands for near microsecond) + uint16 durationPollTimeout_nus; //rx timeout duration after tx poll + uint16 durationRespTimeout_nus; //rx timeout duration after tx resp + uint16 durationFinalTimeout_nus; //rx timeout duration after tx final uint32 durationBlinkTxDoneTimeout_ms; //tx done timeout after tx blink uint32 durationRngInitTxDoneTimeout_ms; //tx done timeout after tx rng_init @@ -72,15 +70,18 @@ typedef struct uint32 durationReportTxDoneTimeout_ms; //tx done timeout after tx report uint32 durationSyncTxDoneTimeout_ms; //tx done timeout after tx sync + uint32 durationUwbCommTimeout_ms; //how long to wait before changing UWB_LIST_TYPE if we haven't communicated with or received an information about a UWB in a while + uint32 durationWaitRangeInit_ms; //discovery mode WAIT_RNG_INIT duration + uint64 durationSlotMax_us; // longest anticipated time required for a slot based on UWB_LIST_SIZE and S1 switch settings uint32 delayedReplyTime; // delayed reply time of delayed TX message - high 32 bits // Pre-computed frame lengths for frames involved in the ranging process, // in microseconds. uint32 frameLengths_us[FRAME_TYPE_NB]; - uint32 storedPreLen; //precomputed conversion of preamble and sfd + uint32 storedPreLen; //precomputed conversion of preamble and sfd in DW1000 time units uint64 storedPreLen_us; //precomputed conversion of preamble and sfd in microseconds //message structures used for transmitted messages @@ -110,27 +111,15 @@ typedef struct uint32 resp_dly_us[RESP_DLY_NB]; //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 anchorRespTxTime ; // anchor's reponse tx timestamp uint64 anchorRespRxTime ; // receive time of response message uint64 tagPollRxTime ; // receive time of poll message //application control parameters - uint8 wait4ack ; // if this is set to DWT_RESPONSE_EXPECTED, then the receiver will turn on automatically after TX completion - uint8 goToSleep; // if set the instance will go to sleep before sending the blink/poll message - uint8 instanceTimerEnabled; // enable/start a timer - uint32 instanceTimerTime; // e.g. this timer is used to timeout Tag when in deep sleep so it can send the next poll message - uint32 instanceTimerTimeSaved; - uint8 gotTO; // got timeout event - + uint8 wait4ack ; // if this is set to DWT_RESPONSE_EXPECTED, then the receiver will turn on automatically after TX completion + uint8 gotTO; // got timeout event //diagnostic counters/data, results and logging - int64 tof[UWB_LIST_SIZE] ; double clockOffset ; @@ -152,16 +141,11 @@ typedef struct uint8 uwbListLen ; uint8 uwbList[UWB_LIST_SIZE][8]; //index 0 reserved for self, rest for other tracked uwbs - uint32 timeofTx; - uint32 txDoneTimeoutDuration; - bool tx_poll; - bool tx_anch_resp; - uint32 blink_start; //TODO remove - uint32 range_start; //TODO remove - uint64 timeofRX; //TODO remove + uint32 timeofTx; //used to calculate tx done callback timeouts + uint32 txDoneTimeoutDuration; //duration used for tx done callback timeouts. (set differently for each tx message) - uint32 blink_duration; //expected duration of a blink/response exchange //TODO remove? - uint32 range_duration; //expected duration of a range/response/final exchange //TODO remove + bool tx_poll; //was the last tx message a POLL message? + bool tx_anch_resp; //was the last tx message an ANCH_RESP message? //event queue - used to store DW1000 events as they are processed by the dw_isr/callback functions event_data_t dwevent[MAX_EVENT_NUMBER]; //this holds any TX/RX events and associated message data @@ -208,7 +192,7 @@ void setupmacframedata(instance_data_t *inst, int fcode); // initialise the instance (application) structures and DW1000 device int instance_init(void); int instance_init_s(); -int tdma_init_s(); +int tdma_init_s(uint64 slot_duration); // configure the instance and DW1000 device void instance_config(instanceConfig_t *config) ; @@ -294,6 +278,7 @@ int instance_starttxtest(int framePeriod); const char* get_instanceModes_string(enum instanceModes mode); const char* get_discovery_modes_string(enum discovery_modes mode); +const char* get_inst_states_string(enum inst_states state); instance_data_t* instance_get_local_structure_ptr(unsigned int x); struct TDMAHandler* tdma_get_local_structure_ptr(); diff --git a/src/application/instance_common.c b/src/application/instance_common.c index ae20797b6f19bfb5647094683775fec7681a7993..0daf79209d395abbd56f9847359ce593bc720f9d 100644 --- a/src/application/instance_common.c +++ b/src/application/instance_common.c @@ -70,12 +70,12 @@ struct TDMAHandler* tdma_get_local_structure_ptr() // function to initialise tdma structures // // Returns 0 on success and -1 on error -int tdma_init_s() +int tdma_init_s(uint64 slot_duration) { - tdma_handler = TDMAHandler.new(); + tdma_handler = TDMAHandler.new(slot_duration); - return 0 ; + return 0; } @@ -353,7 +353,7 @@ int instance_init(void) instance_data[instance].mode = DISCOVERY; // instance_data[instance].ranging = 0; - instance_data[instance].goToSleep = 0; +// instance_data[instance].goToSleep = 0; for(uint8 i=0; i<UWB_LIST_SIZE; i++) { @@ -384,10 +384,8 @@ int instance_init(void) instanceclearcounts() ; - instance_data[instance].sleepingEabled = 1; instance_data[instance].panID = 0xdeca ; instance_data[instance].wait4ack = 0; - instance_data[instance].instanceTimerEnabled = 0; instance_clearevents(); @@ -395,6 +393,12 @@ int instance_init(void) instance_data[instance].clockOffset = 0; + instance_data[instance].lcdEnabled = FALSE; + if(port_is_switch_on(TA_SW1_4) == S1_SWITCH_ON) + { + instance_data[instance].lcdEnabled = TRUE; + } + return 0 ; } @@ -698,29 +702,28 @@ void inst_processtxrxtimeout(instance_data_t *inst) { inst->testAppState = TA_RXE_WAIT; } - - dwt_setrxtimeout(0); } else if(inst->mode == ANCHOR) //we did not receive the final/ACK - wait for next poll { inst->wait4ack = 0; inst->uwbToRangeWith = 255; inst->testAppState = TA_RXE_WAIT ; // wait for next frame - dwt_setrxtimeout(0); } else //if(inst->mode == TAG) { inst->testAppState = TA_TX_SELECT ; } + inst->canPrintInfo = TRUE; inst->previousState = TA_INIT; - inst->canPrintInfo = TRUE; + dwt_setrxtimeout(0); //units are 1.0256us //timeout - disable the radio (if using SW timeout the rx will not be off) dwt_forcetrxoff() ; } void instance_txcallback(const dwt_cb_data_t *txd) { + uint8 txTimeStamp[5] = {0, 0, 0, 0, 0}; event_data_t dw_event; @@ -765,12 +768,6 @@ void instance_txcallback(const dwt_cb_data_t *txd) instance_putevent(dw_event); -#if (DEEP_SLEEP == 1) - int instance = 0; - if (instance_data[instance].sleepingEabled) - instance_data[instance].txmsgcount++; -#endif - } void instance_rxtimeoutcallback(const dwt_cb_data_t *rxd) @@ -818,7 +815,7 @@ void instance_rxerrorcallback(const dwt_cb_data_t *rxd) { instance_data[instance].uwbToRangeWith = 255; - instancerxon(&instance_data[instance], 0, 0); //immediate enable if anchor or listener + instancerxon(&instance_data[instance], 0, 0); //immediate enable if anchor } } @@ -826,12 +823,6 @@ void instance_rxerrorcallback(const dwt_cb_data_t *rxd) void instance_rxgoodcallback(const dwt_cb_data_t *rxd) { -// uint8 sys_time_arr[5] = {0, 0, 0, 0, 0}; -// dwt_readsystime(sys_time_arr); -// uint64 rxcb_time_now = 0; -// rxcb_time_now = (uint64)sys_time_arr[0] + ((uint64)sys_time_arr[1] << 8) + ((uint64)sys_time_arr[2] << 16) + ((uint64)sys_time_arr[3] << 24) + ((uint64)sys_time_arr[4] << 32); -// uint64 time_now_us = portGetTickCntMicro(); - int instance = 0; uint8 rxTimeStamp[5] = {0, 0, 0, 0, 0}; uint8 srcAddr_index = 0; @@ -840,7 +831,6 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) event_data_t dw_event; uint32 time_now = portGetTickCnt(); - instance_data[instance].timeofRX = portGetTickCntMicro(); //if we got a frame with a good CRC - RX OK rxd_event = DWT_SIG_RX_OKAY; @@ -964,7 +954,6 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) #if (USING_64BIT_ADDR==0) memcpy(&blink_address, &dw_event.msgu.rxblinkmsg.tagID[0], instance_data[instance].addrByteSize); #else -// uint16 blink_address_short = address64to16(&dw_event.msgu.rxblinkmsg.tagID[0]); //TODO remove memcpy(&blink_address, &dw_event.msgu.rxblinkmsg.tagID[0], instance_data[instance].addrByteSize); #endif @@ -1003,26 +992,18 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) // uint64 rxcb_time_now_us = portGetTickCntMicro(); - //TODO remove +// //TODO remove // uint8 debug_msg[100]; // uint16 my_addr = instance_data[instance].uwbShortAdd; -// int n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s,%04X,uwb_index: %04d, uwb_trw: %04d", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), my_addr,uwb_index, instance_data[instance].uwbToRangeWith); -// send_usbmessage(&debug_msg[0], n); -// usb_run(); +//// int n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s,%04X,uwb_index: %04d, uwb_trw: %04d", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), my_addr,uwb_index, instance_data[instance].uwbToRangeWith); +//// send_usbmessage(&debug_msg[0], n); +//// usb_run(); // int n = 0; // uint64 time = (uint64)(convertdevicetimetosec(rxcb_time_now - dw_event.timeStamp)*1000000.0) + instance_data[instance].storedPreLen_us; // time -= inst->frameLengths_us[RNG_INIT ]; // inst->storedPreLen_us //dwt_time_now - (rx_timestamp - (framelength - preamble_sfd)) -// inst->frameLengths_us[i] -// BLINK = 0, -// RNG_INIT, -// POLL, -// RESP, -// FINAL, -// SYNC, -// FRAME_TYPE_NB @@ -1044,7 +1025,10 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) // } // n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s, rx_to_cb_delay: %llu", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), time); -// if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT ) + + + +// if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_RNG_INIT ) // { // n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s,%04X,uwb_index: %04d, uwb_trw: %04d", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), my_addr,uwb_index, instance_data[instance].uwbToRangeWith); // } @@ -1084,7 +1068,7 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) // { // n = sprintf((char*)&debug_msg[0], "RX CB RX: DWT_SIG_RX_OKAY-%s,%04X,uwb_index: %04d, uwb_trw: %04d", get_msg_fcode_string(dw_event.msgu.frame[fcode_index]), my_addr,uwb_index, instance_data[instance].uwbToRangeWith); // } - +// // send_usbmessage(&debug_msg[0], n); // usb_run(); @@ -1176,13 +1160,6 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) if(dw_event.msgu.frame[fcode_index] == RTLS_DEMO_MSG_TAG_POLL) { int psduLength = RESP_FRAME_LEN_BYTES; -// int psduLength = 0; //TODO remove -//#if (USING_64BIT_ADDR == 1) -// psduLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC; -//#else -// psduLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC; -//#endif - instance_data[instance].tagPollRxTime = dw_event.timeStamp ; //Poll's Rx time instance_data[instance].msg.messageData[FCODE] = RTLS_DEMO_MSG_ANCH_RESP; //message function code (specifies if message is a poll, response or other...) @@ -1190,53 +1167,30 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) instance_data[instance].msg.seqNum = instance_data[instance].frameSN++; - dwt_setrxaftertxdelay(0); //units are 1.0256us - wait for wait4respTIM before RX on (delay RX) - dwt_setrxtimeout(instance_data[instance].durationRespTimeout); + dwt_setrxaftertxdelay(0); //units are 1.0256us + dwt_setrxtimeout(instance_data[instance].durationRespTimeout_nus*0);//units are 1.0256us instance_data[instance].wait4ack = DWT_RESPONSE_EXPECTED; - //TODO remove -// uint64 time_now_us = portGetTickCntMicro(); -// uint64 diff = get_dt64(instance_data[instance].timeofRX, time_now_us); -// uint8 debug_msg[100]; -// int n = sprintf((char*)&debug_msg[0], "ANCH_TURNAROUND: %llu", diff); -// send_usbmessage(&debug_msg[0], n); -// usb_run(); - -// uint64 tx_dly_us = instance_data[instance].storedPreLen_us + 280; -// uint64 tx_dly = convertmicrosectodevicetimeu(tx_dly_us); -// uint64 tx_dly = 140000000; - -// uint8 sys_time_arr[5] = {0, 0, 0, 0, 0}; -// dwt_readsystime(sys_time_arr); -// uint64 dwt_time_now = 0; -// dwt_time_now = (uint64)sys_time_arr[0] + ((uint64)sys_time_arr[1] << 8) + ((uint64)sys_time_arr[2] << 16) + ((uint64)sys_time_arr[3] << 24) + ((uint64)sys_time_arr[4] << 32); -// -// uint64 diff = convertdevicetimetosec( get_dt64(rxcb_time_now, dwt_time_now))*1000000; -// instance_data[instance].delayedReplyTime = (dwt_time_now + tx_dly) >> 8; - -// dwt_time_now = dwt_time_now >> 8; -// tx_dly = tx_dly >> 8; - dwt_writetxdata(psduLength, (uint8 *) &instance_data[instance].msg, 0) ; // write the frame data if(instancesendpacket(psduLength, DWT_START_TX_IMMEDIATE | instance_data[instance].wait4ack, 0)) { + uint8 debug_msg[100]; + int n = sprintf((char*)&debug_msg[0], "RESP late tx!"); + send_usbmessage(&debug_msg[0], n); + usb_run(); + instance_data[0].tx_anch_resp = FALSE; - instance_data[instance].previousState = TA_INIT; //TODO should we place this event??? maybe place an error? + instance_data[instance].previousState = TA_INIT; instance_data[instance].nextState = TA_INIT; instance_data[instance].testAppState = TA_RXE_WAIT; instance_data[instance].wait4ack = 0; } else { -// pass = TRUE; -// uint8 debug_msg[100]; -// int n = sprintf((char*)&debug_msg[0], "RESP SENT!"); -// send_usbmessage(&debug_msg[0], n); -// usb_run(); instance_data[0].tx_anch_resp = TRUE; dw_event.typePend = DWT_SIG_TX_PENDING ; // exit this interrupt and notify the application/instance that TX is in progress. instance_data[instance].timeofTx = time_now; - //TODO check below + instance_data[instance].txDoneTimeoutDuration = instance_data[instance].durationRespTxDoneTimeout_ms; instance_data[instance].canPrintInfo = FALSE; //don't print to LCD or USB while ranging } @@ -1246,12 +1200,6 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) { //process RTLS_DEMO_MSG_ANCH_RESP immediately. int psduLength = FINAL_FRAME_LEN_BYTES; -// int psduLength = 0;//TODO remove -// #if (USING_64BIT_ADDR==1) -// psduLength = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_L + FRAME_CRC; -// #else -// psduLength = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC; -// #endif instance_data[instance].anchorRespRxTime = dw_event.timeStamp ; //Response's Rx time // Embbed into Final message:40-bit respRxTime @@ -1259,62 +1207,16 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) memcpy(&(instance_data[instance].msg.messageData[RRXT]), (uint8 *)&instance_data[instance].anchorRespRxTime, 5); instance_data[instance].msg.messageData[FCODE] = RTLS_DEMO_MSG_TAG_FINAL; //message function code (specifies if message is a poll, response or other...) - dwt_setrxaftertxdelay(0); - dwt_setrxtimeout(instance_data[instance].durationFinalTimeout); + dwt_setrxaftertxdelay(0); //units are 1.0256us + dwt_setrxtimeout(instance_data[instance].durationFinalTimeout_nus*0); //TODO//units are 1.0256us instance_data[instance].wait4ack = 0;//DWT_RESPONSE_EXPECTED; - //TODO does this number get larger with more UWBS? - //should we call this in rxgoodcallback to minimize time and time variance???? -// uint64 time_now_us = portGetTickCntMicro(); -// uint64 diff = get_dt64(instance_data[instance].timeofRX, time_now_us); -// uint8 debug_msg[100]; -// int n = sprintf((char*)&debug_msg[0], "TAG_TURNAROUND: %llu", diff); -// send_usbmessage(&debug_msg[0], n); -// usb_run(); - -// //TODO remove below -// //from RX time till now (need some amount of padding as well...) -// uint8 sys_time_arr[5] = {0, 0, 0, 0, 0}; -// dwt_readsystime(sys_time_arr); -// uint64 dwt_time_now = 0; -// dwt_time_now = (uint64)sys_time_arr[0] + ((uint64)sys_time_arr[1] << 8) + ((uint64)sys_time_arr[2] << 16) + ((uint64)sys_time_arr[3] << 24) + ((uint64)sys_time_arr[4] << 32); -// dwt_time_now = dwt_time_now >> 8; - -// uint64 tx_dly_us = instance_data[instance].storedPreLen_us + MIN_DELAYED_TX_DLY_US; -// uint64 tx_dly = convertmicrosectodevicetimeu(tx_dly_us); -// -// uint64 opt_dly = (dwt_time_now + tx_dly) >> 8; -// uint64 actual_dl = instance_data[instance].delayedReplyTime; - -// uint8 sys_time_arr[5] = {0, 0, 0, 0, 0}; -// dwt_readsystime(sys_time_arr); -// uint64 dwt_time_now = 0; -// dwt_time_now = (uint64)sys_time_arr[0] + ((uint64)sys_time_arr[1] << 8) + ((uint64)sys_time_arr[2] << 16) + ((uint64)sys_time_arr[3] << 24) + ((uint64)sys_time_arr[4] << 32); -// -// uint64 diff = convertdevicetimetosec( get_dt64(rxcb_time_now, dwt_time_now))*1000000; -// -// instance_data[instance].delayedReplyTime = (dwt_time_now + tx_dly) >> 8; -// - - - -// dwt_time_now = dwt_time_now >> 8; -// tx_dly = tx_dly >> 8; - - - dwt_writetxdata(psduLength, (uint8 *)&instance_data[instance].msg, 0) ; // write the frame data if(instancesendpacket(psduLength, DWT_START_TX_DELAYED | instance_data[instance].wait4ack, instance_data[instance].delayedReplyTime)) { -// //TODO remove -// uint8 debug_msg[100]; -// int n = sprintf((char*)&debug_msg[0], "tx/dwt: %lu/%llu ", instance_data[instance].delayedReplyTime, dwt_time_now); -// send_usbmessage(&debug_msg[0], n); -// usb_run(); - instance_data[instance].previousState = TA_INIT; instance_data[instance].nextState = TA_INIT; - instance_data[instance].testAppState = TA_RXE_WAIT; //TODO should we place this event??? maybe palce an error? + instance_data[instance].testAppState = TA_RXE_WAIT; instance_data[instance].wait4ack = 0; //clear the flag as the TX has failed the TRX is off instance_data[instance].lateTX++; @@ -1327,17 +1229,16 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) } else { -// uint8 debug_msg[100];//TODO remove -// int n = sprintf((char*)&debug_msg[0], "FINAL SENT!"); -// send_usbmessage(&debug_msg[0], n); -// usb_run(); dw_event.typePend = DWT_SIG_TX_PENDING ; // exit this interrupt and notify the application/instance that TX is in progress. instance_data[instance].timeofTx = time_now; - //TODO check below + instance_data[instance].txDoneTimeoutDuration = instance_data[instance].durationFinalTxDoneTimeout_ms; } } + //we received response to our POLL, select oldest range UWB next poll + tdma_handler.nthOldest = 1; + place_event = 1; } else if (rxd_event == DWT_SIG_RX_BLINK) @@ -1349,13 +1250,6 @@ void instance_rxgoodcallback(const dwt_cb_data_t *rxd) if(place_event) { instance_putevent(dw_event); - -#if (DEEP_SLEEP == 1) - if (instance_data[instance].sleepingEabled) - { - instance_data[instance].rxmsgcount++; - } -#endif } else { @@ -1461,50 +1355,27 @@ int instance_run(void) message = 0; } - uint32 time_now = portGetTickCnt(); +// uint32 time_now = portGetTickCnt(); - //check timeouts. - if(tdma_handler.check_timeouts(&tdma_handler, time_now)) + //only check timeouts if we aren't in the middle of ranging messages + //the TDMA reoptimization may mess up the timing + if(instance_data[instance].canPrintInfo == TRUE) { - //handle case where we timeout and no longer have any neighbors - instance_data[instance].mode = DISCOVERY; - tdma_handler.enter_discovery_mode(&tdma_handler); - inst_processtxrxtimeout(&instance_data[instance]); + //check timeouts. + if(tdma_handler.check_timeouts(&tdma_handler)) + { +// uint8 debug_msg[100]; //TODO remove +// int n = sprintf((char *)&debug_msg, "ALL TIMEOUT time_now_us: %llu", portGetTickCntMicro()); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); + + //handle case where we timeo7ut and no longer have any neighbors + instance_data[instance].mode = DISCOVERY; + tdma_handler.enter_discovery_mode(&tdma_handler); + inst_processtxrxtimeout(&instance_data[instance]); + } } -// //TODO below may not be needed or may need to be updated? -// if(done == INST_DONE_WAIT_FOR_NEXT_EVENT_TO) //we are in RX and need to timeout (Tag needs to send another poll if no Rx frame) -// { -// if(instance_data[instance].mode == DISCOVERY) -// { -// if(instance_data[instance].previousState == TA_TXBLINK_WAIT_SEND) -// { -// instance_data[instance].instanceTimerTime += instance_data[instance].tagBlinkSleepTime_ms; //set timeout time -// instance_data[instance].instanceTimerEnabled = 1; //start timer -// } -// } -// -// if(instance_data[instance].mode == TAG) //Tag (is either in RX or sleeping) -// { -// instance_data[instance].instanceTimerTime = instance_data[instance].instanceTimerTimeSaved + instance_data[instance].tagSleepTime_ms; //set timeout time -// instance_data[instance].instanceTimerEnabled = 1; //start timer -// } -// } -// -// //check if timer has expired -// if(instance_data[instance].instanceTimerEnabled == 1) -// { -// if(instance_data[instance].instanceTimerTime < portGetTickCnt()) -// { -// event_data_t dw_event; -// instance_data[instance].instanceTimerEnabled = 0; -// dw_event.rxLength = 0; -// dw_event.type = DWT_SIG_RX_TIMEOUT; -// dw_event.typeSave = 0x80 | DWT_SIG_RX_TIMEOUT; -// instance_putevent(dw_event); -// } -// } - return ((done != INST_NOT_DONE_YET) ? 1 : 0); } diff --git a/src/application/tdma_handler.c b/src/application/tdma_handler.c index 3eb870b587175ea9d955b939a757ae8670861669..0d776276c3e72d885b7cee9fbf546a97c0edfd35 100644 --- a/src/application/tdma_handler.c +++ b/src/application/tdma_handler.c @@ -21,11 +21,19 @@ static bool slot_transition(struct TDMAHandler *this) if(timeSinceSlotStart64 >= this->slotDuration_us) { +// uint8 debug_msg[100]; //TODO remove +//// int n = sprintf((char *)&debug_msg, "new slot, time_now_us: %llu", time_now_us); +// +// int n = sprintf((char *)&debug_msg, "new slot, time_now_us: %llu, state: %s, mode: %s", time_now_us, get_inst_states_string(inst->testAppState), get_instanceModes_string(inst->mode)); +// send_usbmessage(&debug_msg[0], n); +// usb_run(); + transition = TRUE; this->firstPollSentThisSlot = FALSE; this->firstPollComplete = FALSE; this->secondPollSentThisSlot = FALSE; this->infSentThisSlot = FALSE; + inst->canPrintInfo = TRUE; //we have transitioned into the next slot. //get the slot number and set the start time appropriately @@ -36,19 +44,14 @@ static bool slot_transition(struct TDMAHandler *this) if(timeSinceFrameStart64 >= frameDuration64) { //TODO remove -// uint8 debug_msg[100]; -////// int n = sprintf((char*)&debug_msg[0], "NEW FRAME, %llX, this->frameStartTime: %lu, this->slotDuration*this->framelength: %lu", instance_get_addr(), this->frameStartTime, (this->slotDuration*this->framelength)); -// int n = sprintf((char*)&debug_msg[0], "%llX, %llu, %llu", instance_get_addr(), this->lastFST, time_now_us); -// send_usbmessage(&debug_msg[0], n); -// usb_run(); + uint8 debug_msg[100]; +//// int n = sprintf((char*)&debug_msg[0], "NEW FRAME, %llX, this->frameStartTime: %lu, this->slotDuration*this->framelength: %lu", instance_get_addr(), this->frameStartTime, (this->slotDuration*this->framelength)); + int n = sprintf((char*)&debug_msg[0], "%llX, %llu, %llu", instance_get_addr(), this->lastFST, time_now_us); + send_usbmessage(&debug_msg[0], n); + usb_run(); } -// while(timeSinceFrameStart64 >= frameDuration64) -// { -// this->uwbListTDMAInfo[0].frameStartTime = timestamp_add64(this->uwbListTDMAInfo[0].frameStartTime, frameDuration64); -// timeSinceFrameStart64 -= frameDuration64; -// }//TODO check and remove if(timeSinceFrameStart64 >= frameDuration64) { int div = timeSinceFrameStart64/frameDuration64; @@ -75,6 +78,7 @@ static bool slot_transition(struct TDMAHandler *this) { //go to RX inst->mode = ANCHOR; + inst->wait4ack = 0; inst->testAppState = TA_RXE_WAIT; } } @@ -111,8 +115,8 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 f dwt_time_now = (uint64)sys_time_arr[0] + ((uint64)sys_time_arr[1] << 8) + ((uint64)sys_time_arr[2] << 16) + ((uint64)sys_time_arr[3] << 24) + ((uint64)sys_time_arr[4] << 32); uint64 time_now_us = portGetTickCntMicro(); - //time from message to tx - //assuming zero since we use DWT_START_TX_IMMEDIATE + //time from command tx to tx timestamp + uint64 infCmdToTsDelay_us = TX_CMD_TO_TX_CB_DLY_US + inst->storedPreLen_us; //tx antenna delay uint64 tx_antenna_delay = (uint64)inst->txAntennaDelay; @@ -126,7 +130,7 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 f //time from rx timestamp to now uint64 rxfs_process_delay = dwt_getdt(dw_event->timeStamp, dwt_time_now); - uint64 txrx_delay = (uint64)(convertdevicetimetosec(tx_antenna_delay + rxfs_process_delay)*1000000.0) + inst->storedPreLen_us; + uint64 txrx_delay = (uint64)(convertdevicetimetosec(tx_antenna_delay + rxfs_process_delay)*1000000.0) + infCmdToTsDelay_us; uint64 hisTimeSinceFrameStart_us = timeSinceFrameStart_us + txrx_delay; this->uwbListTDMAInfo[srcIndex].frameStartTime = timestamp_subtract64(time_now_us, hisTimeSinceFrameStart_us); @@ -242,12 +246,6 @@ static void frame_sync(struct TDMAHandler *this, event_data_t *dw_event, uint8 f static bool tx_sync_msg(struct TDMAHandler *this) { int psduLength = SYNC_FRAME_LEN_BYTES; -// int psduLength = 0; //TODO remove -//#if (USING_64BIT_ADDR==1) -// psduLength = SYNC_MSG_LEN + FRAME_CRTL_AND_ADDRESS_LS + FRAME_CRC; -//#else -// psduLength = SYNC_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC; -//#endif instance_data_t *inst = instance_get_local_structure_ptr(0); uint64 time_now_us = portGetTickCntMicro(); @@ -256,8 +254,8 @@ static bool tx_sync_msg(struct TDMAHandler *this) memcpy(&inst->sync_msg.messageData[SYNC_TSFS], &myTimeSinceFrameStart_us, 6); inst->sync_msg.seqNum = inst->frameSN++; - dwt_setrxaftertxdelay((uint16)0); - dwt_setrxtimeout((uint16)0); + dwt_setrxaftertxdelay(0); //units are 1.0256us + dwt_setrxtimeout(0); //units are 1.0256us inst->wait4ack = 0; dwt_writetxdata(psduLength, (uint8 *)&inst->sync_msg, 0) ; // write the frame data @@ -275,8 +273,7 @@ static bool tx_sync_msg(struct TDMAHandler *this) inst->testAppState = TA_TX_WAIT_CONF; // wait confirmation inst->timeofTx = portGetTickCnt(); - //TODO check below - inst->txDoneTimeoutDuration = inst->durationSyncTxDoneTimeout_ms; //NOTE timeout duration found experimentally, may need to be changed if the delays in instance.h are modified + inst->txDoneTimeoutDuration = inst->durationSyncTxDoneTimeout_ms; //NOTE timeout duration found experimentally return TRUE; } } @@ -341,55 +338,147 @@ static bool tx_select(struct TDMAHandler *this) } else { - if(this->firstPollSentThisSlot == TRUE && this->secondPollSentThisSlot == FALSE && this->firstPollComplete == FALSE) + + uint32 timeSinceRange[UWB_LIST_SIZE] = {0}; //0th entry unused + uint32 numNeighbors = 0; + uint32 time_now = portGetTickCnt(); + + //get time since range for each neighbor + for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self + { + if(this->uwbListTDMAInfo[i].connectionType == UWB_LIST_NEIGHBOR) + { + numNeighbors++; + timeSinceRange[i] = get_dt32(this->uwbListTDMAInfo[i].lastRange, time_now); + } + } + + if(this->nthOldest > numNeighbors) { - int test = 1; - test++; + this->nthOldest = 1; } - //check which neighbor UWB hasn't been ranged with for the longest amount of time - uint32 timeSinceOldestRange = 0; - uint32 timeSinceSecondOldestRange = 0; - uint8 second_oldest_uwb_index = 255; + //get the nth oldest for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self { if(this->uwbListTDMAInfo[i].connectionType == UWB_LIST_NEIGHBOR) { - uint32 timeSinceRange = get_dt32(this->uwbListTDMAInfo[i].lastRange, portGetTickCnt()); - - if(timeSinceOldestRange == 0) + uint8 numOlder = 0; + for(int j = 1; j < inst->uwbListLen; j++)//0 reserved for self { - timeSinceOldestRange = timeSinceRange; - timeSinceSecondOldestRange = timeSinceRange; - - uwb_index = i; - second_oldest_uwb_index = i; + if(i != j) + { + if(this->uwbListTDMAInfo[j].connectionType == UWB_LIST_NEIGHBOR) + { + if(timeSinceRange[i] < timeSinceRange[j]) + { + numOlder++; + } + } + } } - else if(timeSinceRange > timeSinceOldestRange) + + if(numOlder + 1 == this->nthOldest) { - timeSinceSecondOldestRange = timeSinceOldestRange; - second_oldest_uwb_index = uwb_index; - timeSinceOldestRange = timeSinceRange; uwb_index = i; - } - else if(timeSinceRange > timeSinceSecondOldestRange) - { - timeSinceSecondOldestRange = timeSinceRange; - second_oldest_uwb_index = i; - } - else if(timeSinceOldestRange == timeSinceSecondOldestRange) - { - timeSinceSecondOldestRange = timeSinceRange; - second_oldest_uwb_index = i; + break; } } - } - if(this->firstPollSentThisSlot == TRUE && this->secondPollSentThisSlot == FALSE && this->firstPollComplete == FALSE) - { - uwb_index = second_oldest_uwb_index; +// if(this->uwbListTDMAInfo[i].connectionType == UWB_LIST_NEIGHBOR) +// { +// uint8 numOlder = 0; +// for(int j = 1; j < inst->uwbListLen; j++)//0 reserved for self +// { +// if(i != j) +// { +// if(this->uwbListTDMAInfo[j].connectionType == UWB_LIST_NEIGHBOR) +// { +// if(timeSinceRange[i] <= timeSinceRange[j]) +// { +// numOlder++; +// } +// } +// } +// } +// +// bool range = FALSE; +// if(this->firstPollSentThisSlot == TRUE) +// { +// if(this->firstPollComplete == FALSE && this->secondPollSentThisSlot == FALSE) +// { +// //second poll this slot +// +// if(numOlder + 1 == this->nthOldest) +// { +// range = TRUE; +// } +// } +// } +// else //first poll this slot +// { +// //want to range with the oldest index +// if(numOlder + 1 == this->nthOldest) +// { +// range = TRUE; +// } +// } +// +// if(range == TRUE) +// { +// uwb_index = i; +//// this->nthOldest++; +// break; +// } +// } } +// //TODO make this work right when two or more drop out at the same time +// //check which neighbor UWB hasn't been ranged with for the longest amount of time +// uint32 timeSinceOldestRange = 0; +// uint32 timeSinceSecondOldestRange = 0; +// uint8 second_oldest_uwb_index = 255; +// for(int i = 1; i < inst->uwbListLen; i++)//0 reserved for self +// { +// if(this->uwbListTDMAInfo[i].connectionType == UWB_LIST_NEIGHBOR) +// { +// uint32 timeSinceRange = get_dt32(this->uwbListTDMAInfo[i].lastRange, portGetTickCnt()); +// +// if(timeSinceOldestRange == 0) +// { +// timeSinceOldestRange = timeSinceRange; +// timeSinceSecondOldestRange = timeSinceRange; +// +// uwb_index = i; +// second_oldest_uwb_index = i; +// } +// else if(timeSinceRange > timeSinceOldestRange) +// { +// timeSinceSecondOldestRange = timeSinceOldestRange; +// second_oldest_uwb_index = uwb_index; +// timeSinceOldestRange = timeSinceRange; +// uwb_index = i; +// } +// else if(timeSinceRange > timeSinceSecondOldestRange) +// { +// timeSinceSecondOldestRange = timeSinceRange; +// second_oldest_uwb_index = i; +// } +// else if(timeSinceOldestRange == timeSinceSecondOldestRange) +// { +// timeSinceSecondOldestRange = timeSinceRange; +// second_oldest_uwb_index = i; +// } +// } +// } +// +// if(this->firstPollSentThisSlot == TRUE && this->secondPollSentThisSlot == FALSE && this->firstPollComplete == FALSE) +// { +// uwb_index = second_oldest_uwb_index; +// } + + + if(uwb_index == 255 && inst->uwbListLen > 1) { uwb_index = 1; @@ -429,7 +518,7 @@ static bool tx_select(struct TDMAHandler *this) else if(this->secondPollSentThisSlot == FALSE && this->firstPollComplete == FALSE) { this->secondPollSentThisSlot = TRUE; - inst->testAppState = TA_TXPOLL_WAIT_SEND; //select new uwb index! + inst->testAppState = TA_TXPOLL_WAIT_SEND; } else if(this->infSentThisSlot == FALSE) { @@ -1019,7 +1108,8 @@ static void find_assign_slot(struct TDMAHandler *this) while(TRUE) { //GU - for(uint8 i = 1; i < info->framelength; i++) //TODO make sure we don't accidentally assign to slot 0 + uint8 slotsAssigned = 0; + for(uint8 i = 1; i < info->framelength; i++)//do not assign to 0th slot { bool assigned = FALSE; @@ -1076,7 +1166,13 @@ static void find_assign_slot(struct TDMAHandler *this) if(assigned == FALSE) { this->assign_slot(info, i, FALSE); - assignment_made = TRUE; //TODO just stop here? or get all unassigned slots? + assignment_made = TRUE; + + slotsAssigned++; + if(slotsAssigned > 1) //assign self up to two empty slots + { + break; + } } } @@ -1531,6 +1627,9 @@ static void enter_discovery_mode(struct TDMAHandler *this) this->set_discovery_mode(this, WAIT_INF_REG, time_now); this->collectInfStartTime = time_now; + instance_data_t *inst = instance_get_local_structure_ptr(0); + inst->canPrintInfo = TRUE; + this->tdma_free_all_slots(this); } @@ -1556,13 +1655,14 @@ static void set_discovery_mode(struct TDMAHandler *this, DISCOVERY_MODE discover } case WAIT_INF_INIT: { - this->discovery_mode_duration = 400;//TODO use a smart timeout value + this->discovery_mode_duration = this->slotDuration_ms; this->discovery_mode_expires = TRUE; break; } case WAIT_RNG_INIT: { - this->discovery_mode_duration = 400;//TODO use a smart timeout value + instance_data_t *inst = instance_get_local_structure_ptr(0); + this->discovery_mode_duration = inst->durationWaitRangeInit_ms; this->discovery_mode_expires = TRUE; break; } @@ -1816,7 +1916,7 @@ static void check_discovery_mode_expiration(struct TDMAHandler *this) } -static bool check_timeouts(struct TDMAHandler *this, uint32 time_now) +static bool check_timeouts(struct TDMAHandler *this) { instance_data_t *inst = instance_get_local_structure_ptr(0); uint32 delta_t = 0; @@ -1833,9 +1933,9 @@ static bool check_timeouts(struct TDMAHandler *this, uint32 time_now) { case UWB_LIST_NEIGHBOR: { - delta_t = get_dt32(info->lastCommNeighbor, time_now); + delta_t = get_dt32(info->lastCommNeighbor, portGetTickCnt()); //get time now here in case rx interrupt occurs before get_dt call - if(delta_t > UWB_COMM_TIMEOUT) + if(delta_t > inst->durationUwbCommTimeout_ms) { if(info->lastCommHidden != 0) { @@ -1870,9 +1970,9 @@ static bool check_timeouts(struct TDMAHandler *this, uint32 time_now) } case UWB_LIST_HIDDEN: { - delta_t = get_dt32(info->lastCommHidden, time_now); + delta_t = get_dt32(info->lastCommHidden, portGetTickCnt()); //get time now here in case rx interrupt occurs before get_dt call - if(delta_t > UWB_COMM_TIMEOUT) + if(delta_t > inst->durationUwbCommTimeout_ms) { if(info->lastCommTwiceHidden != 0) { @@ -1892,9 +1992,9 @@ static bool check_timeouts(struct TDMAHandler *this, uint32 time_now) } case UWB_LIST_TWICE_HIDDEN: { - delta_t = get_dt32(info->lastCommTwiceHidden, time_now); + delta_t = get_dt32(info->lastCommTwiceHidden, portGetTickCnt()); //get time now here in case rx interrupt occurs before get_dt call - if(delta_t > UWB_COMM_TIMEOUT) + if(delta_t > inst->durationUwbCommTimeout_ms) { info->connectionType = UWB_LIST_INACTIVE; this->free_slots(info); @@ -1948,47 +2048,6 @@ static bool check_timeouts(struct TDMAHandler *this, uint32 time_now) } -static void remove_uwbinfo(struct TDMAHandler *this, uint8 uwb_index) -{ - instance_data_t *inst = instance_get_local_structure_ptr(0); - - if(uwb_index > 0 && uwb_index < inst->uwbListLen) - { - this->free_slots(&this->uwbListTDMAInfo[uwb_index]); - - for(int i=uwb_index; i<inst->uwbListLen-1; i++) - { - struct TDMAInfo *info_a = &this->uwbListTDMAInfo[i]; - struct TDMAInfo *info_b = &this->uwbListTDMAInfo[i+1]; - - info_a->connectionType = info_b->connectionType; - info_a->lastCommNeighbor = info_b->lastCommNeighbor; - info_a->lastCommHidden = info_b->lastCommHidden; - info_a->lastCommTwiceHidden = info_b->lastCommTwiceHidden; - info_a->lastRange = info_b->lastRange; - info_a->frameStartTime = info_b->frameStartTime; - info_a->framelength = info_b->framelength; - info_a->slotsLength = info_b->slotsLength; - info_a->slots = info_b->slots; - } - - - struct TDMAInfo *info_end = &this->uwbListTDMAInfo[inst->uwbListLen-1]; //maybe this! - info_end->connectionType = UWB_LIST_INACTIVE; - info_end->lastCommNeighbor = 0; - info_end->lastCommHidden = 0; - info_end->lastCommTwiceHidden = 0; - info_end->lastRange = 0; - info_end->frameStartTime = 0; - info_end->framelength = MIN_FRAMELENGTH; - this->free_slots(info_end); - } -} - - - - - static void usb_dump_tdma(struct TDMAHandler *this) { instance_data_t *inst = instance_get_local_structure_ptr(0); @@ -2050,33 +2109,8 @@ static void usb_dump_tdma(struct TDMAHandler *this) } -//uint8 get_largest_framelength(struct TDMAHandler *this) -//{ -// instance_data_t *inst = instance_get_local_structure_ptr(0); -// -// uint8 max_framelength = MIN_FRAMELENGTH; -// if(this->myTDMAInfo.framelength > max_framelength) -// { -// max_framelength = this->myTDMAInfo.framelength; -// } -// -// for(int i = 0; i < inst->uwbListLen; i++) -// { -// if(inst->uwbListType[i] == UWB_LIST_NEIGHBOR) -// { -// if(this->uwbFramelengths[i] > max_framelength) -// { -// max_framelength = this->uwbFramelengths[i]; -// } -// } -// -// } -// -// return max_framelength; -//} - -static struct TDMAHandler new(){ +static struct TDMAHandler new(uint64 slot_duration){ struct TDMAHandler ret = {}; ret.slot_transition = &slot_transition; @@ -2103,7 +2137,6 @@ static struct TDMAHandler new(){ ret.set_discovery_mode = &set_discovery_mode; ret.check_discovery_mode_expiration = &check_discovery_mode_expiration; ret.check_timeouts = &check_timeouts; - ret.remove_uwbinfo = &remove_uwbinfo; ret.usb_dump_tdma = &usb_dump_tdma; @@ -2112,11 +2145,11 @@ static struct TDMAHandler new(){ ret.deconflict_slot_pair = &deconflict_slot_pair; ret.self_conflict = &self_conflict; - - ret.slotDuration_ms = 50; //TODO should be a function of the data rate and the max number of UWBs - ret.slotDuration_us = ret.slotDuration_ms*1000; + ret.slotDuration_us = slot_duration; + ret.slotDuration_ms = slot_duration/1000 + (slot_duration%1000 == 0 ? 0 : 1); uint64 time_now_us = portGetTickCntMicro(); + uint32 time_now = portGetTickCnt(); ret.maxFramelength = (uint8)MIN_FRAMELENGTH; while(ret.maxFramelength < (int)UWB_LIST_SIZE + 1) @@ -2134,7 +2167,7 @@ static struct TDMAHandler new(){ ret.uwbListTDMAInfo[i].lastCommNeighbor = 0; ret.uwbListTDMAInfo[i].lastCommHidden = 0; ret.uwbListTDMAInfo[i].lastCommTwiceHidden = 0; - ret.uwbListTDMAInfo[i].lastRange = 0; + ret.uwbListTDMAInfo[i].lastRange = time_now; } ret.uwbListTDMAInfo[0].connectionType = UWB_LIST_SELF; @@ -2144,13 +2177,14 @@ static struct TDMAHandler new(){ ret.firstPollSentThisSlot = FALSE; ret.firstPollComplete = FALSE; ret.secondPollSentThisSlot = FALSE; - ret.slotStartDelay_us = 4000; - ret.frameSyncThreshold_us = 2*ret.slotStartDelay_us; + ret.nthOldest = 1; + ret.nthOldestPlus = 2; + ret.slotStartDelay_us = SLOT_START_BUFFER_US; + ret.frameSyncThreshold_us = ret.slotStartDelay_us; ret.infMessageLength = 0; ret.enter_discovery_mode(&ret); -// ret.collectInfDuration = ret.maxFramelength*ret.slotDuration; - ret.collectInfDuration = 10000; //TODO change this back + ret.collectInfDuration = ret.maxFramelength*ret.slotDuration_ms; ret.waitInfDuration = ret.collectInfDuration; ret.blinkPeriodRand = (uint32)rand()%BLINK_PERIOD_RAND_MS; diff --git a/src/application/tdma_handler.h b/src/application/tdma_handler.h index 29aa932159f9040d513f7ff34635d34d3d7116e2..19fa087d9bef7942ceacd94ff7f61ca49ca8c4ec 100644 --- a/src/application/tdma_handler.h +++ b/src/application/tdma_handler.h @@ -46,12 +46,14 @@ struct TDMAHandler uint64 lastFST; uint64 lastSlotStartTime64; - 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 + uint32 slotDuration_ms; + uint32 slotDuration_us; bool infSentThisSlot; bool firstPollSentThisSlot; bool firstPollComplete; bool secondPollSentThisSlot; + uint8 nthOldest; + uint8 nthOldestPlus; uint64 slotStartDelay_us; //time between slot start and transmission within that slot uint64 frameSyncThreshold_us; @@ -83,7 +85,7 @@ struct TDMAHandler void (*enter_discovery_mode)(struct TDMAHandler *this); void (*set_discovery_mode)(struct TDMAHandler *this, DISCOVERY_MODE mode, uint32 time_now); void (*check_discovery_mode_expiration)(struct TDMAHandler *this); - bool (*check_timeouts)(struct TDMAHandler *this, uint32 time_now); + bool (*check_timeouts)(struct TDMAHandler *this); void (*remove_uwbinfo)(struct TDMAHandler *this, uint8 uwb_index); void (*usb_dump_tdma)(struct TDMAHandler *this); bool (*slot_assigned)(struct TDMAInfo *info, uint8 slot); @@ -108,7 +110,7 @@ struct TDMAHandler extern const struct TDMAHandlerClass { - struct TDMAHandler (*new)(); + struct TDMAHandler (*new)(uint64 slot_duration); } TDMAHandler;