DW1000 UWB driver based on work of Matthias Grob & Manuel Stalder - ETH Zürich - 2015

Dependencies:   BurstSPI

Files at this revision

API Documentation at this revision

Comitter:
AndyA
Date:
Thu Apr 07 16:25:31 2016 +0000
Parent:
3:1459d2aa6b97
Child:
5:68ffaa5962d1
Commit message:
Moved config to it's own class

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	Thu Apr 07 14:31:28 2016 +0000
+++ b/DW1000.cpp	Thu Apr 07 16:25:31 2016 +0000
@@ -16,13 +16,13 @@
     switch (setup) {
         case user110k:  // values from Matthias Grob & Manuel Stalder - ETH Zürich - library
 
-            systemConfig.channel = 5;
-            systemConfig.prf = prf16MHz;
-            systemConfig.dataRate = kbps110;
-            systemConfig.sfd = standard;
-            systemConfig.preamble = pre1024;
-            systemConfig.preambleCode = 3;
-            systemConfig.enableSmartPower = true;
+            systemConfig.setChannel(5);
+            systemConfig.setPRF(DW1000Setup::prf16MHz);
+            systemConfig.setDataRate(DW1000Setup::kbps110);
+            systemConfig.setSfd(DW1000Setup::standard);
+            systemConfig.setPreambleLength(DW1000Setup::pre1024);
+            systemConfig.setPreambleCode(3);
+            systemConfig.setSmartPower(false);
 
             setupRadio();
 
@@ -35,13 +35,13 @@
         case tunedDefault:    // User Manual "2.5.5 Default Configurations that should be modified" p. 22
         default:
 
-            systemConfig.channel = 5;
-            systemConfig.prf = prf16MHz;
-            systemConfig.dataRate = kbps6800;
-            systemConfig.sfd = standard;
-            systemConfig.preamble = pre128;
-            systemConfig.preambleCode = 3;
-            systemConfig.enableSmartPower = false;;
+            systemConfig.setChannel(5);
+            systemConfig.setPRF(DW1000Setup::prf16MHz);
+            systemConfig.setDataRate(DW1000Setup::kbps6800);
+            systemConfig.setSfd(DW1000Setup::standard);
+            systemConfig.setPreambleLength(DW1000Setup::pre128);
+            systemConfig.setPreambleCode(3);
+            systemConfig.setSmartPower(false);
 
             setupRadio();
 
@@ -51,18 +51,18 @@
 
             break;
         case minPacketSize:
-            systemConfig.channel = 5;
-            systemConfig.prf = prf16MHz;
-            systemConfig.dataRate = kbps6800;
-            systemConfig.sfd = standard;
-            systemConfig.preamble = pre64;
-            systemConfig.preambleCode = 3;
-            systemConfig.enableSmartPower = true;;
+            systemConfig.setChannel(5);
+            systemConfig.setPRF(DW1000Setup::prf64MHz);
+            systemConfig.setDataRate(DW1000Setup::kbps6800);
+            systemConfig.setSfd(DW1000Setup::standard);
+            systemConfig.setPreambleLength(DW1000Setup::pre64);
+            systemConfig.setPreambleCode(10);
+            systemConfig.setSmartPower(true);
 
             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
+            // 2 packets per ms max. So can increase TX power of 250us packets by 10log(4/2) dB and 125us packets by 10log(8/2) dB
+            setTxPower(txPower,txPower,txPower+30,txPower+60); // power = 23dB gain
 
             setRxDelay(0);
             setTxDelay(0);
@@ -70,11 +70,64 @@
             break;
     }
 
-    writeRegister8(DW1000_SYS_CFG, 3, 0x20);    // enable auto reenabling receiver after error
 
     irq.rise(this, &DW1000::ISR);       // attach interrupt handler to rising edge of interrupt pin from DW1000
 }
 
