DW1000 TX and RX Delay

Hello,

I’m working with two EVK boards and am attempting to measure the TX and RX delay of the DW1000 chip, I’ve been unable to find any mention of it in the user manual or data sheet. I am using a modified version of the Decawave 3.05 software, a logic analyzer, and the LCD_RW GPIO pin to make the measurements, lowering it on the TX board when the transmission is being sent over SPI and raising it when the callback for successful transmission occurs. I am using a similar approach for the receiver. Using this method I get a TX delay of approximately 200 us, and a RX delay of approximately 12 us. Essentially I’m wondering if these are expected values or if I’ve made an incorrect assumption/improper implementation somewhere as the TX delay is significantly larger.

The code I’m using for the transmit side is as follows:

[code]/*! ----------------------------------------------------------------------------

  • @file main.c
  • @brief main loop for the DecaRanging application
  • @attention
  • Copyright 2016 © DecaWave Ltd, Dublin, Ireland.
  • All rights reserved.
  • @author DecaWave
    */

#include “port.h”

#include “compiler.h”
#include “instance.h”
#include “deca_types.h”
#include “deca_spi.h”

#include “deca_device_api.h”

extern int dw_main(void);
extern uint32 inittestapplication(uint8 s1switch);
extern int decarangingmode(uint8 s1switch);

