/**
 * @file    decawave_app.h
 * @brief   deacarange
 * @version 6.0
 * @date 27/06/2017
 */
 
#ifndef _DECAWAVE_APP_H_
#define _DECAWAVE_APP_H_

#include "deca_types.h"
#include "deca_device_api.h"


typedef void (*ReportRangeType)(double distance);
typedef void (*ReportTagInfoType)(uint8_t,uint8_t);
typedef void (*OperationChangeType)(void);


/******************************************************************************************************************
********************* NOTES on DW (MP) features/options ***********************************************************
*******************************************************************************************************************/

//DEEP_SLEEP mode can be used, for example, by a Tag instance to put the DW1000 into low-power deep-sleep mode, there are two cases:
// 1. when the Anchor is sending the range report back to the Tag, the Tag will enter sleep after a ranging exchange is finished
// once it receives a report or times out, before the next poll message is sent (before next ranging exchange is started).
// 2. when the Anchor is not sending the report the Tag will go automatically to sleep after the final message is sent
#define DEEP_SLEEP 			(1) 	// To enable deep-sleep set this to 1
#define CORRECT_RANGE_BIAS  (1)     // Compensate for small bias due to uneven accumulator growth at close up high power
#define USING_64BIT_ADDR 	(1) 	// when set to 0 - the DecaRanging application will use 16-bit addresses (TODO 0 is not tested/fonctional yet)
#define IMMEDIATE_RESPONSE 	(1)

/***************************************************************************************************
 * DEFINES 
 *
 **************************************************************************************************/	
#define CEIL_DIV(A, B)      \
    (((A) + (B) - 1) / (B))

#define NUM_INST            1
#define SPEED_OF_LIGHT      (299702547.0)     	// in m/s in air
#define MASK_40BIT			(0x00FFFFFFFFFF)  	// MP counter is 40 bits
#define MASK_TXDTS			(0x00FFFFFFFE00)  	// The TX timestamp will snap to 8 ns resolution - mask lower 9 bits.
#define SIG_RX_BLINK		7					// Received ISO EUI 64 blink message
#define SIG_RX_UNKNOWN		99					// Received an unknown frame

//Fast 2WR function codes
#define RTLS_DEMO_MSG_RNG_INIT 		(0x20)          // Ranging initiation message
#define RTLS_DEMO_MSG_TAG_POLL   	(0x21)          // Tag poll message
#define RTLS_DEMO_MSG_ANCH_RESP   	(0x10)          // Anchor response to poll
#define RTLS_DEMO_MSG_TAG_FINAL    	(0x29)          // Tag final massage back to Anchor (0x29 because of 5 byte timestamps needed for PC app)

//lengths including the Decaranging Message Function Code byte
#define TAG_POLL_MSG_LEN			1					// FunctionCode(1),
#define ANCH_RESPONSE_MSG_LEN 		9               	// FunctionCode(1), RespOption (1), OptionParam(2), Measured_TOF_Time(5)
#define TAG_FINAL_MSG_LEN     		16              	// FunctionCode(1), Poll_TxTime(5), Resp_RxTime(5), Final_TxTime(5)
#define RANGINGINIT_MSG_LEN			7					// FunctionCode(1), Tag Address (2), Response Time (2) * 2
#define MAX_MAC_MSG_DATA_LEN   		(TAG_FINAL_MSG_LEN) //max message len of the above

#define STANDARD_FRAME_SIZE         127
#define ADDR_BYTE_SIZE_L            (8)
#define ADDR_BYTE_SIZE_S            (2)
#define FRAME_CONTROL_BYTES         2
#define FRAME_SEQ_NUM_BYTES         1
#define FRAME_PANID                 2
#define FRAME_CRC					2
#define FRAME_SOURCE_ADDRESS_S		(ADDR_BYTE_SIZE_S)
#define FRAME_DEST_ADDRESS_S 		(ADDR_BYTE_SIZE_S)
#define FRAME_SOURCE_ADDRESS_L   	(ADDR_BYTE_SIZE_L)
#define FRAME_DEST_ADDRESS_L  		(ADDR_BYTE_SIZE_L)
#define FRAME_CTRLP					(FRAME_CONTROL_BYTES + FRAME_SEQ_NUM_BYTES + FRAME_PANID) 		//5
#define FRAME_CRTL_AND_ADDRESS_L    (FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_L + FRAME_CTRLP) 	//21 bytes for 64-bit addresses)
#define FRAME_CRTL_AND_ADDRESS_S    (FRAME_DEST_ADDRESS_S + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) 	//9 bytes for 16-bit addresses)
#define FRAME_CRTL_AND_ADDRESS_LS	(FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) 	//15 bytes for 1 16-bit address and 1 64-bit address)
#define MAX_USER_PAYLOAD_STRING_LL 	(STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-TAG_FINAL_MSG_LEN-FRAME_CRC) 	//127 - 21 - 16 - 2 = 88
#define MAX_USER_PAYLOAD_STRING_SS 	(STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-TAG_FINAL_MSG_LEN-FRAME_CRC) 	//127 - 9 - 16 - 2 = 100
#define MAX_USER_PAYLOAD_STRING_LS 	(STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 15 - 16 - 2 = 94