+void DW1000::getSetup(char *buffer, int len)
+{
+
+    char dataRateString[10];
+    if (systemConfig.getDataRate() == DW1000Setup::kbps6800)
+        strcpy(dataRateString,"6.8 Mbps");
+    else if (systemConfig.getDataRate() == DW1000Setup::kbps850)
+        strcpy(dataRateString,"850 kbps");
+    else
+        strcpy(dataRateString,"110 kbps");
+
+    char preambleString[8];
+    switch (systemConfig.getPreambleLength()) {
+        default:
+            strcpy(preambleString,"error");
+            break;
+        case DW1000Setup::pre64:
+            strcpy(preambleString,"64");
+            break;
+        case DW1000Setup::pre128:
+            strcpy(preambleString,"128");
+            break;
+        case DW1000Setup::pre256:
+            strcpy(preambleString,"256");
+            break;
+        case DW1000Setup::pre512:
+            strcpy(preambleString,"512");
+            break;
+        case DW1000Setup::pre1024:
+            strcpy(preambleString,"1024");
+            break;
+        case DW1000Setup::pre1536:
+            strcpy(preambleString,"1536");
+            break;
+        case DW1000Setup::pre2048:
+            strcpy(preambleString,"2048");
+            break;
+        case DW1000Setup::pre4096:
+            strcpy(preambleString,"4096");
+            break;
+    }
+
+    snprintf(buffer,len,"Channel:\t%u\r\nPRF:\t%s\r\nData Rate:\t%s\r\nPreamble length:\t%s\r\nPreamble code:\t%u\r\nSmart power:\t%s\r\nSFD:\t%s\r\n",
+             systemConfig.getChannel(),
+             (systemConfig.getPRF() == DW1000Setup::prf16MHz)?"16 MHz":"64 MHz",
+             dataRateString,
+             preambleString,
+             systemConfig.getPreambleCode(),
+             systemConfig.getSmartPower()?"Enabled":"Disabled",
+             (systemConfig.getSfd() == DW1000Setup::standard)?"Standard":"Non-standard");
+
+}
+
+
 void DW1000::setupRadio()
 {
     setupAGC();
@@ -93,7 +146,7 @@
 {
 
     writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_CTRL1, 0x0001);
-    if (systemConfig.prf == prf16MHz)
+    if (systemConfig.getPRF() == DW1000Setup::prf16MHz)
         writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE1, 0x8870);
     else
         writeRegister16(DW1000_AGC_CTRL, DWAGCCTRL_AGC_TUNE1, 0x889B);
@@ -110,84 +163,86 @@
 
 //    valueToUse |= 3<<16; // enable long (>125bytes data) packets
 
-    if (!systemConfig.enableSmartPower)
+    if (!systemConfig.getSmartPower())
         valueToUse |= 1<<18; // disable smart power
 
-    if (systemConfig.dataRate == kbps110)
+    if (systemConfig.getDataRate() == DW1000Setup::kbps110)
         valueToUse |= 1<<22;
 
-    writeRegister8(DW1000_SYS_CFG, 0, valueToUse);
+    valueToUse |= 1<<29;// enable auto reenabling receiver after error
+
+    writeRegister32(DW1000_SYS_CFG, 0, valueToUse);
 }
 
 void DW1000::setupRxConfig()
 {
 
-    switch (systemConfig.dataRate) {
-        case kbps110:
-            if (systemConfig.sfd == standard)
+    switch (systemConfig.getDataRate()) {
+        case DW1000Setup::kbps110:
+            if (systemConfig.getSfd() == DW1000Setup::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)
+        case DW1000Setup::kbps850:
+            if (systemConfig.getSfd() == DW1000Setup::standard)
                 writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0001);
             else
                 writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0006);
             break;
-        case kbps6800:
+        case DW1000Setup::kbps6800:
         default:
-            if (systemConfig.sfd == standard)
+            if (systemConfig.getSfd() == DW1000Setup::standard)
                 writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0001);
             else
                 writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE0B, 0x0002);
             break;
     }
 
