Simple driver for DWM1000 modules.

Committer:
bhepp
Date:
Tue Mar 29 10:00:23 2016 +0000
Revision:
4:faf802b4af85
Parent:
2:12a2907957b8
Child:
5:c34ebc7f650c
Added some status query methods

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