//NOTE: the user payload assumes that there are only 88 "free" bytes to be used for the user message (it does not scale according to the addressing modes)
#define MAX_USER_PAYLOAD_STRING	MAX_USER_PAYLOAD_STRING_LL

// 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 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)
#else
    #define RNG_INIT_FRAME_LEN_BYTES (RANGINGINIT_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)
    #define RESP_FRAME_LEN_BYTES (ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
    #define FINAL_FRAME_LEN_BYTES (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC)
#endif

#define BLINK_FRAME_CONTROL_BYTES       (1)
#define BLINK_FRAME_SEQ_NUM_BYTES       (1)
#define BLINK_FRAME_CRC					(FRAME_CRC)
#define BLINK_FRAME_SOURCE_ADDRESS      (ADDR_BYTE_SIZE_L)
#define BLINK_FRAME_CTRLP				(BLINK_FRAME_CONTROL_BYTES + BLINK_FRAME_SEQ_NUM_BYTES) //2
#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 ANCHOR_LIST_SIZE			(4) 	//this is limited to 4 in this application see also
#define TAG_LIST_SIZE				(1)		//anchor will range with 1st Tag it gets blink from

#define DELAYRX_WAIT4REPORT			(160)   //this is the time in us the RX turn on is delayed (after Final transmission and before Report reception starts)

#define BLINK_SLEEP_DELAY			1000 	// default Blink delay in ms
#define POLL_SLEEP_DELAY			500 	// default poll delay in ms
//#define POLL_SLEEP_DELAY			50 		//ms	//NOTE 200 gives 5 Hz range period

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// NOTE: the maximum RX timeout is ~ 65ms
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#define INST_DONE_WAIT_FOR_NEXT_EVENT   	1   //this signifies that the current event has been processed and instance is ready for next one
#define INST_DONE_WAIT_FOR_NEXT_EVENT_TO    2   //this signifies that the current event has been processed and that instance is waiting for next one with a timeout
												//which will trigger if no event coming in specified time
#define INST_NOT_DONE_YET               	0   //this signifies that the instance is still processing the current event

// Function code byte offset (valid for all message types).
#define FCODE                               0               // Function code is 1st byte of messageData

// Final message byte offsets.
#define PTXT                                1
#define RRXT                                6
#define FTXT                                11

// Length of ToF value in report message. Can be used as offset to put up to 4 ToF values in the report message.
#define TOFR                                4

// Anchor response byte offsets.
#define RES_R1                              1               // Response option octet 0x02 (1),
#define RES_R2                              2               // Response option parameter 0x00 (1) - used to notify Tag that the report is coming
#define RES_R3                              3               // Response option parameter 0x00 (1),

// Ranging init message byte offsets. Composed of tag short address, anchor response delay and tag response delay.
#define RNG_INIT_TAG_SHORT_ADDR_LO 1
#define RNG_INIT_TAG_SHORT_ADDR_HI 2
#define RNG_INIT_ANC_RESP_DLY_LO 3
#define RNG_INIT_ANC_RESP_DLY_HI 4
#define RNG_INIT_TAG_RESP_DLY_LO 5
#define RNG_INIT_TAG_RESP_DLY_HI 6

// 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
#define RESP_DLY_UNIT_MASK 0x8000

// Response time possible units: microseconds or milliseconds.
#define RESP_DLY_UNIT_US 0
#define RESP_DLY_UNIT_MS 1

// Convert microseconds to symbols, float version.
// param  x  value in microseconds
// return  value in symbols.
#define US_TO_SY(x) ((x) / 1.0256)

