DW1000 UWB driver based on work of Matthias Grob & Manuel Stalder - ETH Zürich - 2015
Diff: DW1000.h
- Revision:
- 8:0b408e77b701
- Parent:
- 7:b13881dbb09d
- Child:
- 9:326bf149c8bc
--- 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);