Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
DW1000.cpp
00001 #include "DW1000.h" 00002 00003 DW1000::DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ) : irq(IRQ), spi(MOSI, MISO, SCLK), cs(CS) { 00004 setCallbacks(NULL, NULL); 00005 00006 deselect(); // Chip must be deselected first 00007 spi.format(8,0); // Setup the spi for standard 8 bit data and SPI-Mode 0 (GPIO5, GPIO6 open circuit or ground on DW1000) 00008 spi.frequency(5000000); // with a 1MHz clock rate (worked up to 49MHz in our Test) 00009 00010 resetAll(); // we do a soft reset of the DW1000 everytime the driver starts 00011 00012 // Configuration TODO: make method for that 00013 // User Manual "2.5.5 Default Configurations that should be modified" p. 22 00014 //Those values are for the standard mode (6.8Mbps, 5, 16Mhz, 32 Symbols) and are INCOMPLETE! 00015 // writeRegister16(DW1000_AGC_CTRL, 0x04, 0x8870); 00016 // writeRegister32(DW1000_AGC_CTRL, 0x0C, 0x2502A907); 00017 // writeRegister32(DW1000_DRX_CONF, 0x08, 0x311A002D); 00018 // writeRegister8 (DW1000_LDE_CTRL, 0x0806, 0xD); 00019 // writeRegister16(DW1000_LDE_CTRL, 0x1806, 0x1607); 00020 // writeRegister32(DW1000_TX_POWER, 0, 0x0E082848); 00021 // writeRegister32(DW1000_RF_CONF, 0x0C, 0x001E3FE0); 00022 // writeRegister8 (DW1000_TX_CAL, 0x0B, 0xC0); 00023 // writeRegister8 (DW1000_FS_CTRL, 0x0B, 0xA6); 00024 00025 00026 //Those values are for the 110kbps mode (5, 16MHz, 1024 Symbols) and are quite complete 00027 writeRegister16(DW1000_AGC_CTRL, 0x04, 0x8870); //AGC_TUNE1 for 16MHz PRF 00028 writeRegister32(DW1000_AGC_CTRL, 0x0C, 0x2502A907); //AGC_TUNE2 (Universal) 00029 writeRegister16(DW1000_AGC_CTRL, 0x12, 0x0055); //AGC_TUNE3 (Universal) 00030 00031 writeRegister16(DW1000_DRX_CONF, 0x02, 0x000A); //DRX_TUNE0b for 110kbps 00032 writeRegister16(DW1000_DRX_CONF, 0x04, 0x0087); //DRX_TUNE1a for 16MHz PRF 00033 writeRegister16(DW1000_DRX_CONF, 0x06, 0x0064); //DRX_TUNE1b for 110kbps & > 1024 symbols 00034 writeRegister32(DW1000_DRX_CONF, 0x08, 0x351A009A); //PAC size for 1024 symbols preamble & 16MHz PRF 00035 //writeRegister32(DW1000_DRX_CONF, 0x08, 0x371A011D); //PAC size for 2048 symbols preamble 00036 00037 writeRegister8 (DW1000_LDE_CTRL, 0x0806, 0xD); //LDE_CFG1 00038 writeRegister16(DW1000_LDE_CTRL, 0x1806, 0x1607); //LDE_CFG2 for 16MHz PRF 00039 00040 writeRegister32(DW1000_TX_POWER, 0, 0x28282828); //Power for channel 5 00041 00042 writeRegister8(DW1000_RF_CONF, 0x0B, 0xD8); //RF_RXCTRLH for channel 5 00043 writeRegister32(DW1000_RF_CONF, 0x0C, 0x001E3FE0); //RF_TXCTRL for channel 5 00044 00045 writeRegister8 (DW1000_TX_CAL, 0x0B, 0xC0); //TC_PGDELAY for channel 5 00046 00047 writeRegister32 (DW1000_FS_CTRL, 0x07, 0x0800041D); //FS_PLLCFG for channel 5 00048 writeRegister8 (DW1000_FS_CTRL, 0x0B, 0xA6); //FS_PLLTUNE for channel 5 00049 00050 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 00051 00052 // 110kbps CAUTION: a lot of other registers have to be set for an optimized operation on 110kbps 00053 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 00054 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...] 00055 00056 writeRegister16(DW1000_TX_ANTD, 0, 16384); // set TX and RX Antenna delay to neutral because we calibrate afterwards 00057 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) 00058 00059 writeRegister8(DW1000_SYS_CFG, 3, 0x20); // enable auto reenabling receiver after error 00060 00061 irq.rise(this, &DW1000::ISR); // attach interrupt handler to rising edge of interrupt pin from DW1000 00062 } 00063 00064 void DW1000::setCallbacks(void (*callbackRX)(void), void (*callbackTX)(void)) { 00065 bool RX = false; 00066 bool TX = false; 00067 if (callbackRX) { 00068 DW1000::callbackRX.attach(callbackRX); 00069 RX = true; 00070 } 00071 if (callbackTX) { 00072 DW1000::callbackTX.attach(callbackTX); 00073 TX = true; 00074 } 00075 setInterrupt(RX,TX); 00076 } 00077 00078 uint32_t DW1000::getDeviceID() { 00079 uint32_t result; 00080 readRegister(DW1000_DEV_ID, 0, (uint8_t*)&result, 4); 00081 return result; 00082 } 00083 00084 uint64_t DW1000::getEUI() { 00085 uint64_t result; 00086 readRegister(DW1000_EUI, 0, (uint8_t*)&result, 8); 00087 return result; 00088 } 00089 00090 void DW1000::setEUI(uint64_t EUI) { 00091 writeRegister(DW1000_EUI, 0, (uint8_t*)&EUI, 8); 00092 } 00093 00094 float DW1000::getVoltage() { 00095 uint8_t buffer[7] = {0x80, 0x0A, 0x0F, 0x01, 0x00}; // algorithm form User Manual p57 00096 writeRegister(DW1000_RF_CONF, 0x11, buffer, 2); 00097 writeRegister(DW1000_RF_CONF, 0x12, &buffer[2], 1); 00098 writeRegister(DW1000_TX_CAL, 0x00, &buffer[3], 1); 00099 writeRegister(DW1000_TX_CAL, 0x00, &buffer[4], 1); 00100 readRegister(DW1000_TX_CAL, 0x03, &buffer[5], 2); // get the 8-Bit readings for Voltage and Temperature 00101 float Voltage = buffer[5] * 0.0057 + 2.3; 00102 //float Temperature = buffer[6] * 1.13 - 113.0; // TODO: getTemperature was always ~35 degree with better formula/calibration 00103 return Voltage; 00104 } 00105 00106 uint64_t DW1000::getStatus() { 00107 return readRegister40(DW1000_SYS_STATUS, 0); 00108 } 00109 00110 uint64_t DW1000::getRXTimestamp() { 00111 return readRegister40(DW1000_RX_TIME, 0); 00112 } 00113 00114 uint64_t DW1000::getTXTimestamp() { 00115 return readRegister40(DW1000_TX_TIME, 0); 00116 } 00117 00118 void DW1000::sendString(char* message) { 00119 sendFrame((uint8_t*)message, strlen(message)+1); 00120 } 00121 00122 void DW1000::receiveString(char* message) { 00123 readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)message, getFramelength()); // get data from buffer 00124 } 00125 00126 void DW1000::sendFrame(uint8_t* message, uint16_t length) { 00127 //if (length >= 1021) length = 1021; // check for maximim length a frame can have with 1024 Byte frames [not used, see constructor] 00128 if (length >= 125) length = 125; // check for maximim length a frame can have with 127 Byte frames 00129 writeRegister(DW1000_TX_BUFFER, 0, message, length); // fill buffer 00130 00131 uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame 00132 length += 2; // including 2 CRC Bytes 00133 length = ((backup & 0xFC) << 8) | (length & 0x03FF); 00134 writeRegister16(DW1000_TX_FCTRL, 0, length); 00135 00136 stopTRX(); // stop receiving 00137 writeRegister8(DW1000_SYS_CTRL, 0, 0x02); // trigger sending process by setting the TXSTRT bit 00138 startRX(); // enable receiver again 00139 } 00140 00141 void DW1000::sendDelayedFrame(uint8_t* message, uint16_t length, uint64_t TxTimestamp) { 00142 //if (length >= 1021) length = 1021; // check for maximim length a frame can have with 1024 Byte frames [not used, see constructor] 00143 if (length >= 125) length = 125; // check for maximim length a frame can have with 127 Byte frames 00144 writeRegister(DW1000_TX_BUFFER, 0, message, length); // fill buffer 00145 00146 uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame 00147 length += 2; // including 2 CRC Bytes 00148 length = ((backup & 0xFC) << 8) | (length & 0x03FF); 00149 writeRegister16(DW1000_TX_FCTRL, 0, length); 00150 00151 writeRegister40(DW1000_DX_TIME, 0, TxTimestamp); //write the timestamp on which to send the message 00152 00153 stopTRX(); // stop receiving 00154 writeRegister8(DW1000_SYS_CTRL, 0, 0x02 | 0x04); // trigger sending process by setting the TXSTRT and TXDLYS bit 00155 startRX(); // enable receiver again 00156 } 00157 00158 void DW1000::startRX() { 00159 writeRegister8(DW1000_SYS_CTRL, 0x01, 0x01); // start listening for preamble by setting the RXENAB bit 00160 } 00161 00162 void DW1000::stopTRX() { 00163 writeRegister8(DW1000_SYS_CTRL, 0, 0x40); // disable tranceiver go back to idle mode 00164 } 00165 00166 // PRIVATE Methods ------------------------------------------------------------------------------------ 00167 void DW1000::loadLDE() { // initialise LDE algorithm LDELOAD User Manual p22 00168 writeRegister16(DW1000_PMSC, 0, 0x0301); // set clock to XTAL so OTP is reliable 00169 writeRegister16(DW1000_OTP_IF, 0x06, 0x8000); // set LDELOAD bit in OTP 00170 wait_us(150); 00171 writeRegister16(DW1000_PMSC, 0, 0x0200); // recover to PLL clock 00172 } 00173 00174 void DW1000::resetRX() { 00175 writeRegister8(DW1000_PMSC, 3, 0xE0); // set RX reset 00176 writeRegister8(DW1000_PMSC, 3, 0xF0); // clear RX reset 00177 } 00178 00179 void DW1000::resetAll() { 00180 writeRegister8(DW1000_PMSC, 0, 0x01); // set clock to XTAL 00181 writeRegister8(DW1000_PMSC, 3, 0x00); // set All reset 00182 wait_us(10); // wait for PLL to lock 00183 writeRegister8(DW1000_PMSC, 3, 0xF0); // clear All reset 00184 } 00185 00186 00187 void DW1000::setInterrupt(bool RX, bool TX) { 00188 writeRegister16(DW1000_SYS_MASK, 0, RX*0x4000 | TX*0x0080); // RX good frame 0x4000, TX done 0x0080 00189 } 00190 00191 void DW1000::ISR() { 00192 uint64_t status = getStatus(); 00193 if (status & 0x4000) { // a frame was received 00194 callbackRX.call(); 00195 writeRegister16(DW1000_SYS_STATUS, 0, 0x6F00); // clearing of receiving status bits 00196 } 00197 if (status & 0x80) { // sending complete 00198 callbackTX.call(); 00199 writeRegister8(DW1000_SYS_STATUS, 0, 0xF8); // clearing of sending status bits 00200 } 00201 } 00202 00203 uint16_t DW1000::getFramelength() { 00204 uint16_t framelength = readRegister16(DW1000_RX_FINFO, 0); // get framelength 00205 framelength = (framelength & 0x03FF) - 2; // take only the right bits and subtract the 2 CRC Bytes 00206 return framelength; 00207 } 00208 00209 // SPI Interface ------------------------------------------------------------------------------------ 00210 uint8_t DW1000::readRegister8(uint8_t reg, uint16_t subaddress) { 00211 uint8_t result; 00212 readRegister(reg, subaddress, &result, 1); 00213 return result; 00214 } 00215 00216 uint16_t DW1000::readRegister16(uint8_t reg, uint16_t subaddress) { 00217 uint16_t result; 00218 readRegister(reg, subaddress, (uint8_t*)&result, 2); 00219 return result; 00220 } 00221 00222 uint64_t DW1000::readRegister40(uint8_t reg, uint16_t subaddress) { 00223 uint64_t result; 00224 readRegister(reg, subaddress, (uint8_t*)&result, 5); 00225 result &= 0xFFFFFFFFFF; // only 40-Bit 00226 return result; 00227 } 00228 00229 void DW1000::writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer) { 00230 writeRegister(reg, subaddress, &buffer, 1); 00231 } 00232 00233 void DW1000::writeRegister16(uint8_t reg, uint16_t subaddress, uint16_t buffer) { 00234 writeRegister(reg, subaddress, (uint8_t*)&buffer, 2); 00235 } 00236 00237 void DW1000::writeRegister32(uint8_t reg, uint16_t subaddress, uint32_t buffer) { 00238 writeRegister(reg, subaddress, (uint8_t*)&buffer, 4); 00239 } 00240 00241 void DW1000::writeRegister40(uint8_t reg, uint16_t subaddress, uint64_t buffer) { 00242 writeRegister(reg, subaddress, (uint8_t*)&buffer, 5); 00243 } 00244 00245 void DW1000::readRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) { 00246 setupTransaction(reg, subaddress, false); 00247 for(int i=0; i<length; i++) // get data 00248 buffer[i] = spi.write(0x00); 00249 deselect(); 00250 } 00251 00252 void DW1000::writeRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) { 00253 setupTransaction(reg, subaddress, true); 00254 for(int i=0; i<length; i++) // put data 00255 spi.write(buffer[i]); 00256 deselect(); 00257 } 00258 00259 void DW1000::setupTransaction(uint8_t reg, uint16_t subaddress, bool write) { 00260 reg |= (write * DW1000_WRITE_FLAG); // set read/write flag 00261 select(); 00262 if (subaddress > 0) { // there's a subadress, we need to set flag and send second header byte 00263 spi.write(reg | DW1000_SUBADDRESS_FLAG); 00264 if (subaddress > 0x7F) { // sub address too long, we need to set flag and send third header byte 00265 spi.write((uint8_t)(subaddress & 0x7F) | DW1000_2_SUBADDRESS_FLAG); // and 00266 spi.write((uint8_t)(subaddress >> 7)); 00267 } else { 00268 spi.write((uint8_t)subaddress); 00269 } 00270 } else { 00271 spi.write(reg); // say which register address we want to access 00272 } 00273 } 00274 00275 void DW1000::select() { // always called to start an SPI transmission 00276 irq.disable_irq(); // disable interrupts from DW1000 during SPI becaus this leads to crashes! TODO: if you have other interrupt handlers attached on the micro controller, they could also interfere. 00277 cs = 0; // set Cable Select pin low to start transmission 00278 } 00279 void DW1000::deselect() { // always called to end an SPI transmission 00280 cs = 1; // set Cable Select pin high to stop transmission 00281 irq.enable_irq(); // reenable the interrupt handler 00282 }
Generated on Tue Jul 12 2022 23:01:16 by
1.7.2