// Convert microseconds to symbols, integer version.
// param  x  value in microseconds
// return  value in symbols.
#define US_TO_SY_INT(x) (((x) * 10000) / 10256)

// Minimum delay between reception and following transmission.
#define RX_TO_TX_TIME_US 350 						// default : 150, MODIF JF mesure 350us entre RX and TX
#define RXTOTXTIME       ((int)(150.0 / 1.0256)) 	// e.g. Poll RX to Response TX time

// Default anchor turn-around time: has to be RX_TO_TX_TIME_US when using immediate response, cannot be less than 170 us when not.
#define ANC_TURN_AROUND_TIME_US RX_TO_TX_TIME_US
#if (IMMEDIATE_RESPONSE == 1) && (ANC_TURN_AROUND_TIME_US != RX_TO_TX_TIME_US)
    #error "When using immediate response, anchor turn-around time has to be equal to RX to TX time!"
#endif

// Default tag turn-around time: cannot be less than 300 us. Defined as 500 us
// so that the tag is not transmitting more than one frame by millisecond (for
// power management purpose).
#define TAG_TURN_AROUND_TIME_US 600 //500

// "Long" response delays value. Over this limit, special processes must be applied.
#define LONG_RESP_DLY_LIMIT_US 25000

// Delay between blink reception and ranging init message. This is the same for all modes.
#define RNG_INIT_REPLY_DLY_MS 10 //(150)

// Reception start-up time, in symbols.
#define RX_START_UP_SY 16

#define DWT_PRF_64M_RFDLY   (514.462f)
#define DWT_PRF_16M_RFDLY   (513.9067f)

// Liste of Roles :
//Listener = in this mode, the instance only receives frames, does not respond
//Tag = Exchanges DecaRanging messages (Poll-Response-Final) with Anchor and enabling Anchor to calculate the range between the two instances
//Anchor = see above
typedef enum instanceModes {LISTENER, TAG, ANCHOR, TAG_TDOA, NUM_MODES} INST_MODE;

// Existing frames type in ranging process.
enum
{
    BLINK = 0,
    RNG_INIT,
    POLL,
    RESP,
    FINAL,
    FRAME_TYPE_NB
};

// Response delays types present in ranging init message.
enum
{
    RESP_DLY_ANC = 0,
    RESP_DLY_TAG,
    RESP_DLY_NB
};

 /***************************************************************************************************
 * STRUCTURE DEFINITIONS 
 *
 **************************************************************************************************/	

/** @struct chConfig_t
 *  @brief UWB Signal Configuration structure
 */
typedef struct
{
    uint8 channel ;				/*!< Channel */
    uint8 prf ;					/*!< Pulse repetition frequency */
    uint8 datarate ;			/*!< Data rate */
    uint8 preambleCode ;		/*!< Preamble Code */
    uint8 preambleLength ;		/*!< Preamble Length */
    uint8 pacSize ;				/*!< Pac Size */
    uint8 nsSFD ;				/*!< Non-Standard SFD */
    uint16 sfdTO ;				/*!< SFD Time-Out */
} chConfig_t ;

typedef struct
{
    uint8 frameCtrl[2];                         	/*!<  frame control bytes 00-01 */
    uint8 seqNum;                               	/*!<  sequence_number 02 */
    uint8 panID[2];                             	/*!<  PAN ID 03-04 */
    uint8 destAddr[ADDR_BYTE_SIZE_L];             	/*!<  05-12 using 64 bit addresses */
    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	/*!<  13-20 using 64 bit addresses */
    uint8 messageData[MAX_USER_PAYLOAD_STRING_LL] ; /*!<  22-124 (application data and any user payload) */
    uint8 fcs[2] ;                              	/*!<  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes. */
} srd_msg_dlsl ;

typedef struct
{
    uint8 frameCtrl[2];                         	/*!<  frame control bytes 00-01 */
    uint8 seqNum;                               	/*!<  sequence_number 02 */
    uint8 panID[2];                             	/*!<  PAN ID 03-04 */
    uint8 destAddr[ADDR_BYTE_SIZE_S];             	/*!<  05-06 */
    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	/*!<  07-08 */
    uint8 messageData[MAX_USER_PAYLOAD_STRING_SS] ; /*!<  09-124 (application data and any user payload) */
    uint8 fcs[2] ;                              	/*!<  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes. */
} srd_msg_dsss ;

