DW1000 UWB driver based on work of Matthias Grob & Manuel Stalder - ETH Zürich - 2015
Revision 3:1459d2aa6b97, committed 2016-04-07
- Comitter:
- AndyA
- Date:
- Thu Apr 07 14:31:28 2016 +0000
- Parent:
- 1:dcbd071f38d5
- Child:
- 4:5f1025df5530
- Commit message:
- Simplified system config.
Changed in this revision
DW1000.cpp | Show annotated file Show diff for this revision Revisions of this file |
DW1000.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/DW1000.cpp Tue Apr 05 11:37:23 2016 +0000 +++ b/DW1000.cpp Thu Apr 07 14:31:28 2016 +0000 @@ -15,71 +15,59 @@ switch (setup) { case user110k: // values from Matthias Grob & Manuel Stalder - ETH Zürich - library - //Those values are for the 110kbps mode (5, 16MHz, 1024 Symbols) and are quite complete - writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE1, 0x8870); //AGC_TUNE1 for 16MHz PRF - writeRegister32(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE2, 0x2502A907); //AGC_TUNE2 (Universal) - writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE3, 0x0055); //AGC_TUNE3 (Universal) - - writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x000A); //DRX_TUNE0b for 110kbps - writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE1A, 0x0087); //DRX_TUNE1a for 16MHz PRF - writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE1B, 0x0064); //DRX_TUNE1b for 110kbps & > 1024 symbols - writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x351A009A); //PAC size for 1024 symbols preamble & 16MHz PRF - //writeRegister32(DW1000_DRX_CONF, 0x08, 0x371A011D); //PAC size for 2048 symbols preamble - - writeRegister8 (DW1000_LDE_CTRL, DWLDE_LDE_CFG1, 0xD); //LDE_CFG1 - writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_CFG2, 0x1607); //LDE_CFG2 for 16MHz PRF - - writeRegister32(DW1000_TX_POWER, 0, 0x28282828); //Power for channel 5 - writeRegister8(DW1000_RF_CONF, DWRFCONF_RF_RXCTRLH, 0xD8); //RF_RXCTRLH for channel 5 - writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x001E3FE0); //RF_TXCTRL for channel 5 - - writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0xC0); //TC_PGDELAY for channel 5 - - writeRegister32 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLCFG, 0x0800041D); //FS_PLLCFG for channel 5 - writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLTUNE, 0xBE); // changed from 0xA6 //FS_PLLTUNE for channel 5 + systemConfig.channel = 5; + systemConfig.prf = prf16MHz; + systemConfig.dataRate = kbps110; + systemConfig.sfd = standard; + systemConfig.preamble = pre1024; + systemConfig.preambleCode = 3; + systemConfig.enableSmartPower = true; - 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 + setupRadio(); - // 110kbps CAUTION: a lot of other registers have to be set for an optimized operation on 110kbps - 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 - 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...] + setTxPower(230); // power = 23dB gain - writeRegister16(DW1000_TX_ANTD, 0, 16384); // set TX and RX Antenna delay to neutral because we calibrate afterwards - writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_RXANTD, 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) + setRxDelay(1<<14); // set delays to 2^14 (1/4 of max) + setTxDelay(1<<14); break; case tunedDefault: // User Manual "2.5.5 Default Configurations that should be modified" p. 22 - //Those values are for the standard mode (6.8Mbps, 5, 16Mhz, 32 Symbols) and are (may be?) INCOMPLETE! - writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE1, 0x8870); - writeRegister32(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE2, 0x2502A907); - writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x311A002D); - writeRegister8(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0001); - writeRegister8(DW1000_DRX_CONF, DWDRX_DRX_TUNE1A, 0x0087); - writeRegister8(DW1000_DRX_CONF, DWDRX_DRX_TUNE1B, 0x0020); - writeRegister8 (DW1000_LDE_CTRL, DWLDE_LDE_CFG1, 0xD); - writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_CFG2, 0x1607); - writeRegister32(DW1000_TX_POWER, 0, 0x0E082848); -// writeRegister32(DW1000_TX_POWER, 0, 0x75757575); - writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x001E3FE0); - writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0xC0); - writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLTUNE, 0xBE); + default: + + systemConfig.channel = 5; + systemConfig.prf = prf16MHz; + systemConfig.dataRate = kbps6800; + systemConfig.sfd = standard; + systemConfig.preamble = pre128; + systemConfig.preambleCode = 3; + systemConfig.enableSmartPower = false;; + + setupRadio(); - 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 + setTxPower(230,260,290); // power = 23dB gain + setRxDelay(0); + setTxDelay(0); - writeRegister32(DW1000_GPIO_CTRL,DWGPIO_GPIO_MODE,0x00001400); - writeRegister16(DW1000_PMSC,DWPMSC_PMSC_LEDC,0x0120); + break; + case minPacketSize: + systemConfig.channel = 5; + systemConfig.prf = prf16MHz; + systemConfig.dataRate = kbps6800; + systemConfig.sfd = standard; + systemConfig.preamble = pre64; + systemConfig.preambleCode = 3; + systemConfig.enableSmartPower = true;; -// writeRegister8(DW1000_SYS_CFG, 3, 0x20); // enable auto RX reenable + setupRadio(); + uint16_t txPower = 25*10; // 25dB gain. + // 3 packets per ms max. So can increase TX power of 250us packets by 10log(4/3) dB and 125us packets by 10log(8/3) dB + setTxPower(txPower,txPower,txPower+15,txPower+45); // power = 23dB gain setRxDelay(0); setTxDelay(0); break; - case defaultConfig: - default: - 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 - break; } writeRegister8(DW1000_SYS_CFG, 3, 0x20); // enable auto reenabling receiver after error @@ -87,6 +75,455 @@ irq.rise(this, &DW1000::ISR); // attach interrupt handler to rising edge of interrupt pin from DW1000 } +void DW1000::setupRadio() +{ + setupAGC(); + setupRxConfig(); + setupLDE(); + setupChannel(); + setupAnalogRF(); + setupFreqSynth(); + setupTxCalibration(); + setupTxFrameCtrl(); + setupSystemConfig(); + +} + +void DW1000::setupAGC() +{ + + writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_CTRL1, 0x0001); + if (systemConfig.prf == prf16MHz) + writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE1, 0x8870); + else + writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE1, 0x889B); + + writeRegister32(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE2, 0x2502A907); + writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE3, 0x0035); +} + +void DW1000::setupSystemConfig() +{ + uint32_t valueToUse = 0; + valueToUse |= 1<<9; // IRQ output is active high (default) + valueToUse |= 1<<12; // Disable double buffered Rx (default) + +// valueToUse |= 3<<16; // enable long (>125bytes data) packets + + if (!systemConfig.enableSmartPower) + valueToUse |= 1<<18; // disable smart power + + if (systemConfig.dataRate == kbps110) + valueToUse |= 1<<22; + + writeRegister8(DW1000_SYS_CFG, 0, valueToUse); +} + +void DW1000::setupRxConfig() +{ + + switch (systemConfig.dataRate) { + case kbps110: + if (systemConfig.sfd == standard) + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x000A); + else + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0016); + break; + case kbps850: + if (systemConfig.sfd == standard) + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0001); + else + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0006); + break; + case kbps6800: + default: + if (systemConfig.sfd == standard) + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0001); + else + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0002); + break; + } + + if (systemConfig.prf == prf16MHz) + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE1A, 0x0087); //DRX_TUNE1a for 16MHz PRF + else + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE1A, 0x008D); + + switch (systemConfig.preamble) { + case pre1536: + case pre2048: + case pre4096: + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE1B, 0x0064); //DRX_TUNE1b for 110kbps & > 1024 symbols + break; + default: // 128 to 1024 + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE1B, 0x0020); //DRX_TUNE1b for 128- 1024 symbols + break; + case pre64: + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE1B, 0x0010); //DRX_TUNE1b for 64 symbols + break; + } + + switch (systemConfig.preamble) { + case pre64: + case pre128: // PAC = 8 + if (systemConfig.prf == prf16MHz) + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x311A002D); //DRX_TUNE2 PAC 8 for 64MHz PRF + else + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x313B006B); //DRX_TUNE2 PAC 8 for 64MHz PRF + break; + case pre256: + case pre512: + if (systemConfig.prf == prf16MHz) + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x331A0052); //DRX_TUNE2 PAC 16 for 64MHz PRF + else + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x333B00BE); //DRX_TUNE2 PAC 16 for 64MHz PRF + break; + case pre1024: + if (systemConfig.prf == prf16MHz) + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x351A009A); //DRX_TUNE2 PAC 32 for 64MHz PRF + else + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x353B015E); //DRX_TUNE2 PAC 32 for 64MHz PRF + break; + case pre1536: + case pre2048: + case pre4096: + if (systemConfig.prf == prf16MHz) + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x371A011D); //DRX_TUNE2 PAC 64 for 64MHz PRF + else + writeRegister32(DW1000_DRX_CONF, DWDRX_DRX_TUNE2, 0x373B0296); //DRX_TUNE2 PAC 64 for 64MHz PRF + break; + } + + + if (systemConfig.preamble == pre64) + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE4H, 0x0010); + else + writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE4H, 0x0028); + +} + + +void DW1000::setupLDE() +{ + + writeRegister8 (DW1000_LDE_CTRL, DWLDE_LDE_CFG1, 0x13 | 0x03<<5); //NTM = 13 (12 may be better in some situations. PMULT = 3 + + if (systemConfig.prf == prf16MHz) + writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_CFG2, 0x1607); //LDE_CFG2 for 16MHz PRF + else + writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_CFG2, 0x0607); //LDE_CFG2 for 64MHz PRF + + uint16_t replicaCoeff; + switch (systemConfig.preambleCode) { + default: + case 1: + case 2: + replicaCoeff = 0x5998; + break; + case 3: + replicaCoeff = 0x51EA; + break; + case 4: + replicaCoeff = 0x428E; + break; + case 5: + replicaCoeff = 0x451E; + break; + case 6: + replicaCoeff = 0x2E14; + break; + case 7: + replicaCoeff = 0x8000; + break; + case 8: + replicaCoeff = 0x51EA; + break; + case 9: + replicaCoeff = 0x28F4; + break; + case 10: + replicaCoeff = 0x3332; + break; + case 11: + replicaCoeff = 0x3AE0; + break; + case 12: + replicaCoeff = 0x3D70; + break; + case 13: + replicaCoeff = 0x3AE0; + break; + case 14: + replicaCoeff = 0x35C2; + break; + case 15: + replicaCoeff = 0x2B84; + break; + case 16: + replicaCoeff = 0x35C2; + break; + case 17: + replicaCoeff = 0x3332; + break; + case 18: + replicaCoeff = 0x35C2; + break; + case 19: + replicaCoeff = 0x35C2; + break; + case 20: + replicaCoeff = 0x47AE; + break; + case 21: + replicaCoeff = 0x3AE0; + break; + case 22: + replicaCoeff = 0x3850; + break; + case 23: + replicaCoeff = 0x30A2; + break; + case 24: + replicaCoeff = 0x3850; + break; + } + + if (systemConfig.dataRate == kbps110) + replicaCoeff = replicaCoeff>>3; + + writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_REPC, replicaCoeff); + + loadLDE(); +} + +void DW1000::setupChannel() +{ + uint16_t registerValue = 0; + + registerValue = systemConfig.channel; // set Tx channel + registerValue |= systemConfig.channel<<4; // set Rx channel + + if ( systemConfig.prf == prf16MHz) // set PRF (2 bit value 01 or 10) + registerValue |= 0x01 << 18; + else + registerValue |= 0x02 << 18; + + if (systemConfig.sfd == nonStandard) { + registerValue |= 0x01 << 17; // enable DW own SFD +// registerValue |= 0x01 << 20; // enable user set SFD Tx +// registerValue |= 0x01 << 21; // enable user set SFD Rx + } + + registerValue |= systemConfig.preambleCode << 22; // set Tx preamble code + registerValue |= systemConfig.preambleCode << 27; // set Rx preamble code + + writeRegister16(DW1000_CHAN_CTRL, 0, registerValue); +} + + +uint8_t DW1000::powerToRegValue(uint16_t powercB) +{ + + // course power control - 0 = 18dB, 6 = 0dB in 3dB steps. + uint8_t course = powercB / 30; + + if(course > 6) + course = 6; + + // remaining power + powercB -= course * 30; + + // value in reg is inverse. + course = 6-course; + + // fine control in steps of 0.5dB + uint8_t fine = powercB / 5; + if (fine > 31) + fine = 31; + + + return (course << 5) | fine; + +} + +// transmit power: 0 to 33.5 dB gain in steps of 0.5. Inputs are in 10ths of a dB (0 to 335) +void DW1000::setTxPower(uint16_t normalPowercB, uint16_t boost500, uint16_t boost250, uint16_t boost125) +{ + if(normalPowercB > 335) + normalPowercB = 335; + + if (boost500 < normalPowercB) + boost500 = normalPowercB; + if(boost500 > 335) + boost500 = 335; + + if (boost250 < boost500) + boost250 = boost500; + if(boost250 > 335) + boost250 = 335; + + if (boost125 < boost250) + boost125 = boost250; + if(boost125 > 335) + boost125 = 335; + + uint32_t powerReg = powerToRegValue(normalPowercB); + powerReg |= powerToRegValue(boost500) << 8; + powerReg |= powerToRegValue(boost250) << 16; + powerReg |= powerToRegValue(boost125) << 24; +} + +void DW1000::setupAnalogRF() +{ + switch (systemConfig.channel) { + case 1: + writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x00005C40); + break; + case 2: + writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x00045CA0); + break; + case 3: + writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x00086CC0); + break; + case 4: + writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x00045C80); + break; + case 5: + default: + writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x001E3FE0); + break; + case 7: + writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x001E7DE0); + break; + } + + switch (systemConfig.channel) { + case 1: + case 2: + case 3: + case 5: + default: + writeRegister8(DW1000_RF_CONF, DWRFCONF_RF_RXCTRLH, 0xD8); + break; + case 4: + case 7: + writeRegister8(DW1000_RF_CONF, DWRFCONF_RF_RXCTRLH, 0xBC); + break; + } + + loadLDOTUNE(); + +} + +void DW1000::setupTxCalibration() +{ + switch (systemConfig.channel) { + case 1: + writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0xC9); + break; + case 2: + writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0xC2); + break; + case 3: + writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0xC5); + break; + case 4: + writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0x95); + break; + case 5: + default: + writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0xC0); + break; + case 7: + writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0x93); + break; + } +} + +void DW1000::setupFreqSynth() +{ + + switch (systemConfig.channel) { + case 1: + writeRegister32 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLCFG, 0x09000407); //FS_PLLCFG for channel 1 + writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLTUNE, 0x1E); + break; + case 2: + case 4: + writeRegister32 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLCFG, 0x08400508); //FS_PLLCFG for channel 2,4 + writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLTUNE, 0x26); + break; + case 3: + writeRegister32 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLCFG, 0x08401009); //FS_PLLCFG for channel 3 + writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLTUNE, 0x5E); + break; + case 5: + case 7: + default: + writeRegister32 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLCFG, 0x0800041D); //FS_PLLCFG for channel 5,7 + writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLTUNE, 0xBE); //FS_PLLTUNE for channel 5 + break; + } +} + +void DW1000::setupTxFrameCtrl() +{ + uint16_t frameCtrlValue = 0; + switch (systemConfig.dataRate) { + case kbps110: + break; + case kbps850: + frameCtrlValue |= 0x01<<13; + break; + case kbps6800: + default: + frameCtrlValue |= 0x02<<13; + break; + } + frameCtrlValue |= 0x01<<15; + + if (systemConfig.prf == prf16MHz) + frameCtrlValue |= 0x01<<16; + else + frameCtrlValue |= 0x02<<16; + + switch (systemConfig.preamble) { + case pre64: + frameCtrlValue |= 0x01<<18; // TXPSR + frameCtrlValue |= 0x00<<20; // PE + break; + case pre128: + default: + frameCtrlValue |= 0x01<<18; // TXPSR + frameCtrlValue |= 0x01<<20; // PE + break; + case pre256: + frameCtrlValue |= 0x01<<18; // TXPSR + frameCtrlValue |= 0x02<<20; // PE + break; + case pre512: + frameCtrlValue |= 0x01<<18; // TXPSR + frameCtrlValue |= 0x03<<20; // PE + break; + case pre1024: + frameCtrlValue |= 0x02<<18; // TXPSR + frameCtrlValue |= 0x00<<20; // PE + break; + case pre1536: + frameCtrlValue |= 0x02<<18; // TXPSR + frameCtrlValue |= 0x01<<20; // PE + break; + case pre2048: + frameCtrlValue |= 0x02<<18; // TXPSR + frameCtrlValue |= 0x02<<20; // PE + break; + case pre4096: + frameCtrlValue |= 0x03<<18; // TXPSR + frameCtrlValue |= 0x00<<20; // PE + break; + } +} + void DW1000::setRxDelay(uint16_t ticks) { writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_RXANTD, ticks); @@ -192,12 +629,12 @@ uint8_t len_7bit = length; writeRegister(DW1000_TX_BUFFER, 0, message, len_7bit); // fill buffer -/* support for frames over 127 bytes - uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame - length += 2; // including 2 CRC Bytes - length = ((backup & 0xFC) << 8) | (length & 0x03FF); - writeRegister16(DW1000_TX_FCTRL, 0, length); -*/ + /* support for frames over 127 bytes + uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1); // put length of frame + length += 2; // including 2 CRC Bytes + length = ((backup & 0xFC) << 8) | (length & 0x03FF); + writeRegister16(DW1000_TX_FCTRL, 0, length); + */ len_7bit += 2; // including 2 CRC Bytes writeRegister8(DW1000_TX_FCTRL, 0, len_7bit); @@ -206,7 +643,8 @@ // startRX(); // enable receiver again } -void DW1000::setupSyncedFrame(uint8_t* message, uint16_t length) { +void DW1000::setupSyncedFrame(uint8_t* message, uint16_t length) +{ //if (length >= 1021) length = 1021; // check for maximim length a frame can have with 1024 Byte frames [not used, see constructor] if (length >= 125) length = 125; // check for maximim length a frame can have with 127 Byte frames writeRegister(DW1000_TX_BUFFER, 0, message, length); // fill buffer @@ -217,10 +655,11 @@ writeRegister16(DW1000_TX_FCTRL, 0, length); } -void DW1000::armSyncedFrame() { +void DW1000::armSyncedFrame() +{ stopTRX(); // stop receiving writeRegister16(DW1000_EXT_SYNC, DWEXTSYNC_EC_CTRL, 33<<3 | 0x01); // Sync register = TX start with a wait of 33 (recomended, value must fulfill wait % 4 = 1) - } +} void DW1000::sendDelayedFrame(uint8_t* message, uint16_t length, uint64_t TxTimestamp) {
--- a/DW1000.h Tue Apr 05 11:37:23 2016 +0000 +++ b/DW1000.h Thu Apr 07 14:31:28 2016 +0000 @@ -152,7 +152,22 @@ #define DW1000_SUBADDRESS_FLAG 0x40 // if we have a sub address second Bit has to be 1 #define DW1000_2_SUBADDRESS_FLAG 0x80 // if we have a long sub adress (more than 7 Bit) we set this Bit in the first part -typedef enum {defaultConfig, tunedDefault, user110k} UWBMode; +/* +From user manual 10.5 +Table 59: +DW1000 supported UWB channels and recommended preamble codes + +channel 16MHzPrf 64MHzPrf +1 1,2 9, 10, 11, 12 +2 3, 4 9, 10, 11, 12 +3 5, 6 9, 10, 11, 12 +4 7, 8 17, 18, 19, 20 +5 3, 4 9, 10, 11, 12 +7 7, 8 17, 18, 19, 20 +*/ + + +typedef enum {minPacketSize, tunedDefault, user110k} UWBMode; class DW1000 { @@ -204,11 +219,54 @@ void resetRX(); // soft reset only the tranciever part of DW1000 void setInterrupt(bool RX, bool TX); // set Interrupt for received a good frame (CRC ok) or transmission done + /** Set Transmit gain + * + * @param normalPowercB Normal transmit gain to use. + * @param boost500 Gain to use for 6.8Mb/s packets of under 500ms. + * @param boost250 Gain to use for 6.8Mb/s packets of under 250ms. + * @param boost125 Gain to use for 6.8Mb/s packets of under 125ms. + * + * All gains are in cB (dB * 10). Gains can be between 0 and 335 (33.5dB). + * Boost gains are optional, if not specified boost gains are set to the power for the lower rate (e.g. boost125 is set to the boost250 level). + */ + void setTxPower(uint16_t normalPowercB, uint16_t boost500 = 0, uint16_t boost250 = 0, uint16_t boost125 = 0); + private: void resetAll(); // soft reset the entire DW1000 (some registers stay as they were see User Manual) + + void setupRadio(); + + // system register setup functions + void setupAGC(); + void setupRxConfig(); + void setupLDE(); + void setupChannel(); + void setupTxFrameCtrl(); + void setupAnalogRF(); + void setupFreqSynth(); + void setupTxCalibration(); + void setupSystemConfig(); void loadLDE(); // load the leading edge detection algorithm to RAM, [IMPORTANT because receiving malfunction may occur] see User Manual LDELOAD on p22 & p158 void loadLDOTUNE(); // load the LDO tuning as set in the factory + + uint8_t powerToRegValue(uint16_t powercB); + + enum prf_e {prf16MHz,prf64MHz}; + enum dataRate_e {kbps110,kbps850,kbps6800}; + enum sfd_e {standard, nonStandard}; + enum preamble_e { pre64, pre128, pre256, pre512, pre1024, pre1536, pre2048, pre4096}; + + struct { + unsigned char channel; // 1-5 , 7 + enum prf_e prf; + enum dataRate_e dataRate; + enum sfd_e sfd; + enum preamble_e preamble; + unsigned char preambleCode; // 1-24. See section 10.5 of user manual for details. + bool enableSmartPower; + } systemConfig; + // Interrupt