I couldn't resist trying to get the temperature right.  It led me to write a fair bit of code to print out all of the DW registers.  I expect that will turn out to be pretty useful soon.

There are two weird things though:
I kept getting 0 for the calibration data.  So I ran the register dump to find out if I was read any registers, and sure enough it all looked kosher, and indeed the temp. calibration was 0x7A.  After some fiddling around I discovered that I couldn't read that register unless a read a whole bunch of others.  I have stopped digging into it, because I suspect it's some kind of weird timing bug.  Maybe the DW has to be in some special state to read the OTP.  It can wait.
The other thing is that if I plugged in the calibration value it didn't make much difference, which I suppose makes some kind of sense.  But the temp went up!  And the T is measured in C, not F, so I'm pretty confused.
Temp = 88.14(uncalibrated) 86.84(using calibration).  Volts =  2.99 

//Mik

A little bit of progress.  One TS06 sent a packet and the other noticed it.  The recieved packet was flagged as having all sorts of errors, which is appropriate because it seems of be full of junk.

Recieved something with status SYS_STATUS_IRQS SYS_STATUS_RXSFDD SYS_STATUS_LDEDONE SYS_STATUS_RXPHD SYS_STATUS_RXPHE SYS_STATUS_RXFCG SYS_STATUS_RXRFSL

But the good news is that something got transmitted.

Top window is the sender, and bottom the receiver.

And a DW packet?

The next example shows output from packets sent by the DW EVK1000 which seems to have much better status.

Recieved something with status SYS_STATUS_IRQS SYS_STATUS_RXSFDD SYS_STATUS_LDEDONE SYS_STATUS_RXPHD SYS_STATUS_RXPHE SYS_STATUS_RXSFDTO SYS_STATUS_HSRBP

Just taking a break from porting the DW code over to the nRF51822.  I’m finding it a steep learning curve, but mostly it makes sense.  There seems to be a lot of flexibility, which in turn means that there is a lot to configure, which in turn means there’s a lot to  understand about the configuration: channels, packet sizes, speeds, preambles and so forth.  And it all has to be perfect to work.  Of course the example code provides one set of parameters that clearly work, so that’s a comfort.

I think the code was originally written to run on a PC, because it is been written to drive multiple EVK1000s from a single processor – I suspect via multiple Cheetah boxes they talk about in one of the manuals. It looks like it has been hacked, and hacked because there is a lot of redundant code, and comments that clearly don’t make sense (well to me anyway).  I guess after the PC they ported it to the ARM m3 without cleaning it up, so there is a lot of extra complexity that we don’t need, and also buffers for the data for multiple devices, each of which is huge, so I don’t think we’d have enough RAM.
the good news is that the documentation is better than the code.  I read the documentation and didn’t understand it all.  Now I am looking at the code and not understanding it all, but the documentation starts to make more sense 😀
Of course they also run the demo nodes in either anchor, or tag mode exclusively, and we need to run it in either mode on demand, so the code is going to be quite a bit different anyway.  But right now I’m simply trying to get a one-byte packet from one TS to other, and I have not even got all the code ported yet.
I notice that a bunch of config parameters are allegedly set up in the factory and stored in the OTP memory of the chip.  I sure hope that they setup some decent default parameters in each module. 
As I get bits of code running I print out diagnostics to see if it makes sense. 
I notice that our two modules have LF clocks that tick at slightly different rates as you might expect (see below).  I guess a difference of 3/1555ths is < 0.2%. But that’s ~3 mins/ day – is that respectable?   Of course it’s calibrated against the high speed crystal which may be wrong too I guess.  Why is a HF crystal more trustworthy?  It wanders around too. 1555 became 1559 very quickly.
low-power osc calibration 1555; blink time 5s; blinktime counter 3.012500
low-power osc calibration 1552; blink time 5s; blinktime counter 2.989700
I think it will take another day or so to laboriously work through the code and understand what needs to be ported, clean it up, and port it over.  then I can start to debug it.
The good news is that so far the code is about 72K, and the data is about 4K, so we are still well above water.  But of course I have not linked in all the DW library yet, so it could suddenly mushroom.
Onwards…  need to sharpen my pickaxe.

//Mik

I had a few minutes of uninterrupted time to begin to scrutinize the DW code.   The code base is pretty big.  The actual demo “application” code, (not even the libraries) are extensive.  See ->

I printed out just the demo part of the code so that I could start to understand how they set up the radios for TOF calculations.  Now it got depressing.

The following code translates TOF to a distance.  It appears that the hardware can produce TOF results that are negative!  OK, I can see how that can happen, but simply turning it into a positive number seems like a odd solution.  I wonder why that is the right thing to do?

