On-chip DW1000 channel diagnostic info


While I was reading the application note APS006 to understand range and accuracy better, came across the reference to “On-chip DW1000 channel diagnostic information” in section 4.4.3

This is supposed to provide the additional info to determine if the time-stamp is due to direct signal path or multi-path signal.

How to access this diagnostic info?


The information is the CIR memory - Register 25 in the DW1000.

The Decawave drivers provide a means to read this. Or if you are writing your own firmware the code below worked for me and should be fairly easy to translate to however you are accessing the device. One warning, this must be done after a packet has been received but before you re-enable the receiver. As soon as you enable receive this memory is wiped. My initial attempt at this failed because my receive interrupt automatically re-enabled things :frowning:

void enableCIRMemory(bool enable) {
uint16_t regValue = readRegister16(DW1000_PMSC,DWPMSC_PMSC_CTRL0);
regValue &= 0x7fb3; // clear bits 15, 6, 2 and 3
if (enable) {
regValue |= (1<<6 | 1<<15 | 1<<3);
writeRegister16(DW1000_PMSC,DWPMSC_PMSC_CTRL0, regValue);

void readCIRLine(int line, uint8_t data) {
readRegister(DW1000_ACC_MEM, line
4,data, 5);

void readCIR() {
int16_t real;
int16_t imag;
uint8_t data[5];


for(int i = 0;i<dataPoints;i++) {
real = ((uint16_t)data[2])<<8 | data[1];
imag = ((uint16_t)data[4])<<8 | data[3];
float mag = (float)realreal + (float)imagimag;
mag = sqrt(mag);
pc.printf("%i,%i,%i,%.1f\n", i,real,imag,mag);


You can also read out the detected leading edge location, peak and detection thresholds used. I’ve sometimes plotted the threshold and detection point onto the CIR plot, it makes for a useful live diagnostics display when you have something odd going on. The code I used to get those values was:

void readLEDData(uint16_t *threshold, uint16_t *location, uint16_t peak,uint16_t noise, uint16_t leadingEdge) {
readRegister(DW1000_LDE_CTRL, 0, (uint8_t
)threshold, 2); // register, sub address, result buffer, bytes to read
readRegister(DW1000_LDE_CTRL, 0x1000, (uint8_t
)location, 2);
readRegister(DW1000_LDE_CTRL, 0x1002, (uint8_t
)peak, 2);

readRegister(DW1000_RX_FQUAL, 0, (uint8_t*)noise, 2);
uint32_t tmp = readRegister32(DW1000_RX_TIME,4); // register, sub address
*leadingEdge = (tmp>>8) & 0xffff;

Thanks Andy for your valuable inputs.

At present, I am using the kit with API calls and yet to go to writing own firmware.

Is there any API that provides access to this[color=#333333] CIR memory - Register 25? Though I went through the API document, I am not able to figure out.[/color]