-    if (systemConfig.prf == prf16MHz)
+    if (systemConfig.getPRF() == DW1000Setup::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:
+    switch (systemConfig.getPreambleLength()) {
+        case DW1000Setup::pre1536:
+        case DW1000Setup::pre2048:
+        case DW1000Setup::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:
+        case DW1000Setup::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)
+    switch (systemConfig.getPreambleLength()) {
+        case DW1000Setup::pre64:
+        case DW1000Setup::pre128:  // PAC = 8
+            if (systemConfig.getPRF() == DW1000Setup::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)
+        case DW1000Setup::pre256:
+        case DW1000Setup::pre512: // PAC = 16
+            if (systemConfig.getPRF() == DW1000Setup::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)
+        case DW1000Setup::pre1024: // PAC = 32
+            if (systemConfig.getPRF() == DW1000Setup::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)
+        case DW1000Setup::pre1536:
+        case DW1000Setup::pre2048:
+        case DW1000Setup::pre4096: // PAC = 64
+            if (systemConfig.getPRF() == DW1000Setup::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
@@ -195,7 +250,7 @@
     }
 
 
-    if (systemConfig.preamble == pre64)
+    if (systemConfig.getPreambleLength() == DW1000Setup::pre64)
         writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE4H, 0x0010);
     else
         writeRegister16(DW1000_DRX_CONF, DWDRX_DRX_TUNE4H, 0x0028);
@@ -208,13 +263,13 @@
 
     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)