typedef struct
{
    uint8 frameCtrl[2];                         	/*!<  frame control bytes 00-01 */
    uint8 seqNum;                               	/*!<  sequence_number 02 */
    uint8 panID[2];                             	/*!<  PAN ID 03-04 */
    uint8 destAddr[ADDR_BYTE_SIZE_L];             	/*!<  05-12 using 64 bit addresses */
    uint8 sourceAddr[ADDR_BYTE_SIZE_S];           	/*!<  13-14 */
    uint8 messageData[MAX_USER_PAYLOAD_STRING_LS] ; /*!<  15-124 (application data and any user payload) */
    uint8 fcs[2] ;                              	/*!<  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes. */
} srd_msg_dlss ;

typedef struct
{
    uint8 frameCtrl[2];                         	/*!<  frame control bytes 00-01 */
    uint8 seqNum;                               	/*!<  sequence_number 02 */
    uint8 panID[2];                             	/*!<  PAN ID 03-04 */
    uint8 destAddr[ADDR_BYTE_SIZE_S];             	/*!<  05-06 */
    uint8 sourceAddr[ADDR_BYTE_SIZE_L];           	/*!<  07-14 using 64 bit addresses */
    uint8 messageData[MAX_USER_PAYLOAD_STRING_LS] ; /*!<  15-124 (application data and any user payload) */
    uint8 fcs[2] ;                              	/*!<  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes. */
} srd_msg_dssl ;

//12 octets for Minimum IEEE ID blink
typedef struct
{
    uint8 frameCtrl;                         		/*!<  frame control bytes 00 */
    uint8 seqNum;                               	/*!<  sequence_number 01 */
    uint8 tagID[BLINK_FRAME_SOURCE_ADDRESS];        /*!<  02-09 64 bit address */
    uint8 fcs[2] ;                              	/*!<  10-11  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes. */
} iso_IEEE_EUI64_blink_msg ;

//18 octets for IEEE ID blink with Temp and Vbat values
typedef struct
{
    uint8 frameCtrl;                         		/*!<  frame control bytes 00 */
    uint8 seqNum;                               	/*!<  sequence_number 01 */
    uint8 tagID[BLINK_FRAME_SOURCE_ADDRESS];        /*!<  02-09 64 bit addresses */
	uint8 enchead[2];								/*!<  10-11 2 bytes (encoded header and header extension) */
	uint8 messageID;								/*!<  12 message ID (0xD1) - DecaWave message */
	uint8 temp;										/*!<  13 temperature value */
	uint8 vbat;										/*!<  14 voltage value */ 
	uint8 gpio;										/*!<  15 gpio status */
    uint8 fcs[2] ;                              	/*!<  16-17  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes. */
} iso_IEEE_EUI64_blinkdw_msg ;

typedef struct
{
    uint8 frameCtrl[2];                         	/*!<  frame control bytes 00-01 */
    uint8 seqNum;                               	/*!<  sequence_number 02 */
    uint8 fcs[2] ;                              	/*!<  03-04  CRC */
} ack_msg ;

typedef struct
{
    uint8 channelNumber ;       					/*!< valid range is 1 to 11 */
    uint8 preambleCode ;        					/*!< 00 = use NS code, 1 to 24 selects code */
    uint8 pulseRepFreq ;        					/*!< NOMINAL_4M, NOMINAL_16M, or NOMINAL_64M */ 
    uint8 dataRate ;            					/*!< DATA_RATE_1 (110K), DATA_RATE_2 (850K), DATA_RATE_3 (6M81) */
    uint8 preambleLen ;         					/*!< values expected are 64, (128), (256), (512), 1024, (2048), and 4096 */
    uint8 pacSize ;
    uint8 nsSFD ;									/*!< Non-Standard SFD */
    uint16 sfdTO;  									/*!< SFD timeout value (in symbols) e.g. preamble length (128) + SFD(8) - PAC + some margin ~ 135us... DWT_SFDTOC_DEF; */
} instanceConfig_t ;

typedef struct
{
	uint32 diffRmP;
	uint32 diffFmR;
} rtd_t;

typedef struct 
{
	uint8 PGdelay;

	//TX POWER
    //31:24     BOOST_0.125ms_PWR
	//23:16     BOOST_0.25ms_PWR-TX_SHR_PWR
	//15:8      BOOST_0.5ms_PWR-TX_PHR_PWR
	//7:0       DEFAULT_PWR-TX_DATA_PWR
	uint32 txPwr[2]; 
}tx_struct;

