DW1000 UWB driver based on work of Matthias Grob & Manuel Stalder - ETH Zürich - 2015
DW1000.h@10:f1e3c04080d6, 2016-08-01 (annotated)
- Committer:
- AndyA
- Date:
- Mon Aug 01 08:45:36 2016 +0000
- Revision:
- 10:f1e3c04080d6
- Parent:
- 9:326bf149c8bc
- Child:
- 12:da4b09aff6af
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AndyA | 0:bddb8cd5e7df | 1 | // by Matthias Grob & Manuel Stalder - ETH Zürich - 2015 |
AndyA | 0:bddb8cd5e7df | 2 | |
AndyA | 0:bddb8cd5e7df | 3 | #ifndef DW1000_H |
AndyA | 0:bddb8cd5e7df | 4 | #define DW1000_H |
AndyA | 0:bddb8cd5e7df | 5 | |
AndyA | 0:bddb8cd5e7df | 6 | #include "mbed.h" |
AndyA | 7:b13881dbb09d | 7 | #include "BurstSPI.h" |
AndyA | 8:0b408e77b701 | 8 | #include "DW1000Registers.h" |
AndyA | 8:0b408e77b701 | 9 | #include "DW1000Setup.h" |
AndyA | 3:1459d2aa6b97 | 10 | |
AndyA | 8:0b408e77b701 | 11 | #define TIMEUNITS_TO_US (1/(128*499.2)) // conversion between the decawave timeunits (ca 15.65ps) to microseconds. |
AndyA | 8:0b408e77b701 | 12 | #define US_TO_TIMEUNITS ((uint32_t)(128*499.2)) // conversion between microseconds to the decawave timeunits (ca 15.65ps). |
AndyA | 8:0b408e77b701 | 13 | #define c_mPerS 299792458 |
AndyA | 8:0b408e77b701 | 14 | #define c_mmPerTick (c_mPerS * TIMEUNITS_TO_US / 1000) |
AndyA | 8:0b408e77b701 | 15 | #define c_mPerTick (c_mmPerTick/1000) |
AndyA | 4:5f1025df5530 | 16 | |
AndyA | 4:5f1025df5530 | 17 | |
AndyA | 0:bddb8cd5e7df | 18 | |
AndyA | 4:5f1025df5530 | 19 | /** A DW1000 driver |
AndyA | 9:326bf149c8bc | 20 | * |
AndyA | 9:326bf149c8bc | 21 | * It is expected that the protocol implimentation above this will inherit this object. |
AndyA | 9:326bf149c8bc | 22 | * If not using this structure then move the protected functions to being public. |
AndyA | 9:326bf149c8bc | 23 | * |
AndyA | 4:5f1025df5530 | 24 | */ |
AndyA | 0:bddb8cd5e7df | 25 | class DW1000 |
AndyA | 0:bddb8cd5e7df | 26 | { |
AndyA | 0:bddb8cd5e7df | 27 | public: |
AndyA | 0:bddb8cd5e7df | 28 | |
AndyA | 6:2c77afdf7367 | 29 | /** Constructor. |
AndyA | 6:2c77afdf7367 | 30 | * |
AndyA | 9:326bf149c8bc | 31 | * The radio will default to DW1000Setup::tunedDefault until you call applySetup() with a new configuration. |
AndyA | 6:2c77afdf7367 | 32 | */ |
AndyA | 9:326bf149c8bc | 33 | DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ); // constructor, uses SPI class |
AndyA | 6:2c77afdf7367 | 34 | |
AndyA | 6:2c77afdf7367 | 35 | /** Read the device ID |
AndyA | 6:2c77afdf7367 | 36 | * @return the device ID (0xDECA0130) |
AndyA | 6:2c77afdf7367 | 37 | */ |
AndyA | 0:bddb8cd5e7df | 38 | uint32_t getDeviceID(); // gets the Device ID which should be 0xDECA0130 (good for testing SPI!) |
AndyA | 6:2c77afdf7367 | 39 | |
AndyA | 6:2c77afdf7367 | 40 | /** Read the Extended Unique ID |
AndyA | 6:2c77afdf7367 | 41 | * @return The device EUI as stored in the system registers |
AndyA | 6:2c77afdf7367 | 42 | */ |
AndyA | 6:2c77afdf7367 | 43 | uint64_t getEUI(); |
AndyA | 6:2c77afdf7367 | 44 | |
AndyA | 6:2c77afdf7367 | 45 | /** Set the Extended Unique ID |
AndyA | 6:2c77afdf7367 | 46 | * @param EUI The EUID to use |
AndyA | 6:2c77afdf7367 | 47 | * |
AndyA | 10:f1e3c04080d6 | 48 | * @note ID is only valid until the next power cycle and overrides the value in the OTP memory. |
AndyA | 6:2c77afdf7367 | 49 | * To set a value that is automatically loaded on startup set OTP memory addresses 0 and 1. |
AndyA | 6:2c77afdf7367 | 50 | */ |
AndyA | 0:bddb8cd5e7df | 51 | void setEUI(uint64_t EUI); // sets 64 bit Extended Unique Identifier according to IEEE standard |
AndyA | 6:2c77afdf7367 | 52 | |
AndyA | 6:2c77afdf7367 | 53 | /** Read voltage input |
AndyA | 6:2c77afdf7367 | 54 | |
AndyA | 6:2c77afdf7367 | 55 | @return the current device voltage |
AndyA | 6:2c77afdf7367 | 56 | |
AndyA | 6:2c77afdf7367 | 57 | For accurate ranging the voltage of the device should be taken into account. |
AndyA | 6:2c77afdf7367 | 58 | User manual give variation as ~5.35cm / V |
AndyA | 6:2c77afdf7367 | 59 | */ |
AndyA | 0:bddb8cd5e7df | 60 | float getVoltage(); // gets the current chip voltage measurement form the A/D converter |
AndyA | 6:2c77afdf7367 | 61 | |
AndyA | 6:2c77afdf7367 | 62 | /** Read on board temperature sensor |
AndyA | 6:2c77afdf7367 | 63 | @return The temperature in C |
AndyA | 6:2c77afdf7367 | 64 | |
AndyA | 6:2c77afdf7367 | 65 | For accurate ranging the temperature of the device should be taken into account. |
AndyA | 6:2c77afdf7367 | 66 | User manual give variation as ~2.15mm / C |
AndyA | 6:2c77afdf7367 | 67 | */ |
AndyA | 0:bddb8cd5e7df | 68 | float getTemperature(); // gets the current chip temperature measurement form the A/D converter |
AndyA | 6:2c77afdf7367 | 69 | |
AndyA | 6:2c77afdf7367 | 70 | /** Get the status register |
AndyA | 6:2c77afdf7367 | 71 | * @return The system status register |
AndyA | 6:2c77afdf7367 | 72 | * |
AndyA | 6:2c77afdf7367 | 73 | * See user manual section 7.2.17 for details |
AndyA | 6:2c77afdf7367 | 74 | */ |
AndyA | 0:bddb8cd5e7df | 75 | uint64_t getStatus(); // get the 40 bit device status |
AndyA | 6:2c77afdf7367 | 76 | |
AndyA | 9:326bf149c8bc | 77 | |
AndyA | 9:326bf149c8bc | 78 | /** Set receive antenna delay |
AndyA | 9:326bf149c8bc | 79 | * @param ticks Delay in system clock cycles |
AndyA | 9:326bf149c8bc | 80 | */ |
AndyA | 9:326bf149c8bc | 81 | void setRxDelay(uint16_t ticks); |
AndyA | 9:326bf149c8bc | 82 | /** Set transmit antenna delay |
AndyA | 9:326bf149c8bc | 83 | * @param ticks Delay in system clock cycles |
AndyA | 9:326bf149c8bc | 84 | */ |
AndyA | 9:326bf149c8bc | 85 | void setTxDelay(uint16_t ticks); |
AndyA | 9:326bf149c8bc | 86 | |
AndyA | 9:326bf149c8bc | 87 | /** Set receive antenna delay in meters |
AndyA | 9:326bf149c8bc | 88 | * @param errorDistance Delay in meters at speed of light |
AndyA | 9:326bf149c8bc | 89 | */ |
AndyA | 9:326bf149c8bc | 90 | void setRxDelayDistance(double errorDistance) { |
AndyA | 9:326bf149c8bc | 91 | setRxDelay(errorDistance/c_mPerTick); |
AndyA | 9:326bf149c8bc | 92 | }; |
AndyA | 9:326bf149c8bc | 93 | |
AndyA | 9:326bf149c8bc | 94 | /** Set transmit antenna delay in meters |
AndyA | 9:326bf149c8bc | 95 | * @param errorDistance Delay in meters at speed of light |
AndyA | 9:326bf149c8bc | 96 | */ |
AndyA | 9:326bf149c8bc | 97 | void setTxDelayDistance(double errorDistance) { |
AndyA | 9:326bf149c8bc | 98 | setTxDelay(errorDistance/c_mPerTick); |
AndyA | 9:326bf149c8bc | 99 | }; |
AndyA | 9:326bf149c8bc | 100 | |
AndyA | 9:326bf149c8bc | 101 | /** Read a value from the OTP memory |
AndyA | 9:326bf149c8bc | 102 | * @param word_address The OTP memory address to read. |
AndyA | 9:326bf149c8bc | 103 | * @return The 32 bit value at that address. |
AndyA | 9:326bf149c8bc | 104 | * |
AndyA | 9:326bf149c8bc | 105 | * See Section 6.3.1 of the user manual for the memory map. |
AndyA | 9:326bf149c8bc | 106 | */ |
AndyA | 9:326bf149c8bc | 107 | uint32_t readOTP (uint16_t word_address); |
AndyA | 9:326bf149c8bc | 108 | |
AndyA | 9:326bf149c8bc | 109 | /** Write a value to the OTP memory |
AndyA | 9:326bf149c8bc | 110 | * @param word_address The OTP memory address to read. |
AndyA | 9:326bf149c8bc | 111 | * @param data The value to write |
AndyA | 9:326bf149c8bc | 112 | * @return True if the write was sucessful. |
AndyA | 9:326bf149c8bc | 113 | * |
AndyA | 9:326bf149c8bc | 114 | * Writes the supplied data to the OTP memory and then reads it back to verify it was sucessfully programmed. |
AndyA | 10:f1e3c04080d6 | 115 | * @warning This is a one time operation for each memory address. |
AndyA | 9:326bf149c8bc | 116 | * See Section 6.3.1 of the user manual for the memory map. |
AndyA | 10:f1e3c04080d6 | 117 | * |
AndyA | 10:f1e3c04080d6 | 118 | * @note It is recommened that the device is reset or power cycled after programing. |
AndyA | 9:326bf149c8bc | 119 | */ |
AndyA | 9:326bf149c8bc | 120 | bool writeOTP(uint16_t word_address,uint32_t data); // program a value in the OTP. It is recommended to reset afterwards. |
AndyA | 9:326bf149c8bc | 121 | |
AndyA | 9:326bf149c8bc | 122 | /** get the current radio configuration |
AndyA | 9:326bf149c8bc | 123 | * @return A pointer to a DW1000Setup object of the current setup. |
AndyA | 9:326bf149c8bc | 124 | * |
AndyA | 9:326bf149c8bc | 125 | * Note to change the setup you must make a copy of the current setup and then pass that to applySetup(). |
AndyA | 9:326bf149c8bc | 126 | */ |
AndyA | 9:326bf149c8bc | 127 | DW1000Setup *getSetup(); |
AndyA | 9:326bf149c8bc | 128 | |
AndyA | 9:326bf149c8bc | 129 | /** Get the current Transmit gain settings. |
AndyA | 9:326bf149c8bc | 130 | * |
AndyA | 9:326bf149c8bc | 131 | * @param power Optional, is set to the first power in dBm |
AndyA | 9:326bf149c8bc | 132 | * @param boost500 Optional, is set to the second power in dBm |
AndyA | 9:326bf149c8bc | 133 | * @param boost250 Optional, is set to the third power in dBm |
AndyA | 9:326bf149c8bc | 134 | * @param boost125 Optional, is set to the forth power in dBm |
AndyA | 9:326bf149c8bc | 135 | * @return The raw transmit gain register value |
AndyA | 9:326bf149c8bc | 136 | * |
AndyA | 9:326bf149c8bc | 137 | * If smart power is on then power represents the normal transmit power, |
AndyA | 9:326bf149c8bc | 138 | * boost500-boost125 indicates the power used for packets of that number of us or less. |
AndyA | 9:326bf149c8bc | 139 | * |
AndyA | 9:326bf149c8bc | 140 | * If smart power is off then boost500 represents the gain for the PHY header, boost250 the gain for the main message. |
AndyA | 9:326bf149c8bc | 141 | * power and boost125 are not used. |
AndyA | 9:326bf149c8bc | 142 | */ |
AndyA | 9:326bf149c8bc | 143 | uint32_t getTxPower(float *power = NULL, float *boost500 = NULL, float *boost250 = NULL, float *boost125 = NULL); |
AndyA | 9:326bf149c8bc | 144 | |
AndyA | 9:326bf149c8bc | 145 | /** Set Transmit gain |
AndyA | 9:326bf149c8bc | 146 | * |
AndyA | 9:326bf149c8bc | 147 | * @param normalPowercB Normal transmit gain to use. |
AndyA | 9:326bf149c8bc | 148 | * @param boost500 Gain to use for 6.8Mb/s packets of under 500ms. |
AndyA | 9:326bf149c8bc | 149 | * @param boost250 Gain to use for 6.8Mb/s packets of under 250ms. |
AndyA | 9:326bf149c8bc | 150 | * @param boost125 Gain to use for 6.8Mb/s packets of under 125ms. |
AndyA | 9:326bf149c8bc | 151 | * |
AndyA | 9:326bf149c8bc | 152 | * All gains are in dB. Gains can be between 0 and 33.5dB. |
AndyA | 9:326bf149c8bc | 153 | * 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). |
AndyA | 9:326bf149c8bc | 154 | * If smart power is disabled then the normal gain is used for all settings. |
AndyA | 9:326bf149c8bc | 155 | * The values in the internal DW1000Setup are updated to reflect the configured powers. |
AndyA | 9:326bf149c8bc | 156 | */ |
AndyA | 9:326bf149c8bc | 157 | void setTxPower(float normalPowerdB, float boost500 = 0, float boost250 = 0, float boost125 = 0); |
AndyA | 9:326bf149c8bc | 158 | |
AndyA | 9:326bf149c8bc | 159 | /** Get the rx signal power for the last packet |
AndyA | 9:326bf149c8bc | 160 | * |
AndyA | 9:326bf149c8bc | 161 | * @param direct Is set to the direct path Rx power in dBm |
AndyA | 9:326bf149c8bc | 162 | * @param total Is set to the total Rx power in dBm |
AndyA | 9:326bf149c8bc | 163 | * |
AndyA | 9:326bf149c8bc | 164 | * According to the DW1000 manual if the direct path power is within 6dB of the total then it was probably a LoS measurment. |
AndyA | 9:326bf149c8bc | 165 | * If there is more than 10dB difference then it's probably an indirect path. |
AndyA | 9:326bf149c8bc | 166 | */ |
AndyA | 9:326bf149c8bc | 167 | void getRxSignalPower(float *direct, float *total); |
AndyA | 9:326bf149c8bc | 168 | |
AndyA | 10:f1e3c04080d6 | 169 | |
AndyA | 10:f1e3c04080d6 | 170 | void getFullQualityMetrics(uint16_t *std_noise, uint16_t *fp_amp1, uint16_t *fp_amp2, uint16_t *fp_amp3, |
AndyA | 10:f1e3c04080d6 | 171 | uint16_t *cir_pwr, uint16_t *preAmbleAcc, uint16_t *preAmbleAcc_NoSat); |
AndyA | 10:f1e3c04080d6 | 172 | |
AndyA | 9:326bf149c8bc | 173 | |
AndyA | 9:326bf149c8bc | 174 | protected: |
AndyA | 9:326bf149c8bc | 175 | |
AndyA | 9:326bf149c8bc | 176 | /** |
AndyA | 9:326bf149c8bc | 177 | * Sets the callbacks on packet Rx and Tx |
AndyA | 9:326bf149c8bc | 178 | * @param callbackRX The function to call on packet Rx complete |
AndyA | 9:326bf149c8bc | 179 | * @param callbackTX The function to call on packet Tx complete |
AndyA | 9:326bf149c8bc | 180 | * |
AndyA | 9:326bf149c8bc | 181 | * set either or both to null to disable the appropriate interupt |
AndyA | 9:326bf149c8bc | 182 | */ |
AndyA | 9:326bf149c8bc | 183 | void setCallbacks(void (*callbackRX)(void), void (*callbackTX)(void)); // setter for callback functions, automatically enables interrupt, if NULL is passed the coresponding interrupt gets disabled |
AndyA | 9:326bf149c8bc | 184 | |
AndyA | 9:326bf149c8bc | 185 | /** |
AndyA | 9:326bf149c8bc | 186 | * c++ version of setCallbacks() |
AndyA | 9:326bf149c8bc | 187 | * @param tptr object for callbacks |
AndyA | 9:326bf149c8bc | 188 | * @param mptrRX method to call on packet Rx complete |
AndyA | 9:326bf149c8bc | 189 | * @param mptrTX method to call on packet Tx complete |
AndyA | 9:326bf149c8bc | 190 | * |
AndyA | 9:326bf149c8bc | 191 | */ |
AndyA | 9:326bf149c8bc | 192 | template<typename T> |
AndyA | 9:326bf149c8bc | 193 | void setCallbacks(T* tptr, void (T::*mptrRX)(void), void (T::*mptrTX)(void)) { // overloaded setter to treat member function pointers of objects |
AndyA | 9:326bf149c8bc | 194 | callbackRX.attach(tptr, mptrRX); // possible client code: dw.setCallbacks(this, &A::callbackRX, &A::callbackTX); |
AndyA | 9:326bf149c8bc | 195 | 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 |
AndyA | 9:326bf149c8bc | 196 | setInterrupt(true,true); |
AndyA | 9:326bf149c8bc | 197 | } |
AndyA | 9:326bf149c8bc | 198 | |
AndyA | 6:2c77afdf7367 | 199 | /** Get the last packet recieve time |
AndyA | 6:2c77afdf7367 | 200 | * @return the internal time stamp for the last packet Rx |
AndyA | 6:2c77afdf7367 | 201 | * |
AndyA | 6:2c77afdf7367 | 202 | * Time is counted on a clock running at 499.2MHz * 128 (~15.65ps) |
AndyA | 6:2c77afdf7367 | 203 | * This value is raw time minus user set Rx antenna delay. |
AndyA | 6:2c77afdf7367 | 204 | */ |
AndyA | 0:bddb8cd5e7df | 205 | uint64_t getRXTimestamp(); |
AndyA | 6:2c77afdf7367 | 206 | |
AndyA | 6:2c77afdf7367 | 207 | /** Get the last packet transmit time |
AndyA | 6:2c77afdf7367 | 208 | * @return the internal time stamp for the last packet Tx |
AndyA | 6:2c77afdf7367 | 209 | * |
AndyA | 6:2c77afdf7367 | 210 | * Time is counted on a clock running at 499.2MHz * 128 (~15.65ps) |
AndyA | 6:2c77afdf7367 | 211 | * This value is raw time plus user set Tx antenna delay to give time at the antenna. |
AndyA | 6:2c77afdf7367 | 212 | */ |
AndyA | 0:bddb8cd5e7df | 213 | uint64_t getTXTimestamp(); |
AndyA | 0:bddb8cd5e7df | 214 | |
AndyA | 6:2c77afdf7367 | 215 | /** Send a packet |
AndyA | 6:2c77afdf7367 | 216 | * @param message A buffer containing the data to send |
AndyA | 6:2c77afdf7367 | 217 | * @param length The length of the data in bytes. |
AndyA | 6:2c77afdf7367 | 218 | * |
AndyA | 6:2c77afdf7367 | 219 | * The supplied packet is transmitted as soon as possible and the reciever re-enabled once transmission is complete. |
AndyA | 6:2c77afdf7367 | 220 | * Maximum packet size is 125 bytes. |
AndyA | 9:326bf149c8bc | 221 | * |
AndyA | 9:326bf149c8bc | 222 | * The receiver is re-activated as soon as packet transmission is complete. |
AndyA | 6:2c77afdf7367 | 223 | */ |
AndyA | 0:bddb8cd5e7df | 224 | void sendFrame(uint8_t* message, uint16_t length); // send a raw frame (length in bytes) |
AndyA | 6:2c77afdf7367 | 225 | |
AndyA | 6:2c77afdf7367 | 226 | /** Send a packet at a certain time |
AndyA | 6:2c77afdf7367 | 227 | * @param message A buffer containing the data to send |
AndyA | 6:2c77afdf7367 | 228 | * @param length The length of the data in bytes. |
AndyA | 6:2c77afdf7367 | 229 | * @param TxTimestamp The timestamp to send the packet. |
AndyA | 6:2c77afdf7367 | 230 | * |
AndyA | 6:2c77afdf7367 | 231 | * The supplied packet is transmitted once the internal clock reaches the specified timestamp. |
AndyA | 6:2c77afdf7367 | 232 | * Maximum packet size is 125 bytes. |
AndyA | 6:2c77afdf7367 | 233 | * Rx is disabled as soon as this command is issued and re-enabled once transmission is complete. |
AndyA | 6:2c77afdf7367 | 234 | * Note - 9 LSBs are ignored so timings are only accurate to ~8ns. For more accurate timing check the |
AndyA | 6:2c77afdf7367 | 235 | * tx timestamp after transmission is complete. |
AndyA | 9:326bf149c8bc | 236 | * |
AndyA | 9:326bf149c8bc | 237 | * The receiver is re-activated as soon as packet transmission is complete. |
AndyA | 9:326bf149c8bc | 238 | * |
AndyA | 6:2c77afdf7367 | 239 | */ |
AndyA | 0:bddb8cd5e7df | 240 | void sendDelayedFrame(uint8_t* message, uint16_t length, uint64_t TxTimestamp); |
AndyA | 0:bddb8cd5e7df | 241 | |
AndyA | 6:2c77afdf7367 | 242 | /** Set up data for a transmit on sync |
AndyA | 6:2c77afdf7367 | 243 | * @param message A buffer containing the data to send |
AndyA | 6:2c77afdf7367 | 244 | * @param length The length of the data in bytes. |
AndyA | 6:2c77afdf7367 | 245 | * |
AndyA | 6:2c77afdf7367 | 246 | * Data is loaded into the transmit buffer but the transmission is not started. |
AndyA | 6:2c77afdf7367 | 247 | * Maximum packet size is 125 bytes. |
AndyA | 6:2c77afdf7367 | 248 | */ |
AndyA | 0:bddb8cd5e7df | 249 | void setupSyncedFrame(uint8_t* message, uint16_t length); |
AndyA | 6:2c77afdf7367 | 250 | |
AndyA | 6:2c77afdf7367 | 251 | /** Transmit on the next sync pulse |
AndyA | 6:2c77afdf7367 | 252 | * |
AndyA | 6:2c77afdf7367 | 253 | * On the next rising edge of the sync line the transmitter will be activated. |
AndyA | 6:2c77afdf7367 | 254 | * The packet must have previously been set up using setupSyncedFrame() |
AndyA | 6:2c77afdf7367 | 255 | * |
AndyA | 9:326bf149c8bc | 256 | * Rx is disabled until transmission is complete and then re-enabled. |
AndyA | 6:2c77afdf7367 | 257 | */ |
AndyA | 0:bddb8cd5e7df | 258 | void armSyncedFrame(); |
AndyA | 0:bddb8cd5e7df | 259 | |
AndyA | 9:326bf149c8bc | 260 | /** Get last packet size |
AndyA | 9:326bf149c8bc | 261 | * @return The length in bytes of the last packet received |
AndyA | 9:326bf149c8bc | 262 | */ |
AndyA | 9:326bf149c8bc | 263 | uint16_t getFramelength(); // to get the framelength of the received frame from the PHY header |
AndyA | 9:326bf149c8bc | 264 | |
AndyA | 9:326bf149c8bc | 265 | /** Get last recieved packet |
AndyA | 9:326bf149c8bc | 266 | * @param buffer The location to put the received data |
AndyA | 9:326bf149c8bc | 267 | * @param length The number of bytes to read |
AndyA | 9:326bf149c8bc | 268 | */ |
AndyA | 9:326bf149c8bc | 269 | void readRxBuffer( uint8_t *buffer, int length ) { |
AndyA | 9:326bf149c8bc | 270 | readRegister(DW1000_RX_BUFFER, 0, buffer, length); |
AndyA | 9:326bf149c8bc | 271 | } |
AndyA | 9:326bf149c8bc | 272 | |
AndyA | 6:2c77afdf7367 | 273 | /** Enable reciever |
AndyA | 6:2c77afdf7367 | 274 | * |
AndyA | 6:2c77afdf7367 | 275 | * This is automatically done after each Tx completes but can also be forced manually |
AndyA | 6:2c77afdf7367 | 276 | */ |
AndyA | 0:bddb8cd5e7df | 277 | void startRX(); // start listening for frames |
AndyA | 6:2c77afdf7367 | 278 | |
AndyA | 6:2c77afdf7367 | 279 | /** Disable radio link |
AndyA | 6:2c77afdf7367 | 280 | * |
AndyA | 6:2c77afdf7367 | 281 | * Disables both the recieve and transmit systems. |
AndyA | 6:2c77afdf7367 | 282 | * Any transmissions waiting for a delayed time or sync pulse will be canceled. |
AndyA | 6:2c77afdf7367 | 283 | */ |
AndyA | 0:bddb8cd5e7df | 284 | void stopTRX(); // disable tranceiver go back to idle mode |
AndyA | 0:bddb8cd5e7df | 285 | |
AndyA | 6:2c77afdf7367 | 286 | /** Reset the reciever logic |
AndyA | 6:2c77afdf7367 | 287 | * |
AndyA | 6:2c77afdf7367 | 288 | * This should be done after any receive errors |
AndyA | 6:2c77afdf7367 | 289 | */ |
AndyA | 0:bddb8cd5e7df | 290 | void resetRX(); // soft reset only the tranciever part of DW1000 |
AndyA | 6:2c77afdf7367 | 291 | |
AndyA | 6:2c77afdf7367 | 292 | /** Enable/Disable interrupts |
AndyA | 6:2c77afdf7367 | 293 | * @param RX true to enable recieve interrupts |
AndyA | 6:2c77afdf7367 | 294 | * @param TX true to enable transmit interrupts |
AndyA | 6:2c77afdf7367 | 295 | * |
AndyA | 6:2c77afdf7367 | 296 | * For c style callbacks simply set the callback to null to disable it. |
AndyA | 6:2c77afdf7367 | 297 | * When using c++ style callbacks both are enabled as default, this allows a method to disabled one or both. |
AndyA | 6:2c77afdf7367 | 298 | */ |
AndyA | 0:bddb8cd5e7df | 299 | void setInterrupt(bool RX, bool TX); // set Interrupt for received a good frame (CRC ok) or transmission done |
AndyA | 0:bddb8cd5e7df | 300 | |
AndyA | 9:326bf149c8bc | 301 | |
AndyA | 9:326bf149c8bc | 302 | /** apply a new radio setup to the UWB system |
AndyA | 9:326bf149c8bc | 303 | * @param setup The new settings to use |
AndyA | 9:326bf149c8bc | 304 | * @return true if the setup was applied. |
AndyA | 3:1459d2aa6b97 | 305 | * |
AndyA | 9:326bf149c8bc | 306 | * The setup object supplied is copied and can be disposed of after the call. |
AndyA | 9:326bf149c8bc | 307 | * If the supplied setup fails DW1000Setup::check() then it is ignored and the function returns false. |
AndyA | 10:f1e3c04080d6 | 308 | * @note This will reset the radio. You must re-enable interupts, receiver etc. after calling it. |
AndyA | 3:1459d2aa6b97 | 309 | */ |
AndyA | 9:326bf149c8bc | 310 | bool applySetup(DW1000Setup *setup); |
AndyA | 0:bddb8cd5e7df | 311 | |
AndyA | 10:f1e3c04080d6 | 312 | |
AndyA | 10:f1e3c04080d6 | 313 | /** Get the first path amplitude values |
AndyA | 10:f1e3c04080d6 | 314 | * @param fp_amp2 Will be set to first path second peak amplitude |
AndyA | 10:f1e3c04080d6 | 315 | * @param fp_amp3 Will be set to first path third peak amplitude |
AndyA | 10:f1e3c04080d6 | 316 | * |
AndyA | 10:f1e3c04080d6 | 317 | * Reads the two registers for the last packet recieved. Used for quality metrics. |
AndyA | 10:f1e3c04080d6 | 318 | */ |
AndyA | 10:f1e3c04080d6 | 319 | void getFirstPath(uint16_t *fp_amp2,uint16_t *fp_amp3); |
AndyA | 10:f1e3c04080d6 | 320 | |
AndyA | 0:bddb8cd5e7df | 321 | private: |
AndyA | 0:bddb8cd5e7df | 322 | void resetAll(); // soft reset the entire DW1000 (some registers stay as they were see User Manual) |
AndyA | 3:1459d2aa6b97 | 323 | |
AndyA | 3:1459d2aa6b97 | 324 | void setupRadio(); |
AndyA | 3:1459d2aa6b97 | 325 | |
AndyA | 4:5f1025df5530 | 326 | // system register setup functions |
AndyA | 9:326bf149c8bc | 327 | void setupGPIO(); |
AndyA | 3:1459d2aa6b97 | 328 | void setupAGC(); |
AndyA | 3:1459d2aa6b97 | 329 | void setupRxConfig(); |
AndyA | 3:1459d2aa6b97 | 330 | void setupLDE(); |
AndyA | 3:1459d2aa6b97 | 331 | void setupChannel(); |
AndyA | 3:1459d2aa6b97 | 332 | void setupTxFrameCtrl(); |
AndyA | 3:1459d2aa6b97 | 333 | void setupAnalogRF(); |
AndyA | 3:1459d2aa6b97 | 334 | void setupFreqSynth(); |
AndyA | 3:1459d2aa6b97 | 335 | void setupTxCalibration(); |
AndyA | 3:1459d2aa6b97 | 336 | void setupSystemConfig(); |
AndyA | 9:326bf149c8bc | 337 | void setupPower(); |
AndyA | 9:326bf149c8bc | 338 | |
AndyA | 0:bddb8cd5e7df | 339 | void loadLDE(); // load the leading edge detection algorithm to RAM, [IMPORTANT because receiving malfunction may occur] see User Manual LDELOAD on p22 & p158 |
AndyA | 0:bddb8cd5e7df | 340 | void loadLDOTUNE(); // load the LDO tuning as set in the factory |
AndyA | 0:bddb8cd5e7df | 341 | |
AndyA | 9:326bf149c8bc | 342 | uint8_t powerToRegValue(float powerdB); |
AndyA | 9:326bf149c8bc | 343 | float regToPowerValue(uint8_t powerVal); |
AndyA | 3:1459d2aa6b97 | 344 | |
AndyA | 4:5f1025df5530 | 345 | DW1000Setup systemConfig; |
AndyA | 3:1459d2aa6b97 | 346 | |
AndyA | 0:bddb8cd5e7df | 347 | // Interrupt |
AndyA | 0:bddb8cd5e7df | 348 | InterruptIn irq; // Pin used to handle Events from DW1000 by an Interrupthandler |
AndyA | 0:bddb8cd5e7df | 349 | FunctionPointer callbackRX; // function pointer to callback which is called when successfull RX took place |
AndyA | 0:bddb8cd5e7df | 350 | FunctionPointer callbackTX; // function pointer to callback which is called when successfull TX took place |
AndyA | 0:bddb8cd5e7df | 351 | void ISR(); // interrupt handling method (also calls according callback methods) |
AndyA | 0:bddb8cd5e7df | 352 | |
AndyA | 0:bddb8cd5e7df | 353 | // SPI Inteface |
AndyA | 7:b13881dbb09d | 354 | BurstSPI spi; // SPI Bus |
AndyA | 0:bddb8cd5e7df | 355 | DigitalOut cs; // Slave selector for SPI-Bus (here explicitly needed to start and end SPI transactions also usable to wake up DW1000) |
AndyA | 0:bddb8cd5e7df | 356 | |
AndyA | 0:bddb8cd5e7df | 357 | uint8_t readRegister8(uint8_t reg, uint16_t subaddress); // expressive methods to read or write the number of bits written in the name |
AndyA | 0:bddb8cd5e7df | 358 | uint16_t readRegister16(uint8_t reg, uint16_t subaddress); |
AndyA | 9:326bf149c8bc | 359 | uint32_t readRegister32(uint8_t reg, uint16_t subaddress); |
AndyA | 0:bddb8cd5e7df | 360 | uint64_t readRegister40(uint8_t reg, uint16_t subaddress); |
AndyA | 0:bddb8cd5e7df | 361 | uint64_t readRegister64(uint8_t reg, uint16_t subaddress); |
AndyA | 0:bddb8cd5e7df | 362 | void writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer); |
AndyA | 0:bddb8cd5e7df | 363 | void writeRegister16(uint8_t reg, uint16_t subaddress, uint16_t buffer); |
AndyA | 0:bddb8cd5e7df | 364 | void writeRegister32(uint8_t reg, uint16_t subaddress, uint32_t buffer); |
AndyA | 0:bddb8cd5e7df | 365 | void writeRegister40(uint8_t reg, uint16_t subaddress, uint64_t buffer); |
AndyA | 0:bddb8cd5e7df | 366 | |
AndyA | 0:bddb8cd5e7df | 367 | 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 |
AndyA | 0:bddb8cd5e7df | 368 | void writeRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length); // writes the buffer memory to the selected slave register |
AndyA | 0:bddb8cd5e7df | 369 | void setupTransaction(uint8_t reg, uint16_t subaddress, bool write); // sets up an SPI read or write transaction with correct register address and offset |
AndyA | 0:bddb8cd5e7df | 370 | void select(); // selects the only slave for a transaction |
AndyA | 0:bddb8cd5e7df | 371 | void deselect(); // deselects the only slave after transaction |
AndyA | 0:bddb8cd5e7df | 372 | }; |
AndyA | 0:bddb8cd5e7df | 373 | |
AndyA | 0:bddb8cd5e7df | 374 | #endif |