instanceConfig_t chConfig2[8] ={
//mode 1 - S1: 7 off, 6 off, 5 off
{
2, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 2
{
2, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
},
//mode 3
{
2, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 4
{
2, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
},
//mode 5
{
5, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 6
{
5, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
},
//mode 7
{
5, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 8
{
5, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
}
};

void instance_txcallback2(const dwt_cb_data_t *txd)
{
GPIO_SetBits(SPIy_GPIO, LCD_RW);
}

void instance_rxtimeoutcallback2(const dwt_cb_data_t *rxd)
{
}

void instance_rxgoodcallback2(const dwt_cb_data_t *rxd)
{
}

void instance_rxerrorcallback2(const dwt_cb_data_t *rxd)
{
}

int main(void)
{

peripherals_init();
spi_peripheral_init();
Sleep(2000);
port_DisableEXT_IRQ();

uint8 s1switch = port_is_boot1_on(0) << 1 // is_switch_on(TA_SW1_2) << 2
		| port_is_switch_on(TA_SW1_3) << 2
		| port_is_switch_on(TA_SW1_4) << 3
		| port_is_switch_on(TA_SW1_5) << 4
	    | port_is_switch_on(TA_SW1_6) << 5
		| port_is_switch_on(TA_SW1_7) << 6
		| port_is_switch_on(TA_SW1_8) << 7;


Sleep(1000);

if(inittestapplication(s1switch) == (uint32)-1)
    {
        int x = 0;
        return 0; //error
    }

Sleep(5000);

port_EnableEXT_IRQ();

int dr_mode = decarangingmode(s1switch);

instance_config(&chConfig2[dr_mode]);  

dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1);

dwt_setcallbacks(instance_txcallback2, instance_rxgoodcallback2, instance_rxtimeoutcallback2, instance_rxerrorcallback2);

int length = 3;

uint8 * data = (uint8 *)malloc(length-2);
data[0] = 'H';

bool stateabcd = false;

GPIO_SetBits(SPIy_GPIO, LCD_RW);

while(1){

	stateabcd = !stateabcd;

	if(stateabcd){
		//drive the RSTn pin low
		dwt_writetxdata(length, data, 0) ; // write the frame data

		dwt_writetxfctrl(length, 0, 0);
        
        GPIO_ResetBits(SPIy_GPIO, LCD_RW);
		dwt_starttx(DWT_START_TX_IMMEDIATE);

        GPIO_ResetBits(GPIOC, GPIO_Pin_6);
 		GPIO_ResetBits(GPIOC, GPIO_Pin_7);

 		GPIO_SetBits(GPIOC, GPIO_Pin_8);
 		GPIO_SetBits(GPIOC, GPIO_Pin_9);


	}
	else
	{
		GPIO_ResetBits(GPIOC, GPIO_Pin_8);
		GPIO_ResetBits(GPIOC, GPIO_Pin_9);

		GPIO_SetBits(GPIOC, GPIO_Pin_6);
		GPIO_SetBits(GPIOC, GPIO_Pin_7);
	}

	Sleep(1000);
	

}

return 0;

}[/code]

The receive code can be seen below:

[code]/*! ----------------------------------------------------------------------------

  • @file main.c
  • @brief main loop for the DecaRanging application
  • @attention
  • Copyright 2016 © DecaWave Ltd, Dublin, Ireland.
  • All rights reserved.
  • @author DecaWave
    */

#include “port.h”

#include “compiler.h”
#include “instance.h”
#include “deca_types.h”
//#include “deca_spi.h”

#include “deca_device_api.h”

extern int dw_main(void);
extern uint32 inittestapplication(uint8 s1switch);
extern int decarangingmode(uint8 s1switch);

instanceConfig_t chConfig2[8] ={
//mode 1 - S1: 7 off, 6 off, 5 off
{
2, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 2
{
2, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
},
//mode 3
{
2, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 4
{
2, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
},
//mode 5
{
5, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 6
{
5, // channel
3, // preambleCode
DWT_PRF_16M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
},
//mode 7
{
5, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_110K, // datarate
DWT_PLEN_1024, // preambleLength
DWT_PAC32, // pacSize
1, // non-standard SFD
(1025 + 64 - 32) //SFD timeout
},
//mode 8
{
5, // channel
9, // preambleCode
DWT_PRF_64M, // prf
DWT_BR_6M8, // datarate
DWT_PLEN_128, // preambleLength
DWT_PAC8, // pacSize
0, // non-standard SFD
(129 + 8 - 8) //SFD timeout
}
};

void instance_txcallback2(const dwt_cb_data_t *txd)
{
int x =0;
x++;
}

void instance_rxtimeoutcallback2(const dwt_cb_data_t *rxd)
{
int x =0;
x++;
}

bool hasUnprocessedRxd = false;
dwt_cb_data_t unprocessedRxd;

void instance_rxgoodcallback2(const dwt_cb_data_t *rxd)
{
GPIO_SetBits(SPIy_GPIO, LCD_RW);
memcpy(&unprocessedRxd, rxd, sizeof(dwt_cb_data_t));
hasUnprocessedRxd = true;
}

void instance_rxerrorcallback2(const dwt_cb_data_t *rxd)
{
int x =0;
x++;
}

int main(void)
{

//int ret = dw_main();
peripherals_init();
spi_peripheral_init();
Sleep(1000);
port_DisableEXT_IRQ();

uint8 s1switch = port_is_boot1_on(0) << 1 // is_switch_on(TA_SW1_2) << 2
		| port_is_switch_on(TA_SW1_3) << 2
		| port_is_switch_on(TA_SW1_4) << 3
		| port_is_switch_on(TA_SW1_5) << 4
	    | port_is_switch_on(TA_SW1_6) << 5
		| port_is_switch_on(TA_SW1_7) << 6
		| port_is_switch_on(TA_SW1_8) << 7;

inittestapplication(s1switch);
port_EnableEXT_IRQ();

int dr_mode = decarangingmode(s1switch);

instance_config(&chConfig2[dr_mode]) ;   

dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1);

dwt_setcallbacks(instance_txcallback2, instance_rxgoodcallback2, instance_rxtimeoutcallback2, instance_rxerrorcallback2);

bool stateabcd = false;

dwt_rxenable(DWT_START_RX_IMMEDIATE);

while(1){

	stateabcd = !stateabcd;

	if(stateabcd){
		//drive the RSTn pin low
        
        if (hasUnprocessedRxd) {
            hasUnprocessedRxd = false;
            uint16 length = unprocessedRxd.datalength;
            uint8 data[length];
            dwt_readrxdata(data, length, 0);
            GPIO_ResetBits(SPIy_GPIO, LCD_RW);
            if(data[0]=='H'){
                bool test1 = true;
            }
            
        }
	}
	else
	{
		
	}

	

}

return 0;

}[/code]

The RX on delay, the time the IC receives the RX on command to the time the RX is enabled, is 16 us. During this time the receiver cannot receive anything.

The TX on delay, is about 5 us… again the time for the TX blocks to power on before start of transmission of the 1st symbol.

Not sure exactly what signals you are looking at, you should look at DW ICs GPIOs 5&6 and monitor TX/RX states - see also Debugging Note APS022.

Zoran,

I’m looking at the delay in the communication link, i.e. I give the host controller the startTX command and measure the latency between that command and when I have access to the sent data on the receiver end. I am trying to make the lowest latency link possible.

Thank you for mentioning APS022 - that’s helped with my understanding of the TX/RX functionality.