DW1000 UWB driver based on work of Matthias Grob & Manuel Stalder - ETH Zürich - 2015

Dependencies:   BurstSPI

Revision:
15:6faab70a5b19
Parent:
14:02f0912e4ce4
Child:
17:1fb08dfef237
--- a/DW1000.cpp	Thu Mar 30 11:32:35 2017 +0000
+++ b/DW1000.cpp	Wed Nov 08 10:43:03 2017 +0000
@@ -1,7 +1,7 @@
 #include "DW1000.h"
-
+#include "main.h"
 #define SPIRATE_PLL (10*1000*1000)
-#define SPIRATE_OSC (2*1000*1000)
+#define SPIRATE_OSC (1*1000*1000)
 
 DW1000::DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ) : irq(IRQ), spi(MOSI, MISO, SCLK), cs(CS)
 {
@@ -20,6 +20,32 @@
 }
 
 
+void DW1000::setSPISpeed(uint32_t speed) {
+    spi.frequency(speed);
+    }
+
+
+void DW1000::enterRFTestMode() {
+        writeRegister32(DW1000_RF_CONF,0,0x0009A000);
+        wait_ms(1);
+        writeRegister16(DW1000_PMSC,DWPMSC_PMSC_CTRL1,0x0000);
+        wait_ms(1);
+        writeRegister32(DW1000_TX_POWER,0,0x1f1f1f1f);
+        wait_ms(1);
+        uint32_t config = rangingSystem.readRegister32(DW1000_SYS_CFG,0);
+        config |= 1<<18;
+        writeRegister32(DW1000_SYS_CFG,0,config);
+        wait_ms(1);
+        writeRegister16(DW1000_PMSC,DWPMSC_PMSC_CTRL0,0x0222);
+        wait_ms(1);
+        writeRegister32(DW1000_PMSC,DWPMSC_PMSC_TXFSEQ,0x00000000);
+        wait_ms(1);
+        writeRegister32(DW1000_RF_CONF,0,0x005fff00);
+        wait_ms(1);
+        writeRegister8(DW1000_TX_CAL,DWTXCAL_TC_PGTEST,0x13);
+}
+
+
 DW1000Setup* DW1000::getSetup()
 {
     return &systemConfig;
@@ -334,6 +360,15 @@
     writeRegister32(DW1000_CHAN_CTRL, 0, registerValue);
 }
 
+uint8_t DW1000::readXTALTune() {
+  return readRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_XTALT);               
+    }
+
+void DW1000::setXTALTune(uint8_t value) {
+  value &= 0x1f; // mask reserved bits
+  value |= 0x60; // set reserved bits
+  writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_XTALT,value);                 
+    }
 
 uint8_t DW1000::powerToRegValue(float powerdB)
 {
@@ -387,7 +422,7 @@
 // transmit power: 0 to 33.5 dB gain in steps of 0.5. Inputs are in 10ths of a dB (0 to 335)
 void DW1000::setTxPower(float normalPowerdB, float boost500, float boost250, float boost125)
 {
-   
+
     if(normalPowerdB > 33.5)
         normalPowerdB = 33.5;
 
@@ -417,7 +452,7 @@
     powerReg |= powerToRegValue(boost250) << 16;
     powerReg |= powerToRegValue(boost125) << 24;
     writeRegister32(DW1000_TX_POWER,0,powerReg);
-    
+
     systemConfig.setSmartTxPower(normalPowerdB,boost500,boost250,boost125); // update the systemConfig
 }
 
@@ -589,7 +624,7 @@
 }
 
 void DW1000::getFullQualityMetrics(uint16_t *std_noise, uint16_t *fp_amp1, uint16_t *fp_amp2, uint16_t *fp_amp3,
-                                        uint16_t *cir_pwr, uint16_t *preAmbleAcc, uint16_t *preAmbleAcc_NoSat)
+                                   uint16_t *cir_pwr, uint16_t *preAmbleAcc, uint16_t *preAmbleAcc_NoSat)
 {
     *fp_amp1 = readRegister16(DW1000_RX_TIME,7);
     *std_noise = readRegister16(DW1000_RX_FQUAL,0);
@@ -600,11 +635,12 @@
     *preAmbleAcc_NoSat = readRegister16(DW1000_DRX_CONF,DWDRX_RXPAC_NOSAT);
 }
 
-void DW1000::getFullLEDMetrics(uint16_t *led_thresh, uint16_t *led_ppindx, uint16_t *led_ppampl) {
+void DW1000::getFullLEDMetrics(uint16_t *led_thresh, uint16_t *led_ppindx, uint16_t *led_ppampl)
+{
     *led_thresh = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_THRESH);
     *led_ppindx = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_PPINDX);
-    *led_ppampl = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_PPAMPL);   
-    }
+    *led_ppampl = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_PPAMPL);
+}
 
 
 #define SQR(x) ((float)(x) * (float)(x))
@@ -922,10 +958,12 @@
 void DW1000::setInterrupt(bool RX, bool TX)
 {
     writeRegister16(DW1000_SYS_MASK, 0, RX*0x4000 | TX*0x0080);  // RX good frame 0x4000, TX done 0x0080
+//    writeRegister32(DW1000_SYS_MASK, 0, 0x377fff0);  // RX good frame 0x4000, TX done 0x0080
 }
 
 void DW1000::ISR()
 {
+//    led1 = !led1;
     uint64_t status = getStatus();
     if (status & 0x4000) {                                          // a frame was received
         callbackRX.call();
@@ -1044,3 +1082,22 @@
     cs = 1;                 // set Cable Select pin high to stop transmission
     irq.enable_irq();       // reenable the interrupt handler
 }
+
+void DW1000::getRxClockInfo(int32_t *offset, uint8_t* phase, uint8_t* delta)
+{
+    uint64_t data = readRegister40(DW1000_RX_TTCKO,0);
+    *phase = (data >> 32)&0x07f;
+    *delta = data >> 24 & 0x0ff;
+    int32_t RXTofs = data &0x07ffff;
+    if (RXTofs & 0x040000)
+      RXTofs |= 0xfff80000;
+    *offset =  RXTofs;
+
+//    uint32_t RXTTCKI =  0x01FC0000;
+//    if (getSetup()->getPRF() == DW1000Setup::prf16MHz)
+//        RXTTCKI =  0x01F00000;
+
+//    double clockOffset = (1000000.0 * RXTofs) / RXTTCKI;
+//    printf("Clock offset %.4f ppm, re-sample delay %d, phase adjustment %d\n",clockOffset,RSMPDel,RCPhase);
+
+}