Simple driver for DWM1000 modules.

Committer:
bhepp
Date:
Fri Feb 05 13:48:42 2016 +0000
Revision:
2:12a2907957b8
Parent:
0:2c8820705cdd
Child:
4:faf802b4af85
Added 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 0:2c8820705cdd 130 bool DW1000::hasSentFrame() {
bhepp 0:2c8820705cdd 131 uint64_t status = getStatus();
bhepp 0:2c8820705cdd 132 return status & 0x80;
bhepp 0:2c8820705cdd 133 }
bhepp 0:2c8820705cdd 134
bhepp 0:2c8820705cdd 135 void DW1000::clearSentFlag() {
bhepp 0:2c8820705cdd 136 writeRegister8(DW1000_SYS_STATUS, 0, 0xF8); // clearing of sending status bits
bhepp 0:2c8820705cdd 137 }
bhepp 0:2c8820705cdd 138
bhepp 2:12a2907957b8 139 uint64_t DW1000::getSYSTimestamp() {
bhepp 2:12a2907957b8 140 return readRegister40(DW1000_SYS_TIME, 0);
bhepp 2:12a2907957b8 141 }
bhepp 2:12a2907957b8 142
bhepp 0:2c8820705cdd 143 uint64_t DW1000::getRXTimestamp() {
bhepp 0:2c8820705cdd 144 return readRegister40(DW1000_RX_TIME, 0);
bhepp 0:2c8820705cdd 145 }
bhepp 0:2c8820705cdd 146
bhepp 0:2c8820705cdd 147 uint64_t DW1000::getTXTimestamp() {
bhepp 0:2c8820705cdd 148 return readRegister40(DW1000_TX_TIME, 0);
bhepp 0:2c8820705cdd 149 }
bhepp 0:2c8820705cdd 150
bhepp 2:12a2907957b8 151 float DW1000::getSYSTimestampUS() {
bhepp 2:12a2907957b8 152 return getSYSTimestamp() * TIMEUNITS_TO_US;
bhepp 2:12a2907957b8 153 }
bhepp 2:12a2907957b8 154
bhepp 2:12a2907957b8 155 float DW1000::getRXTimestampUS() {
bhepp 2:12a2907957b8 156 return getRXTimestamp() * TIMEUNITS_TO_US;
bhepp 2:12a2907957b8 157 }
bhepp 2:12a2907957b8 158
bhepp 2:12a2907957b8 159 float DW1000::getTXTimestampUS() {
bhepp 2:12a2907957b8 160 return getTXTimestamp() * TIMEUNITS_TO_US;
bhepp 2:12a2907957b8 161 }
bhepp 2:12a2907957b8 162
bhepp 0:2c8820705cdd 163 uint16_t DW1000::getStdNoise() {
bhepp 0:2c8820705cdd 164 return readRegister16(DW1000_RX_FQUAL, 0x00);
bhepp 0:2c8820705cdd 165 }
bhepp 0:2c8820705cdd 166
bhepp 0:2c8820705cdd 167 uint16_t DW1000::getPACC() {
bhepp 0:2c8820705cdd 168 uint32_t v = readRegister32(DW1000_RX_FINFO, 0x00);
bhepp 0:2c8820705cdd 169 v >>= 20;
bhepp 0:2c8820705cdd 170 return static_cast<uint16_t>(v);
bhepp 0:2c8820705cdd 171 }
bhepp 0:2c8820705cdd 172
bhepp 0:2c8820705cdd 173 uint16_t DW1000::getFPINDEX() {
bhepp 0:2c8820705cdd 174 return readRegister16(DW1000_RX_TIME, 0x05);
bhepp 0:2c8820705cdd 175 }
bhepp 0:2c8820705cdd 176
bhepp 0:2c8820705cdd 177 uint16_t DW1000::getFPAMPL1() {
bhepp 0:2c8820705cdd 178 return readRegister16(DW1000_RX_TIME, 0x07);
bhepp 0:2c8820705cdd 179 }
bhepp 0:2c8820705cdd 180
bhepp 0:2c8820705cdd 181 uint16_t DW1000::getFPAMPL2() {
bhepp 0:2c8820705cdd 182 return readRegister16(DW1000_RX_FQUAL, 0x02);
bhepp 0:2c8820705cdd 183 }
bhepp 0:2c8820705cdd 184
bhepp 0:2c8820705cdd 185 uint16_t DW1000::getFPAMPL3() {
bhepp 0:2c8820705cdd 186 return readRegister16(DW1000_RX_FQUAL, 0x04);
bhepp 0:2c8820705cdd 187 }
bhepp 0:2c8820705cdd 188
bhepp 0:2c8820705cdd 189 uint16_t DW1000::getCIRPWR() {
bhepp 0:2c8820705cdd 190 return readRegister16(DW1000_RX_FQUAL, 0x06);
bhepp 0:2c8820705cdd 191 }
bhepp 0:2c8820705cdd 192
bhepp 2:12a2907957b8 193 uint8_t DW1000::getPRF()
bhepp 2:12a2907957b8 194 {
bhepp 2:12a2907957b8 195 uint32_t prf_mask = static_cast<uint32_t>(0x1 << 19 | 0x1 << 18);
bhepp 2:12a2907957b8 196 uint32_t prf = readRegister32(DW1000_CHAN_CTRL, 0x00);
bhepp 2:12a2907957b8 197 prf >>= 18;
bhepp 2:12a2907957b8 198 return static_cast<uint8_t>(prf & prf_mask);
bhepp 0:2c8820705cdd 199 }
bhepp 0:2c8820705cdd 200
bhepp 0:2c8820705cdd 201 void DW1000::sendString(char* message) {
bhepp 0:2c8820705cdd 202 sendFrame((uint8_t*)message, strlen(message)+1);
bhepp 0:2c8820705cdd 203 }
bhepp 0:2c8820705cdd 204
bhepp 0:2c8820705cdd 205 void DW1000::receiveString(char* message) {
bhepp 0:2c8820705cdd 206 readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)message, getFramelength()); // get data from buffer
bhepp 0:2c8820705cdd 207 }
bhepp 0:2c8820705cdd 208
bhepp 0:2c8820705cdd 209 void DW1000::sendFrame(uint8_t* message, uint16_t length) {
bhepp 0:2c8820705cdd 210 //if (length >= 1021) length = 1021; // check for maximim length a frame can have with 1024 Byte frames [not used, see constructor]
bhepp 0:2c8820705cdd 211 if (length >= 125) length = 125; // check for maximim length a frame can have with 127 Byte frames
bhepp 0:2c8820705cdd 212 writeRegister(DW1000_TX_BUFFER, 0, message, length); // fill buffer
bhepp 0:2c8820705cdd 213
bhepp 0:2c8820705cdd 214 uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame
bhepp 0:2c8820705cdd 215 length += 2; // including 2 CRC Bytes
bhepp 0:2c8820705cdd 216 length = ((backup & 0xFC) << 8) | (length & 0x03FF);
bhepp 0:2c8820705cdd 217 writeRegister16(DW1000_TX_FCTRL, 0, length);
bhepp 0:2c8820705cdd 218
bhepp 0:2c8820705cdd 219 stopTRX(); // stop receiving
bhepp 0:2c8820705cdd 220 writeRegister8(DW1000_SYS_CTRL, 0, 0x02); // trigger sending process by setting the TXSTRT bit
bhepp 0:2c8820705cdd 221 startRX(); // enable receiver again
bhepp 0:2c8820705cdd 222 }
bhepp 0:2c8820705cdd 223
bhepp 0:2c8820705cdd 224 void DW1000::sendDelayedFrame(uint8_t* message, uint16_t length, uint64_t TxTimestamp) {
bhepp 2:12a2907957b8 225 if (TxTimestamp > CONST_2POWER40)
bhepp 2:12a2907957b8 226 {
bhepp 2:12a2907957b8 227 TxTimestamp -= CONST_2POWER40;
bhepp 2:12a2907957b8 228 }
bhepp 2:12a2907957b8 229
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 0:2c8820705cdd 232 writeRegister(DW1000_TX_BUFFER, 0, message, length); // fill buffer
bhepp 0:2c8820705cdd 233
bhepp 0:2c8820705cdd 234 uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame
bhepp 0:2c8820705cdd 235 length += 2; // including 2 CRC Bytes
bhepp 0:2c8820705cdd 236 length = ((backup & 0xFC) << 8) | (length & 0x03FF);
bhepp 0:2c8820705cdd 237 writeRegister16(DW1000_TX_FCTRL, 0, length);
bhepp 0:2c8820705cdd 238
bhepp 0:2c8820705cdd 239 writeRegister40(DW1000_DX_TIME, 0, TxTimestamp); //write the timestamp on which to send the message
bhepp 0:2c8820705cdd 240
bhepp 0:2c8820705cdd 241 stopTRX(); // stop receiving
bhepp 0:2c8820705cdd 242 writeRegister8(DW1000_SYS_CTRL, 0, 0x02 | 0x04); // trigger sending process by setting the TXSTRT and TXDLYS bit
bhepp 0:2c8820705cdd 243 startRX(); // enable receiver again
bhepp 0:2c8820705cdd 244 }
bhepp 0:2c8820705cdd 245
bhepp 0:2c8820705cdd 246 void DW1000::startRX() {
bhepp 0:2c8820705cdd 247 writeRegister8(DW1000_SYS_CTRL, 0x01, 0x01); // start listening for preamble by setting the RXENAB bit
bhepp 0:2c8820705cdd 248 }
bhepp 0:2c8820705cdd 249
bhepp 0:2c8820705cdd 250 void DW1000::stopTRX() {
bhepp 0:2c8820705cdd 251 writeRegister8(DW1000_SYS_CTRL, 0, 0x40); // disable tranceiver go back to idle mode
bhepp 0:2c8820705cdd 252 }
bhepp 0:2c8820705cdd 253
bhepp 0:2c8820705cdd 254 // PRIVATE Methods ------------------------------------------------------------------------------------
bhepp 0:2c8820705cdd 255 void DW1000::loadLDE() { // initialise LDE algorithm LDELOAD User Manual p22
bhepp 0:2c8820705cdd 256 writeRegister16(DW1000_PMSC, 0, 0x0301); // set clock to XTAL so OTP is reliable
bhepp 0:2c8820705cdd 257 writeRegister16(DW1000_OTP_IF, 0x06, 0x8000); // set LDELOAD bit in OTP
bhepp 0:2c8820705cdd 258 wait_us(150);
bhepp 0:2c8820705cdd 259 writeRegister16(DW1000_PMSC, 0, 0x0200); // recover to PLL clock
bhepp 0:2c8820705cdd 260 }
bhepp 0:2c8820705cdd 261
bhepp 0:2c8820705cdd 262 void DW1000::resetRX() {
bhepp 0:2c8820705cdd 263 writeRegister8(DW1000_PMSC, 3, 0xE0); // set RX reset
bhepp 0:2c8820705cdd 264 writeRegister8(DW1000_PMSC, 3, 0xF0); // clear RX reset
bhepp 0:2c8820705cdd 265 }
bhepp 0:2c8820705cdd 266
bhepp 0:2c8820705cdd 267 void DW1000::hardwareReset(PinName reset_pin) {
bhepp 0:2c8820705cdd 268 // DWM1000 RESET logic.
bhepp 0:2c8820705cdd 269 if (DWM1000_DAMAGED) {
bhepp 0:2c8820705cdd 270 // The following code works for damaged DWM1000 modules.
bhepp 0:2c8820705cdd 271 // IMPORTANT: This will damage healthy DWM1000 modules!
bhepp 0:2c8820705cdd 272 DigitalInOut reset(reset_pin);
bhepp 0:2c8820705cdd 273 reset.output();
bhepp 0:2c8820705cdd 274 reset = 1;
bhepp 0:2c8820705cdd 275 wait_ms(100);
bhepp 0:2c8820705cdd 276 reset = 0;
bhepp 0:2c8820705cdd 277 wait_ms(100);
bhepp 0:2c8820705cdd 278 reset = 1;
bhepp 0:2c8820705cdd 279 wait_ms(100);
bhepp 0:2c8820705cdd 280 } else {
bhepp 0:2c8820705cdd 281 // The following code works for healthy DWM1000 modules
bhepp 0:2c8820705cdd 282 DigitalInOut reset(reset_pin);
bhepp 0:2c8820705cdd 283 reset.output();
bhepp 0:2c8820705cdd 284 reset = 0;
bhepp 0:2c8820705cdd 285 wait_ms(100);
bhepp 0:2c8820705cdd 286 reset.input();
bhepp 0:2c8820705cdd 287 }
bhepp 0:2c8820705cdd 288 }
bhepp 0:2c8820705cdd 289
bhepp 0:2c8820705cdd 290 void DW1000::resetAll() {
bhepp 0:2c8820705cdd 291 if (reset.is_connected()) {
bhepp 0:2c8820705cdd 292 reset = 1;
bhepp 0:2c8820705cdd 293 wait_ms(100);
bhepp 0:2c8820705cdd 294 reset = 0;
bhepp 0:2c8820705cdd 295 wait_ms(100);
bhepp 0:2c8820705cdd 296 reset = 1;
bhepp 0:2c8820705cdd 297 wait_ms(100);
bhepp 0:2c8820705cdd 298 }
bhepp 0:2c8820705cdd 299
bhepp 0:2c8820705cdd 300 writeRegister8(DW1000_PMSC, 0, 0x01); // set clock to XTAL
bhepp 0:2c8820705cdd 301 writeRegister8(DW1000_PMSC, 3, 0x00); // set All reset
bhepp 0:2c8820705cdd 302 wait_us(10); // wait for PLL to lock
bhepp 0:2c8820705cdd 303 writeRegister8(DW1000_PMSC, 3, 0xF0); // clear All reset
bhepp 0:2c8820705cdd 304 }
bhepp 0:2c8820705cdd 305
bhepp 0:2c8820705cdd 306
bhepp 0:2c8820705cdd 307 void DW1000::setInterrupt(bool RX, bool TX) {
bhepp 0:2c8820705cdd 308 writeRegister16(DW1000_SYS_MASK, 0, RX*0x4000 | TX*0x0080); // RX good frame 0x4000, TX done 0x0080
bhepp 0:2c8820705cdd 309 }
bhepp 0:2c8820705cdd 310
bhepp 0:2c8820705cdd 311 void DW1000::ISR() {
bhepp 0:2c8820705cdd 312 uint64_t status = getStatus();
bhepp 0:2c8820705cdd 313 if (status & 0x4000) { // a frame was received
bhepp 0:2c8820705cdd 314 callbackRX.call();
bhepp 0:2c8820705cdd 315 writeRegister16(DW1000_SYS_STATUS, 0, 0x6F00); // clearing of receiving status bits
bhepp 0:2c8820705cdd 316 }
bhepp 0:2c8820705cdd 317 if (status & 0x80) { // sending complete
bhepp 0:2c8820705cdd 318 callbackTX.call();
bhepp 0:2c8820705cdd 319 writeRegister8(DW1000_SYS_STATUS, 0, 0xF8); // clearing of sending status bits
bhepp 0:2c8820705cdd 320 }
bhepp 0:2c8820705cdd 321 }
bhepp 0:2c8820705cdd 322
bhepp 0:2c8820705cdd 323 uint16_t DW1000::getFramelength() {
bhepp 0:2c8820705cdd 324 uint16_t framelength = readRegister16(DW1000_RX_FINFO, 0); // get framelength
bhepp 0:2c8820705cdd 325 framelength = (framelength & 0x03FF) - 2; // take only the right bits and subtract the 2 CRC Bytes
bhepp 0:2c8820705cdd 326 return framelength;
bhepp 0:2c8820705cdd 327 }
bhepp 0:2c8820705cdd 328
bhepp 0:2c8820705cdd 329 // SPI Interface ------------------------------------------------------------------------------------
bhepp 0:2c8820705cdd 330 uint8_t DW1000::readRegister8(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 331 uint8_t result;
bhepp 0:2c8820705cdd 332 readRegister(reg, subaddress, &result, 1);
bhepp 0:2c8820705cdd 333 return result;
bhepp 0:2c8820705cdd 334 }
bhepp 0:2c8820705cdd 335
bhepp 0:2c8820705cdd 336 uint16_t DW1000::readRegister16(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 337 uint16_t result;
bhepp 0:2c8820705cdd 338 readRegister(reg, subaddress, (uint8_t*)&result, 2);
bhepp 0:2c8820705cdd 339 return result;
bhepp 0:2c8820705cdd 340 }
bhepp 0:2c8820705cdd 341
bhepp 0:2c8820705cdd 342 uint32_t DW1000::readRegister32(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 343 uint32_t result;
bhepp 0:2c8820705cdd 344 readRegister(reg, subaddress, (uint8_t*)&result, 4);
bhepp 0:2c8820705cdd 345 return result;
bhepp 0:2c8820705cdd 346 }
bhepp 0:2c8820705cdd 347
bhepp 0:2c8820705cdd 348 uint64_t DW1000::readRegister40(uint8_t reg, uint16_t subaddress) {
bhepp 0:2c8820705cdd 349 uint64_t result;
bhepp 0:2c8820705cdd 350 readRegister(reg, subaddress, (uint8_t*)&result, 5);
bhepp 0:2c8820705cdd 351 result &= 0xFFFFFFFFFF; // only 40-Bit
bhepp 0:2c8820705cdd 352 return result;
bhepp 0:2c8820705cdd 353 }
bhepp 0:2c8820705cdd 354
bhepp 0:2c8820705cdd 355 void DW1000::writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer) {
bhepp 0:2c8820705cdd 356 writeRegister(reg, subaddress, &buffer, 1);
bhepp 0:2c8820705cdd 357 }
bhepp 0:2c8820705cdd 358
bhepp 0:2c8820705cdd 359 void DW1000::writeRegister16(uint8_t reg, uint16_t subaddress, uint16_t buffer) {
bhepp 0:2c8820705cdd 360 writeRegister(reg, subaddress, (uint8_t*)&buffer, 2);
bhepp 0:2c8820705cdd 361 }
bhepp 0:2c8820705cdd 362
bhepp 0:2c8820705cdd 363 void DW1000::writeRegister32(uint8_t reg, uint16_t subaddress, uint32_t buffer) {
bhepp 0:2c8820705cdd 364 writeRegister(reg, subaddress, (uint8_t*)&buffer, 4);
bhepp 0:2c8820705cdd 365 }
bhepp 0:2c8820705cdd 366
bhepp 0:2c8820705cdd 367 void DW1000::writeRegister40(uint8_t reg, uint16_t subaddress, uint64_t buffer) {
bhepp 0:2c8820705cdd 368 writeRegister(reg, subaddress, (uint8_t*)&buffer, 5);
bhepp 0:2c8820705cdd 369 }
bhepp 0:2c8820705cdd 370
bhepp 0:2c8820705cdd 371 void DW1000::readRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) {
bhepp 0:2c8820705cdd 372 setupTransaction(reg, subaddress, false);
bhepp 0:2c8820705cdd 373 for(int i=0; i<length; i++) // get data
bhepp 0:2c8820705cdd 374 buffer[i] = spi.write(0x00);
bhepp 0:2c8820705cdd 375 deselect();
bhepp 0:2c8820705cdd 376 }
bhepp 0:2c8820705cdd 377
bhepp 0:2c8820705cdd 378 void DW1000::writeRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) {
bhepp 0:2c8820705cdd 379 setupTransaction(reg, subaddress, true);
bhepp 0:2c8820705cdd 380 for(int i=0; i<length; i++) // put data
bhepp 0:2c8820705cdd 381 spi.write(buffer[i]);
bhepp 0:2c8820705cdd 382 deselect();
bhepp 0:2c8820705cdd 383 }
bhepp 0:2c8820705cdd 384
bhepp 0:2c8820705cdd 385 void DW1000::setupTransaction(uint8_t reg, uint16_t subaddress, bool write) {
bhepp 0:2c8820705cdd 386 reg |= (write * DW1000_WRITE_FLAG); // set read/write flag
bhepp 0:2c8820705cdd 387 select();
bhepp 0:2c8820705cdd 388 if (subaddress > 0) { // there's a subadress, we need to set flag and send second header byte
bhepp 0:2c8820705cdd 389 spi.write(reg | DW1000_SUBADDRESS_FLAG);
bhepp 0:2c8820705cdd 390 if (subaddress > 0x7F) { // sub address too long, we need to set flag and send third header byte
bhepp 0:2c8820705cdd 391 spi.write((uint8_t)(subaddress & 0x7F) | DW1000_2_SUBADDRESS_FLAG); // and
bhepp 0:2c8820705cdd 392 spi.write((uint8_t)(subaddress >> 7));
bhepp 0:2c8820705cdd 393 } else {
bhepp 0:2c8820705cdd 394 spi.write((uint8_t)subaddress);
bhepp 0:2c8820705cdd 395 }
bhepp 0:2c8820705cdd 396 } else {
bhepp 0:2c8820705cdd 397 spi.write(reg); // say which register address we want to access
bhepp 0:2c8820705cdd 398 }
bhepp 0:2c8820705cdd 399 }
bhepp 0:2c8820705cdd 400
bhepp 0:2c8820705cdd 401 void DW1000::select() { // always called to start an SPI transmission
bhepp 0:2c8820705cdd 402 irq.disable_irq();
bhepp 0:2c8820705cdd 403 cs = 0; // set Cable Select pin low to start transmission
bhepp 0:2c8820705cdd 404 }
bhepp 0:2c8820705cdd 405
bhepp 0:2c8820705cdd 406 void DW1000::deselect() { // always called to end an SPI transmission
bhepp 0:2c8820705cdd 407 cs = 1; // set Cable Select pin high to stop transmission
bhepp 0:2c8820705cdd 408 irq.enable_irq();
bhepp 0:2c8820705cdd 409 }