Simple driver for DWM1000 modules.

Committer:
bhepp
Date:
Thu Mar 31 15:36:39 2016 +0000
Revision:
5:c34ebc7f650c
Parent:
4:faf802b4af85
Child:
6:028891b5f03b
Some cleanup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bhepp 2:12a2907957b8 1 // Adapted from Matthias Grob & Manuel Stalder - ETH Zürich - 2015
bhepp 2:12a2907957b8 2
bhepp 0:2c8820705cdd 3 #include "DW1000.h"
bhepp 0:2c8820705cdd 4
bhepp 0:2c8820705cdd 5 // Change this depending on whether damaged or heatlhy DWM1000 modules are used.
bhepp 0:2c8820705cdd 6 const bool DWM1000_DAMAGED = true;
bhepp 5:c34ebc7f650c 7 //const bool DWM1000_DAMAGED = false;
bhepp 0:2c8820705cdd 8
bhepp 0:2c8820705cdd 9 //#include "PC.h"
bhepp 0:2c8820705cdd 10 //static PC pc(USBTX, USBRX, 115200); // USB UART Terminal
bhepp 0:2c8820705cdd 11
bhepp 5:c34ebc7f650c 12 DW1000::DW1000(SPI& spi, InterruptIn* irq, PinName CS, PinName RESET)
bhepp 2:12a2907957b8 13 : irq(irq), spi(spi), cs(CS), reset(RESET) {
bhepp 5:c34ebc7f650c 14 if (irq != NULL) {
bhepp 5:c34ebc7f650c 15 irq->rise(this, &DW1000::ISR);
bhepp 5:c34ebc7f650c 16 }
bhepp 0:2c8820705cdd 17
bhepp 0:2c8820705cdd 18 setCallbacks(NULL, NULL);
bhepp 0:2c8820705cdd 19
bhepp 0:2c8820705cdd 20 select();
bhepp 0:2c8820705cdd 21 deselect(); // Chip must be deselected first
bhepp 0:2c8820705cdd 22 resetAll(); // we do a soft reset of the DW1000 everytime the driver starts
bhepp 0:2c8820705cdd 23
bhepp 0:2c8820705cdd 24 // Configuration TODO: make method for that
bhepp 0:2c8820705cdd 25 // User Manual "2.5.5 Default Configurations that should be modified" p. 22
bhepp 0:2c8820705cdd 26 //Those values are for the standard mode (6.8Mbps, 5, 16Mhz, 32 Symbols) and are INCOMPLETE!
bhepp 0:2c8820705cdd 27 // writeRegister16(DW1000_AGC_CTRL, 0x04, 0x8870);
bhepp 0:2c8820705cdd 28 // writeRegister32(DW1000_AGC_CTRL, 0x0C, 0x2502A907);
bhepp 0:2c8820705cdd 29 // writeRegister32(DW1000_DRX_CONF, 0x08, 0x311A002D);
bhepp 0:2c8820705cdd 30 // writeRegister8 (DW1000_LDE_CTRL, 0x0806, 0xD);
bhepp 0:2c8820705cdd 31 // writeRegister16(DW1000_LDE_CTRL, 0x1806, 0x1607);
bhepp 0:2c8820705cdd 32 // writeRegister32(DW1000_TX_POWER, 0, 0x0E082848);
bhepp 0:2c8820705cdd 33 // writeRegister32(DW1000_RF_CONF, 0x0C, 0x001E3FE0);
bhepp 0:2c8820705cdd 34 // writeRegister8 (DW1000_TX_CAL, 0x0B, 0xC0);
bhepp 0:2c8820705cdd 35 // writeRegister8 (DW1000_FS_CTRL, 0x0B, 0xA6);
bhepp 0:2c8820705cdd 36
bhepp 0:2c8820705cdd 37
bhepp 0:2c8820705cdd 38 //Those values are for the 110kbps mode (5, 16MHz, 1024 Symbols) and are quite complete
bhepp 0:2c8820705cdd 39 writeRegister16(DW1000_AGC_CTRL, 0x04, 0x8870); //AGC_TUNE1 for 16MHz PRF
bhepp 0:2c8820705cdd 40 writeRegister32(DW1000_AGC_CTRL, 0x0C, 0x2502A907); //AGC_TUNE2 (Universal)
bhepp 0:2c8820705cdd 41 writeRegister16(DW1000_AGC_CTRL, 0x12, 0x0055); //AGC_TUNE3 (Universal)
bhepp 0:2c8820705cdd 42
bhepp 0:2c8820705cdd 43 writeRegister16(DW1000_DRX_CONF, 0x02, 0x000A); //DRX_TUNE0b for 110kbps
bhepp 0:2c8820705cdd 44 writeRegister16(DW1000_DRX_CONF, 0x04, 0x0087); //DRX_TUNE1a for 16MHz PRF
bhepp 0:2c8820705cdd 45 writeRegister16(DW1000_DRX_CONF, 0x06, 0x0064); //DRX_TUNE1b for 110kbps & > 1024 symbols
bhepp 0:2c8820705cdd 46 writeRegister32(DW1000_DRX_CONF, 0x08, 0x351A009A); //PAC size for 1024 symbols preamble & 16MHz PRF
bhepp 0:2c8820705cdd 47 //writeRegister32(DW1000_DRX_CONF, 0x08, 0x371A011D); //PAC size for 2048 symbols preamble
bhepp 0:2c8820705cdd 48
bhepp 0:2c8820705cdd 49 writeRegister8 (DW1000_LDE_CTRL, 0x0806, 0xD); //LDE_CFG1
bhepp 0:2c8820705cdd 50 writeRegister16(DW1000_LDE_CTRL, 0x1806, 0x1607); //LDE_CFG2 for 16MHz PRF
bhepp 0:2c8820705cdd 51
bhepp 0:2c8820705cdd 52 writeRegister32(DW1000_TX_POWER, 0, 0x28282828); //Power for channel 5
bhepp 0:2c8820705cdd 53
bhepp 0:2c8820705cdd 54 writeRegister8(DW1000_RF_CONF, 0x0B, 0xD8); //RF_RXCTRLH for channel 5
bhepp 0:2c8820705cdd 55 writeRegister32(DW1000_RF_CONF, 0x0C, 0x001E3FE0); //RF_TXCTRL for channel 5
bhepp 0:2c8820705cdd 56
bhepp 0:2c8820705cdd 57 writeRegister8 (DW1000_TX_CAL, 0x0B, 0xC0); //TC_PGDELAY for channel 5
bhepp 0:2c8820705cdd 58
bhepp 0:2c8820705cdd 59 writeRegister32 (DW1000_FS_CTRL, 0x07, 0x0800041D); //FS_PLLCFG for channel 5
bhepp 0:2c8820705cdd 60 writeRegister8 (DW1000_FS_CTRL, 0x0B, 0xA6); //FS_PLLTUNE for channel 5
bhepp 0:2c8820705cdd 61
bhepp 0:2c8820705cdd 62 loadLDE(); // important everytime DW1000 initialises/awakes otherwise the LDE algorithm must be turned off or there's receiving malfunction see User Manual LDELOAD on p22 & p158
bhepp 0:2c8820705cdd 63
bhepp 0:2c8820705cdd 64 // 110kbps CAUTION: a lot of other registers have to be set for an optimized operation on 110kbps
bhepp 0:2c8820705cdd 65 writeRegister16(DW1000_TX_FCTRL, 1, 0x0800 | 0x0100 | 0x0080); // use 1024 symbols preamble (0x0800) (previously 2048 - 0x2800), 16MHz pulse repetition frequency (0x0100), 110kbps bit rate (0x0080) see p.69 of DW1000 User Manual
bhepp 0:2c8820705cdd 66 writeRegister8(DW1000_SYS_CFG, 2, 0x44); // enable special receiving option for 110kbps (disable smartTxPower)!! (0x44) see p.64 of DW1000 User Manual [DO NOT enable 1024 byte frames (0x03) becuase it generates disturbance of ranging don't know why...]
bhepp 0:2c8820705cdd 67
bhepp 0:2c8820705cdd 68 writeRegister16(DW1000_TX_ANTD, 0, 16384); // set TX and RX Antenna delay to neutral because we calibrate afterwards
bhepp 0:2c8820705cdd 69 writeRegister16(DW1000_LDE_CTRL, 0x1804, 16384); // = 2^14 a quarter of the range of the 16-Bit register which corresponds to zero calibration in a round trip (TX1+RX2+TX2+RX1)
bhepp 0:2c8820705cdd 70
bhepp 0:2c8820705cdd 71 writeRegister8(DW1000_SYS_CFG, 3, 0x20); // enable auto reenabling receiver after error
bhepp 0:2c8820705cdd 72
bhepp 5:c34ebc7f650c 73 if (irq != NULL) {
bhepp 5:c34ebc7f650c 74 irq->enable_irq();
bhepp 5:c34ebc7f650c 75 }
bhepp 2:12a2907957b8 76
bhepp 5:c34ebc7f650c 77 //startRX();
bhepp 0:2c8820705cdd 78 }
bhepp 0:2c8820705cdd 79
bhepp 0:2c8820705cdd 80 void DW1000::setCallbacks(void (*callbackRX)(void), void (*callbackTX)(void)) {
bhepp 0:2c8820705cdd 81 bool RX = false;
bhepp 0:2c8820705cdd 82 bool TX = false;
bhepp 0:2c8820705cdd 83 if (callbackRX) {
bhepp 0:2c8820705cdd 84 this->callbackRX.attach(callbackRX);
bhepp 0:2c8820705cdd 85 RX = true;
bhepp 0:2c8820705cdd 86 }
bhepp 0:2c8820705cdd 87 if (callbackTX) {
bhepp 0:2c8820705cdd 88 this->callbackTX.attach(callbackTX);
bhepp 0:2c8820705cdd 89 TX = true;
bhepp 0:2c8820705cdd 90 }
bhepp 0:2c8820705cdd 91 setInterrupt(RX, TX);
bhepp 0:2c8820705cdd 92 }
bhepp 0:2c8820705cdd 93
bhepp 0:2c8820705cdd 94 uint32_t DW1000::getDeviceID() {
bhepp 0:2c8820705cdd 95 uint32_t result;
bhepp 0:2c8820705cdd 96 readRegister(DW1000_DEV_ID, 0, (uint8_t*)&result, 4);
bhepp 0:2c8820705cdd 97 return result;
bhepp 0:2c8820705cdd 98 }
bhepp 0:2c8820705cdd 99
bhepp 0:2c8820705cdd 100 uint64_t DW1000::getEUI() {
bhepp 0:2c8820705cdd 101 uint64_t result;
bhepp 0:2c8820705cdd 102 readRegister(DW1000_EUI, 0, (uint8_t*)&result, 8);
bhepp 0:2c8820705cdd 103 return result;
bhepp 0:2c8820705cdd 104 }
bhepp 0:2c8820705cdd 105
bhepp 0:2c8820705cdd 106 void DW1000::setEUI(uint64_t EUI) {
bhepp 0:2c8820705cdd 107 writeRegister(DW1000_EUI, 0, (uint8_t*)&EUI, 8);
bhepp 0:2c8820705cdd 108 }
bhepp 0:2c8820705cdd 109
bhepp 0:2c8820705cdd 110 float DW1000::getVoltage() {
bhepp 0:2c8820705cdd 111 uint8_t buffer[7] = {0x80, 0x0A, 0x0F, 0x01, 0x00}; // algorithm form User Manual p57
bhepp 0:2c8820705cdd 112 writeRegister(DW1000_RF_CONF, 0x11, buffer, 2);
bhepp 0:2c8820705cdd 113 writeRegister(DW1000_RF_CONF, 0x12, &buffer[2], 1);
bhepp 0:2c8820705cdd 114 writeRegister(DW1000_TX_CAL, 0x00, &buffer[3], 1);
bhepp 0:2c8820705cdd 115 writeRegister(DW1000_TX_CAL, 0x00, &buffer[4], 1);
bhepp 0:2c8820705cdd 116 readRegister(DW1000_TX_CAL, 0x03, &buffer[5], 2); // get the 8-Bit readings for Voltage and Temperature
bhepp 0:2c8820705cdd 117 float Voltage = buffer[5] * 0.0057 + 2.3;
bhepp 0:2c8820705cdd 118 //float Temperature = buffer[6] * 1.13 - 113.0; // TODO: getTemperature was always ~35 degree with better formula/calibration
bhepp 0:2c8820705cdd 119 return Voltage;
bhepp 0:2c8820705cdd 120 }
bhepp 0:2c8820705cdd 121
bhepp 0:2c8820705cdd 122 uint64_t DW1000::getStatus() {
bhepp 0:2c8820705cdd 123 return readRegister40(DW1000_SYS_STATUS, 0);
bhepp 0:2c8820705cdd 124 }
bhepp 0:2c8820705cdd 125
bhepp 0:2c8820705cdd 126 bool DW1000::hasReceivedFrame() {
bhepp 0:2c8820705cdd 127 uint64_t status = getStatus();
bhepp 0:2c8820705cdd 128 return status & 0x4000;
bhepp 0:2c8820705cdd 129 }
bhepp 0:2c8820705cdd 130
bhepp 0:2c8820705cdd 131 void DW1000::clearReceivedFlag() {
bhepp 0:2c8820705cdd 132 writeRegister16(DW1000_SYS_STATUS, 0, 0x6F00); // clearing of receiving status bits
bhepp 0:2c8820705cdd 133 }
bhepp 0:2c8820705cdd 134
bhepp 4:faf802b4af85 135 bool DW1000::hasTransmissionStarted() {
bhepp 4:faf802b4af85 136 uint64_t status = getStatus();
bhepp 4:faf802b4af85 137 return status & 0x10;
bhepp 4:faf802b4af85 138 }
bhepp 4:faf802b4af85 139
bhepp 4:faf802b4af85 140 bool DW1000::hasSentPreamble() {
bhepp 4:faf802b4af85 141 uint64_t status = getStatus();
bhepp 4:faf802b4af85 142 return status & 0x20;
bhepp 4:faf802b4af85 143 }
bhepp 4:faf802b4af85 144
bhepp 4:faf802b4af85 145 bool DW1000::hasSentPHYHeader() {
bhepp 4:faf802b4af85 146 uint64_t status = getStatus();
bhepp 4:faf802b4af85 147 return status & 0x40;
bhepp 4:faf802b4af85 148 }
bhepp 4:faf802b4af85 149
bhepp 0:2c8820705cdd 150 bool DW1000::hasSentFrame() {
bhepp 0:2c8820705cdd 151 uint64_t status = getStatus();
bhepp 0:2c8820705cdd 152 return status & 0x80;
bhepp 0:2c8820705cdd 153 }
bhepp 0:2c8820705cdd 154
bhepp 0:2c8820705cdd 155 void DW1000::clearSentFlag() {
bhepp 0:2c8820705cdd 156 writeRegister8(DW1000_SYS_STATUS, 0, 0xF8); // clearing of sending status bits
bhepp 0:2c8820705cdd 157 }
bhepp 0:2c8820705cdd 158
bhepp 2:12a2907957b8 159 uint64_t DW1000::getSYSTimestamp() {
bhepp 2:12a2907957b8 160 return readRegister40(DW1000_SYS_TIME, 0);
bhepp 2:12a2907957b8 161 }
bhepp 2:12a2907957b8 162
bhepp 0:2c8820705cdd 163 uint64_t DW1000::getRXTimestamp() {
bhepp 0:2c8820705cdd 164 return readRegister40(DW1000_RX_TIME, 0);
bhepp 0:2c8820705cdd 165 }
bhepp 0:2c8820705cdd 166
bhepp 0:2c8820705cdd 167 uint64_t DW1000::getTXTimestamp() {
bhepp 0:2c8820705cdd 168 return readRegister40(DW1000_TX_TIME, 0);
bhepp 0:2c8820705cdd 169 }
bhepp 0:2c8820705cdd 170
bhepp 2:12a2907957b8 171 float DW1000::getSYSTimestampUS() {
bhepp 2:12a2907957b8 172 return getSYSTimestamp() * TIMEUNITS_TO_US;
bhepp 2:12a2907957b8 173 }
bhepp 2:12a2907957b8 174
bhepp 2:12a2907957b8 175 float DW1000::getRXTimestampUS() {
bhepp 2:12a2907957b8 176 return getRXTimestamp() * TIMEUNITS_TO_US;
bhepp 2:12a2907957b8 177 }
bhepp 2:12a2907957b8 178
bhepp 2:12a2907957b8 179 float DW1000::getTXTimestampUS() {
bhepp 2:12a2907957b8 180 return getTXTimestamp() * TIMEUNITS_TO_US;
bhepp 2:12a2907957b8 181 }
bhepp 2:12a2907957b8 182
bhepp 0:2c8820705cdd 183 uint16_t DW1000::getStdNoise() {
bhepp 0:2c8820705cdd 184 return readRegister16(DW1000_RX_FQUAL, 0x00);
bhepp 0:2c8820705cdd 185 }
bhepp 0:2c8820705cdd 186
bhepp 0:2c8820705cdd 187 uint16_t DW1000::getPACC() {
bhepp 0:2c8820705cdd 188 uint32_t v = readRegister32(DW1000_RX_FINFO, 0x00);
bhepp 0:2c8820705cdd 189 v >>= 20;
bhepp 0:2c8820705cdd 190 return static_cast<uint16_t>(v);
bhepp 0:2c8820705cdd 191 }
bhepp 0:2c8820705cdd 192
bhepp 0:2c8820705cdd 193 uint16_t DW1000::getFPINDEX() {
bhepp 0:2c8820705cdd 194 return readRegister16(DW1000_RX_TIME, 0x05);
bhepp 0:2c8820705cdd 195 }
bhepp 0:2c8820705cdd 196
bhepp 0:2c8820705cdd 197 uint16_t DW1000::getFPAMPL1() {
bhepp 0:2c8820705cdd 198 return readRegister16(DW1000_RX_TIME, 0x07);
bhepp 0:2c8820705cdd 199 }
bhepp 0:2c8820705cdd 200
bhepp 0:2c8820705cdd 201 uint16_t DW1000::getFPAMPL2() {
bhepp 0:2c8820705cdd 202 return readRegister16(DW1000_RX_FQUAL, 0x02);
bhepp 0:2c8820705cdd 203 }
bhepp 0:2c8820705cdd 204
bhepp 0:2c8820705cdd 205 uint16_t DW1000::getFPAMPL3() {
bhepp 0:2c8820705cdd 206 return readRegister16(DW1000_RX_FQUAL, 0x04);
bhepp 0:2c8820705cdd 207 }
bhepp 0:2c8820705cdd 208
bhepp 0:2c8820705cdd 209 uint16_t DW1000::getCIRPWR() {
bhepp 0:2c8820705cdd 210 return readRegister16(DW1000_RX_FQUAL, 0x06);
bhepp 0:2c8820705cdd 211 }
bhepp 0:2c8820705cdd 212
bhepp 2:12a2907957b8 213 uint8_t DW1000::getPRF()
bhepp 2:12a2907957b8 214 {
bhepp 2:12a2907957b8 215 uint32_t prf_mask = static_cast<uint32_t>(0x1 << 19 | 0x1 << 18);
bhepp 2:12a2907957b8 216 uint32_t prf = readRegister32(DW1000_CHAN_CTRL, 0x00);
bhepp 2:12a2907957b8 217 prf >>= 18;
bhepp 2:12a2907957b8 218 return static_cast<uint8_t>(prf & prf_mask);
bhepp 0:2c8820705cdd 219 }
bhepp 0:2c8820705cdd 220
bhepp 0:2c8820705cdd 221 void DW1000::sendString(char* message) {
bhepp 0:2c8820705cdd 222 sendFrame((uint8_t*)message, strlen(message)+1);
bhepp 0:2c8820705cdd 223 }
bhepp 0:2c8820705cdd 224
bhepp 0:2c8820705cdd 225 void DW1000::receiveString(char* message) {
bhepp 0:2c8820705cdd 226 readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)message, getFramelength()); // get data from buffer
bhepp 0:2c8820705cdd 227 }
bhepp 0:2c8820705cdd 228
bhepp 0:2c8820705cdd 229 void DW1000::sendFrame(uint8_t* message, uint16_t length) {
bhepp 0:2c8820705cdd 230 //if (length >= 1021) length = 1021; // check for maximim length a frame can have with 1024 Byte frames [not used, see constructor]
bhepp 0:2c8820705cdd 231 if (length >= 125) length = 125; // check for maximim length a frame can have with 127 Byte frames
bhepp 5:c34ebc7f650c 232
bhepp 5:c34ebc7f650c 233 Timer timer;
bhepp 5:c34ebc7f650c 234 timer.start();
bhepp 0:2c8820705cdd 235 writeRegister(DW1000_TX_BUFFER, 0, message, length); // fill buffer
bhepp 0:2c8820705cdd 236
bhepp 0:2c8820705cdd 237 uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame
bhepp 0:2c8820705cdd 238 length += 2; // including 2 CRC Bytes
bhepp 0:2c8820705cdd 239 length = ((backup & 0xFC) << 8) | (length & 0x03FF);
bhepp 0:2c8820705cdd 240 writeRegister16(DW1000_TX_FCTRL, 0, length);
bhepp 0:2c8820705cdd 241
bhepp 0:2c8820705cdd 242 stopTRX(); // stop receiving
bhepp 0:2c8820705cdd 243 writeRegister8(DW1000_SYS_CTRL, 0, 0x02); // trigger sending process by setting the TXSTRT bit
bhepp 5:c34ebc7f650c 244 // startRX(); // enable receiver again
bhepp 0:2c8820705cdd 245 }
bhepp 0:2c8820705cdd 246
bhepp 0:2c8820705cdd 247 void DW1000::sendDelayedFrame(uint8_t* message, uint16_t length, uint64_t TxTimestamp) {
bhepp 5:c34ebc7f650c 248 clearSentFlag(); // This is necessary, otherwise we pick up the transmission time of the previous send
bhepp 5:c34ebc7f650c 249
bhepp 4:faf802b4af85 250 if (TxTimestamp > CONST_2POWER40) {
bhepp 2:12a2907957b8 251 TxTimestamp -= CONST_2POWER40;
bhepp 2:12a2907957b8 252 }
bhepp 2:12a2907957b8 253
bhepp 0:2c8820705cdd 254 //if (length >= 1021) length = 1021; // check for maximim length a frame can have with 1024 Byte frames [not used, see constructor]
bhepp 0:2c8820705cdd 255 if (length >= 125) length = 125; // check for maximim length a frame can have with 127 Byte frames
bhepp 0:2c8820705cdd 256 writeRegister(DW1000_TX_BUFFER, 0, message, length); // fill buffer
bhepp 0:2c8820705cdd 257
bhepp 0:2c8820705cdd 258 uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame
bhepp 0:2c8820705cdd 259 length += 2; // including 2 CRC Bytes
bhepp 0:2c8820705cdd 260 length = ((backup & 0xFC) << 8) | (length & 0x03FF);
bhepp 0:2c8820705cdd 261 writeRegister16(DW1000_TX_FCTRL, 0, length);
bhepp 0:2c8820705cdd 262
bhepp 0:2c8820705cdd 263 writeRegister40(DW1000_DX_TIME, 0, TxTimestamp); //write the timestamp on which to send the message
bhepp 0:2c8820705cdd 264
bhepp 5:c34ebc7f650c 265 stopTRX(); // stop receiving
bhepp 0:2c8820705cdd 266 writeRegister8(DW1000_SYS_CTRL, 0, 0x02 | 0x04); // trigger sending process by setting the TXSTRT and TXDLYS bit
bhepp 5:c34ebc7f650c 267 // startRX(); // enable receiver again
bhepp 0:2c8820705cdd 268 }
bhepp 0:2c8820705cdd 269
bhepp 0:2c8820705cdd 270 void DW1000::startRX() {
bhepp 0:2c8820705cdd 271 writeRegister8(DW1000_SYS_CTRL, 0x01, 0x01); // start listening for preamble by setting the RXENAB bit
bhepp 5:c34ebc7f650c 272 wait_us(16); // According to page 81 in the user manual (RXENAB bit)
bhepp 0:2c8820705cdd 273 }
bhepp 0:2c8820705cdd 274
bhepp 0:2c8820705cdd 275 void DW1000::stopTRX() {
bhepp 4:faf802b4af85 276 writeRegister8(DW1000_SYS_CTRL, 0, 0x40); // disable tranceiver go back to idle mode by setting the TRXOFF bit
bhepp 0:2c8820705cdd 277 }
bhepp 0:2c8820705cdd 278
bhepp 0:2c8820705cdd 279 // PRIVATE Methods ------------------------------------------------------------------------------------
bhepp 0:2c8820705cdd 280 void DW1000::loadLDE() { // initialise LDE algorithm LDELOAD User Manual p22
bhepp 0:2c8820705cdd 281 writeRegister16(DW1000_PMSC, 0, 0x0301); // set clock to XTAL so OTP is reliable
bhepp 0:2c8820705cdd 282 writeRegister16(DW1000_OTP_IF, 0x06, 0x8000); // set LDELOAD bit in OTP
bhepp 0:2c8820705cdd 283 wait_us(150);
bhepp 0:2c8820705cdd 284 writeRegister16(DW1000_PMSC, 0, 0x0200); // recover to PLL clock
bhepp 0:2c8820705cdd 285 }
bhepp 0:2c8820705cdd 286
bhepp 0:2c8820705cdd 287 void DW1000::resetRX() {
bhepp 0:2c8820705cdd 288 writeRegister8(DW1000_PMSC, 3, 0xE0); // set RX reset
bhepp 0:2c8820705cdd 289 writeRegister8(DW1000_PMSC, 3, 0xF0); // clear RX reset
bhepp 0:2c8820705cdd 290 }
bhepp 0:2c8820705cdd 291
bhepp 0:2c8820705cdd 292 void DW1000::hardwareReset(PinName reset_pin) {
bhepp 5:c34ebc7f650c 293 DigitalInOut reset(reset_pin);
bhepp 5:c34ebc7f650c 294 hardwareReset(reset);
bhepp 5:c34ebc7f650c 295 }
bhepp 5:c34ebc7f650c 296
bhepp 5:c34ebc7f650c 297 void DW1000::hardwareReset(DigitalInOut& reset) {
bhepp 5:c34ebc7f650c 298 if (reset.is_connected()) {
bhepp 5:c34ebc7f650c 299 // DWM1000 RESET logic.
bhepp 5:c34ebc7f650c 300 if (DWM1000_DAMAGED) {
bhepp 5:c34ebc7f650c 301 // The following code works for damaged DWM1000 modules.
bhepp 5:c34ebc7f650c 302 // IMPORTANT: This will damage healthy DWM1000 modules!
bhepp 5:c34ebc7f650c 303 reset.output();
bhepp 5:c34ebc7f650c 304 reset = 1;
bhepp 5:c34ebc7f650c 305 wait_ms(100);
bhepp 5:c34ebc7f650c 306 reset = 0;
bhepp 5:c34ebc7f650c 307 wait_ms(100);
bhepp 5:c34ebc7f650c 308 reset = 1;
bhepp 5:c34ebc7f650c 309 wait_ms(100);
bhepp 5:c34ebc7f650c 310 } else {
bhepp 5:c34ebc7f650c 311 // The following code works for healthy DWM1000 modules
bhepp 5:c34ebc7f650c 312 reset.output();
bhepp 5:c34ebc7f650c 313 reset = 0;
bhepp 5:c34ebc7f650c 314 wait_ms(100);
bhepp 5:c34ebc7f650c 315 reset.input();
bhepp 5:c34ebc7f650c 316 }
bhepp 0:2c8820705cdd 317 }
bhepp 0:2c8820705cdd 318 }
bhepp 0:2c8820705cdd 319
bhepp 5:c34ebc7f650c 320 void DW1000::softwareReset() {
bhepp 5:c34ebc7f650c 321 stopTRX();
bhepp 5:c34ebc7f650c 322 clearReceivedFlag();
bhepp 5:c34ebc7f650c 323 clearSentFlag();
bhepp 5:c34ebc7f650c 324 }
bhepp 5:c34ebc7f650c 325
bhepp 0:2c8820705cdd 326 void DW1000::resetAll() {
bhepp 5:c34ebc7f650c 327 hardwareReset(reset);
bhepp 0:2c8820705cdd 328
bhepp 0:2c8820705cdd 329 writeRegister8(DW1000_PMSC, 0, 0x01); // set clock to XTAL
bhepp 0:2c8820705cdd 330 writeRegister8(DW1000_PMSC, 3, 0x00); // set All reset
bhepp 0:2c8820705cdd 331 wait_us(10); // wait for PLL to lock
bhepp 0:2c8820705cdd 332 writeRegister8(DW1000_PMSC, 3, 0xF0); // clear All reset
bhepp 0:2c8820705cdd 333 }
bhepp 0:2c8820705cdd 334
bhepp 0:2c8820705cdd 335
bhepp 0:2c8820705cdd 336 void DW1000::setInterrupt(bool RX, bool TX) {
bhepp 0:2c8820705cdd 337 writeRegister16(DW1000_SYS_MASK, 0, RX*0x4000 | TX*0x0080); // RX good frame 0x4000, TX done 0x0080
bhepp 0:2c8820705cdd 338 }
bhepp 0:2c8820705cdd 339
bhepp 0:2c8820705cdd 340 void DW1000::ISR() {
bhepp 0:2c8820705cdd 341 uint64_t status = getStatus();
bhepp 0:2c8820705cdd 342 if (status & 0x4000) { // a frame was received
bhepp 0:2c8820705cdd 343 callbackRX.call();
bhepp 0:2c8820705cdd 344 writeRegister16(DW1000_SYS_STATUS, 0, 0x6F00); // clearing of receiving status bits
bhepp 0:2c8820705cdd 345 }
bhepp 0:2c8820705cdd 346 if (status & 0x80) { // sending complete
bhepp 0:2c8820705cdd 347 callbackTX.call();
bhepp 0:2c8820705cdd 348 writeRegister8(DW1000_SYS_STATUS, 0, 0xF8); // clearing of sending status bits
bhepp 0:2c8820705cdd 349 }
bhepp 0:2c8820705cdd 350 }
bhepp 0:2c8820705cdd 351
bhepp 0:2c8820705cdd 352 uint16_t DW1000::getFramelength() {
bhepp 0:2c8820705cdd 353 uint16_t framelength = readRegister16(DW1000_RX_FINFO, 0); // get framelength
bhepp 0:2c8820705cdd 354 framelength = (framelength & 0x03FF) - 2; // take only the right bits and subtract the 2 CRC Bytes
bhepp 0:2c8820705cdd 355 return framelength;
bhepp 0:2c8820705cdd 356 }
bhepp 0:2c8820705cdd 357
bhepp 0:2c8820705cdd 358 // SPI Interface ------------------------------------------------------------------------------------
bhepp 0:2c8820705cdd 359 uint8_t DW1000::readRegister8(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 360 uint8_t result;
bhepp 0:2c8820705cdd 361 readRegister(reg, subaddress, &result, 1);
bhepp 0:2c8820705cdd 362 return result;
bhepp 0:2c8820705cdd 363 }
bhepp 0:2c8820705cdd 364
bhepp 0:2c8820705cdd 365 uint16_t DW1000::readRegister16(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 366 uint16_t result;
bhepp 0:2c8820705cdd 367 readRegister(reg, subaddress, (uint8_t*)&result, 2);
bhepp 0:2c8820705cdd 368 return result;
bhepp 0:2c8820705cdd 369 }
bhepp 0:2c8820705cdd 370
bhepp 0:2c8820705cdd 371 uint32_t DW1000::readRegister32(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 372 uint32_t result;
bhepp 0:2c8820705cdd 373 readRegister(reg, subaddress, (uint8_t*)&result, 4);
bhepp 0:2c8820705cdd 374 return result;
bhepp 0:2c8820705cdd 375 }
bhepp 0:2c8820705cdd 376
bhepp 0:2c8820705cdd 377 uint64_t DW1000::readRegister40(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 378 uint64_t result;
bhepp 0:2c8820705cdd 379 readRegister(reg, subaddress, (uint8_t*)&result, 5);
bhepp 0:2c8820705cdd 380 result &= 0xFFFFFFFFFF; // only 40-Bit
bhepp 0:2c8820705cdd 381 return result;
bhepp 0:2c8820705cdd 382 }
bhepp 0:2c8820705cdd 383
bhepp 0:2c8820705cdd 384 void DW1000::writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer) {
bhepp 0:2c8820705cdd 385 writeRegister(reg, subaddress, &buffer, 1);
bhepp 0:2c8820705cdd 386 }
bhepp 0:2c8820705cdd 387
bhepp 0:2c8820705cdd 388 void DW1000::writeRegister16(uint8_t reg, uint16_t subaddress, uint16_t buffer) {
bhepp 0:2c8820705cdd 389 writeRegister(reg, subaddress, (uint8_t*)&buffer, 2);
bhepp 0:2c8820705cdd 390 }
bhepp 0:2c8820705cdd 391
bhepp 0:2c8820705cdd 392 void DW1000::writeRegister32(uint8_t reg, uint16_t subaddress, uint32_t buffer) {
bhepp 0:2c8820705cdd 393 writeRegister(reg, subaddress, (uint8_t*)&buffer, 4);
bhepp 0:2c8820705cdd 394 }
bhepp 0:2c8820705cdd 395
bhepp 0:2c8820705cdd 396 void DW1000::writeRegister40(uint8_t reg, uint16_t subaddress, uint64_t buffer) {
bhepp 0:2c8820705cdd 397 writeRegister(reg, subaddress, (uint8_t*)&buffer, 5);
bhepp 0:2c8820705cdd 398 }
bhepp 0:2c8820705cdd 399
bhepp 0:2c8820705cdd 400 void DW1000::readRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) {
bhepp 0:2c8820705cdd 401 setupTransaction(reg, subaddress, false);
bhepp 0:2c8820705cdd 402 for(int i=0; i<length; i++) // get data
bhepp 0:2c8820705cdd 403 buffer[i] = spi.write(0x00);
bhepp 0:2c8820705cdd 404 deselect();
bhepp 0:2c8820705cdd 405 }
bhepp 0:2c8820705cdd 406
bhepp 0:2c8820705cdd 407 void DW1000::writeRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) {
bhepp 0:2c8820705cdd 408 setupTransaction(reg, subaddress, true);
bhepp 0:2c8820705cdd 409 for(int i=0; i<length; i++) // put data
bhepp 0:2c8820705cdd 410 spi.write(buffer[i]);
bhepp 0:2c8820705cdd 411 deselect();
bhepp 0:2c8820705cdd 412 }
bhepp 0:2c8820705cdd 413
bhepp 0:2c8820705cdd 414 void DW1000::setupTransaction(uint8_t reg, uint16_t subaddress, bool write) {
bhepp 0:2c8820705cdd 415 reg |= (write * DW1000_WRITE_FLAG); // set read/write flag
bhepp 0:2c8820705cdd 416 select();
bhepp 0:2c8820705cdd 417 if (subaddress > 0) { // there's a subadress, we need to set flag and send second header byte
bhepp 0:2c8820705cdd 418 spi.write(reg | DW1000_SUBADDRESS_FLAG);
bhepp 0:2c8820705cdd 419 if (subaddress > 0x7F) { // sub address too long, we need to set flag and send third header byte
bhepp 0:2c8820705cdd 420 spi.write((uint8_t)(subaddress & 0x7F) | DW1000_2_SUBADDRESS_FLAG); // and
bhepp 0:2c8820705cdd 421 spi.write((uint8_t)(subaddress >> 7));
bhepp 0:2c8820705cdd 422 } else {
bhepp 0:2c8820705cdd 423 spi.write((uint8_t)subaddress);
bhepp 0:2c8820705cdd 424 }
bhepp 0:2c8820705cdd 425 } else {
bhepp 0:2c8820705cdd 426 spi.write(reg); // say which register address we want to access
bhepp 0:2c8820705cdd 427 }
bhepp 0:2c8820705cdd 428 }
bhepp 0:2c8820705cdd 429
bhepp 0:2c8820705cdd 430 void DW1000::select() { // always called to start an SPI transmission
bhepp 5:c34ebc7f650c 431 if (irq != NULL) {
bhepp 5:c34ebc7f650c 432 irq->disable_irq();
bhepp 5:c34ebc7f650c 433 }
bhepp 0:2c8820705cdd 434 cs = 0; // set Cable Select pin low to start transmission
bhepp 0:2c8820705cdd 435 }
bhepp 0:2c8820705cdd 436
bhepp 0:2c8820705cdd 437 void DW1000::deselect() { // always called to end an SPI transmission
bhepp 0:2c8820705cdd 438 cs = 1; // set Cable Select pin high to stop transmission
bhepp 5:c34ebc7f650c 439 if (irq != NULL) {
bhepp 5:c34ebc7f650c 440 irq->enable_irq();
bhepp 5:c34ebc7f650c 441 }
bhepp 0:2c8820705cdd 442 }