+    if (systemConfig.getPRF() == DW1000Setup::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) {
+    switch (systemConfig.getPreambleCode()) {
         default:
         case 1:
         case 2:
@@ -288,7 +343,7 @@
             break;
     }
 
-    if (systemConfig.dataRate == kbps110)
+    if (systemConfig.getDataRate() == DW1000Setup::kbps110)
         replicaCoeff = replicaCoeff>>3;
 
     writeRegister16(DW1000_LDE_CTRL, DWLDE_LDE_REPC, replicaCoeff);
@@ -298,26 +353,28 @@
 
 void DW1000::setupChannel()
 {
-    uint16_t registerValue = 0;
+    uint32_t registerValue = 0;
 
-    registerValue = systemConfig.channel; // set Tx channel
-    registerValue |= systemConfig.channel<<4; // set Rx channel
+    registerValue = systemConfig.getChannel(); // set Tx channel
+    registerValue |= systemConfig.getChannel()<<4; // set Rx channel
 
-    if (    systemConfig.prf == prf16MHz) // set PRF (2 bit value 01 or 10)
+    if (systemConfig.getPRF() == DW1000Setup::prf16MHz) // set PRF (2 bit value 01 or 10)
         registerValue |= 0x01 << 18;
     else
         registerValue |= 0x02 << 18;
 
-    if (systemConfig.sfd == nonStandard)  {
+    if (systemConfig.getSfd() == DW1000Setup::decaWave) 
         registerValue |= 0x01 << 17; // enable DW own SFD
-//    registerValue |= 0x01 << 20; // enable user set SFD Tx
-//    registerValue |= 0x01 << 21; // enable user set SFD Rx
+
+    if (systemConfig.getSfd() == DW1000Setup::user) {     
+        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
+    registerValue |= systemConfig.getPreambleCode() << 22; // set Tx preamble code
+    registerValue |= systemConfig.getPreambleCode() << 27; // set Rx preamble code
 
-    writeRegister16(DW1000_CHAN_CTRL, 0, registerValue);
+    writeRegister32(DW1000_CHAN_CTRL, 0, registerValue);
 }
 
 
@@ -349,6 +406,7 @@
 // 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;
 
@@ -367,6 +425,12 @@
     if(boost125 > 335)
         boost125 = 335;
 
+    if (systemConfig.getSmartPower() == false) {
+        boost500 = normalPowercB;
+        boost250 = normalPowercB;
+        boost125 = normalPowercB;
+    }
+
     uint32_t powerReg = powerToRegValue(normalPowercB);
     powerReg |= powerToRegValue(boost500) << 8;
     powerReg |= powerToRegValue(boost250) << 16;
@@ -375,7 +439,7 @@
 
 void DW1000::setupAnalogRF()
 {
-    switch (systemConfig.channel) {
+    switch (systemConfig.getChannel()) {
         case 1:
             writeRegister32(DW1000_RF_CONF, DWRFCONF_RF_TXCTRL, 0x00005C40);
             break;
@@ -397,7 +461,7 @@
             break;
     }
 
-    switch (systemConfig.channel) {
+    switch (systemConfig.getChannel()) {
         case 1:
         case 2:
         case 3:
@@ -417,7 +481,7 @@
 
 void DW1000::setupTxCalibration()
 {
-    switch (systemConfig.channel) {
+    switch (systemConfig.getChannel()) {
         case 1:
             writeRegister8 (DW1000_TX_CAL, DWTXCAL_TC_PGDELAY, 0xC9);
             break;
@@ -443,7 +507,7 @@
 void DW1000::setupFreqSynth()
 {
 
-    switch (systemConfig.channel) {
+    switch (systemConfig.getChannel()) {
         case 1:
             writeRegister32 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLCFG, 0x09000407);         //FS_PLLCFG for channel 1
             writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_PLLTUNE, 0x1E);
@@ -468,60 +532,61 @@
 
 void DW1000::setupTxFrameCtrl()
 {
-    uint16_t frameCtrlValue = 0;
-    switch (systemConfig.dataRate) {
-        case kbps110:
+    uint32_t frameCtrlValue = 0;
+    switch (systemConfig.getDataRate()) {
+        case DW1000Setup::kbps110:
             break;
-        case kbps850:
+        case DW1000Setup::kbps850:
             frameCtrlValue |= 0x01<<13;
             break;
-        case kbps6800:
+        case DW1000Setup::kbps6800:
         default:
             frameCtrlValue |= 0x02<<13;
             break;
     }
     frameCtrlValue |= 0x01<<15;
 
-    if (systemConfig.prf == prf16MHz)
+    if (systemConfig.getPRF() == DW1000Setup::prf16MHz)
         frameCtrlValue |= 0x01<<16;
     else
         frameCtrlValue |= 0x02<<16;
 
-    switch    (systemConfig.preamble)            {
-        case pre64:
+    switch    (systemConfig.getPreambleLength())            {
+        case DW1000Setup::pre64:
             frameCtrlValue |= 0x01<<18; // TXPSR
             frameCtrlValue |= 0x00<<20; // PE
             break;
-        case pre128:
+        case DW1000Setup::pre128:
         default:
             frameCtrlValue |= 0x01<<18; // TXPSR
             frameCtrlValue |= 0x01<<20; // PE
             break;
-        case pre256:
+        case DW1000Setup::pre256:
             frameCtrlValue |= 0x01<<18; // TXPSR
             frameCtrlValue |= 0x02<<20; // PE
             break;
-        case pre512:
+        case DW1000Setup::pre512:
             frameCtrlValue |= 0x01<<18; // TXPSR
             frameCtrlValue |= 0x03<<20; // PE
             break;
-        case pre1024:
+        case DW1000Setup::pre1024:
             frameCtrlValue |= 0x02<<18; // TXPSR
             frameCtrlValue |= 0x00<<20; // PE
             break;
-        case pre1536:
+        case DW1000Setup::pre1536:
             frameCtrlValue |= 0x02<<18; // TXPSR
             frameCtrlValue |= 0x01<<20; // PE
             break;
-        case pre2048:
+        case DW1000Setup::pre2048:
             frameCtrlValue |= 0x02<<18; // TXPSR
             frameCtrlValue |= 0x02<<20; // PE
             break;
-        case pre4096:
+        case DW1000Setup::pre4096:
             frameCtrlValue |= 0x03<<18; // TXPSR
             frameCtrlValue |= 0x00<<20; // PE
             break;
     }
+    writeRegister32(DW1000_TX_FCTRL,0,frameCtrlValue);
 }
 
 void DW1000::setRxDelay(uint16_t ticks)
--- a/DW1000.h	Thu Apr 07 14:31:28 2016 +0000
+++ b/DW1000.h	Thu Apr 07 16:25:31 2016 +0000
@@ -167,8 +167,137 @@
 */
 
 
+/** Class for holding DW1000 config options
+*
+*/
+class DW1000Setup
+{
+public:
+
+/// Constructor - default settings are close to hardware defaults.
+    DW1000Setup() {
+        channel = 5;
+        prf =prf16MHz;
+        dataRate = kbps850;
+        sfd = standard;
+        preamble = pre128;
+        preambleCode = 3;
+        enableSmartPower = true;
+    }
+
+/// enum for PRF options
+    enum prf_e {prf16MHz,prf64MHz};
+
+/// enum for data rate options    
+    enum dataRate_e {kbps110,kbps850,kbps6800};
+    
+/// enum for SFD options    
+    enum sfd_e {standard, decaWave, user};
+    
+/// enum for preamble length options    
+    enum preamble_e { pre64, pre128, pre256, pre512, pre1024, pre1536, pre2048, pre4096};
+
+/** Set the PRF
+* @return true if a valid option
+*/
+    bool setPRF(enum prf_e newSetting) {
+        prf = newSetting;
+        return true;
+    };
+
+/** Set the Channel
+* @return true if a valid option
+*/
+    bool setChannel(unsigned char newChannel) {
+        if ((channel > 0) && ((channel <= 5) || (channel == 7))) {
+            channel = newChannel;
+            return true;
+        }
+        return false;
+    };
+/** Set the SFD
+* @return true if a valid option
+*/
+    bool setSfd(enum sfd_e newSetting) {
+        sfd = newSetting;
+        return true;
+    };
+/** Set the Preamble length
+* @return true if a valid option
+*/
+    bool setPreambleLength(enum preamble_e newSetting) {
+        preamble = newSetting;
+        return true;
+    };
+/** Set the Data rate
+* @return true if a valid option
+*/
+    bool setDataRate(enum dataRate_e newSetting)  {
+        dataRate = newSetting;
+        return true;
+    };
+/** Set the Preamble code
+* @return true if a valid option
+*
+* note - not all codes are valid for all channels. Set the channel first.
+* TODO - enforce code restrictions
+*/
+    bool setPreambleCode(unsigned char newCode) {
+        if ((newCode > 0) && (newCode <= 24)) {
+            preambleCode = newCode;
+            return true;
+        }
+        return false;
+    };
+/** Set the smartpower state
+* @return true if a valid option
+*
+* only takes effect at 6.8Mb/s
+*/
+    bool setSmartPower(bool enable) {
+        enableSmartPower = enable;
+        return true;
+    };
+
+/** Get the current channel
+* @return the channel number
+*/
+    unsigned char getChannel() {
+        return channel;
+    };
+    enum prf_e getPRF() {
+        return prf;
+    };
+    enum dataRate_e getDataRate() {
+        return dataRate;
+    };
+    
+    enum sfd_e getSfd() {return sfd;};
+    enum preamble_e getPreambleLength() {
+        return preamble;
+    };
+    unsigned char getPreambleCode() {
+        return preambleCode;
+    };
+    bool getSmartPower() {
+        return  enableSmartPower;
+    };
+
+private:
+    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;
+};
+
+
 typedef enum {minPacketSize, tunedDefault, user110k} UWBMode;
 
+/** A DW1000 driver
+*/
 class DW1000
 {
 public:
@@ -215,6 +344,15 @@
     uint32_t readOTP (uint16_t word_address);
     bool writeOTP(uint16_t word_address,uint32_t data);                                          // program a value in the OTP. It is recommended to reset afterwards.
 
+    /** Get setup description
+    *
+    * @param buffer Data buffer to place description in
+    * @param len Length of data buffer
+    *
+    * Places a text string describing the current setup into the suppled buffer.
+    */
+    void getSetup(char *buffer, int len);
+
 protected:
     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
@@ -237,7 +375,7 @@
 
     void setupRadio();
 
-   // system register setup functions
+    // system register setup functions
     void setupAGC();
     void setupRxConfig();
     void setupLDE();
@@ -249,23 +387,10 @@
     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;
+    DW1000Setup systemConfig;