init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

Committer:
pathfindr
Date:
Mon Feb 17 23:24:52 2020 +0000
Revision:
58:8d4a354816b1
usb

Who changed what in which revision?

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