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

Dependencies:   BurstSPI

Revision:
8:0b408e77b701
Parent:
7:b13881dbb09d
Child:
9:326bf149c8bc
diff -r b13881dbb09d -r 0b408e77b701 DW1000.h
--- a/DW1000.h	Wed Apr 13 09:07:14 2016 +0000
+++ b/DW1000.h	Mon Apr 18 16:58:27 2016 +0000
@@ -5,328 +5,14 @@
 
 #include "mbed.h"
 #include "BurstSPI.h"
-
-// register addresses
-//      Mnemonic                    Address Bytes Description
-#define DW1000_DEV_ID               0x00 //     4 Device Identifier – includes device type and revision information
-#define DW1000_EUI                  0x01 //     8 Extended Unique Identifier
-#define DW1000_PANADR               0x03 //     4 PAN Identifier and Short Address
-#define DW1000_SYS_CFG              0x04 //     4 System Configuration bitmap
-#define DW1000_SYS_TIME             0x06 //     5 System Time Counter (40-bit)
-#define DW1000_TX_FCTRL             0x08 //     5 Transmit Frame Control
-#define DW1000_TX_BUFFER            0x09 //  1024 Transmit Data Buffer
-#define DW1000_DX_TIME              0x0A //     5 Delayed Send or Receive Time (40-bit)
-#define DW1000_RX_FWTO              0x0C //     2 Receive Frame Wait Timeout Period
-#define DW1000_SYS_CTRL             0x0D //     4 System Control Register
-#define DW1000_SYS_MASK             0x0E //     4 System Event Mask Register
-#define DW1000_SYS_STATUS           0x0F //     5 System Event Status Register
-#define DW1000_RX_FINFO             0x10 //     4 RX Frame Information                (in double buffer set)
-#define DW1000_RX_BUFFER            0x11 //  1024 Receive Data Buffer                 (in double buffer set)
-#define DW1000_RX_FQUAL             0x12 //     8 Rx Frame Quality information        (in double buffer set)
-#define DW1000_RX_TTCKI             0x13 //     4 Receiver Time Tracking Interval     (in double buffer set)
-#define DW1000_RX_TTCKO             0x14 //     5 Receiver Time Tracking Offset       (in double buffer set)
-#define DW1000_RX_TIME              0x15 //    14 Receive Message Time of Arrival     (in double buffer set)
-#define DW1000_TX_TIME              0x17 //    10 Transmit Message Time of Sending    (in double buffer set)
-#define DW1000_TX_ANTD              0x18 //     2 16-bit Delay from Transmit to Antenna
-#define DW1000_SYS_STATE            0x19 //     5 System State information
-#define DW1000_ACK_RESP_T           0x1A //     4 Acknowledgement Time and Response Time
-#define DW1000_RX_SNIFF             0x1D //     4 Pulsed Preamble Reception Configuration
-#define DW1000_TX_POWER             0x1E //     4 TX Power Control
-#define DW1000_CHAN_CTRL            0x1F //     4 Channel Control
-#define DW1000_USR_SFD              0x21 //    41 User-specified short/long TX/RX SFD sequences
-#define DW1000_AGC_CTRL             0x23 //    32 Automatic Gain Control configuration
-#define DW1000_EXT_SYNC             0x24 //    12 External synchronisation control.
-#define DW1000_ACC_MEM              0x25 //  4064 Read access to accumulator data
-#define DW1000_GPIO_CTRL            0x26 //    44 Peripheral register bus 1 access - GPIO control
-#define DW1000_DRX_CONF             0x27 //    44 Digital Receiver configuration
-#define DW1000_RF_CONF              0x28 //    58 Analog RF Configuration
-#define DW1000_TX_CAL               0x2A //    52 Transmitter calibration block
-#define DW1000_FS_CTRL              0x2B //    21 Frequency synthesiser control block
-#define DW1000_AON                  0x2C //    12 Always-On register set
-#define DW1000_OTP_IF               0x2D //    18 One Time Programmable Memory Interface
-#define DW1000_LDE_CTRL             0x2E //     - Leading edge detection control block
-#define DW1000_DIG_DIAG             0x2F //    41 Digital Diagnostics Interface
-#define DW1000_PMSC                 0x36 //    48 Power Management System Control Block
-
-// AGC_CTRL sub registers
-#define DWAGCCTRL_AGC_CTRL1         0x02
-#define DWAGCCTRL_AGC_TUNE1         0x04
-#define DWAGCCTRL_AGC_TUNE2         0x0C
-#define DWAGCCTRL_AGC_TUNE3         0x12
-
-// EXT_SYNC sub registers
-#define DWEXTSYNC_EC_CTRL           0x00
-#define DWEXTSYNC_EC_RXTC           0x04
-#define DWEXTSYNC_EC_GOLP           0x08
-
-// GPIO sub registers
-#define DWGPIO_GPIO_MODE           0x00
-#define DWGPIO_GPIO_DIR            0x08
-#define DWGPIO_GPIO_DOUT           0x0C
-#define DWGPIO_GPIO_IRQE           0x10
-#define DWGPIO_GPIO_ISEN           0x14
-#define DWGPIO_GPIO_IMODE          0x18
-#define DWGPIO_GPIO_IBES           0x1C
-#define DWGPIO_GPIO_ICLR           0x20
-#define DWGPIO_GPIO_IDBE           0x24
-#define DWGPIO_GPIO_RAW            0x28
-
-// DRX sub registers
-#define DWDRX_DRX_TUNE0B            0x02
-#define DWDRX_DRX_TUNE1A            0x04
-#define DWDRX_DRX_TUNE1B            0x06
-#define DWDRX_DRX_TUNE2             0x08
-#define DWDRX_DRX_SFDTOC            0x20
-#define DWDRX_DRX_PRETOC            0x24
-#define DWDRX_DRX_TUNE4H            0x26
-
-//RF conf sub registers
-#define DWRFCONF_RF_CONF            0x00
-#define DWRFCONF_RF_RXCTRLH         0x0B
-#define DWRFCONF_RF_TXCTRL          0x0C
-#define DWRFCONF_RF_STATUS          0x2C
-#define DWRFCONF_RF_LDOTUNE         0x30
-
-// TX cal sub registers
-#define DWTXCAL_TC_SARC             0x00
-#define DWTXCAL_TC_SARL             0x03
-#define DWTXCAL_TC_SARW             0x06
-#define DWTXCAL_TC_PGDELAY          0x0B
-#define DWTXCAL_TC_PGTEST           0x0C
-
-// Freq synth sub registers
-#define DWFSCTRL_FS_PLLCFG          0x07
-#define DWFSCTRL_FS_PLLTUNE         0x0B
-#define DWFSCTRL_FS_XTALT           0x0E
-
-// Always on sub registers
-#define DWAON_AON_WCFG              0x00
-#define DWAON_AON_CTRL              0x02
-#define DWAON_AON_RDAT              0x03
-#define DWAON_AON_ADDR              0x04
-#define DWAON_AON_CFG0              0x06
-#define DWAON_AON_CFG1              0x0A
-
-// OTP sub registers
-#define DWOTP_OTP_WDAT              0x00
-#define DWOTP_OTP_ADDR              0x04
-#define DWOTP_OTP_CTRL              0x06
-#define DWOTP_OTP_STAT              0x08
-#define DWOTP_OTP_RDAT              0x0A
-#define DWOTP_OTP_SRDAT             0x0E
-#define DWOTP_OTP_SF                0x12
-
-//LDE_IF sub registers
-#define DWLDE_LDE_THRESH            0x0000
-#define DWLDE_LDE_CFG1              0x0806
-#define DWLDE_LDE_PPINDX            0x1000
-#define DWLDE_LDE_PPAMPL            0x1002
-#define DWLDE_LDE_RXANTD            0x1804
-#define DWLDE_LDE_CFG2              0x1806
-#define DWLDE_LDE_REPC              0x2804
-
-// Dig Diag sub registers
-#define DWDIAG_EVC_CTRL             0x00
-#define DWDIAG_EVC_PHE              0x04
-#define DWDIAG_EVC_RSE              0x06
-#define DWDIAG_EVC_FCG              0x08
-#define DWDIAG_EVC_FCE              0x0A
-#define DWDIAG_EVC_FFR              0x0C
-#define DWDIAG_EVC_OVR              0x0E
-#define DWDIAG_EVC_STO              0x10
-#define DWDIAG_EVC_PTO              0x12
-#define DWDIAG_EVC_FWTO             0x14
-#define DWDIAG_EVC_TXFS             0x16
-#define DWDIAG_EVC_HPW              0x18
-#define DWDIAG_EVC_TPW              0x1A
-#define DWDIAG_DIAG_TMC             0x24
-
-// power control sub registers
-#define DWPMSC_PMSC_CTRL0           0x00
-#define DWPMSC_PMSC_CTRL1           0x04
-#define DWPMSC_PMSC_SNOZT           0x0C
-#define DWPMSC_PMSC_TXFSEQ          0x26
-#define DWPMSC_PMSC_LEDC            0x28
-
-
-#define DW1000_WRITE_FLAG           0x80 // First Bit of the address has to be 1 to indicate we want to write
-#define DW1000_SUBADDRESS_FLAG      0x40 // if we have a sub address second Bit has to be 1
-#define DW1000_2_SUBADDRESS_FLAG    0x80 // if we have a long sub adress (more than 7 Bit) we set this Bit in the first part
-
-/*
-From user manual 10.5
-Table 59:
-DW1000 supported UWB channels and recommended preamble codes
+#include "DW1000Registers.h"
+#include "DW1000Setup.h"
 
-channel 16MHzPrf    64MHzPrf
-1       1,2         9, 10, 11, 12
-2       3, 4        9, 10, 11, 12
-3       5, 6        9, 10, 11, 12
-4       7, 8        17, 18, 19, 20
-5       3, 4        9, 10, 11, 12
-7       7, 8        17, 18, 19, 20
-*/
-
-
-/** Class for holding DW1000 config options
-*
-*/
-class DW1000Setup
-{
-public:
-
-/// Constructor - default settings are close to hardware defaults.
-    DW1000Setup() {
-        channel = 5;
-        prf =prf16MHz;
-        dataRate = kbps850;
-        sfd = standard;
-        preamble = pre128;
-        preambleCode = 3;
-        enableSmartPower = true;
-    }
-
-/// enum for PRF options
-    enum prf_e {prf16MHz, ///< PRF rate of 16MHz. Lower power
-                prf64MHz ///< PRF rate of 64MHz. Higher power but more accurate timing.
-               };
-
-/// enum for data rate options
-    enum dataRate_e {kbps110, ///< Data rate of 110kb/s (non-standard)
-                     kbps850,///< Data rate of 850kb/s
-                     kbps6800///< Data rate of 6.8Mb/s
-                    };
-
-/// enum for SFD options
-    enum sfd_e {standard, ///< IEEE standard SFD
-                decaWave, ///< Decawave defined SFD
-                user ///< user defined SFD
-               };
-
-/// enum for preamble length options
-    enum preamble_e { pre64,///< Preamble is 64 symbols
-                      pre128,///< Preamble is 128 symbols (non-standard)
-                      pre256,///< Preamble is 256 symbols (non-standard)
-                      pre512,///< Preamble is 512 symbols (non-standard)
-                      pre1024,///< Preamble is 1024 symbols
-                      pre1536,///< Preamble is 1536 symbols (non-standard)
-                      pre2048, ///< Preamble is 2048 symbols (non-standard)
-                      pre4096///< Preamble is 4096 symbols
-                    };
-
-    /** Set the PRF
-    * @return true if a valid option
-    */
-    bool setPRF(enum prf_e newSetting) {
-        prf = newSetting;
-        return true;
-    };
-
-    /** Set the Channel
-    * @return true if a valid option
-    */
-    bool setChannel(unsigned char newChannel) {
-        if ((channel > 0) && ((channel <= 5) || (channel == 7))) {
-            channel = newChannel;
-            return true;
-        }
-        return false;
-    };
-    /** Set the SFD
-    * @return true if a valid option
-    */
-    bool setSfd(enum sfd_e newSetting) {
-        sfd = newSetting;
-        return true;
-    };
-    /** Set the Preamble length
-    * @return true if a valid option
-    */
-    bool setPreambleLength(enum preamble_e newSetting) {
-        preamble = newSetting;
-        return true;
-    };
-    /** Set the Data rate
-    * @return true if a valid option
-    */
-    bool setDataRate(enum dataRate_e newSetting)  {
-        dataRate = newSetting;
-        return true;
-    };
-    /** Set the Preamble code
-    * @return true if a valid option
-    *
-    * note - not all codes are valid for all channels. Set the channel first.
-    * TODO - enforce code restrictions
-    */
-    bool setPreambleCode(unsigned char newCode) {
-        if ((newCode > 0) && (newCode <= 24)) {
-            preambleCode = newCode;
-            return true;
-        }
-        return false;
-    };
-    /** Set the smartpower state
-    * @return true if a valid option
-    *
-    * only takes effect at 6.8Mb/s
-    */
-    bool setSmartPower(bool enable) {
-        enableSmartPower = enable;
-        return true;
-    };
-
-    /** Get the current channel
-    * @return the channel number
-    */
-    unsigned char getChannel() {
-        return channel;
-    };
-    /** Get the current PRF
-    * @return the PRF
-    */
-    enum prf_e getPRF() {
-        return prf;
-    };
-    /** Get the current data rate
-    * @return the data rate
-    */    enum dataRate_e getDataRate() {
-        return dataRate;
-    };
-
-    /** Get the current SFD mode
-    * @return the SFD
-    */    enum sfd_e getSfd() {
-        return sfd;
-    };
-    /** Get the current preamble length
-    * @return the  preamble length
-    */
-        enum preamble_e getPreambleLength() {
-        return preamble;
-    };
-        /** Get the current preamble code
-    * @return the preamble code
-    */
-    unsigned char getPreambleCode() {
-        return preambleCode;
-    };
-        /** Get the current smart power mode
-    * @return true if smartpower is on
-    */
-    bool getSmartPower() {
-        return  enableSmartPower;
-    };
-
-private:
-    unsigned char channel; // 1-5 , 7
-    enum prf_e prf;
-    enum dataRate_e dataRate;
-    enum sfd_e sfd;
-    enum preamble_e preamble;
-    unsigned char preambleCode; // 1-24. See section 10.5 of user manual for details.
-    bool enableSmartPower;
-};
+#define TIMEUNITS_TO_US       (1/(128*499.2))               // conversion between the decawave timeunits (ca 15.65ps) to microseconds.
+#define US_TO_TIMEUNITS       ((uint32_t)(128*499.2))                   // conversion between microseconds to the decawave timeunits (ca 15.65ps).
+#define c_mPerS     299792458
+#define c_mmPerTick (c_mPerS * TIMEUNITS_TO_US / 1000)
+#define c_mPerTick  (c_mmPerTick/1000)
 
 
 typedef enum {minPacketSize, tunedDefault, user110k} UWBMode;
