DW1000 UWB driver based on work of Matthias Grob & Manuel Stalder - ETH Zürich - 2015
Embed:
(wiki syntax)
Show/hide line numbers
DW1000.h
00001 // by Matthias Grob & Manuel Stalder - ETH Zürich - 2015 00002 00003 #ifndef DW1000_H 00004 #define DW1000_H 00005 00006 #include "mbed.h" 00007 #include "BurstSPI.h" 00008 #include "DW1000Registers.h" 00009 #include "DW1000Setup.h" 00010 00011 #define TIMEUNITS_TO_US (1/(128*499.2)) // conversion between the decawave timeunits (ca 15.65ps) to microseconds. 00012 #define US_TO_TIMEUNITS ((uint32_t)(128*499.2)) // conversion between microseconds to the decawave timeunits (ca 15.65ps). 00013 #define c_mPerS 299792458 00014 #define c_mmPerTick (c_mPerS * TIMEUNITS_TO_US / 1000) 00015 #define c_mPerTick (c_mmPerTick/1000) 00016 00017 00018 00019 /** A DW1000 driver 00020 * 00021 * It is expected that the protocol implimentation above this will inherit this object. 00022 * If not using this structure then move the protected functions to being public. 00023 * 00024 */ 00025 class DW1000 00026 { 00027 public: 00028 00029 /** Constructor. 00030 * 00031 * The radio will default to DW1000Setup::tunedDefault until you call applySetup() with a new configuration. 00032 */ 00033 DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ); // constructor, uses SPI class 00034 00035 void setSPISpeed(uint32_t speed); 00036 00037 /** Read the device ID 00038 * @return the device ID (0xDECA0130) 00039 */ 00040 uint32_t getDeviceID(); // gets the Device ID which should be 0xDECA0130 (good for testing SPI!) 00041 00042 /** Read the Extended Unique ID 00043 * @return The device EUI as stored in the system registers 00044 */ 00045 uint64_t getEUI(); 00046 00047 /** Set the Extended Unique ID 00048 * @param EUI The EUID to use 00049 * 00050 * @note ID is only valid until the next power cycle and overrides the value in the OTP memory. 00051 * To set a value that is automatically loaded on startup set OTP memory addresses 0 and 1. 00052 */ 00053 void setEUI(uint64_t EUI); // sets 64 bit Extended Unique Identifier according to IEEE standard 00054 00055 /** Read voltage input 00056 00057 @return the current device voltage 00058 00059 For accurate ranging the voltage of the device should be taken into account. 00060 User manual give variation as ~5.35cm / V 00061 */ 00062 float getVoltage(); // gets the current chip voltage measurement form the A/D converter 00063 00064 /** Read on board temperature sensor 00065 @return The temperature in C 00066 00067 For accurate ranging the temperature of the device should be taken into account. 00068 User manual give variation as ~2.15mm / C 00069 */ 00070 float getTemperature(); // gets the current chip temperature measurement form the A/D converter 00071 00072 /** Get the status register 00073 * @return The system status register 00074 * 00075 * See user manual section 7.2.17 for details 00076 */ 00077 uint64_t getStatus(); // get the 40 bit device status 00078 00079 00080 /** Set receive antenna delay 00081 * @param ticks Delay in system clock cycles 00082 */ 00083 void setRxDelay(uint16_t ticks); 00084 /** Set transmit antenna delay 00085 * @param ticks Delay in system clock cycles 00086 */ 00087 void setTxDelay(uint16_t ticks); 00088 00089 /** Set receive antenna delay in meters 00090 * @param errorDistance Delay in meters at speed of light 00091 */ 00092 void setRxDelayDistance(double errorDistance) { 00093 setRxDelay(errorDistance/c_mPerTick); 00094 }; 00095 00096 /** Set transmit antenna delay in meters 00097 * @param errorDistance Delay in meters at speed of light 00098 */ 00099 void setTxDelayDistance(double errorDistance) { 00100 setTxDelay(errorDistance/c_mPerTick); 00101 }; 00102 00103 /** Read a value from the OTP memory 00104 * @param word_address The OTP memory address to read. 00105 * @return The 32 bit value at that address. 00106 * 00107 * See Section 6.3.1 of the user manual for the memory map. 00108 */ 00109 uint32_t readOTP (uint16_t word_address); 00110 00111 /** Write a value to the OTP memory 00112 * @param word_address The OTP memory address to read. 00113 * @param data The value to write 00114 * @return True if the write was sucessful. 00115 * 00116 * Writes the supplied data to the OTP memory and then reads it back to verify it was sucessfully programmed. 00117 * @warning This is a one time operation for each memory address. 00118 * See Section 6.3.1 of the user manual for the memory map. 00119 * 00120 * @note It is recommened that the device is reset or power cycled after programing. 00121 */ 00122 bool writeOTP(uint16_t word_address,uint32_t data); // program a value in the OTP. It is recommended to reset afterwards. 00123 00124 /** get the current radio configuration 00125 * @return A pointer to a DW1000Setup object of the current setup. 00126 * 00127 * Note to change the setup you must make a copy of the current setup and then pass that to applySetup(). 00128 */ 00129 DW1000Setup *getSetup(); 00130 00131 /** Get the current Transmit gain settings. 00132 * 00133 * @param power Optional, is set to the first power in dBm 00134 * @param boost500 Optional, is set to the second power in dBm 00135 * @param boost250 Optional, is set to the third power in dBm 00136 * @param boost125 Optional, is set to the forth power in dBm 00137 * @return The raw transmit gain register value 00138 * 00139 * If smart power is on then power represents the normal transmit power, 00140 * boost500-boost125 indicates the power used for packets of that number of us or less. 00141 * 00142 * If smart power is off then boost500 represents the gain for the PHY header, boost250 the gain for the main message. 00143 * power and boost125 are not used. 00144 */ 00145 uint32_t getTxPower(float *power = NULL, float *boost500 = NULL, float *boost250 = NULL, float *boost125 = NULL); 00146 00147 /** Set Transmit gain 00148 * 00149 * @param normalPowercB Normal transmit gain to use. 00150 * @param boost500 Gain to use for 6.8Mb/s packets of under 500ms. 00151 * @param boost250 Gain to use for 6.8Mb/s packets of under 250ms. 00152 * @param boost125 Gain to use for 6.8Mb/s packets of under 125ms. 00153 * 00154 * All gains are in dB. Gains can be between 0 and 33.5dB. 00155 * 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). 00156 * If smart power is disabled then the normal gain is used for all settings. 00157 * The values in the internal DW1000Setup are updated to reflect the configured powers. 00158 */ 00159 void setTxPower(float normalPowerdB, float boost500 = 0, float boost250 = 0, float boost125 = 0); 00160 00161 /** Get the rx signal power for the last packet 00162 * 00163 * @param direct Is set to the direct path Rx power in dBm 00164 * @param total Is set to the total Rx power in dBm 00165 * 00166 * According to the DW1000 manual if the direct path power is within 6dB of the total then it was probably a LoS measurment. 00167 * If there is more than 10dB difference then it's probably an indirect path. 00168 */ 00169 void getRxSignalPower(float *direct, float *total); 00170 00171 00172 void getFullQualityMetrics(uint16_t *std_noise, uint16_t *fp_amp1, uint16_t *fp_amp2, uint16_t *fp_amp3, 00173 uint16_t *cir_pwr, uint16_t *preAmbleAcc, uint16_t *preAmbleAcc_NoSat); 00174 00175 void getFullLEDMetrics(uint16_t *led_thresh, uint16_t *led_ppindx, uint16_t *led_ppampl); 00176 00177 void getRxClockInfo(int32_t *offset, uint8_t* phase, uint8_t* delta); 00178 00179 /** Read the current crystal tuning value 00180 * 00181 * Reads the current FX_XTALT value from 0 to 0x1f. 00182 * See section 8.1 of the manual for details. 00183 * 00184 * @return The current value. 00185 */ 00186 uint8_t readXTALTune(); 00187 00188 00189 /** Set the crystal tuning value 00190 * 00191 * Sets the value of the FX_XTALT register. 00192 * See section 8.1 of the manual for details. 00193 * 00194 * Values will be lost on reset, consider programming the final value 00195 * into the OTP memory to store perminently. 00196 * 00197 * @value The value to use from 0 to 0x1f 00198 */ 00199 void setXTALTune(uint8_t value); 00200 00201 /** Puts the device into CW test mode 00202 * 00203 * The radio will be set to output a constant wave at carrier frequency. 00204 * Transmit gain will be set to the maximum of 33.5dB but can be chaged by 00205 * setting the TX power register 00206 * To exit test mode the radio should be reset. 00207 */ 00208 void enterRFTestMode(); 00209 00210 /** apply a new radio setup to the UWB system 00211 * @param setup The new settings to use 00212 * @return true if the setup was applied. 00213 * 00214 * The setup object supplied is copied and can be disposed of after the call. 00215 * If the supplied setup fails DW1000Setup::check() then it is ignored and the function returns false. 00216 * @note This will reset the radio. You must re-enable interupts, receiver etc. after calling it. 00217 */ 00218 bool applySetup(DW1000Setup *setup); 00219 00220 protected: 00221 00222 /** 00223 * Sets the callbacks on packet Rx and Tx 00224 * @param callbackRX The function to call on packet Rx complete 00225 * @param callbackTX The function to call on packet Tx complete 00226 * 00227 * set either or both to null to disable the appropriate interupt 00228 */ 00229 void setCallbacks(void (*callbackRX)(void), void (*callbackTX)(void)); // setter for callback functions, automatically enables interrupt, if NULL is passed the coresponding interrupt gets disabled 00230 00231 /** 00232 * c++ version of setCallbacks() 00233 * @param tptr object for callbacks 00234 * @param mptrRX method to call on packet Rx complete 00235 * @param mptrTX method to call on packet Tx complete 00236 * 00237 */ 00238 template<typename T> 00239 void setCallbacks(T* tptr, void (T::*mptrRX)(void), void (T::*mptrTX)(void)) { // overloaded setter to treat member function pointers of objects 00240 callbackRX.attach(tptr, mptrRX); // possible client code: dw.setCallbacks(this, &A::callbackRX, &A::callbackTX); 00241 callbackTX.attach(tptr, mptrTX); // concept seen in line 100 of http://developer.mbed.org/users/mbed_official/code/mbed/docs/4fc01daae5a5/InterruptIn_8h_source.html 00242 setInterrupt(true,true); 00243 } 00244 00245 /** Get the last packet recieve time 00246 * @return the internal time stamp for the last packet Rx 00247 * 00248 * Time is counted on a clock running at 499.2MHz * 128 (~15.65ps) 00249 * This value is raw time minus user set Rx antenna delay. 00250 */ 00251 uint64_t getRXTimestamp(); 00252 00253 /** Get the last packet transmit time 00254 * @return the internal time stamp for the last packet Tx 00255 * 00256 * Time is counted on a clock running at 499.2MHz * 128 (~15.65ps) 00257 * This value is raw time plus user set Tx antenna delay to give time at the antenna. 00258 */ 00259 uint64_t getTXTimestamp(); 00260 00261 /** Send a packet 00262 * @param message A buffer containing the data to send 00263 * @param length The length of the data in bytes. 00264 * 00265 * The supplied packet is transmitted as soon as possible and the reciever re-enabled once transmission is complete. 00266 * Maximum packet size is 125 bytes. 00267 * 00268 * The receiver is re-activated as soon as packet transmission is complete. 00269 */ 00270 void sendFrame(uint8_t* message, uint16_t length); // send a raw frame (length in bytes) 00271 00272 /** Send a packet at a certain time 00273 * @param message A buffer containing the data to send 00274 * @param length The length of the data in bytes. 00275 * @param TxTimestamp The timestamp to send the packet. 00276 * 00277 * The supplied packet is transmitted once the internal clock reaches the specified timestamp. 00278 * Maximum packet size is 125 bytes. 00279 * Rx is disabled as soon as this command is issued and re-enabled once transmission is complete. 00280 * Note - 9 LSBs are ignored so timings are only accurate to ~8ns. For more accurate timing check the 00281 * tx timestamp after transmission is complete. 00282 * 00283 * The receiver is re-activated as soon as packet transmission is complete. 00284 * 00285 */ 00286 void sendDelayedFrame(uint8_t* message, uint16_t length, uint64_t TxTimestamp); 00287 00288 /** Set up data for a transmit on sync 00289 * @param message A buffer containing the data to send 00290 * @param length The length of the data in bytes. 00291 * 00292 * Data is loaded into the transmit buffer but the transmission is not started. 00293 * Maximum packet size is 125 bytes. 00294 */ 00295 void setupSyncedFrame(uint8_t* message, uint16_t length); 00296 00297 /** Transmit on the next sync pulse 00298 * 00299 * On the next rising edge of the sync line the transmitter will be activated. 00300 * The packet must have previously been set up using setupSyncedFrame() 00301 * 00302 * Rx is disabled until transmission is complete and then re-enabled. 00303 */ 00304 void armSyncedFrame(); 00305 00306 /** Get last packet size 00307 * @return The length in bytes of the last packet received 00308 */ 00309 uint16_t getFramelength(); // to get the framelength of the received frame from the PHY header 00310 00311 /** Get last recieved packet 00312 * @param buffer The location to put the received data 00313 * @param length The number of bytes to read 00314 */ 00315 void readRxBuffer( uint8_t *buffer, int length ) { 00316 readRegister(DW1000_RX_BUFFER, 0, buffer, length); 00317 } 00318 00319 /** Enable reciever 00320 * 00321 * This is automatically done after each Tx completes but can also be forced manually 00322 */ 00323 void startRX(); // start listening for frames 00324 00325 /** Disable radio link 00326 * 00327 * Disables both the recieve and transmit systems. 00328 * Any transmissions waiting for a delayed time or sync pulse will be canceled. 00329 */ 00330 void stopTRX(); // disable tranceiver go back to idle mode 00331 00332 /** Reset the reciever logic 00333 * 00334 * This should be done after any receive errors 00335 */ 00336 void resetRX(); // soft reset only the tranciever part of DW1000 00337 00338 /** Enable/Disable interrupts 00339 * @param RX true to enable recieve interrupts 00340 * @param TX true to enable transmit interrupts 00341 * 00342 * For c style callbacks simply set the callback to null to disable it. 00343 * When using c++ style callbacks both are enabled as default, this allows a method to disabled one or both. 00344 */ 00345 void setInterrupt(bool RX, bool TX); // set Interrupt for received a good frame (CRC ok) or transmission done 00346 00347 00348 /** Get the first path amplitude values 00349 * @param fp_amp2 Will be set to first path second peak amplitude 00350 * @param fp_amp3 Will be set to first path third peak amplitude 00351 * 00352 * Reads the two registers for the last packet recieved. Used for quality metrics. 00353 */ 00354 void getFirstPath(uint16_t *fp_amp2,uint16_t *fp_amp3); 00355 00356 00357 /** Get the LDE threshold value 00358 * @return the Leading edge detection threshold register value 00359 */ 00360 inline uint16_t getLDE_THRESH() { 00361 return readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_THRESH); 00362 } 00363 00364 /** Get the LDE Peak path amplitude 00365 * @return the Leading edge detection peak path amplitude value 00366 */ 00367 inline uint16_t getLDE_PPAMPL() { 00368 return readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_PPAMPL); 00369 } 00370 00371 00372 00373 #define DW1000_RX_TTCKO 0x14 // 5 Receiver Time Tracking Offset (in double buffer set) 00374 00375 private: 00376 00377 void resetAll(); // soft reset the entire DW1000 (some registers stay as they were see User Manual) 00378 00379 void setupRadio(); 00380 00381 // system register setup functions 00382 void setupGPIO(); 00383 void setupAGC(); 00384 void setupRxConfig(); 00385 void setupLDE(); 00386 void setupChannel(); 00387 void setupTxFrameCtrl(); 00388 void setupAnalogRF(); 00389 void setupFreqSynth(); 00390 void setupTxCalibration(); 00391 void setupSystemConfig(); 00392 void setupPower(); 00393 void setupXtalTrim(); 00394 00395 void loadLDE(); // load the leading edge detection algorithm to RAM, [IMPORTANT because receiving malfunction may occur] see User Manual LDELOAD on p22 & p158 00396 void loadLDOTUNE(); // load the LDO tuning as set in the factory 00397 00398 uint8_t powerToRegValue(float powerdB); 00399 float regToPowerValue(uint8_t powerVal); 00400 00401 DW1000Setup systemConfig; 00402 00403 // Interrupt 00404 InterruptIn irq; // Pin used to handle Events from DW1000 by an Interrupthandler 00405 FunctionPointer callbackRX; // function pointer to callback which is called when successfull RX took place 00406 FunctionPointer callbackTX; // function pointer to callback which is called when successfull TX took place 00407 void ISR(); // interrupt handling method (also calls according callback methods) 00408 00409 // SPI Inteface 00410 BurstSPI spi; // SPI Bus 00411 DigitalOut cs; // Slave selector for SPI-Bus (here explicitly needed to start and end SPI transactions also usable to wake up DW1000) 00412 00413 uint8_t readRegister8(uint8_t reg, uint16_t subaddress); // expressive methods to read or write the number of bits written in the name 00414 uint16_t readRegister16(uint8_t reg, uint16_t subaddress); 00415 uint32_t readRegister32(uint8_t reg, uint16_t subaddress); 00416 uint64_t readRegister40(uint8_t reg, uint16_t subaddress); 00417 uint64_t readRegister64(uint8_t reg, uint16_t subaddress); 00418 void writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer); 00419 void writeRegister16(uint8_t reg, uint16_t subaddress, uint16_t buffer); 00420 void writeRegister32(uint8_t reg, uint16_t subaddress, uint32_t buffer); 00421 void writeRegister40(uint8_t reg, uint16_t subaddress, uint64_t buffer); 00422 00423 void readRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length); // reads the selected part of a slave register into the buffer memory 00424 void writeRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length); // writes the buffer memory to the selected slave register 00425 void setupTransaction(uint8_t reg, uint16_t subaddress, bool write); // sets up an SPI read or write transaction with correct register address and offset 00426 void select(); // selects the only slave for a transaction 00427 void deselect(); // deselects the only slave after transaction 00428 }; 00429 00430 #endif
Generated on Mon Jul 18 2022 07:51:56 by 1.7.2