typedef struct
{
    INST_MODE mode;						/**< instance mode (tag or anchor) */

	//configuration structures
	dwt_config_t    configData ;		/**< DW1000 channel configuration */
	dwt_txconfig_t  configTX ;			/**< DW1000 TX power configuration */
	uint16			txantennaDelay ; 	/**< DW1000 TX antenna delay */
	uint16			rxantennaDelay ; 	/**< DW1000 RX antenna delay */
	uint8 antennaDelayChanged;			/**< Indicates if antenna settings has been changed */
	
	// "MAC" features
    uint8 frameFilteringEnabled ;		/**< frame filtering is enabled */

    // Is sleeping between frames enabled?
    uint8 sleep_en;						/**< Sleep enabled? */

	//timeouts and delays
	int tagSleepTime_ms; 				/**< Time between each poll in milliseconds */
	int tagBlinkSleepTime_ms; 			/**< Time between each blink in milliseconds */
	
	//this is the delay used for the delayed transmit (when sending the ranging init, response, and final messages)
	uint64 rnginitReplyDelay ;
	uint64 finalReplyDelay ;
	uint64 responseReplyDelay ;
	int finalReplyDelay_ms ;

	// xx_sy the units are 1.0256 us
	uint32 txToRxDelayAnc_sy ;    		/**<  this is the delay used after sending a response and turning on the receiver to receive final */
	uint32 txToRxDelayTag_sy ;   		/**<  this is the delay used after sending a poll and turning on the receiver to receive response */
	int rnginitW4Rdelay_sy ;			/**<  this is the delay used after sending a blink and turning on the receiver to receive the ranging init message */

	int fwtoTime_sy ;					/**<  this is final message duration (longest out of ranging messages) */
	int fwtoTimeB_sy ;					/**<  this is the ranging init message duration */

	uint32 delayedReplyTime;			/**<  delayed reply time of delayed TX message - high 32 bits */

    uint32 rxTimeouts ;

    // Pre-computed frame lengths for frames involved in the ranging process, in microseconds.
    uint32 fl_us[FRAME_TYPE_NB];

	//message structures used for transmitted messages
#if (USING_64BIT_ADDR == 1)
	srd_msg_dlsl rng_initmsg ;	// ranging init message (destination long, source long)
    srd_msg_dlsl msg ;			// simple 802.15.4 frame structure (used for tx message) - using long addresses
#else
	srd_msg_dlss rng_initmsg ;  // ranging init message (destination long, source short)
    srd_msg_dsss msg ;			// simple 802.15.4 frame structure (used for tx message) - using short addresses
#endif
	iso_IEEE_EUI64_blink_msg blinkmsg ; // frame structure (used for tx blink message)

	//messages used in "fast" ranging ...
	srd_msg_dlss rnmsg ; 			// ranging init message structure
	srd_msg_dsss msg_f ; 			// ranging message with 16-bit addresses - used for "fast" ranging

	//Tag function address/message configuration
	uint8   eui64[8];				/**<  devices EUI 64-bit address */
	uint16  tagShortAdd ;		    /**<  Tag's short address (16-bit) used when USING_64BIT_ADDR == 0 */
	uint16  psduLength ;			/**<  used for storing the frame length */
    uint8   frame_sn;				/**< modulo 256 frame sequence number - it is incremented for each new frame transmittion */
	uint16  panid ;					/**< panid used in the frames */

    uint8 relpyAddress[8] ;         /**< address of the anchor the tag is ranging with */

	//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 anchorRespRxTime ;	    // receive time of response message
	uint64 tagPollRxTime ;          // receive time of poll message

	//32 bit timestamps (when "fast" ranging is used)
	uint32 tagPollTxTime32l ;      	// poll tx time - low 32 bits
	uint32 tagPollRxTime32l ;      	// poll rx time - low 32 bits
	uint32 anchorRespTxTime32l ;    // response tx time - low 32 bits
	uint32 anchResp1RxTime32l ;		// response 1 rx time - low 32 bits

    //diagnostic counters/data, results and logging
    int64 tof ;						/**< Time of Fligth*/
    uint32 blinkRXcount ;			/**< Number of Blink messages received - ANCHOR only */
	int txmsgcount;					/**< Number of  messages sent	*/
	int	rxmsgcount;					/**< Number of  messages received */
	int lateTX;						/**< Number of  messages that couldn't be sent because it is too late */
	int lateRX;						/**< Number of  messages that couldn't be received because it is too late */

    int newrangeancaddress; 		//last 4 bytes of anchor address
    int newrangetagaddress; 		//last 4 bytes of tag address

	uint8 tagToRangeWith;			//it is the index of the tagList array which contains the address of the Tag we are ranging with
    uint8 tagListLen ;
	uint8 tagList[TAG_LIST_SIZE][8];
	
} instance_data_t ;


/******************************************************************************************************************
******************************************** Prototypes ***********************************************************
*******************************************************************************************************************/

/******** Decawave_range.c *********/

// User functions
void DecawaveApp_InitExchange		(void);
void DecawaveApp_EndExchange		(void);
void DecawaveApp_WakeUp				(void);
void DecawaveApp_EnterSleep			(void);
void DecawaveApp_ChannelConfigure 	(uint16 value);	
void DecawaveApp_SetReportDistanceMeasurementFunction 	(ReportRangeType addr);
void DecawaveApp_SetGoToRangingModeFunction 			(OperationChangeType addr);

// Send msg
void DecawaveApp_SendBlinkMsg		(void);
void DecawaveApp_SendPollMsg		(void);
void DecawaveApp_SendRangeInitMsg	(void);
void DecawaveApp_SendRespMsg		(void);
void DecawaveApp_SendFinalMsg		(void);

// Receive msg
void DecawaveApp_ReceiveRangeInitMsg	(uint8* messageData);
void DecawaveApp_ReceiveFinalMsg		(uint8* messageData, uint64 tagFinalRxTime);


void DecawaveApp_ReportDistanceMeasurement (double distance);
void DecawaveApp_GoToRangingOperation (void);


/******** Decawave_app_common.c *********/
void DecawaveApp_SetTagSleepDelay	(int sleepdelay, int blinksleepdelay);
int DecawaveApp_GetTagSleepDelay	(void);
void DecawaveApp_SetRole			(int mode);  
int DecawaveApp_GetTagSleepDelay	(void);
int DecawaveApp_getrole				(void);
int DecawaveApp_get_dly				(void);
uint32 DecawaveApp_getblinkrxcount	(void);
int DecawaveApp_get_rxf				(void);
int DecawaveApp_get_txf				(void);
int DecawaveApp_get_txl				(void);
int DecawaveApp_get_rxl				(void);
uint16 DecawaveApp_get_txantdly		(void);
uint16 DecawaveApp_get_rxantdly		(void);
uint64 DecawaveApp_get_addr			(void);
uint64 DecawaveApp_get_tagaddr		(void);
uint64 DecawaveApp_get_anchaddr		(void);

uint32 DecawaveApp_ReadRevId		(void);
int DecawaveApp_InitInstance		(uint32_t DeviceNumber);
int DecawaveApp_InitInterrupts		(int mode);
int DecawaveApp_SendPacket			(uint16 length, uint8 txmode, uint32 dtime);
int DecawaveApp_AddTagToList		(instance_data_t *inst, uint8 *tagAddr);
void DecawaveApp_ConfigInstance		(instanceConfig_t *config);
void DecawaveApp_ClearTagList		(void);
void DecawaveApp_ClearCounts		(void);
void DecawaveApp_ProcessRxTimeout	(instance_data_t *inst);
void DecawaveApp_ConfigAntennaDelays(uint16 tx, uint16 rx);
void DecawaveApp_SetAntennaDelays	(void);
void DecawaveApp_ConfigFrameHeader	(instance_data_t *inst);
void DecawaveApp_SetupMacFrameData	(instance_data_t *inst, int fcode);
void DecawaveApp_rxON				(instance_data_t *inst, int delayed, uint64 delayedReceiveTime);
void DecawaveApp_InitTimings		(void);
double DecawaveApp_CalculateDistance(int64 input_tof);

/******** Decawave_app_callbacks.c *********/
void DecawaveApp_TxCallback		(const dwt_callback_data_t *txd);
void DecawaveApp_RxCallback		(const dwt_callback_data_t *rxd);

/******** Decawave_app_misc.c *********/
uint64 convertmicrosectodevicetimeu (double microsecu);
uint32 convertmicrosectodevicetimeu32 (double microsecu);
double convertdevicetimetosec		(int32 dt);
double convertdevicetimetosec8		(uint8* dt);

// Global variables
extern const uint16 rfDelays[2];
extern const tx_struct txSpectrumConfig[8];
extern instance_data_t instance_data[NUM_INST] ;

#endif