@@ -489,6 +175,21 @@
     */
     void setTxDelay(uint16_t ticks);
 
+
+    /** Set receive antenna delay in meters
+    * @param errorDistance Delay in meters at speed of light
+    */
+    void setRxDelayDistance(double errorDistance) {
+        setRxDelay(errorDistance/c_mPerTick);
+    };
+
+    /** Set transmit antenna delay  in meters
+    * @param errorDistance Delay in meters at speed of light
+    */
+    void setTxDelayDistance(double errorDistance) {
+        setTxDelay(errorDistance/c_mPerTick);
+    };
+
     /** Get last packet size
     * @return The length in bytes of the last packet received
     */
@@ -522,15 +223,25 @@
     */
     bool writeOTP(uint16_t word_address,uint32_t data);                                          // program a value in the OTP. It is recommended to reset afterwards.
 
-
-    /** Get setup description
+    /** get the current radio configuration
+    * @return A pointer to a DW1000Setup object of the current setup.
     *
-    * @param buffer Data buffer to place description in
-    * @param len Length of data buffer
+    * Note to change the setup you must make a copy of the current setup and then pass that to applySetup().
+    */
+    DW1000Setup *getSetup();
+
+    /** apply a new radio setup to the UWB system
+    * @param setup The new settings to use
+    * @return true if the setup was applied.
     *
-    * Places a text string describing the current setup into the suppled buffer.
+    * The setup object supplied is copied and can be disposed of after the call.
+    * If the supplied setup fails DW1000Setup::check() then it is ignored and the function returns false.
     */
