Simple driver for DWM1000 modules.

Committer:
bhepp
Date:
Fri Jan 29 10:47:13 2016 +0000
Revision:
0:2c8820705cdd
Child:
2:12a2907957b8
Simple DW1000 driver

Who changed what in which revision?

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