Then I notice that the code assumes two complete round trips, i.e. 4 transmissions, and averages them.
Then if the result is less than -50cms discard it – which is odd because the previous line of code should have guaranteed that the TOF is positive.
And then if the distance is still negative then the sign is inverted –  after all the previous work, how can it be negative anyway?
Finally, just to be sure, they generate a moving average of the last 8 estimates.

So each report is actually the average of 32 TOF estimates.   That can’t be good for our power budget!

void reportTOF_f(instance_data_t *inst)
{
        double distance ;
        double tof ;
        int32 tofi ;

        // check for negative results and accept them making them proper negative integers
        tofi = (int32) inst->tof32 ;                          // make it signed
        if (tofi < 0)                          // close up TOF may be negative
        {
            tofi *= -1 ;                       // make it positive
        }

        // convert to seconds (as floating point)
        tof = convertdevicetimetosec(tofi) * 0.25;          //this is divided by 4 to get single time of flight
        distance = tof * SPEED_OF_LIGHT;

        if ((distance < -0.5) || (distance > 20000.000))    // discard any results less than <50 cm or >20km
            return;

#if (CORRECT_RANGE_BIAS == 1)
        distance = distance – dwt_getrangebias(inst->configData.chan, (float) distance, inst->configData.prf);
#endif

        distance = fabs(distance) ;                         // make any (small) negatives positive.

        inst_idist = distance;

        inst->longTermRangeCount++ ;

        inst->adist[inst->tofindex++] = distance;

        if(inst->tofindex == RTD_MED_SZ) inst->tofindex = 0;

        if(inst->tofcount == RTD_MED_SZ)
        {
            int i;
            double sumdiff, avg;

            avg = 0;
            sumdiff = 0;
            for(i = 0; i < inst->tofcount; i++)
            {
                avg += inst->adist[i];
            }
            avg /= inst->tofcount;

            inst_adist = avg ;

        }
        else
            inst->tofcount++;
    return ;
}// end of reportTOF_f

This is my first program that actually needed to know the speed of light.

Glorious fudge factors (pulled out of rectal orifice) require floating point.  N.B. No FP hardware on the Nordic.


//assume PHR length is 172308us for 110k and 21539us for 850k/6.81M
if(instance_data[instance].configData.dataRate == DWT_BR_110K)
{
msgdatalen *= 8205.13f;
msgdatalen += 172308;

}
else if(instance_data[instance].configData.dataRate == DWT_BR_850K)
{
msgdatalen *= 1025.64f;
msgdatalen += 21539;
}
else
{
msgdatalen *= 128.21f;
msgdatalen += 21539;

}

Antenna delay

               //MP bug – TX antenna delay needs reprogramming as it is not preserved
                dwt_settxantennadelay(inst->txantennaDelay) ;

So we have to figure out the antenna delay.

Here’s a useful bit of code for later

int instance_starttxtest(int framePeriod)
{
//define some test data for the tx buffer
uint8 msg[127] = “The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the l”; 
//NOTE: SPI frequency must be < 3MHz

// the value here 0x1000 gives a period of 32.82 µs
//this is setting 0x1000 as frame period (125MHz clock cycles) (time from Tx en – to next – Tx en)
dwt_configcontinuousframemode(framePeriod);

dwt_writetxdata(127, (uint8 *)  msg, 0) ;
dwt_writetxfctrl(127, 0);

    //to start the first frame – set TXSTRT
dwt_starttx(DWT_START_TX_IMMEDIATE); 

//measure the power 
//Spectrum Analyser set:
//FREQ to be channel default e.g. 3.9936 GHz for channel 2
//SPAN to 1GHz
//SWEEP TIME 1s
//RBW and VBW 1MHz
//measure channel power

return DWT_SUCCESS ;
}


This looks like code for using a spectrum analyzer to trim the crystal.


//NOTE: SPI frequency must be < 3MHz
//reduce the SPI speed before switching to XTAL
//
// reset device 
//
dwt_softreset();
//
// configure TX channel parameters
//
configTx.PGdly = txSpectrumConfig[chan].PGdelay ;
//Assume smart power is disabled – not relevant for XTAL trimming as CW mode
    pow = txSpectrumConfig[chan].txPwr[prf – DWT_PRF_16M] & 0xFF ;
configTx.power = (pow | (pow << 8) | (pow << 16) | (pow << 24));
dwt_configuretxrf(&configTx);
dwt_configcwmode(chan);
for(i=0; i<=0x1F; i++)
{
dwt_xtaltrim(i);
//measure the frequency
//Spectrum Analyser set:
//FREQ to be channel default e.g. 3.9936 GHz for channel 2
//SPAN to 10MHz
//PEAK SEARCH
}