-    void getSetup(char *buffer, int len);
+//    bool applySetup(DW1000Setup *setup);
+
+
+    uint32_t readRegister32(uint8_t reg, uint16_t subaddress);
+    void setTxPower(uint16_t normalPowercB, uint16_t boost500 = 0, uint16_t boost250 = 0, uint16_t boost125 = 0);
 
 protected:
     /** Reset the reciever logic
@@ -558,8 +269,9 @@
     * All gains are in cB (dB * 10). Gains can be between 0 and 335 (33.5dB).
     * Boost gains are optional, if not specified boost gains are set to the power for the lower rate (e.g. boost125 is set to the boost250 level).
     */
-    void setTxPower(uint16_t normalPowercB, uint16_t boost500 = 0, uint16_t boost250 = 0, uint16_t boost125 = 0);
+//    void setTxPower(uint16_t normalPowercB, uint16_t boost500 = 0, uint16_t boost250 = 0, uint16_t boost125 = 0);
 
+    
 
 private:
     void resetAll();                                                                        // soft reset the entire DW1000 (some registers stay as they were see User Manual)
@@ -597,7 +309,7 @@
 
     uint8_t readRegister8(uint8_t reg, uint16_t subaddress);                                // expressive methods to read or write the number of bits written in the name
     uint16_t readRegister16(uint8_t reg, uint16_t subaddress);
-    uint32_t readRegister32(uint8_t reg, uint16_t subaddress);
+//    uint32_t readRegister32(uint8_t reg, uint16_t subaddress);
     uint64_t readRegister40(uint8_t reg, uint16_t subaddress);
     uint64_t readRegister64(uint8_t reg, uint16_t subaddress);
     void writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer);