DWM3000EVB Raw CIR Capture Issues

For what it’s worth here’s my code for this that seems to work fine. I call this function in a loop reading blocks of 16 values. No specific reason why, it’s written so it should work fine for anything from 1 value to all of them at once. I just used smaller blocks when debugging it and never increased them once it was working because it wasn’t speed critical.

Keep in mind this is a lot of data, quick back of the envelope numbers, assuming you run the SPI bus at 30 MHz you’re still looking at over 1.5 ms to read all the data. Reading the full CIR is not very compatible with high sample rates. I only ever use it in special diagnostics modes rather than normal operation for this reason.

Depending on the application you could read the leading edge location & peak location and then only read the CIR data for that region, that would significantly reduce the time required assuming it gives you the information you need.

/// read len CIR values starting at offset
/// store magnitudes in float array CIRValues
bool Dw1000::readDW3000CIRData(float *CIRValues, int len, int offset) {

    // DW3000 is 3 byte I, 3 byte Q (18 bits per value) with a 1 byte blank at the start. 
    // DW1000 is 2 byte I, 2 byte Q with a 1 byte blank at the start. 
    //	Max of 992 or 1016 points (16/64 prf)

    if ((len + offset)>1016)
        len = 1016-offset;
    if (len <1) 
        return false;

    const int bytesPerValue = 6; // dw3000


    uint8_t cir_buffer[1016*bytesPerValue+1]; // worst case
    dwt_readaccdata(cir_buffer, len*bytesPerValue+1, offset);
    int byteAddress = 1;
    for (int i=0;i<len;i++) {
        int32_t iValue = cir_buffer[byteAddress++];
        iValue |= ((int32_t)cir_buffer[byteAddress++]<<8);
        iValue |= ((int32_t)(cir_buffer[byteAddress++] & 0x03)<<16);

        int32_t qValue = cir_buffer[byteAddress++];
        qValue |= ((int32_t)cir_buffer[byteAddress++]<<8);         
        qValue |= ((int32_t)(cir_buffer[byteAddress++] & 0x03)<<16);
	
        if (iValue & 0x020000)  // MSB of 18 bit value is 1
            iValue |= 0xfffc0000;
        if (qValue & 0x020000)  // MSB of 18 bit value is 1
            qValue |= 0xfffc0000;
        *(CIRValues+i) = sqrt((float)(iValue*iValue+qValue*qValue));
    }
    return true;	
}
2 Likes