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

Dependencies:   BurstSPI

Revision:
3:1459d2aa6b97
Parent:
1:dcbd071f38d5
Child:
4:5f1025df5530
--- 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)
 {