commit 69a601a511eccc23b9ebcde220039fc3b69e7edb
Author: Cung Sang <csang@techfak.uni-bielefeld.de>
Date:   Thu Feb 7 16:09:07 2019 +0100

    Introduced DW1000 v1 driver

diff --git a/include/DW1000/alld_DW1000.h b/include/DW1000/alld_DW1000.h
index 0c3dfa0..a0e7f5a 100644
--- a/include/DW1000/alld_DW1000.h
+++ b/include/DW1000/alld_DW1000.h
@@ -30,10 +30,21 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #if defined(AMIROLLD_CFG_DW1000)
 
-#error "DW1000 LLD implementation is not ready yet."
+#if (AMIROLLD_CFG_DW1000 == 1)
+    #include "v1/alld_dw1000_v1.h"
+    #include "v1/alld_dw1000_regs_v1.h"
+    #include "v1/deca_instance_v1.h"
+#elif (AMIROLLD_CFG_DW1000 == 0)
+    #error "DW1000 LLD implementation for v0 is not ready yet."
+#else
+    #error "invalid value assigned to AMIROLLD_CFG_DW1000 in alldconf.h"
+
+#endif /* defined(AMIROLLD_CFG_DW1000) == 1 */
 
 #endif /* defined(AMIROLLD_CFG_DW1000) */
 
+
 #endif /* AMIROLLD_DW1000_H */
 
 /** @} */
+
diff --git a/include/DW1000/v1/alld_dw1000_regs_v1.h b/include/DW1000/v1/alld_dw1000_regs_v1.h
new file mode 100755
index 0000000..ae5c379
--- /dev/null
+++ b/include/DW1000/v1/alld_dw1000_regs_v1.h
@@ -0,0 +1,1365 @@
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @file    deca_regs.h
+ * @brief   DW1000 Register Definitions
+ *          This file supports assembler and C development for DW1000 enabled devices
+ *
+ * @attention
+ *
+ * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland.
+ *
+ * All rights reserved.
+ *
+ */
+
+#ifndef __DECA_REGS_V1_H
+#define DECA_REGS_V1_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <amiro-lld.h>
+#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register DEV_ID
+**/
+#define DEV_ID_ID               0x00            /* Device ID register, includes revision info (0xDECA0130) */
+#define DEV_ID_LEN              (4)
+/* mask and shift */
+#define DEV_ID_REV_MASK         0x0000000FUL    /* Revision */
+#define DEV_ID_VER_MASK         0x000000F0UL    /* Version */
+#define DEV_ID_MODEL_MASK       0x0000FF00UL    /* The MODEL identifies the device. The DW1000 is device type 0x01 */
+#define DEV_ID_RIDTAG_MASK      0xFFFF0000UL    /* Register Identification Tag 0XDECA */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register EUI_64
+**/
+#define EUI_64_ID               0x01            /* IEEE Extended Unique Identifier (63:0) */
+#define EUI_64_OFFSET           0x00
+#define EUI_64_LEN              (8)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register PANADR
+**/
+#define PANADR_ID               0x03            /* PAN ID (31:16) and Short Address (15:0) */
+#define PANADR_LEN              (4)
+/*mask and shift */
+#define PANADR_SHORT_ADDR_OFFSET 0              /* In bytes */
+#define PANADR_SHORT_ADDR_MASK  0x0000FFFFUL    /* Short Address */
+#define PANADR_PAN_ID_OFFSET     2              /* In bytes */
+#define PANADR_PAN_ID_MASK      0xFFFF00F0UL    /* PAN Identifier */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register 0x05
+**/
+#define REG_05_ID_RESERVED      0x05
+
+/****************************************************************************//**
+ * @brief Bit definitions for register SYS_CFG
+**/
+#define SYS_CFG_ID              0x04            /* System Configuration (31:0) */
+#define SYS_CFG_LEN             (4)
+/*mask and shift */
+#define SYS_CFG_MASK            0xF047FFFFUL    /* access mask to SYS_CFG_ID */
+#define SYS_CFG_FF_ALL_EN       0x000001FEUL    /* Frame filtering options all frames allowed */
+/*offset 0 */
+#define SYS_CFG_FFE             0x00000001UL    /* Frame Filtering Enable. This bit enables the frame filtering functionality */
+#define SYS_CFG_FFBC            0x00000002UL    /* Frame Filtering Behave as a Co-ordinator */
+#define SYS_CFG_FFAB            0x00000004UL    /* Frame Filtering Allow Beacon frame reception */
+#define SYS_CFG_FFAD            0x00000008UL    /* Frame Filtering Allow Data frame reception */
+#define SYS_CFG_FFAA            0x00000010UL    /* Frame Filtering Allow Acknowledgment frame reception */
+#define SYS_CFG_FFAM            0x00000020UL    /* Frame Filtering Allow MAC command frame reception */
+#define SYS_CFG_FFAR            0x00000040UL    /* Frame Filtering Allow Reserved frame types */
+#define SYS_CFG_FFA4            0x00000080UL    /* Frame Filtering Allow frames with frame type field of 4, (binary 100) */
+/*offset 8 */
+#define SYS_CFG_FFA5            0x00000100UL    /* Frame Filtering Allow frames with frame type field of 5, (binary 101) */
+#define SYS_CFG_HIRQ_POL        0x00000200UL    /* Host interrupt polarity */
+#define SYS_CFG_SPI_EDGE        0x00000400UL    /* SPI data launch edge */
+#define SYS_CFG_DIS_FCE         0x00000800UL    /* Disable frame check error handling */
+#define SYS_CFG_DIS_DRXB        0x00001000UL    /* Disable Double RX Buffer */
+#define SYS_CFG_DIS_PHE         0x00002000UL    /* Disable receiver abort on PHR error */
+#define SYS_CFG_DIS_RSDE        0x00004000UL    /* Disable Receiver Abort on RSD error */
+#define SYS_CFG_FCS_INIT2F      0x00008000UL    /* initial seed value for the FCS generation and checking function */
+/*offset 16 */
+#define SYS_CFG_PHR_MODE_SHFT   16
+#define SYS_CFG_PHR_MODE_00     0x00000000UL    /* Standard Frame mode */
+#define SYS_CFG_PHR_MODE_11     0x00030000UL    /* Long Frames mode */
+#define SYS_CFG_DIS_STXP        0x00040000UL    /* Disable Smart TX Power control */
+#define SYS_CFG_RXM110K         0x00400000UL    /* Receiver Mode 110 kbps data rate */
+/*offset 24 */
+#define SYS_CFG_RXWTOE          0x10000000UL    /* Receive Wait Timeout Enable. */
+#define SYS_CFG_RXAUTR          0x20000000UL    /* Receiver Auto-Re-enable. This bit is used to cause the receiver to re-enable automatically */
+#define SYS_CFG_AUTOACK         0x40000000UL    /* Automatic Acknowledgement Enable */
+#define SYS_CFG_AACKPEND        0x80000000UL    /* Automatic Acknowledgement Pending bit control */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register SYS_TIME
+**/
+#define SYS_TIME_ID             0x06            /* System Time Counter (40-bit) */
+#define SYS_TIME_OFFSET         0x00
+#define SYS_TIME_LEN            (5)             /* Note 40 bit register */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register  0x07
+**/
+#define REG_07_ID_RESERVED      0x07
+
+/****************************************************************************//**
+ * @brief Bit definitions for register TX_FCTRL
+**/
+#define TX_FCTRL_ID             0x08            /* Transmit Frame Control */
+#define TX_FCTRL_LEN            (5)             /* Note 40 bit register */
+/*masks (low 32 bit) */
+#define TX_FCTRL_TFLEN_MASK     0x0000007FUL    /* bit mask to access Transmit Frame Length */
+#define TX_FCTRL_TFLE_MASK      0x00000380UL    /* bit mask to access Transmit Frame Length Extension */
+#define TX_FCTRL_FLE_MASK       0x000003FFUL    /* bit mask to access Frame Length field */
+#define TX_FCTRL_TXBR_MASK      0x00006000UL    /* bit mask to access Transmit Bit Rate */
+#define TX_FCTRL_TXPRF_MASK     0x00030000UL    /* bit mask to access Transmit Pulse Repetition Frequency */
+#define TX_FCTRL_TXPSR_MASK     0x000C0000UL    /* bit mask to access Transmit Preamble Symbol Repetitions (PSR). */
+#define TX_FCTRL_PE_MASK        0x00300000UL    /* bit mask to access Preamble Extension */
+#define TX_FCTRL_TXPSR_PE_MASK  0x003C0000UL    /* bit mask to access Transmit Preamble Symbol Repetitions (PSR). */
+#define TX_FCTRL_SAFE_MASK_32   0xFFFFE3FFUL    /* FSCTRL has fields which should always be writen zero */
+/*offset 0 */
+/*offset 8 */
+#define TX_FCTRL_TXBR_110k      0x00000000UL    /* Transmit Bit Rate = 110k */
+#define TX_FCTRL_TXBR_850k      0x00002000UL    /* Transmit Bit Rate = 850k */
+#define TX_FCTRL_TXBR_6M        0x00004000UL    /* Transmit Bit Rate = 6.8M */
+#define TX_FCTRL_TXBR_SHFT      (13)            /* shift to access Data Rate field */
+#define TX_FCTRL_TR             0x00008000UL    /* Transmit Ranging enable */
+#define TX_FCTRL_TR_SHFT        (15)            /* shift to access Ranging bit */
+/*offset 16 */
+#define TX_FCTRL_TXPRF_SHFT     (16)            /* shift to access Pulse Repetition Frequency field */
+#define TX_FCTRL_TXPRF_4M       0x00000000UL    /* Transmit Pulse Repetition Frequency = 4 Mhz */
+#define TX_FCTRL_TXPRF_16M      0x00010000UL    /* Transmit Pulse Repetition Frequency = 16 Mhz */
+#define TX_FCTRL_TXPRF_64M      0x00020000UL    /* Transmit Pulse Repetition Frequency = 64 Mhz */
+#define TX_FCTRL_TXPSR_SHFT     (18)            /* shift to access Preamble Symbol Repetitions field */
+#define TX_FCTRL_PE_SHFT        (20)            /* shift to access Preamble length Extension to allow specification of non-standard values */
+#define TX_FCTRL_TXPSR_PE_16    0x00000000UL    /* bit mask to access Preamble Extension = 16 */
+#define TX_FCTRL_TXPSR_PE_64    0x00040000UL    /* bit mask to access Preamble Extension = 64 */
+#define TX_FCTRL_TXPSR_PE_128   0x00140000UL    /* bit mask to access Preamble Extension = 128 */
+#define TX_FCTRL_TXPSR_PE_256   0x00240000UL    /* bit mask to access Preamble Extension = 256 */
+#define TX_FCTRL_TXPSR_PE_512   0x00340000UL    /* bit mask to access Preamble Extension = 512 */
+#define TX_FCTRL_TXPSR_PE_1024  0x00080000UL    /* bit mask to access Preamble Extension = 1024 */
+#define TX_FCTRL_TXPSR_PE_1536  0x00180000UL    /* bit mask to access Preamble Extension = 1536 */
+#define TX_FCTRL_TXPSR_PE_2048  0x00280000UL    /* bit mask to access Preamble Extension = 2048 */
+#define TX_FCTRL_TXPSR_PE_4096  0x000C0000UL    /* bit mask to access Preamble Extension = 4096 */
+/*offset 22 */
+#define TX_FCTRL_TXBOFFS_SHFT   (22)            /* Shift to access transmit buffer index offset */
+#define TX_FCTRL_TXBOFFS_MASK   0xFFC00000UL    /* bit mask to access Transmit buffer index offset 10-bit field */
+/*offset 32 */
+#define TX_FCTRL_IFSDELAY_MASK  0xFF00000000ULL /* bit mask to access Inter-Frame Spacing field */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register TX_BUFFER
+**/
+#define TX_BUFFER_ID            0x09            /* Transmit Data Buffer */
+#define TX_BUFFER_LEN           (1024)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register  DX_TIME
+**/
+#define DX_TIME_ID              0x0A            /* Delayed Send or Receive Time (40-bit) */
+#define DX_TIME_LEN             (5)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register 0x08
+**/
+#define REG_0B_ID_RESERVED      0x0B
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_FWTO
+**/
+#define RX_FWTO_ID              0x0C            /* Receive Frame Wait Timeout Period */
+#define RX_FWTO_OFFSET          0x00
+#define RX_FWTO_LEN             (2)             /* doc bug*/
+/*mask and shift */
+#define RX_FWTO_MASK            0xFFFF
+
+/****************************************************************************//**
+ * @brief Bit definitions for register SYS_CTRL
+**/
+#define SYS_CTRL_ID             0x0D            /* System Control Register */
+#define SYS_CTRL_OFFSET         0x00
+#define SYS_CTRL_LEN            (4)
+/*masks */
+#define SYS_CTRL_MASK_32        0x010003CFUL    /* System Control Register access mask (all unused fields should always be writen as zero) */
+/*offset 0 */
+#define SYS_CTRL_SFCST          0x00000001UL    /* Suppress Auto-FCS Transmission (on this frame) */
+#define SYS_CTRL_TXSTRT         0x00000002UL    /* Start Transmitting Now */
+#define SYS_CTRL_TXDLYS         0x00000004UL    /* Transmitter Delayed Sending (initiates sending when SYS_TIME == TXD_TIME */
+#define SYS_CTRL_CANSFCS        0x00000008UL    /* Cancel Suppression of auto-FCS transmission (on the current frame) */
+#define SYS_CTRL_TRXOFF         0x00000040UL    /* Transceiver Off. Force Transciever OFF abort TX or RX immediately */
+#define SYS_CTRL_WAIT4RESP      0x00000080UL    /* Wait for Response */
+/*offset 8 */
+#define SYS_CTRL_RXENAB         0x00000100UL    /* Enable Receiver Now */
+#define SYS_CTRL_RXDLYE         0x00000200UL    /* Receiver Delayed Enable (Enables Receiver when SY_TIME[0x??] == RXD_TIME[0x??] CHECK comment*/
+/*offset 16 */
+/*offset 24 */
+#define SYS_CTRL_HSRBTOGGLE     0x01000000UL    /* Host side receiver buffer pointer toggle - toggles 0/1 host side data set pointer */
+#define SYS_CTRL_HRBT           (SYS_CTRL_HSRBTOGGLE)
+#define SYS_CTRL_HRBT_OFFSET    (3)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register  SYS_MASK
+**/
+#define SYS_MASK_ID             0x0E            /* System Event Mask Register */
+#define SYS_MASK_LEN            (4)
+/*masks */
+#define SYS_MASK_MASK_32        0x3FF7FFFEUL    /* System Event Mask Register access mask (all unused fields should always be writen as zero) */
+/*offset 0 */
+#define SYS_MASK_MCPLOCK        0x00000002UL    /* Mask clock PLL lock event    */
+#define SYS_MASK_MESYNCR        0x00000004UL    /* Mask clock PLL lock event    */
+#define SYS_MASK_MAAT           0x00000008UL    /* Mask automatic acknowledge trigger event */
+#define SYS_MASK_MTXFRB         0x00000010UL    /* Mask transmit frame begins event */
+#define SYS_MASK_MTXPRS         0x00000020UL    /* Mask transmit preamble sent event    */
+#define SYS_MASK_MTXPHS         0x00000040UL    /* Mask transmit PHY Header Sent event  */
+#define SYS_MASK_MTXFRS         0x00000080UL    /* Mask transmit frame sent event   */
+/*offset 8 */
+#define SYS_MASK_MRXPRD         0x00000100UL    /* Mask receiver preamble detected event    */
+#define SYS_MASK_MRXSFDD        0x00000200UL    /* Mask receiver SFD detected event */
+#define SYS_MASK_MLDEDONE       0x00000400UL    /* Mask LDE processing done event   */
+#define SYS_MASK_MRXPHD         0x00000800UL    /* Mask receiver PHY header detect event    */
+#define SYS_MASK_MRXPHE         0x00001000UL    /* Mask receiver PHY header error event */
+#define SYS_MASK_MRXDFR         0x00002000UL    /* Mask receiver data frame ready event */
+#define SYS_MASK_MRXFCG         0x00004000UL    /* Mask receiver FCS good event */
+#define SYS_MASK_MRXFCE         0x00008000UL    /* Mask receiver FCS error event    */
+/*offset 16 */
+#define SYS_MASK_MRXRFSL        0x00010000UL    /* Mask receiver Reed Solomon Frame Sync Loss event */
+#define SYS_MASK_MRXRFTO        0x00020000UL    /* Mask Receive Frame Wait Timeout event    */
+#define SYS_MASK_MLDEERR        0x00040000UL    /* Mask leading edge detection processing error event   */
+#define SYS_MASK_MRXOVRR        0x00100000UL    /* Mask Receiver Overrun event  */
+#define SYS_MASK_MRXPTO         0x00200000UL    /* Mask Preamble detection timeout event    */
+#define SYS_MASK_MGPIOIRQ       0x00400000UL    /* Mask GPIO interrupt event    */
+#define SYS_MASK_MSLP2INIT      0x00800000UL    /* Mask SLEEP to INIT event */
+/*offset 24*/
+#define SYS_MASK_MRFPLLLL       0x01000000UL    /* Mask RF PLL Loosing Lock warning event   */
+#define SYS_MASK_MCPLLLL        0x02000000UL    /* Mask Clock PLL Loosing Lock warning event    */
+#define SYS_MASK_MRXSFDTO       0x04000000UL    /* Mask Receive SFD timeout event   */
+#define SYS_MASK_MHPDWARN       0x08000000UL    /* Mask Half Period Delay Warning event */
+#define SYS_MASK_MTXBERR        0x10000000UL    /* Mask Transmit Buffer Error event */
+#define SYS_MASK_MAFFREJ        0x20000000UL    /* Mask Automatic Frame Filtering rejection event   */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register SYS_STATUS
+**/
+#define SYS_STATUS_ID           0x0F            /* System event Status Register */
+#define SYS_STATUS_OFFSET       0x00
+#define SYS_STATUS_LEN          (5)             /* Note 40 bit register */
+/*masks */
+#define SYS_STATUS_MASK_32      0xFFF7FFFFUL    /* System event Status Register access mask (all unused fields should always be writen as zero) */
+/*offset 0 */
+#define SYS_STATUS_IRQS         0x00000001UL    /* Interrupt Request Status READ ONLY */
+#define SYS_STATUS_CPLOCK       0x00000002UL    /* Clock PLL Lock */
+#define SYS_STATUS_ESYNCR       0x00000004UL    /* External Sync Clock Reset */
+#define SYS_STATUS_AAT          0x00000008UL    /* Automatic Acknowledge Trigger */
+#define SYS_STATUS_TXFRB        0x00000010UL    /* Transmit Frame Begins */
+#define SYS_STATUS_TXPRS        0x00000020UL    /* Transmit Preamble Sent */
+#define SYS_STATUS_TXPHS        0x00000040UL    /* Transmit PHY Header Sent */
+#define SYS_STATUS_TXFRS        0x00000080UL    /* Transmit Frame Sent: This is set when the transmitter has completed the sending of a frame */
+/*offset 8 */
+#define SYS_STATUS_RXPRD        0x00000100UL    /* Receiver Preamble Detected status */
+#define SYS_STATUS_RXSFDD       0x00000200UL    /* Receiver Start Frame Delimiter Detected. */
+#define SYS_STATUS_LDEDONE      0x00000400UL    /* LDE processing done */
+#define SYS_STATUS_RXPHD        0x00000800UL    /* Receiver PHY Header Detect */
+#define SYS_STATUS_RXPHE        0x00001000UL    /* Receiver PHY Header Error */
+#define SYS_STATUS_RXDFR        0x00002000UL    /* Receiver Data Frame Ready */
+#define SYS_STATUS_RXFCG        0x00004000UL    /* Receiver FCS Good */
+#define SYS_STATUS_RXFCE        0x00008000UL    /* Receiver FCS Error */
+/*offset 16 */
+#define SYS_STATUS_RXRFSL       0x00010000UL    /* Receiver Reed Solomon Frame Sync Loss */
+#define SYS_STATUS_RXRFTO       0x00020000UL    /* Receive Frame Wait Timeout */
+#define SYS_STATUS_LDEERR       0x00040000UL    /* Leading edge detection processing error */
+#define SYS_STATUS_reserved     0x00080000UL    /* bit19 reserved */
+#define SYS_STATUS_RXOVRR       0x00100000UL    /* Receiver Overrun */
+#define SYS_STATUS_RXPTO        0x00200000UL    /* Preamble detection timeout */
+#define SYS_STATUS_GPIOIRQ      0x00400000UL    /* GPIO interrupt */
+#define SYS_STATUS_SLP2INIT     0x00800000UL    /* SLEEP to INIT */
+/*offset 24 */
+#define SYS_STATUS_RFPLL_LL     0x01000000UL    /* RF PLL Losing Lock */
+#define SYS_STATUS_CLKPLL_LL    0x02000000UL    /* Clock PLL Losing Lock */
+#define SYS_STATUS_RXSFDTO      0x04000000UL    /* Receive SFD timeout */
+#define SYS_STATUS_HPDWARN      0x08000000UL    /* Half Period Delay Warning */
+#define SYS_STATUS_TXBERR       0x10000000UL    /* Transmit Buffer Error */
+#define SYS_STATUS_AFFREJ       0x20000000UL    /* Automatic Frame Filtering rejection */
+#define SYS_STATUS_HSRBP        0x40000000UL    /* Host Side Receive Buffer Pointer */
+#define SYS_STATUS_ICRBP        0x80000000UL    /* IC side Receive Buffer Pointer READ ONLY */
+/*offset 32 */
+#define SYS_STATUS_RXRSCS       0x0100000000ULL /* Receiver Reed-Solomon Correction Status */
+#define SYS_STATUS_RXPREJ       0x0200000000ULL /* Receiver Preamble Rejection */
+#define SYS_STATUS_TXPUTE       0x0400000000ULL /* Transmit power up time error */
+
+#define SYS_STATUS_TXERR        (0x0408)        /* These bits are the 16 high bits of status register TXPUTE and HPDWARN flags */
+
+/* All RX events after a correct packet reception mask. */
+#define SYS_STATUS_ALL_RX_GOOD (SYS_STATUS_RXDFR | SYS_STATUS_RXFCG | SYS_STATUS_RXPRD | \
+                                SYS_STATUS_RXSFDD | SYS_STATUS_RXPHD | SYS_STATUS_LDEDONE)
+
+/* All double buffer events mask. */
+#define SYS_STATUS_ALL_DBLBUFF (SYS_STATUS_RXDFR | SYS_STATUS_RXFCG)
+
+/* All RX errors mask. */
+#define SYS_STATUS_ALL_RX_ERR  (SYS_STATUS_RXPHE | SYS_STATUS_RXFCE | SYS_STATUS_RXRFSL | SYS_STATUS_RXSFDTO \
+                                | SYS_STATUS_AFFREJ | SYS_STATUS_LDEERR)
+
+/* User defined RX timeouts (frame wait timeout and preamble detect timeout) mask. */
+#define SYS_STATUS_ALL_RX_TO   (SYS_STATUS_RXRFTO | SYS_STATUS_RXPTO)
+
+/* All TX events mask. */
+#define SYS_STATUS_ALL_TX      (SYS_STATUS_AAT | SYS_STATUS_TXFRB | SYS_STATUS_TXPRS | \
+                                SYS_STATUS_TXPHS | SYS_STATUS_TXFRS )
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_FINFO
+**/
+#define RX_FINFO_ID             0x10            /* RX Frame Information (in double buffer set) */
+#define RX_FINFO_OFFSET         0x00
+#define RX_FINFO_LEN            (4)
+/*mask and shift */
+#define RX_FINFO_MASK_32        0xFFFFFBFFUL    /* System event Status Register access mask (all unused fields should always be writen as zero) */
+#define RX_FINFO_RXFLEN_MASK    0x0000007FUL    /* Receive Frame Length (0 to 127) */
+#define RX_FINFO_RXFLE_MASK     0x00000380UL    /* Receive Frame Length Extension (0 to 7)<<7 */
+#define RX_FINFO_RXFL_MASK_1023 0x000003FFUL    /* Receive Frame Length Extension (0 to 1023) */
+
+#define RX_FINFO_RXNSPL_MASK    0x00001800UL    /* Receive Non-Standard Preamble Length */
+#define RX_FINFO_RXPSR_MASK     0x000C0000UL    /* RX Preamble Repetition. 00 = 16 symbols, 01 = 64 symbols, 10 = 1024 symbols, 11 = 4096 symbols */
+
+#define RX_FINFO_RXPEL_MASK     0x000C1800UL    /* Receive Preamble Length = RXPSR+RXNSPL */
+#define RX_FINFO_RXPEL_64       0x00040000UL    /* Receive Preamble length = 64 */
+#define RX_FINFO_RXPEL_128      0x00040800UL    /* Receive Preamble length = 128 */
+#define RX_FINFO_RXPEL_256      0x00041000UL    /* Receive Preamble length = 256 */
+#define RX_FINFO_RXPEL_512      0x00041800UL    /* Receive Preamble length = 512 */
+#define RX_FINFO_RXPEL_1024     0x00080000UL    /* Receive Preamble length = 1024 */
+#define RX_FINFO_RXPEL_1536     0x00080800UL    /* Receive Preamble length = 1536 */
+#define RX_FINFO_RXPEL_2048     0x00081000UL    /* Receive Preamble length = 2048 */
+#define RX_FINFO_RXPEL_4096     0x000C0000UL    /* Receive Preamble length = 4096 */
+
+#define RX_FINFO_RXBR_MASK      0x00006000UL    /* Receive Bit Rate report. This field reports the received bit rate */
+#define RX_FINFO_RXBR_110k      0x00000000UL    /* Received bit rate = 110 kbps */
+#define RX_FINFO_RXBR_850k      0x00002000UL    /* Received bit rate = 850 kbps */
+#define RX_FINFO_RXBR_6M        0x00004000UL    /* Received bit rate = 6.8 Mbps */
+#define RX_FINFO_RXBR_SHIFT     (13)
+
+#define RX_FINFO_RNG            0x00008000UL    /* Receiver Ranging. Ranging bit in the received PHY header identifying the frame as a ranging packet. */
+#define RX_FINFO_RNG_SHIFT      (15)
+
+#define RX_FINFO_RXPRF_MASK     0x00030000UL    /* RX Pulse Repetition Rate report */
+#define RX_FINFO_RXPRF_16M      0x00010000UL    /* PRF being employed in the receiver = 16M */
+#define RX_FINFO_RXPRF_64M      0x00020000UL    /* PRF being employed in the receiver = 64M */
+#define RX_FINFO_RXPRF_SHIFT    (16)
+
+#define RX_FINFO_RXPACC_MASK    0xFFF00000UL    /* Preamble Accumulation Count */
+#define RX_FINFO_RXPACC_SHIFT   (20)
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_BUFFER
+**/
+#define RX_BUFFER_ID            0x11            /* Receive Data Buffer (in double buffer set) */
+#define RX_BUFFER_LEN           (1024)
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_FQUAL
+**/
+#define RX_FQUAL_ID             0x12            /* Rx Frame Quality information (in double buffer set) */
+#define RX_FQUAL_LEN            (8)             /* note 64 bit register*/
+/*mask and shift */
+/*offset 0 */
+#define RX_EQUAL_STD_NOISE_MASK 0x0000FFFFULL   /* Standard Deviation of Noise */
+#define RX_EQUAL_STD_NOISE_SHIFT (0)
+#define STD_NOISE_MASK          RX_EQUAL_STD_NOISE_MASK
+#define STD_NOISE_SHIFT         RX_EQUAL_STD_NOISE_SHIFT
+/*offset 16 */
+#define RX_EQUAL_FP_AMPL2_MASK  0xFFFF0000ULL   /* First Path Amplitude point 2 */
+#define RX_EQUAL_FP_AMPL2_SHIFT (16)
+#define FP_AMPL2_MASK           RX_EQUAL_FP_AMPL2_MASK
+#define FP_AMPL2_SHIFT          RX_EQUAL_FP_AMPL2_SHIFT
+/*offset 32*/
+#define RX_EQUAL_PP_AMPL3_MASK  0x0000FFFF00000000ULL   /* First Path Amplitude point 3 */
+#define RX_EQUAL_PP_AMPL3_SHIFT (32)
+#define PP_AMPL3_MASK           RX_EQUAL_PP_AMPL3_MASK
+#define PP_AMPL3_SHIFT          RX_EQUAL_PP_AMPL3_SHIFT
+/*offset 48*/
+#define RX_EQUAL_CIR_MXG_MASK   0xFFFF000000000000ULL   /* Channel Impulse Response Max Growth */
+#define RX_EQUAL_CIR_MXG_SHIFT  (48)
+#define CIR_MXG_MASK            RX_EQUAL_CIR_MXG_MASK
+#define CIR_MXG_SHIFT           RX_EQUAL_CIR_MXG_SHIFT
+
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_TTCKI
+ *      The value here is the interval over which the timing offset reported
+ *      in the RXTOFS field of Register file: 0x14 RX_TTCKO is measured.
+ *      The clock offset is calculated by dividing RXTTCKI by RXTOFS.
+ *      The value in RXTTCKI will take just one of two values depending on the PRF: 0x01F00000 @ 16 MHz PRF,
+ *      and 0x01FC0000 @ 64 MHz PRF.
+**/
+#define RX_TTCKI_ID             0x13            /* Receiver Time Tracking Interval (in double buffer set) */
+#define RX_TTCKI_LEN            (4)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_TTCKO
+**/
+#define RX_TTCKO_ID             0x14            /* Receiver Time Tracking Offset (in double buffer set) */
+#define RX_TTCKO_LEN            (5)             /* Note 40 bit register */
+/*mask and shift */
+#define RX_TTCKO_MASK_32        0xFF07FFFFUL    /* Receiver Time Tracking Offset access mask (all unused fields should always be writen as zero) */
+/*offset 0 */
+#define RX_TTCKO_RXTOFS_MASK    0x0007FFFFUL    /* RX time tracking offset. This RXTOFS value is a 19-bit signed quantity*/
+/*offset 24 */
+#define RX_TTCKO_RSMPDEL_MASK   0xFF000000UL    /* This 8-bit field reports an internal re-sampler delay value */
+/*offset 32 */
+#define RX_TTCKO_RCPHASE_MASK   0x7F0000000000ULL   /* This 7-bit field reports the receive carrier phase adjustment at time the ranging timestamp is made. */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_TIME
+**/
+#define RX_TIME_ID              0x15            /* Receive Message Time of Arrival (in double buffer set) */
+#define RX_TIME_LLEN            (14)
+#define RX_TIME_RX_STAMP_LEN    (5)             /* read only 5 bytes (the adjusted timestamp (40:0)) */
+#define RX_STAMP_LEN            RX_TIME_RX_STAMP_LEN
+/*mask and shift */
+#define RX_TIME_RX_STAMP_OFFSET  (0) /* byte 0..4 40 bit Reports the fully adjusted time of reception. */
+#define RX_TIME_FP_INDEX_OFFSET  (5)    /* byte 5..6 16 bit First path index. */
+#define RX_TIME_FP_AMPL1_OFFSET  (7)    /* byte 7..8 16 bit First Path Amplitude point 1 */   /* doc bug */
+#define RX_TIME_FP_RAWST_OFFSET  (9)    /* byte 9..13 40 bit Raw Timestamp for the frame */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register
+**/
+#define REG_16_ID_RESERVED      0x16
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register
+**/
+#define TX_TIME_ID              0x17            /* Transmit Message Time of Sending */
+#define TX_TIME_LLEN            (10)
+#define TX_TIME_TX_STAMP_LEN    (5)             /* 40-bits = 5 bytes */
+#define TX_STAMP_LEN            TX_TIME_TX_STAMP_LEN
+/*mask and shift */
+#define TX_TIME_TX_STAMP_OFFSET  (0) /* byte 0..4 40 bit Reports the fully adjusted time of transmission */
+#define TX_TIME_TX_RAWST_OFFSET  (5) /* byte 5..9 40 bit Raw Timestamp for the frame */
+
+
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register TX_ANTD
+**/
+#define TX_ANTD_ID              0x18            /* 16-bit Delay from Transmit to Antenna */
+#define TX_ANTD_OFFSET          0x00
+#define TX_ANTD_LEN             (2)
+
+
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register SYS_STATES
+ *        Register map register file 0x19 is reserved
+ *
+**/
+#define SYS_STATE_ID            0x19            /* System State information READ ONLY */
+#define SYS_STATE_LEN           (5)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register ACK_RESP_T
+**/
+/* Acknowledge (31:24 preamble symbol delay before auto ACK is sent) and respose (19:0 - unit 1us) timer */
+#define ACK_RESP_T_ID           0x1A            /* Acknowledgement Time and Response Time */
+#define ACK_RESP_T_LEN          (4)
+/*mask and shift */
+#define ACK_RESP_T_MASK         0xFF0FFFFFUL    /* Acknowledgement Time and Response access mask */
+#define ACK_RESP_T_W4R_TIM_OFFSET 0             /* In bytes */
+#define ACK_RESP_T_W4R_TIM_MASK 0x000FFFFFUL    /* Wait-for-Response turn-around Time 20 bit field */
+#define W4R_TIM_MASK            ACK_RESP_T_W4R_TIM_MASK
+#define ACK_RESP_T_ACK_TIM_OFFSET 3             /* In bytes */
+#define ACK_RESP_T_ACK_TIM_MASK 0xFF000000UL    /* Auto-Acknowledgement turn-around Time */
+#define ACK_TIM_MASK            ACK_RESP_T_ACK_TIM_MASK
+
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register 0x1B 0x1C
+**/
+#define REG_1B_ID_RESERVED      0x1B
+#define REG_1C_ID_RESERVED      0x1C
+
+/****************************************************************************//**
+ * @brief Bit definitions for register RX_SNIFF
+ *        Sniff Mode Configuration or Pulsed Preamble Reception Configuration
+**/
+#define RX_SNIFF_ID             0x1D            /* Sniff Mode Configuration */
+#define RX_SNIFF_OFFSET         0x00
+#define RX_SNIFF_LEN            (4)
+/*mask and shift */
+#define RX_SNIFF_MASK           0x0000FF0FUL    /*  */
+#define RX_SNIFF_SNIFF_ONT_MASK 0x0000000FUL    /* SNIFF Mode ON time. Specified in units of PAC */
+#define SNIFF_ONT_MASK          RX_SNIFF_SNIFF_ONT_MASK
+#define RX_SNIFF_SNIFF_OFFT_MASK 0x0000FF00UL   /* SNIFF Mode OFF time specified in units of approximately 1mkS, or 128 system clock cycles.*/
+#define SNIFF_OFFT_MASK         RX_SNIFF_SNIFF_OFFT_MASK
+
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register TX_POWER
+**/
+#define TX_POWER_ID             0x1E            /* TX Power Control */
+#define TX_POWER_LEN            (4)
+/*mask and shift definition for Smart Transmit Power Control*/
+#define TX_POWER_BOOSTNORM_MASK 0x00000000UL    /* This is the normal power setting used for frames that do not fall */
+#define BOOSTNORM_MASK          TX_POWER_BOOSTNORM_MASK
+#define TX_POWER_BOOSTNORM_SHIFT (0)
+#define TX_POWER_BOOSTP500_MASK 0x00000000UL    /* This value sets the power applied during transmission at the 6.8 Mbps data rate frames that are less than 0.5 ms duration */
+#define BOOSTP500_MASK          TX_POWER_BOOSTP500_MASK
+#define TX_POWER_BOOSTP500_SHIFT (8)
+#define TX_POWER_BOOSTP250_MASK 0x00000000UL    /* This value sets the power applied during transmission at the 6.8 Mbps data rate frames that are less than 0.25 ms duration */
+#define BOOSTP250_MASK          TX_POWER_BOOSTP250_MASK
+#define TX_POWER_BOOSTP250_SHIFT (16)
+#define TX_POWER_BOOSTP125_MASK 0x00000000UL    /* This value sets the power applied during transmission at the 6.8 Mbps data rate frames that are less than 0.125 ms */
+#define BOOSTP125_MASK          TX_POWER_BOOSTP125_MASK
+#define TX_POWER_BOOSTP125_SHIFT (24)
+/*mask and shift definition for Manual Transmit Power Control (DIS_STXP=1 in SYS_CFG)*/
+#define TX_POWER_MAN_DEFAULT    0x0E080222UL
+#define TX_POWER_TXPOWPHR_MASK  0x0000FF00UL    /* This power setting is applied during the transmission of the PHY header (PHR) portion of the frame. */
+#define TX_POWER_TXPOWSD_MASK   0x00FF0000UL    /* This power setting is applied during the transmission of the synchronisation header (SHR) and data portions of the frame. */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register CHAN_CTRL
+**/
+#define CHAN_CTRL_ID            0x1F            /* Channel Control */
+#define CHAN_CTRL_LEN           (4)
+/*mask and shift */
+#define CHAN_CTRL_MASK          0xFFFF00FFUL    /* Channel Control Register access mask */
+#define CHAN_CTRL_TX_CHAN_MASK  0x0000000FUL    /* Supported channels are 1, 2, 3, 4, 5, and 7.*/
+#define CHAN_CTRL_TX_CHAN_SHIFT (0)             /* Bits 0..3        TX channel number 0-15 selection */
+
+#define CHAN_CTRL_RX_CHAN_MASK  0x000000F0UL
+#define CHAN_CTRL_RX_CHAN_SHIFT (4)             /* Bits 4..7        RX channel number 0-15 selection */
+
+#define CHAN_CTRL_RXFPRF_MASK   0x000C0000UL    /* Bits 18..19      Specify (Force) RX Pulse Repetition Rate: 00 = 4 MHz, 01 = 16 MHz, 10 = 64MHz. */
+#define CHAN_CTRL_RXFPRF_SHIFT  (18)
+/* Specific RXFPRF configuration */
+#define CHAN_CTRL_RXFPRF_4      0x00000000UL    /* Specify (Force) RX Pulse Repetition Rate: 00 = 4 MHz, 01 = 16 MHz, 10 = 64MHz. */
+#define CHAN_CTRL_RXFPRF_16     0x00040000UL    /* Specify (Force) RX Pulse Repetition Rate: 00 = 4 MHz, 01 = 16 MHz, 10 = 64MHz. */
+#define CHAN_CTRL_RXFPRF_64     0x00080000UL    /* Specify (Force) RX Pulse Repetition Rate: 00 = 4 MHz, 01 = 16 MHz, 10 = 64MHz. */
+#define CHAN_CTRL_TX_PCOD_MASK  0x07C00000UL    /* Bits 22..26      TX Preamble Code selection, 1 to 24. */
+#define CHAN_CTRL_TX_PCOD_SHIFT (22)
+#define CHAN_CTRL_RX_PCOD_MASK  0xF8000000UL    /* Bits 27..31      RX Preamble Code selection, 1 to 24. */
+#define CHAN_CTRL_RX_PCOD_SHIFT (27)
+/*offset 16 */
+#define CHAN_CTRL_DWSFD         0x00020000UL    /* Bit 17 This bit enables a non-standard DecaWave proprietary SFD sequence. */
+#define CHAN_CTRL_DWSFD_SHIFT   (17)
+#define CHAN_CTRL_TNSSFD        0x00100000UL    /* Bit 20 Non-standard SFD in the transmitter */
+#define CHAN_CTRL_TNSSFD_SHIFT  (20)
+#define CHAN_CTRL_RNSSFD        0x00200000UL    /* Bit 21 Non-standard SFD in the receiver */
+#define CHAN_CTRL_RNSSFD_SHIFT  (21)
+
+
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register 0x20
+**/
+#define REG_20_ID_RESERVED      0x20
+
+/****************************************************************************//**
+ * @brief Bit definitions for register USR_SFD
+ *        Please read User Manual : User defined SFD sequence
+**/
+#define USR_SFD_ID              0x21            /* User-specified short/long TX/RX SFD sequences */
+#define USR_SFD_LEN             (41)
+#define DW_NS_SFD_LEN_110K      64              /* Decawave non-standard SFD length for 110 kbps */
+#define DW_NS_SFD_LEN_850K      16              /* Decawave non-standard SFD length for 850 kbps */
+#define DW_NS_SFD_LEN_6M8       8               /* Decawave non-standard SFD length for 6.8 Mbps */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register
+**/
+#define REG_22_ID_RESERVED      0x22
+
+/****************************************************************************//**
+ * @brief Bit definitions for register AGC_CTRL
+ * Please take care to write to this register as doing so may cause the DW1000 to malfunction
+**/
+#define AGC_CTRL_ID             0x23            /* Automatic Gain Control configuration */
+#define AGC_CTRL_LEN            (32)
+#define AGC_CFG_STS_ID          AGC_CTRL_ID
+/* offset from AGC_CTRL_ID in bytes */
+#define AGC_CTRL1_OFFSET        (0x02)
+#define AGC_CTRL1_LEN           (2)
+#define AGC_CTRL1_MASK          0x0001          /* access mask to AGC configuration and control register */
+#define AGC_CTRL1_DIS_AM        0x0001          /* Disable AGC Measurement. The DIS_AM bit is set by default. */
+/* offset from AGC_CTRL_ID in bytes */
+/* Please take care not to write other values to this register as doing so may cause the DW1000 to malfunction */
+#define AGC_TUNE1_OFFSET        (0x04)
+#define AGC_TUNE1_LEN           (2)
+#define AGC_TUNE1_MASK          0xFFFF          /* It is a 16-bit tuning register for the AGC. */
+#define AGC_TUNE1_16M           0x8870
+#define AGC_TUNE1_64M           0x889B
+/* offset from AGC_CTRL_ID in bytes */
+/* Please take care not to write other values to this register as doing so may cause the DW1000 to malfunction */
+#define AGC_TUNE2_OFFSET        (0x0C)
+#define AGC_TUNE2_LEN           (4)
+#define AGC_TUNE2_MASK          0xFFFFFFFFUL
+#define AGC_TUNE2_VAL           0X2502A907UL
+/* offset from AGC_CTRL_ID in bytes */
+/* Please take care not to write other values to this register as doing so may cause the DW1000 to malfunction */
+#define AGC_TUNE3_OFFSET        (0x12)
+#define AGC_TUNE3_LEN           (2)
+#define AGC_TUNE3_MASK          0xFFFF
+#define AGC_TUNE3_VAL           0X0055
+/* offset from AGC_CTRL_ID in bytes */
+#define AGC_STAT1_OFFSET        (0x1E)
+#define AGC_STAT1_LEN           (3)
+#define AGC_STAT1_MASK          0x0FFFFF
+#define AGC_STAT1_EDG1_MASK     0x0007C0        /* This 5-bit gain value relates to input noise power measurement. */
+#define AGC_STAT1_EDG2_MASK     0x0FF800        /* This 9-bit value relates to the input noise power measurement. */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register EXT_SYNC
+**/
+#define EXT_SYNC_ID             0x24            /* External synchronisation control */
+#define EXT_SYNC_LEN            (12)
+/* offset from EXT_SYNC_ID in bytes */
+#define EC_CTRL_OFFSET          (0x00)
+#define EC_CTRL_LEN             (4)
+#define EC_CTRL_MASK            0x00000FFBUL    /* sub-register 0x00 is the External clock synchronisation counter configuration register */
+#define EC_CTRL_OSTSM           0x00000001UL    /* External transmit synchronisation mode enable */
+#define EC_CTRL_OSRSM           0x00000002UL    /* External receive synchronisation mode enable */
+#define EC_CTRL_PLLLCK          0x04            /* PLL lock detect enable */
+#define EC_CTRL_OSTRM           0x00000800UL    /* External timebase reset mode enable */
+#define EC_CTRL_WAIT_MASK       0x000007F8UL    /* Wait counter used for external transmit synchronisation and external timebase reset */
+/* offset from EXT_SYNC_ID in bytes */
+#define EC_RXTC_OFFSET          (0x04)
+#define EC_RXTC_LEN             (4)
+#define EC_RXTC_MASK            0xFFFFFFFFUL    /* External clock synchronisation counter captured on RMARKER */
+/* offset from EXT_SYNC_ID in bytes */
+#define EC_GOLP                 (0x08)
+#define EC_GOLP_LEN             (4)
+#define EC_GOLP_MASK            0x0000003FUL    /* sub-register 0x08 is the External clock offset to first path 1 GHz counter, EC_GOLP */
+#define EC_GOLP_OFFSET_EXT_MASK 0x0000003FUL    /* This register contains the 1 GHz count from the arrival of the RMARKER and the next edge of the external clock. */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register ACC_MEM
+**/
+#define ACC_MEM_ID              0x25            /* Read access to accumulator data */
+#define ACC_MEM_LEN             (4064)
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register GPIO_CTRL
+**/
+#define GPIO_CTRL_ID            0x26            /* Peripheral register bus 1 access - GPIO control */
+#define GPIO_CTRL_LEN           (44)
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_MODE_OFFSET        0x00            /* sub-register 0x00 is the GPIO Mode Control Register */
+#define GPIO_MODE_LEN           (4)
+#define GPIO_MODE_MASK          0x00FFFFC0UL
+
+#define GPIO_MSGP0_MASK         0x000000C0UL    /* Mode Selection for GPIO0/RXOKLED */
+#define GPIO_MSGP1_MASK         0x00000300UL    /* Mode Selection for GPIO1/SFDLED */
+#define GPIO_MSGP2_MASK         0x00000C00UL    /* Mode Selection for GPIO2/RXLED */
+#define GPIO_MSGP3_MASK         0x00003000UL    /* Mode Selection for GPIO3/TXLED */
+#define GPIO_MSGP4_MASK         0x0000C000UL    /* Mode Selection for GPIO4/EXTPA */
+#define GPIO_MSGP5_MASK         0x00030000UL    /* Mode Selection for GPIO5/EXTTXE */
+#define GPIO_MSGP6_MASK         0x000C0000UL    /* Mode Selection for GPIO6/EXTRXE */
+#define GPIO_MSGP7_MASK         0x00300000UL    /* Mode Selection for SYNC/GPIO7 */
+#define GPIO_MSGP8_MASK         0x00C00000UL    /* Mode Selection for IRQ/GPIO8 */
+
+#define GPIO_PIN2_RXLED         0x00000400UL    /* The pin operates as the RXLED output */
+#define GPIO_PIN3_TXLED         0x00001000UL    /* The pin operates as the TXLED output */
+#define GPIO_PIN4_EXTPA         0x00004000UL    /* The pin operates as the EXTPA output */
+#define GPIO_PIN5_EXTTXE        0x00010000UL    /* The pin operates as the EXTTXE output */
+#define GPIO_PIN6_EXTRXE        0x00040000UL    /* The pin operates as the EXTRXE output */
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_DIR_OFFSET         0x08            /* sub-register 0x08 is the GPIO Direction Control Register */
+#define GPIO_DIR_LEN            (3)
+#define GPIO_DIR_MASK           0x0011FFFFUL
+
+#define GxP0                    0x00000001UL    /* GPIO0 Only changed if the GxM0 mask bit has a value of 1 for the write operation*/
+#define GxP1                    0x00000002UL    /* GPIO1. (See GDP0). */
+#define GxP2                    0x00000004UL    /* GPIO2. (See GDP0). */
+#define GxP3                    0x00000008UL    /* GPIO3. (See GDP0). */
+#define GxP4                    0x00000100UL    /* GPIO4. (See GDP0). */
+#define GxP5                    0x00000200UL    /* GPIO5. (See GDP0). */
+#define GxP6                    0x00000400UL    /* GPIO6. (See GDP0). */
+#define GxP7                    0x00000800UL    /* GPIO7. (See GDP0). */
+#define GxP8                    0x00010000UL    /* GPIO8 */
+
+#define GxM0                    0x00000010UL    /* Mask for GPIO0 */
+#define GxM1                    0x00000020UL    /* Mask for GPIO1. (See GDM0). */
+#define GxM2                    0x00000040UL    /* Mask for GPIO2. (See GDM0). */
+#define GxM3                    0x00000080UL    /* Mask for GPIO3. (See GDM0). */
+#define GxM4                    0x00001000UL    /* Mask for GPIO4. (See GDM0). */
+#define GxM5                    0x00002000UL    /* Mask for GPIO5. (See GDM0). */
+#define GxM6                    0x00004000UL    /* Mask for GPIO6. (See GDM0). */
+#define GxM7                    0x00008000UL    /* Mask for GPIO7. (See GDM0). */
+#define GxM8                    0x00100000UL    /* Mask for GPIO8. (See GDM0). */
+
+#define GDP0    GxP0    /* Direction Selection for GPIO0. 1 = input, 0 = output. Only changed if the GDM0 mask bit has a value of 1 for the write operation*/
+#define GDP1    GxP1    /* Direction Selection for GPIO1. (See GDP0). */
+#define GDP2    GxP2    /* Direction Selection for GPIO2. (See GDP0). */
+#define GDP3    GxP3    /* Direction Selection for GPIO3. (See GDP0). */
+#define GDP4    GxP4    /* Direction Selection for GPIO4. (See GDP0). */
+#define GDP5    GxP5    /* Direction Selection for GPIO5. (See GDP0). */
+#define GDP6    GxP6    /* Direction Selection for GPIO6. (See GDP0). */
+#define GDP7    GxP7    /* Direction Selection for GPIO7. (See GDP0). */
+#define GDP8    GxP8    /* Direction Selection for GPIO8 */
+
+#define GDM0    GxM0    /* Mask for setting the direction of GPIO0 */
+#define GDM1    GxM1    /* Mask for setting the direction of GPIO1. (See GDM0). */
+#define GDM2    GxM2    /* Mask for setting the direction of GPIO2. (See GDM0). */
+#define GDM3    GxM3    /* Mask for setting the direction of GPIO3. (See GDM0). */
+#define GDM4    GxM4    /* Mask for setting the direction of GPIO4. (See GDM0). */
+#define GDM5    GxM5    /* Mask for setting the direction of GPIO5. (See GDM0). */
+#define GDM6    GxM6    /* Mask for setting the direction of GPIO6. (See GDM0). */
+#define GDM7    GxM7    /* Mask for setting the direction of GPIO7. (See GDM0). */
+#define GDM8    GxM8    /* Mask for setting the direction of GPIO8. (See GDM0). */
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_DOUT_OFFSET        0x0C            /* sub-register 0x0C is the GPIO data output register. */
+#define GPIO_DOUT_LEN           (3)
+#define GPIO_DOUT_MASK          GPIO_DIR_MASK
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_IRQE_OFFSET        0x10            /* sub-register 0x10 is the GPIO interrupt enable register */
+#define GPIO_IRQE_LEN           (4)
+#define GPIO_IRQE_MASK          0x000001FFUL
+#define GIRQx0                  0x00000001UL    /* IRQ bit0 */
+#define GIRQx1                  0x00000002UL    /* IRQ bit1 */
+#define GIRQx2                  0x00000004UL    /* IRQ bit2 */
+#define GIRQx3                  0x00000008UL    /* IRQ bit3 */
+#define GIRQx4                  0x00000010UL    /* IRQ bit4 */
+#define GIRQx5                  0x00000020UL    /* IRQ bit5 */
+#define GIRQx6                  0x00000040UL    /* IRQ bit6 */
+#define GIRQx7                  0x00000080UL    /* IRQ bit7 */
+#define GIRQx8                  0x00000100UL    /* IRQ bit8 */
+#define GIRQE0  GIRQx0  /* GPIO IRQ Enable for GPIO0 input. Value 1 = enable, 0 = disable*/
+#define GIRQE1  GIRQx1  /*  */
+#define GIRQE2  GIRQx2  /*  */
+#define GIRQE3  GIRQx3  /*  */
+#define GIRQE4  GIRQx4  /*  */
+#define GIRQE5  GIRQx5  /*  */
+#define GIRQE6  GIRQx6  /*  */
+#define GIRQE7  GIRQx7  /*  */
+#define GIRQE8  GIRQx8  /* Value 1 = enable, 0 = disable */
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_ISEN_OFFSET        0x14    /* sub-register 0x14 is the GPIO interrupt sense selection register */
+#define GPIO_ISEN_LEN           (4)
+#define GPIO_ISEN_MASK          GPIO_IRQE_MASK
+#define GISEN0  GIRQx0  /* GPIO IRQ Sense selection GPIO0 input. Value 0 = High or Rising-Edge, 1 = Low or falling-edge.*/
+#define GISEN1  GIRQx1  /*  */
+#define GISEN2  GIRQx2  /*  */
+#define GISEN3  GIRQx3  /*  */
+#define GISEN4  GIRQx4  /*  */
+#define GISEN5  GIRQx5  /*  */
+#define GISEN6  GIRQx6  /*  */
+#define GISEN7  GIRQx7  /*  */
+#define GISEN8  GIRQx8  /* Value 0 = High or Rising-Edge, 1 = Low or falling-edge */
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_IMODE_OFFSET       0x18    /* sub-register 0x18 is the GPIO interrupt mode selection register */
+#define GPIO_IMODE_LEN          (4)
+#define GPIO_IMODE_MASK         GPIO_IRQE_MASK
+#define GIMOD0  GIRQx0  /* GPIO IRQ Mode selection for GPIO0 input. Value 0 = Level sensitive interrupt. Value 1 = Edge triggered interrupt */
+#define GIMOD1  GIRQx1  /*  */
+#define GIMOD2  GIRQx2  /*  */
+#define GIMOD3  GIRQx3  /*  */
+#define GIMOD4  GIRQx4  /*  */
+#define GIMOD5  GIRQx5  /*  */
+#define GIMOD6  GIRQx6  /*  */
+#define GIMOD7  GIRQx7  /*  */
+#define GIMOD8  GIRQx8  /* Value 0 = Level, 1 = Edge. */
+
+/* offset from EXT_SYNC_ID in bytes */
+#define GPIO_IBES_OFFSET        0x1C    /* sub-register 0x1C is the GPIO interrupt Both Edge selection register */
+#define GPIO_IBES_LEN           (4)
+#define GPIO_IBES_MASK          GPIO_IRQE_MASK  /*  */
+#define GIBES0  GIRQx0  /* GPIO IRQ Both Edge selection for GPIO0 input. Value 0 = GPIO_IMODE register selects the edge. Value 1 = Both edges trigger the interrupt. */
+#define GIBES1  GIRQx1  /*  */
+#define GIBES2  GIRQx2  /*  */
+#define GIBES3  GIRQx3  /*  */
+#define GIBES4  GIRQx4  /*  */
+#define GIBES5  GIRQx5  /*  */
+#define GIBES6  GIRQx6  /*  */
+#define GIBES7  GIRQx7  /*  */
+#define GIBES8  GIRQx8  /* Value 0 = use GPIO_IMODE, 1 = Both Edges */
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_ICLR_OFFSET        0x20    /* sub-register 0x20 is the GPIO interrupt clear register */
+#define GPIO_ICLR_LEN           (4)
+#define GPIO_ICLR_MASK          GPIO_IRQE_MASK  /*  */
+#define GICLR0  GIRQx0  /* GPIO IRQ latch clear for GPIO0 input. Write 1 to clear the GPIO0 interrupt latch. Writing 0 has no effect. Reading returns zero */
+#define GICLR1  GIRQx1  /*  */
+#define GICLR2  GIRQx2  /*  */
+#define GICLR3  GIRQx3  /*  */
+#define GICLR4  GIRQx4  /*  */
+#define GICLR5  GIRQx5  /*  */
+#define GICLR6  GIRQx6  /*  */
+#define GICLR7  GIRQx7  /*  */
+#define GICLR8  GIRQx8  /* Write 1 to clear the interrupt latch */
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_IDBE_OFFSET        0x24    /* sub-register 0x24 is the GPIO interrupt de-bounce enable register */
+#define GPIO_IDBE_LEN           (4)
+#define GPIO_IDBE_MASK          GPIO_IRQE_MASK
+#define GIDBE0  GIRQx0  /* GPIO IRQ de-bounce enable for GPIO0. Value 1 = de-bounce enabled. Value 0 = de-bounce disabled */
+#define GIDBE1  GIRQx1  /*  */
+#define GIDBE2  GIRQx2  /*  */
+#define GIDBE3  GIRQx3  /*  */
+#define GIDBE4  GIRQx4  /*  */
+#define GIDBE5  GIRQx5  /*  */
+#define GIDBE6  GIRQx6  /*  */
+#define GIDBE7  GIRQx7  /*  */
+#define GIDBE8  GIRQx8  /* Value 1 = de-bounce enabled, 0 = de-bounce disabled */
+
+/* offset from GPIO_CTRL in bytes */
+#define GPIO_RAW_OFFSET         0x28    /* sub-register 0x28 allows the raw state of the GPIO pin to be read. */
+#define GPIO_RAW_LEN            (4)
+#define GPIO_RAW_MASK           GPIO_IRQE_MASK
+#define GRAWP0  GIRQx0  /* This bit reflects the raw state of GPIO0 */
+#define GRAWP1  GIRQx1  /*  */
+#define GRAWP2  GIRQx2  /*  */
+#define GRAWP3  GIRQx3  /*  */
+#define GRAWP4  GIRQx4  /*  */
+#define GRAWP5  GIRQx5  /*  */
+#define GRAWP6  GIRQx6  /*  */
+#define GRAWP7  GIRQx7  /*  */
+#define GRAWP8  GIRQx8  /* This bit reflects the raw state of GPIO8 */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register  DRX_CONF
+ * Digital Receiver configuration block
+**/
+#define DRX_CONF_ID             0x27            /* Digital Receiver configuration */
+#define DRX_CONF_LEN            (44)
+/* offset from DRX_CONF_ID in bytes */
+#define DRX_TUNE0b_OFFSET       (0x02)  /* sub-register 0x02 is a 16-bit tuning register. */
+#define DRX_TUNE0b_LEN          (2)
+#define DRX_TUNE0b_MASK         0xFFFF  /* 7.2.40.2 Sub-Register 0x27:02  DRX_TUNE0b */
+#define DRX_TUNE0b_110K_STD     0x000A
+#define DRX_TUNE0b_110K_NSTD    0x0016
+#define DRX_TUNE0b_850K_STD     0x0001
+#define DRX_TUNE0b_850K_NSTD    0x0006
+#define DRX_TUNE0b_6M8_STD      0x0001
+#define DRX_TUNE0b_6M8_NSTD     0x0002
+
+/* offset from DRX_CONF_ID in bytes */
+#define DRX_TUNE1a_OFFSET       0x04    /* 7.2.40.3 Sub-Register 0x27:04  DRX_TUNE1a */
+#define DRX_TUNE1a_LEN          (2)
+#define DRX_TUNE1a_MASK         0xFFFF
+#define DRX_TUNE1a_PRF16        0x0087
+#define DRX_TUNE1a_PRF64        0x008D
+
+/* offset from DRX_CONF_ID in bytes */
+#define DRX_TUNE1b_OFFSET       0x06    /* 7.2.40.4 Sub-Register 0x27:06  DRX_TUNE1b */
+#define DRX_TUNE1b_LEN          (2)
+#define DRX_TUNE1b_MASK         0xFFFF
+#define DRX_TUNE1b_110K         0x0064
+#define DRX_TUNE1b_850K_6M8     0x0020
+#define DRX_TUNE1b_6M8_PRE64    0x0010
+
+/* offset from DRX_CONF_ID in bytes */
+#define DRX_TUNE2_OFFSET        0x08    /* 7.2.40.5 Sub-Register 0x27:08  DRX_TUNE2 */
+#define DRX_TUNE2_LEN           (4)
+#define DRX_TUNE2_MASK          0xFFFFFFFFUL
+#define DRX_TUNE2_PRF16_PAC8    0x311A002DUL
+#define DRX_TUNE2_PRF16_PAC16   0x331A0052UL
+#define DRX_TUNE2_PRF16_PAC32   0x351A009AUL
+#define DRX_TUNE2_PRF16_PAC64   0x371A011DUL
+#define DRX_TUNE2_PRF64_PAC8    0x313B006BUL
+#define DRX_TUNE2_PRF64_PAC16   0x333B00BEUL
+#define DRX_TUNE2_PRF64_PAC32   0x353B015EUL
+#define DRX_TUNE2_PRF64_PAC64   0x373B0296UL
+
+/* offset from DRX_CONF_ID in bytes */
+/* WARNING: Please do NOT set DRX_SFDTOC to zero (disabling SFD detection timeout)
+ * since this risks IC malfunction due to prolonged receiver activity in the event of false preamble detection.
+ */
+#define DRX_SFDTOC_OFFSET       0x20    /* 7.2.40.7 Sub-Register 0x27:20  DRX_SFDTOC */
+#define DRX_SFDTOC_LEN          (2)
+#define DRX_SFDTOC_MASK         0xFFFF
+
+/* offset from DRX_CONF_ID in bytes */
+#define DRX_PRETOC_OFFSET       0x24    /* 7.2.40.9 Sub-Register 0x27:24  DRX_PRETOC */
+#define DRX_PRETOC_LEN          (2)
+#define DRX_PRETOC_MASK         0xFFFF
+
+/* offset from DRX_CONF_ID in bytes */
+#define DRX_TUNE4H_OFFSET       0x26    /* 7.2.40.10 Sub-Register 0x27:26  DRX_TUNE4H */
+#define DRX_TUNE4H_LEN          (2)
+#define DRX_TUNE4H_MASK         0xFFFF
+#define DRX_TUNE4H_PRE64        0x0010
+#define DRX_TUNE4H_PRE128PLUS   0x0028
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register  RF_CONF
+ * Analog RF Configuration block
+ * Refer to section 7.2.41 Register file: 0x28  Analog RF configuration block
+**/
+#define RF_CONF_ID              0x28            /* Analog RF Configuration */
+#define RF_CONF_LEN             (58)
+#define RF_CONF_TXEN_MASK       0x00400000UL   /* TX enable */
+#define RF_CONF_RXEN_MASK       0x00200000UL   /* RX enable */
+#define RF_CONF_TXPOW_MASK      0x001F0000UL   /* turn on power all LDOs */
+#define RF_CONF_PLLEN_MASK      0x0000E000UL   /* enable PLLs */
+#define RF_CONF_PGMIXBIASEN_MASK    0x0000A700UL    /* Enable TX mixer bias and pulse gen */
+#define RF_CONF_TXBLOCKSEN_MASK 0x00001F00UL   /* enable TX blocks */
+#define RF_CONF_TXPLLPOWEN_MASK (RF_CONF_PLLEN_MASK | RF_CONF_TXPOW_MASK)
+#define RF_CONF_TXALLEN_MASK    (RF_CONF_TXEN_MASK | RF_CONF_TXPOW_MASK | RF_CONF_PLLEN_MASK | RF_CONF_TXBLOCKSEN_MASK)
+/* offset from TX_CAL_ID in bytes */
+#define RF_RXCTRLH_OFFSET       0x0B            /* Analog RX Control Register */
+#define RF_RXCTRLH_LEN          (1)
+#define RF_RXCTRLH_NBW          0xD8            /* RXCTRLH value for narrow bandwidth channels */
+#define RF_RXCTRLH_WBW          0xBC            /* RXCTRLH value for wide bandwidth channels */
+/* offset from TX_CAL_ID in bytes */
+#define RF_TXCTRL_OFFSET        0x0C            /* Analog TX Control Register */
+#define RF_TXCTRL_LEN           (4)
+#define RF_TXCTRL_TXMTUNE_MASK  0x000001E0UL    /* Transmit mixer tuning register */
+#define RF_TXCTRL_TXTXMQ_MASK   0x00000E00UL    /* Transmit mixer Q-factor tuning register */
+#define RF_TXCTRL_CH1           0x00005C40UL    /* 32-bit value to program to Sub-Register 0x28:0C  RF_TXCTRL */
+#define RF_TXCTRL_CH2           0x00045CA0UL    /* 32-bit value to program to Sub-Register 0x28:0C  RF_TXCTRL */
+#define RF_TXCTRL_CH3           0x00086CC0UL    /* 32-bit value to program to Sub-Register 0x28:0C  RF_TXCTRL */
+#define RF_TXCTRL_CH4           0x00045C80UL    /* 32-bit value to program to Sub-Register 0x28:0C  RF_TXCTRL */
+#define RF_TXCTRL_CH5           0x001E3FE0UL    /* 32-bit value to program to Sub-Register 0x28:0C  RF_TXCTRL */
+#define RF_TXCTRL_CH7           0x001E7DE0UL    /* 32-bit value to program to Sub-Register 0x28:0C  RF_TXCTRL */
+
+/* offset from TX_CAL_ID in bytes */
+#define RF_STATUS_OFFSET        0x2C
+
+/****************************************************************************//**
+ * @brief Bit definitions for register
+**/
+#define REG_29_ID_RESERVED      0x29
+
+/****************************************************************************//**
+ * @brief Bit definitions for register TX_CAL
+ * Refer to section 7.2.43 Register file: 0x2A  Transmitter Calibration block
+**/
+#define TX_CAL_ID                   0x2A        /* Transmitter calibration block */
+#define TX_CAL_LEN                  (52)
+/* offset from TX_CAL_ID in bytes */
+#define TC_SARL_SAR_C               (0)         /* SAR control */
+/*cause bug in register block TX_CAL, we need to read 1 byte in a time*/
+#define TC_SARL_SAR_LVBAT_OFFSET    (3)         /* Latest SAR reading for Voltage level */
+#define TC_SARL_SAR_LTEMP_OFFSET    (4)         /* Latest SAR reading for Temperature level */
+#define TC_SARW_SAR_WTEMP_OFFSET    0x06        /* SAR reading of Temperature level taken at last wakeup event */
+#define TC_SARW_SAR_WVBAT_OFFSET    0x07        /* SAR reading of Voltage level taken at last wakeup event */
+
+#define TC_PGCCTRL_OFFSET       0x08        /* Pulse Generator Calibration control */
+#define TC_PGCCTRL_LEN          (1)
+#define TC_PGCCTRL_CALSTART     0x01        /* Start PG cal procedure */
+#define TC_PGCCTRL_AUTOCAL      0x02        /* Starts a PG autocalibration loop */
+#define TC_PGCCTRL_TMEAS_MASK   0x3C        /* Mask to retrieve number of clock cycles over which to run PG cal counter */
+#define TC_PGCCTRL_ON_TX        0x40        /* Perform autocal on each TX enable */
+#define TC_PGCCTRL_DIR_CONV     0x80        /* Direction (converging) of autocal binary search */
+
+#define TC_PGCAL_STATUS_OFFSET      0x09    /* Status register from PG calibration block */
+#define TC_PGCAL_STATUS_LEN         (1)
+#define TC_PGCAL_STATUS_DELAY_MASK  0xFFF   /* Mask to retrieve PG delay count from calibration */
+
+/* offset from TX_CAL_ID in bytes */
+#define TC_PGDELAY_OFFSET       0x0B            /* Transmitter Calibration  Pulse Generator Delay */
+#define TC_PGDELAY_LEN          (1)
+#define TC_PGDELAY_CH1          0xC9            /* Recommended value for channel 1 */
+#define TC_PGDELAY_CH2          0xC2            /* Recommended value for channel 2 */
+#define TC_PGDELAY_CH3          0xC5            /* Recommended value for channel 3 */
+#define TC_PGDELAY_CH4          0x95            /* Recommended value for channel 4 */
+#define TC_PGDELAY_CH5          0xC0            /* Recommended value for channel 5 */
+#define TC_PGDELAY_CH7          0x93            /* Recommended value for channel 7 */
+/* offset from TX_CAL_ID in bytes */
+#define TC_PGTEST_OFFSET        0x0C            /* Transmitter Calibration  Pulse Generator Test */
+#define TC_PGTEST_LEN           (1)
+#define TC_PGTEST_NORMAL        0x00            /* Normal operation */
+#define TC_PGTEST_CW            0x13            /* Continuous Wave (CW) Test Mode */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register
+ * Refer to section 7.2.44 Register file: 0x2B  Frequency synthesiser control block
+**/
+#define FS_CTRL_ID              0x2B            /* Frequency synthesiser control block */
+#define FS_CTRL_LEN             (21)
+/* offset from FS_CTRL_ID in bytes */
+#define FS_RES1_OFFSET          0x00            /* reserved area. Please take care not to write to this area as doing so may cause the DW1000 to malfunction. */
+#define FS_RES1_LEN             (7)
+/* offset from FS_CTRL_ID in bytes */
+#define FS_PLLCFG_OFFSET        0x07            /* Frequency synthesiser  PLL configuration */
+#define FS_PLLCFG_LEN           (5)
+#define FS_PLLCFG_CH1           0x09000407UL    /* Operating Channel 1 */
+#define FS_PLLCFG_CH2           0x08400508UL    /* Operating Channel 2 */
+#define FS_PLLCFG_CH3           0x08401009UL    /* Operating Channel 3 */
+#define FS_PLLCFG_CH4           FS_PLLCFG_CH2   /* Operating Channel 4 (same as 2) */
+#define FS_PLLCFG_CH5           0x0800041DUL    /* Operating Channel 5 */
+#define FS_PLLCFG_CH7           FS_PLLCFG_CH5   /* Operating Channel 7 (same as 5) */
+/* offset from FS_CTRL_ID in bytes */
+#define FS_PLLTUNE_OFFSET       0x0B            /* Frequency synthesiser  PLL Tuning */
+#define FS_PLLTUNE_LEN          (1)
+#define FS_PLLTUNE_CH1          0x1E            /* Operating Channel 1 */
+#define FS_PLLTUNE_CH2          0x26            /* Operating Channel 2 */
+#define FS_PLLTUNE_CH3          0x56            /* Operating Channel 3 */
+#define FS_PLLTUNE_CH4          FS_PLLTUNE_CH2  /* Operating Channel 4 (same as 2) */
+#define FS_PLLTUNE_CH5          0xBE            /* Operating Channel 5 */
+#define FS_PLLTUNE_CH7          FS_PLLTUNE_CH5  /* Operating Channel 7 (same as 5) */
+/* offset from FS_CTRL_ID in bytes */
+#define FS_RES2_OFFSET          0x0C    /* reserved area. Please take care not to write to this area as doing so may cause the DW1000 to malfunction. */
+#define FS_RES2_LEN             (2)
+/* offset from FS_CTRL_ID in bytes */
+#define FS_XTALT_OFFSET         0x0E    /* Frequency synthesiser  Crystal trim */
+#define FS_XTALT_LEN            (1)
+#define FS_XTALT_MASK           0x1F    /* Crystal Trim. Crystals may be trimmed using this register setting to tune out errors, see 8.1  IC Calibration  Crystal Oscillator Trim. */
+#define FS_XTALT_MIDRANGE       0x10
+/* offset from FS_CTRL_ID in bytes */
+#define FS_RES3_OFFSET          0x0F    /* reserved area. Please take care not to write to this area as doing so may cause the DW1000 to malfunction. */
+#define FS_RES3_LEN             (6)
+
+/****************************************************************************//**
+ * @brief Bit definitions for register
+**/
+#define AON_ID                  0x2C            /* Always-On register set */
+#define AON_LEN                 (12)
+/* offset from AON_ID in bytes */
+#define AON_WCFG_OFFSET         0x00    /* used to control what the DW1000 IC does as it wakes up from low-power SLEEP or DEEPSLEEPstates. */
+#define AON_WCFG_LEN            (2)
+#define AON_WCFG_MASK           0x09CB  /* access mask to AON_WCFG register*/
+#define AON_WCFG_ONW_RADC       0x0001  /* On Wake-up Run the (temperature and voltage) Analog-to-Digital Convertors */
+#define AON_WCFG_ONW_RX         0x0002  /* On Wake-up turn on the Receiver */
+#define AON_WCFG_ONW_LEUI       0x0008  /* On Wake-up load the EUI from OTP memory into Register file: 0x01  Extended Unique Identifier. */
+#define AON_WCFG_ONW_LDC        0x0040  /* On Wake-up load configurations from the AON memory into the host interface register set */
+#define AON_WCFG_ONW_L64P       0x0080  /* On Wake-up load the Length64 receiver operating parameter set */
+#define AON_WCFG_PRES_SLEEP     0x0100  /* Preserve Sleep. This bit determines what the DW1000 does with respect to the ARXSLP and ATXSLP sleep controls */
+#define AON_WCFG_ONW_LLDE       0x0800  /* On Wake-up load the LDE microcode. */
+#define AON_WCFG_ONW_LLDO       0x1000  /* On Wake-up load the LDO tune value. */
+/* offset from AON_ID in bytes */
+#define AON_CTRL_OFFSET         0x02    /* The bits in this register in general cause direct activity within the AON block with respect to the stored AON memory */
+#define AON_CTRL_LEN            (1)
+#define AON_CTRL_MASK           0x8F    /* access mask to AON_CTRL register */
+#define AON_CTRL_RESTORE        0x01    /* When this bit is set the DW1000 will copy the user configurations from the AON memory to the host interface register set. */
+#define AON_CTRL_SAVE           0x02    /* When this bit is set the DW1000 will copy the user configurations from the host interface register set into the AON memory */
+#define AON_CTRL_UPL_CFG        0x04    /* Upload the AON block configurations to the AON  */
+#define AON_CTRL_DCA_READ       0x08    /* Direct AON memory access read */
+#define AON_CTRL_DCA_ENAB       0x80    /* Direct AON memory access enable bit */
+/* offset from AON_ID in bytes */
+#define AON_RDAT_OFFSET         0x03    /* AON Direct Access Read Data Result */
+#define AON_RDAT_LEN            (1)
+/* offset from AON_ID in bytes */
+#define AON_ADDR_OFFSET         0x04    /* AON Direct Access Address */
+#define AON_ADDR_LEN            (1)
+#define AON_ADDR_LPOSC_CAL_0    117     /* Address of low-power oscillator calibration value (lower byte) */
+#define AON_ADDR_LPOSC_CAL_1    118     /* Address of low-power oscillator calibration value (lower byte) */
+
+/* offset from AON_ID in bytes */
+#define AON_CFG0_OFFSET             0x06    /* 32-bit configuration register for the always on block. */
+#define AON_CFG0_LEN                (4)
+#define AON_CFG0_SLEEP_EN           0x00000001UL    /* This is the sleep enable configuration bit */
+#define AON_CFG0_WAKE_PIN           0x00000002UL    /* Wake using WAKEUP pin */
+#define AON_CFG0_WAKE_SPI           0x00000004UL    /* Wake using SPI access SPICSn */
+#define AON_CFG0_WAKE_CNT           0x00000008UL    /* Wake when sleep counter elapses */
+#define AON_CFG0_LPDIV_EN           0x00000010UL    /* Low power divider enable configuration */
+#define AON_CFG0_LPCLKDIVA_MASK     0x0000FFE0UL    /* divider count for dividing the raw DW1000 XTAL oscillator frequency to set an LP clock frequency */
+#define AON_CFG0_LPCLKDIVA_SHIFT    (5)
+#define AON_CFG0_SLEEP_TIM          0xFFFF0000UL    /* Sleep time. This field configures the sleep time count elapse value */
+#define AON_CFG0_SLEEP_SHIFT        (16)
+#define AON_CFG0_SLEEP_TIM_OFFSET   2               /* In bytes */
+/* offset from AON_ID in bytes */
+#define AON_CFG1_OFFSET         0x0A
+#define AON_CFG1_LEN            (2)
+#define AON_CFG1_MASK           0x0007  /* aceess mask to AON_CFG1 */
+#define AON_CFG1_SLEEP_CEN      0x0001  /* This bit enables the sleep counter */
+#define AON_CFG1_SMXX           0x0002  /* This bit needs to be set to 0 for correct operation in the SLEEP state within the DW1000 */
+#define AON_CFG1_LPOSC_CAL      0x0004  /* This bit enables the calibration function that measures the period of the IC\92s internal low powered oscillator */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register OTP_IF
+ * Refer to section 7.2.46 Register file: 0x2D  OTP Memory Interface
+**/
+#define OTP_IF_ID               0x2D            /* One Time Programmable Memory Interface */
+#define OTP_IF_LEN              (18)
+/* offset from OTP_IF_ID in bytes */
+#define OTP_WDAT                0x00            /* 32-bit register. The data value to be programmed into an OTP location  */
+#define OTP_WDAT_LEN            (4)
+/* offset from OTP_IF_ID in bytes */
+#define OTP_ADDR                0x04            /* 16-bit register used to select the address within the OTP memory block */
+#define OTP_ADDR_LEN            (2)
+#define OTP_ADDR_MASK           0x07FF          /* This 11-bit field specifies the address within OTP memory that will be accessed read or written. */
+/* offset from OTP_IF_ID in bytes */
+#define OTP_CTRL                0x06            /* used to control the operation of the OTP memory */
+#define OTP_CTRL_LEN            (2)
+#define OTP_CTRL_MASK           0x8002
+#define OTP_CTRL_OTPRDEN        0x0001          /* This bit forces the OTP into manual read mode */
+#define OTP_CTRL_OTPREAD        0x0002          /* This bit commands a read operation from the address specified in the OTP_ADDR register */
+#define OTP_CTRL_LDELOAD        0x8000          /* This bit forces a load of LDE microcode */
+#define OTP_CTRL_OTPPROG        0x0040          /* Setting this bit will cause the contents of OTP_WDAT to be written to OTP_ADDR. */
+/* offset from OTP_IF_ID in bytes */
+#define OTP_STAT                0x08
+#define OTP_STAT_LEN            (2)
+#define OTP_STAT_MASK           0x0003
+#define OTP_STAT_OTPPRGD        0x0001          /* OTP Programming Done */
+#define OTP_STAT_OTPVPOK        0x0002          /* OTP Programming Voltage OK */
+/* offset from OTP_IF_ID in bytes */
+#define OTP_RDAT                0x0A            /* 32-bit register. The data value read from an OTP location will appear here */
+#define OTP_RDAT_LEN            (4)
+/* offset from OTP_IF_ID in bytes */
+#define OTP_SRDAT               0x0E            /* 32-bit register. The data value stored in the OTP SR (0x400) location will appear here after power up */
+#define OTP_SRDAT_LEN           (4)
+/* offset from OTP_IF_ID in bytes */
+#define OTP_SF                  0x12            /*8-bit special function register used to select and load special receiver operational parameter */
+#define OTP_SF_LEN              (1)
+#define OTP_SF_MASK             0x63
+#define OTP_SF_OPS_KICK         0x01            /* This bit when set initiates a load of the operating parameter set selected by the OPS_SEL */
+#define OTP_SF_LDO_KICK         0x02            /* This bit when set initiates a load of the LDO tune code */
+#define OTP_SF_OPS_SEL_SHFT     5
+#define OTP_SF_OPS_SEL_MASK     0x60
+#define OTP_SF_OPS_SEL_L64      0x00            /* Operating parameter set selection: Length64 */
+#define OTP_SF_OPS_SEL_TIGHT    0x40            /* Operating parameter set selection: Tight */
+
+/****************************************************************************//**
+ * @brief Bit definitions for register LDE_IF
+ * Refer to section 7.2.47 Register file: 0x2E  Leading Edge Detection Interface
+ * PLEASE NOTE: Other areas within the address space of Register file: 0x2E  Leading Edge Detection Interface
+ * are reserved. To ensure proper operation of the LDE algorithm (i.e. to avoid loss of performance or a malfunction),
+ * care must be taken not to write to any byte locations other than those defined in the sub-sections below.
+**/
+#define LDE_IF_ID               0x2E            /* Leading edge detection control block */
+#define LDE_IF_LEN              (0)
+/* offset from LDE_IF_ID in bytes */
+#define LDE_THRESH_OFFSET       0x0000  /* 16-bit status register reporting the threshold that was used to find the first path */
+#define LDE_THRESH_LEN          (2)
+/* offset from LDE_IF_ID in bytes */
+#define LDE_CFG1_OFFSET         0x0806  /*8-bit configuration register*/
+#define LDE_CFG1_LEN            (1)
+#define LDE_CFG1_NSTDEV_MASK    0x1F    /* Number of Standard Deviations mask. */
+#define LDE_CFG1_PMULT_MASK     0xE0    /* Peak Multiplier mask. */
+/* offset from LDE_IF_ID in bytes */
+#define LDE_PPINDX_OFFSET       0x1000  /* reporting the position within the accumulator that the LDE algorithm has determined to contain the maximum */
+#define LDE_PPINDX_LEN          (2)
+/* offset from LDE_IF_ID in bytes */
+#define LDE_PPAMPL_OFFSET       0x1002  /* reporting the magnitude of the peak signal seen in the accumulator data memory */
+#define LDE_PPAMPL_LEN          (2)
+/* offset from LDE_IF_ID in bytes */
+#define LDE_RXANTD_OFFSET       0x1804  /* 16-bit configuration register for setting the receive antenna delay */
+#define LDE_RXANTD_LEN          (2)
+/* offset from LDE_IF_ID in bytes */
+#define LDE_CFG2_OFFSET         0x1806  /* 16-bit LDE configuration tuning register */
+#define LDE_CFG2_LEN            (2)
+/* offset from LDE_IF_ID in bytes */
+#define LDE_REPC_OFFSET         0x2804  /* 16-bit configuration register for setting the replica avoidance coefficient */
+#define LDE_REPC_LEN            (2)
+#define LDE_REPC_PCODE_1        0x5998
+#define LDE_REPC_PCODE_2        0x5998
+#define LDE_REPC_PCODE_3        0x51EA
+#define LDE_REPC_PCODE_4        0x428E
+#define LDE_REPC_PCODE_5        0x451E
+#define LDE_REPC_PCODE_6        0x2E14
+#define LDE_REPC_PCODE_7        0x8000
+#define LDE_REPC_PCODE_8        0x51EA
+#define LDE_REPC_PCODE_9        0x28F4
+#define LDE_REPC_PCODE_10       0x3332
+#define LDE_REPC_PCODE_11       0x3AE0
+#define LDE_REPC_PCODE_12       0x3D70
+#define LDE_REPC_PCODE_13       0x3AE0
+#define LDE_REPC_PCODE_14       0x35C2
+#define LDE_REPC_PCODE_15       0x2B84
+#define LDE_REPC_PCODE_16       0x35C2
+#define LDE_REPC_PCODE_17       0x3332
+#define LDE_REPC_PCODE_18       0x35C2
+#define LDE_REPC_PCODE_19       0x35C2
+#define LDE_REPC_PCODE_20       0x47AE
+#define LDE_REPC_PCODE_21       0x3AE0
+#define LDE_REPC_PCODE_22       0x3850
+#define LDE_REPC_PCODE_23       0x30A2
+#define LDE_REPC_PCODE_24       0x3850
+
+/****************************************************************************//**
+ * @brief Bit definitions for register DIG_DIAG
+ * Digital Diagnostics interface.
+ * It contains a number of sub-registers that give diagnostics information.
+**/
+#define DIG_DIAG_ID             0x2F        /* Digital Diagnostics Interface */
+#define DIG_DIAG_LEN            (41)
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_CTRL_OFFSET         0x00        /* Event Counter Control */
+#define EVC_CTRL_LEN            (4)
+#define EVC_CTRL_MASK           0x00000003UL/* access mask to Register for bits should always be set to zero to avoid any malfunction of the device. */
+#define EVC_EN                  0x00000001UL/* Event Counters Enable bit */
+#define EVC_CLR                 0x00000002UL
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_PHE_OFFSET          0x04        /* PHR Error Event Counter */
+#define EVC_PHE_LEN             (2)
+#define EVC_PHE_MASK            0x0FFF
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_RSE_OFFSET          0x06        /* Reed Solomon decoder (Frame Sync Loss) Error Event Counter */
+#define EVC_RSE_LEN             (2)
+#define EVC_RSE_MASK            0x0FFF
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_FCG_OFFSET          0x08        /* The EVC_FCG field is a 12-bit counter of the frames received with good CRC/FCS sequence. */
+#define EVC_FCG_LEN             (2)
+#define EVC_FCG_MASK            0x0FFF
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_FCE_OFFSET          0x0A        /* The EVC_FCE field is a 12-bit counter of the frames received with bad CRC/FCS sequence. */
+#define EVC_FCE_LEN             (2)
+#define EVC_FCE_MASK            0x0FFF
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_FFR_OFFSET          0x0C        /* The EVC_FFR field is a 12-bit counter of the frames rejected by the receive frame filtering function. */
+#define EVC_FFR_LEN             (2)
+#define EVC_FFR_MASK            0x0FFF
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_OVR_OFFSET          0x0E        /* The EVC_OVR field is a 12-bit counter of receive overrun events */
+#define EVC_OVR_LEN             (2)
+#define EVC_OVR_MASK            0x0FFF
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_STO_OFFSET          0x10        /* The EVC_STO field is a 12-bit counter of SFD Timeout Error events */
+#define EVC_OVR_LEN             (2)
+#define EVC_OVR_MASK            0x0FFF
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_PTO_OFFSET          0x12        /* The EVC_PTO field is a 12-bit counter of Preamble detection Timeout events */
+#define EVC_PTO_LEN             (2)
+#define EVC_PTO_MASK            0x0FFF
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_FWTO_OFFSET         0x14        /* The EVC_FWTO field is a 12-bit counter of receive frame wait timeout events */
+#define EVC_FWTO_LEN            (2)
+#define EVC_FWTO_MASK           0x0FFF
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_TXFS_OFFSET         0x16        /* The EVC_TXFS field is a 12-bit counter of transmit frames sent. This is incremented every time a frame is sent */
+#define EVC_TXFS_LEN            (2)
+#define EVC_TXFS_MASK           0x0FFF
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_HPW_OFFSET          0x18        /* The EVC_HPW field is a 12-bit counter of Half Period Warnings\94. */
+#define EVC_HPW_LEN             (2)
+#define EVC_HPW_MASK            0x0FFF
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_TPW_OFFSET          0x1A        /* The EVC_TPW field is a 12-bit counter of Transmitter Power-Up Warnings\94. */
+#define EVC_TPW_LEN             (2)
+#define EVC_TPW_MASK            0x0FFF
+
+/* offset from DIG_DIAG_ID in bytes */
+#define EVC_RES1_OFFSET         0x1C        /* Please take care not to write to this register as doing so may cause the DW1000 to malfunction. */
+
+/* offset from DIG_DIAG_ID in bytes */
+#define DIAG_TMC_OFFSET         0x24
+#define DIAG_TMC_LEN            (2)
+#define DIAG_TMC_MASK           0x0010
+#define DIAG_TMC_TX_PSTM        0x0010      /* This test mode is provided to help support regulatory approvals spectral testing. When the TX_PSTM bit is set it enables a repeating transmission of the data from the TX_BUFFER */
+
+
+/****************************************************************************//**
+ * @brief Bit definitions for register 0x30-0x35
+ * Please take care not to write to these registers as doing so may cause the DW1000 to malfunction.
+**/
+#define REG_30_ID_RESERVED      0x30
+#define REG_31_ID_RESERVED      0x31
+#define REG_32_ID_RESERVED      0x32
+#define REG_33_ID_RESERVED      0x33
+#define REG_34_ID_RESERVED      0x34
+#define REG_35_ID_RESERVED      0x35
+
+/****************************************************************************//**
+ * @brief Bit definitions for register PMSC
+**/
+#define PMSC_ID                 0x36            /* Power Management System Control Block */
+#define PMSC_LEN                (48)
+/* offset from PMSC_ID in bytes */
+#define PMSC_CTRL0_OFFSET       0x00
+#define PMSC_CTRL0_LEN          (4)
+#define PMSC_CTRL0_MASK         0xF18F847FUL    /* access mask to register PMSC_CTRL0 */
+#define PMSC_CTRL0_SYSCLKS_AUTO 0x00000000UL    /* The system clock will run off the 19.2 MHz XTI clock until the PLL is calibrated and locked, then it will switch over the 125 MHz PLL clock */
+#define PMSC_CTRL0_SYSCLKS_19M  0x00000001UL    /* Force system clock to be the 19.2 MHz XTI clock. */
+#define PMSC_CTRL0_SYSCLKS_125M 0x00000002UL    /* Force system clock to the 125 MHz PLL clock. */
+#define PMSC_CTRL0_RXCLKS_AUTO  0x00000000UL    /* The RX clock will be disabled until it is required for an RX operation */
+#define PMSC_CTRL0_RXCLKS_19M   0x00000004UL    /* Force RX clock enable and sourced clock from the 19.2 MHz XTI clock */
+#define PMSC_CTRL0_RXCLKS_125M  0x00000008UL    /* Force RX clock enable and sourced from the 125 MHz PLL clock */
+#define PMSC_CTRL0_RXCLKS_OFF   0x0000000CUL    /* Force RX clock off. */
+#define PMSC_CTRL0_TXCLKS_AUTO  0x00000000UL    /* The TX clock will be disabled until it is required for a TX operation */
+#define PMSC_CTRL0_TXCLKS_19M   0x00000010UL    /* Force TX clock enable and sourced clock from the 19.2 MHz XTI clock */
+#define PMSC_CTRL0_TXCLKS_125M  0x00000020UL    /* Force TX clock enable and sourced from the 125 MHz PLL clock */
+#define PMSC_CTRL0_TXCLKS_OFF   0x00000030UL    /* Force TX clock off */
+#define PMSC_CTRL0_FACE         0x00000040UL    /* Force Accumulator Clock Enable */
+#define PMSC_CTRL0_GPDCE        0x00040000UL    /* GPIO De-bounce Clock Enable */
+#define PMSC_CTRL0_KHZCLEN      0x00800000UL    /* Kilohertz Clock Enable */
+#define PMSC_CTRL0_PLL2_SEQ_EN  0x01000000UL    /* Enable PLL2 on/off sequencing by SNIFF mode */
+#define PMSC_CTRL0_SOFTRESET_OFFSET 3           /* In bytes */
+#define PMSC_CTRL0_RESET_ALL    0x00            /* Assuming only 4th byte of the register is read */
+#define PMSC_CTRL0_RESET_RX     0xE0            /* Assuming only 4th byte of the register is read */
+#define PMSC_CTRL0_RESET_CLEAR  0xF0            /* Assuming only 4th byte of the register is read */
+/* offset from PMSC_ID in bytes */
+#define PMSC_CTRL1_OFFSET       0x04
+#define PMSC_CTRL1_LEN          (4)
+#define PMSC_CTRL1_MASK         0xFC02F802UL    /* access mask to register PMSC_CTRL1 */
+#define PMSC_CTRL1_ARX2INIT     0x00000002UL    /* Automatic transition from receive mode into the INIT state */
+#define PMSC_CTRL1_ATXSLP       0x00000800UL    /* If this bit is set then the DW1000 will automatically transition into SLEEP or DEEPSLEEP mode after transmission of a frame */
+#define PMSC_CTRL1_ARXSLP       0x00001000UL    /* this bit is set then the DW1000 will automatically transition into SLEEP mode after a receive attempt */
+#define PMSC_CTRL1_SNOZE        0x00002000UL    /* Snooze Enable */
+#define PMSC_CTRL1_SNOZR        0x00004000UL    /* The SNOZR bit is set to allow the snooze timer to repeat twice */
+#define PMSC_CTRL1_PLLSYN       0x00008000UL    /* This enables a special 1 GHz clock used for some external SYNC modes */
+#define PMSC_CTRL1_LDERUNE      0x00020000UL    /* This bit enables the running of the LDE algorithm */
+#define PMSC_CTRL1_KHZCLKDIV_MASK   0xFC000000UL    /* Kilohertz clock divisor */
+#define PMSC_CTRL1_PKTSEQ_DISABLE   0x00        /* writing this to PMSC CONTROL 1 register (bits 10-3) disables PMSC control of analog RF subsystems */
+#define PMSC_CTRL1_PKTSEQ_ENABLE    0xE7        /* writing this to PMSC CONTROL 1 register (bits 10-3) enables PMSC control of analog RF subsystems */
+/* offset from PMSC_ID in bytes */
+#define PMSC_RES1_OFFSET        0x08
+/* offset from PMSC_ID in bytes */
+#define PMSC_SNOZT_OFFSET       0x0C            /* PMSC Snooze Time Register */
+#define PMSC_SNOZT_LEN          (1)
+/* offset from PMSC_ID in bytes */
+#define PMSC_RES2_OFFSET        0x10
+/* offset from PMSC_ID in bytes */
+#define PMSC_RES3_OFFSET        0x24
+/* offset from PMSC_ID in bytes */
+#define PMSC_TXFINESEQ_OFFSET   0x26
+#define PMSC_TXFINESEQ_DISABLE  0x0             /* Writing this disables fine grain sequencing in the transmitter */
+#define PMSC_TXFINESEQ_ENABLE   0x0B74          /* Writing this enables fine grain sequencing in the transmitter */
+/* offset from PMSC_ID in bytes */
+#define PMSC_LEDC_OFFSET        0x28
+#define PMSC_LEDC_LEN           (4)
+#define PMSC_LEDC_MASK          0x000001FFUL    /* 32-bit LED control register. */
+#define PMSC_LEDC_BLINK_TIM_MASK 0x000000FFUL   /* This field determines how long the LEDs remain lit after an event that causes them to be set on. */
+#define PMSC_LEDC_BLNKEN        0x00000100UL    /* Blink Enable. When this bit is set to 1 the LED blink feature is enabled. */
+/* Default blink time. Blink time is expressed in multiples of 14 ms. The value defined here is ~225 ms. */
+#define PMSC_LEDC_BLINK_TIME_DEF 0x10
+/* Command a blink of all LEDs */
+#define PMSC_LEDC_BLINK_NOW_ALL 0x000F0000UL
+
+/****************************************************************************//**
+ * @brief Bit definitions for register 0x37-0x3F
+ * Please take care not to write to these registers as doing so may cause the DW1000 to malfunction.
+**/
+#define REG_37_ID_RESERVED      0x37
+#define REG_38_ID_RESERVED      0x38
+#define REG_39_ID_RESERVED      0x39
+#define REG_3A_ID_RESERVED      0x3A
+#define REG_3B_ID_RESERVED      0x3B
+#define REG_3C_ID_RESERVED      0x3C
+#define REG_3D_ID_RESERVED      0x3D
+#define REG_3E_ID_RESERVED      0x3E
+#define REG_3F_ID_RESERVED      0x3F
+
+/* END DW1000 REGISTER DEFINITION */
+
+#endif /* defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*DECA_REGS_V1_H*/
diff --git a/include/DW1000/v1/alld_dw1000_v1.h b/include/DW1000/v1/alld_dw1000_v1.h
new file mode 100755
index 0000000..9d17bc5
--- /dev/null
+++ b/include/DW1000/v1/alld_dw1000_v1.h
@@ -0,0 +1,1881 @@
+/*
+AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
+Copyright (C) 2016..2018  Thomas Schöpping et al.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! ----------------------------------------------------------------------------
+ * @file    deca_device_api.h
+ * @brief   DW1000 API Functions
+ *
+ * @attention
+ *
+ * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland.
+ *
+ * All rights reserved.
+ *
+ */
+
+#ifndef __AMIROLLD_DW1000_V1_H
+#define AMIROLLD_DW1000_V1_H
+
+
+#include <amiro-lld.h>
+#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define DW1000_DRIVER_VERSION               0x040005
+#define DW1000_DEVICE_DRIVER_VER_STRING     "DW1000 Device Driver Version 04.00.05"
+
+#ifndef DWT_NUM_DW_DEV
+#define DWT_NUM_DW_DEV (1)
+#endif
+
+#define DWT_SUCCESS (0)
+#define DWT_ERROR   (-1)
+
+/**
+ * Parameter declarations
+ */
+
+#define NUM_BR 3
+#define NUM_PRF 2
+#define NUM_PACS 4
+#define NUM_BW 2            //2 bandwidths are supported
+#define NUM_SFD 2           //supported number of SFDs - standard = 0, non-standard = 1
+#define NUM_CH 6            //supported channels are 1, 2, 3, 4, 5, 7
+#define NUM_CH_SUPPORTED 8  //supported channels are '0', 1, 2, 3, 4, 5, '6', 7
+#define PCODES 25           //supported preamble codes
+
+extern const uint8_t chan_idx[NUM_CH_SUPPORTED];
+
+
+/**
+ * @brief The DW1000 driver struct.
+ */
+typedef struct {
+  apalSPIDriver_t* spid;    /**< @brief The SPI Driver */
+  const apalControlGpio_t* gpio_exti;    /**< @brief The GPIO indicating external interrupt */
+  const apalControlGpio_t* gpio_reset;  /**< @brief The GPIO indicating reset sig*/
+//  const apalGpio_t* gpio_exti;    /**< @brief The GPIO indicating external interrupt */
+//  const apalGpio_t* gpio_reset;  /**< @brief The GPIO indicating reset sig*/
+  /* TODO: better apalControlGpio_t instead of apalGpio_t ? */
+  /* TODO: EXTI, GPIO (RESET) */
+} DW1000Driver;
+
+
+#define DWT_TIME_UNITS  (1.0/499.2e6/128.0) //!< = 15.65e-12 s
+
+#define DWT_DEVICE_ID   (0xDECA0130)        //!< DW1000 MP device ID
+
+#define BUFFLEN 	(4096+128)
+
+//! constants for selecting the bit rate for data TX (and RX)
+//! These are defined for write (with just a shift) the TX_FCTRL register
+#define DWT_BR_110K     0   //!< UWB bit rate 110 kbits/s
+#define DWT_BR_850K     1   //!< UWB bit rate 850 kbits/s
+#define DWT_BR_6M8      2   //!< UWB bit rate 6.8 Mbits/s
+
+//! constants for specifying the (Nominal) mean Pulse Repetition Frequency
+//! These are defined for direct write (with a shift if necessary) to CHAN_CTRL and TX_FCTRL regs
+#define DWT_PRF_16M     1   //!< UWB PRF 16 MHz
+#define DWT_PRF_64M     2   //!< UWB PRF 64 MHz
+
+//! constants for specifying Preamble Acquisition Chunk (PAC) Size in symbols
+#define DWT_PAC8        0   //!< PAC  8 (recommended for RX of preamble length  128 and below
+#define DWT_PAC16       1   //!< PAC 16 (recommended for RX of preamble length  256
+#define DWT_PAC32       2   //!< PAC 32 (recommended for RX of preamble length  512
+#define DWT_PAC64       3   //!< PAC 64 (recommended for RX of preamble length 1024 and up
+
+//! constants for specifying TX Preamble length in symbols
+//! These are defined to allow them be directly written into byte 2 of the TX_FCTRL register
+//! (i.e. a four bit value destined for bits 20..18 but shifted left by 2 for byte alignment)
+#define DWT_PLEN_4096   0x0C    //! Standard preamble length 4096 symbols
+#define DWT_PLEN_2048   0x28    //! Non-standard preamble length 2048 symbols
+#define DWT_PLEN_1536   0x18    //! Non-standard preamble length 1536 symbols
+#define DWT_PLEN_1024   0x08    //! Standard preamble length 1024 symbols
+#define DWT_PLEN_512    0x34    //! Non-standard preamble length 512 symbols
+#define DWT_PLEN_256    0x24    //! Non-standard preamble length 256 symbols
+#define DWT_PLEN_128    0x14    //! Non-standard preamble length 128 symbols
+#define DWT_PLEN_64     0x04    //! Standard preamble length 64 symbols
+
+#define DWT_SFDTOC_DEF              0x1041  // default SFD timeout value
+
+#define DWT_PHRMODE_STD             0x0     // standard PHR mode
+#define DWT_PHRMODE_EXT             0x3     // DW proprietary extended frames PHR mode
+
+// Defined constants for "mode" bitmask parameter passed into dwt_starttx() function.
+#define DWT_START_TX_IMMEDIATE      0
+#define DWT_START_TX_DELAYED        1
+#define DWT_RESPONSE_EXPECTED       2
+
+#define DWT_START_RX_IMMEDIATE  0
+#define DWT_START_RX_DELAYED    1    // Set up delayed RX, if "late" error triggers, then the RX will be enabled immediately
+#define DWT_IDLE_ON_DLY_ERR     2    // If delayed RX failed due to "late" error then if this
+                                     // flag is set the RX will not be re-enabled immediately, and device will be in IDLE when function exits
+#define DWT_NO_SYNC_PTRS        4    // Do not try to sync IC side and Host side buffer pointers when enabling RX. This is used to perform manual RX
+                                     // re-enabling when receiving a frame in double buffer mode.
+
+// Defined constants for "mode" bit field parameter passed to dwt_setleds() function.
+#define DWT_LEDS_DISABLE     0x00
+#define DWT_LEDS_ENABLE      0x01
+#define DWT_LEDS_INIT_BLINK  0x02
+
+//frame filtering configuration options
+#define DWT_FF_NOTYPE_EN            0x000           // no frame types allowed (FF disabled)
+#define DWT_FF_COORD_EN             0x002           // behave as coordinator (can receive frames with no dest address (PAN ID has to match))
+#define DWT_FF_BEACON_EN            0x004           // beacon frames allowed
+#define DWT_FF_DATA_EN              0x008           // data frames allowed
+#define DWT_FF_ACK_EN               0x010           // ack frames allowed
+#define DWT_FF_MAC_EN               0x020           // mac control frames allowed
+#define DWT_FF_RSVD_EN              0x040           // reserved frame types allowed
+
+//DW1000 interrupt events
+#define DWT_INT_TFRS            0x00000080          // frame sent
+#define DWT_INT_LDED            0x00000400          // micro-code has finished execution
+#define DWT_INT_RFCG            0x00004000          // frame received with good CRC
+#define DWT_INT_RPHE            0x00001000          // receiver PHY header error
+#define DWT_INT_RFCE            0x00008000          // receiver CRC error
+#define DWT_INT_RFSL            0x00010000          // receiver sync loss error
+#define DWT_INT_RFTO            0x00020000          // frame wait timeout
+#define DWT_INT_RXOVRR          0x00100000          // receiver overrun
+#define DWT_INT_RXPTO           0x00200000          // preamble detect timeout
+#define DWT_INT_SFDT            0x04000000          // SFD timeout
+#define DWT_INT_ARFE            0x20000000          // frame rejected (due to frame filtering configuration)
+
+
+//DW1000 SLEEP and WAKEUP configuration parameters
+#define DWT_PRESRV_SLEEP 0x0100                      // PRES_SLEEP - on wakeup preserve sleep bit
+#define DWT_LOADOPSET    0x0080                      // ONW_L64P - on wakeup load operating parameter set for 64 PSR
+#define DWT_CONFIG       0x0040                      // ONW_LDC - on wakeup restore (load) the saved configurations (from AON array into HIF)
+#define DWT_LOADEUI      0x0008                      // ONW_LEUI - on wakeup load EUI
+#define DWT_RX_EN        0x0002                      // ONW_RX - on wakeup activate reception
+#define DWT_TANDV        0x0001                      // ONW_RADC - on wakeup run ADC to sample temperature and voltage sensor values
+
+#define DWT_XTAL_EN      0x10                       // keep XTAL running during sleep
+#define DWT_WAKE_SLPCNT  0x8                        // wake up after sleep count
+#define DWT_WAKE_CS      0x4                        // wake up on chip select
+#define DWT_WAKE_WK      0x2                        // wake up on WAKEUP PIN
+#define DWT_SLP_EN       0x1                        // enable sleep/deep sleep functionality
+
+//DW1000 INIT configuration parameters
+#define DWT_LOADUCODE     0x1
+#define DWT_LOADNONE      0x0
+
+//DW1000 OTP operating parameter set selection
+#define DWT_OPSET_64LEN   0x0
+#define DWT_OPSET_TIGHT   0x1
+#define DWT_OPSET_DEFLT   0x2
+
+// Call-back data RX frames flags
+#define DWT_CB_DATA_RX_FLAG_RNG 0x1 // Ranging bit
+
+
+// TX/RX call-back data
+typedef struct
+{
+    uint32_t status;      //initial value of register as ISR is entered
+    uint16_t datalength;  //length of frame
+    uint8_t  fctrl[2];    //frame control bytes
+    uint8_t  rx_flags;    //RX frame flags, see above
+} dwt_cb_data_t;
+
+// Call-back type for all events
+typedef void (*dwt_cb_t)(const dwt_cb_data_t *);
+
+
+// -------------------------------------------------------------------------------------------------------------------
+// Structure to hold device data
+typedef struct
+{
+    uint32_t      partID ;            // IC Part ID - read during initialisation
+    uint32_t      lotID ;             // IC Lot ID - read during initialisation
+    uint8_t       longFrames ;        // Flag in non-standard long frame mode
+    uint8_t       otprev ;            // OTP revision number (read during initialisation)
+    uint32_t      txFCTRL ;           // Keep TX_FCTRL register config
+    uint8_t       init_xtrim;         // initial XTAL trim value read from OTP (or defaulted to mid-range if OTP not programmed)
+    uint8_t       dblbuffon;          // Double RX buffer mode flag
+    uint32_t      sysCFGreg ;         // Local copy of system config register
+    uint16_t      sleep_mode;         // Used for automatic reloading of LDO tune and microcode at wake-up
+    uint8_t       wait4resp ;         // wait4response was set with last TX start command
+    dwt_cb_data_t cbData;             // Callback data structure
+    dwt_cb_t      cbTxDone;           // Callback for TX confirmation event
+    dwt_cb_t      cbRxOk;             // Callback for RX good frame event
+    dwt_cb_t      cbRxTo;             // Callback for RX timeout events
+    dwt_cb_t      cbRxErr;            // Callback for RX error events
+    DW1000Driver  *driver;      // Reference to local hardware SPI, GPIO, ...
+} dwt_local_data_t ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * Structure typedef: dwt_config_t
+ *
+ * Structure for setting device configuration via dwt_configure() function
+ *
+ */
+typedef struct
+{
+    uint8_t chan ;           //!< channel number {1, 2, 3, 4, 5, 7 }
+    uint8_t prf ;            //!< Pulse Repetition Frequency {DWT_PRF_16M or DWT_PRF_64M}
+    uint8_t txPreambLength ; //!< DWT_PLEN_64..DWT_PLEN_4096
+    uint8_t rxPAC ;          //!< Acquisition Chunk Size (Relates to RX preamble length)
+    uint8_t txCode ;         //!< TX preamble code
+    uint8_t rxCode ;         //!< RX preamble code
+    uint8_t nsSFD ;          //!< Boolean should we use non-standard SFD for better performance
+    uint8_t dataRate ;       //!< Data Rate {DWT_BR_110K, DWT_BR_850K or DWT_BR_6M8}
+    uint8_t phrMode ;        //!< PHR mode {0x0 - standard DWT_PHRMODE_STD, 0x3 - extended frames DWT_PHRMODE_EXT}
+    uint8_t smartPowerEn ;  //!< Smart Power enable / disable (TODO: Added smartPowerEn in this struct )
+    uint16_t sfdTO ;         //!< SFD timeout value (in symbols)    
+} dwt_config_t ;
+
+
+typedef struct
+{
+    uint8_t   PGdly;
+    //TX POWER
+    //31:24     BOOST_0.125ms_PWR
+    //23:16     BOOST_0.25ms_PWR-TX_SHR_PWR
+    //15:8      BOOST_0.5ms_PWR-TX_PHR_PWR
+    //7:0       DEFAULT_PWR-TX_DATA_PWR
+    uint32_t  power;
+} dwt_txconfig_t ;
+
+
+typedef struct
+{
+
+    uint16_t      maxNoise ;          // LDE max value of noise
+    uint16_t      firstPathAmp1 ;     // Amplitude at floor(index FP) + 1
+    uint16_t      stdNoise ;          // Standard deviation of noise
+    uint16_t      firstPathAmp2 ;     // Amplitude at floor(index FP) + 2
+    uint16_t      firstPathAmp3 ;     // Amplitude at floor(index FP) + 3
+    uint16_t      maxGrowthCIR ;      // Channel Impulse Response max growth CIR
+    uint16_t      rxPreamCount ;      // Count of preamble symbols accumulated
+    uint16_t      firstPath ;         // First path index (10.6 bits fixed point integer)
+}dwt_rxdiag_t ;
+
+
+typedef struct
+{
+    //all of the below are mapped to a 12-bit register in DW1000
+    uint16_t PHE ;                    //number of received header errors
+    uint16_t RSL ;                    //number of received frame sync loss events
+    uint16_t CRCG ;                   //number of good CRC received frames
+    uint16_t CRCB ;                   //number of bad CRC (CRC error) received frames
+    uint16_t ARFE ;                   //number of address filter errors
+    uint16_t OVER ;                   //number of receiver overflows (used in double buffer mode)
+    uint16_t SFDTO ;                  //SFD timeouts
+    uint16_t PTO ;                    //Preamble timeouts
+    uint16_t RTO ;                    //RX frame wait timeouts
+    uint16_t TXF ;                    //number of transmitted frames
+    uint16_t HPW ;                    //half period warn
+    uint16_t TXW ;                    //power up warn
+
+} dwt_deviceentcnts_t ;
+
+
+/********************************************************************************************************************/
+/*                                                 REMOVED API LIST                                                 */
+/********************************************************************************************************************/
+/*
+ * From version 4.0.0:
+ *  - dwt_setGPIOforEXTTRX: Replaced by dwt_setlnapamode to get equivalent functionality.
+ *  - dwt_setGPIOdirection: Renamed to dwt_setgpiodirection.
+ *  - dwt_setGPIOvalue: Renamed to dwt_setgpiovalue.
+ *  - dwt_setrxmode: Replaced by dwt_setsniffmode and dwt_setlowpowerlistening depending on the RX mode the user
+ *    wants to set up.
+ *  - dwt_checkoverrun: As automatic RX re-enabling is not supported anymore, this functions has become useless.
+ *  - dwt_setautorxreenable: As automatic RX re-enabling is not supported anymore, this functions has become
+ *    useless.
+ *  - dwt_getrangebias: Range bias correction values are platform dependent and should therefore be managed at user
+ *    application level.
+ *  - dwt_xtaltrim: Renamed to dwt_setxtaltrim.
+ *  - dwt_checkIRQ: Renamed to dwt_checkirq.
+ *
+ * From version 3.0.0:
+ *  - dwt_getldotune: As LDO loading is now automatically managed by the driver, this function has become useless.
+ *  - dwt_getotptxpower: TX power values and location in OTP memory are platform dependent and should therefore be
+ *    managed at user application level.
+ *  - dwt_readantennadelay: Antenna delay values and location in OTP memory are platform dependent and should
+ *    therefore be managed at user application level.
+ *  - dwt_readdignostics: Renamed to dwt_readdiagnostics.
+ */
+
+/********************************************************************************************************************/
+/*                                                     API LIST                                                     */
+/********************************************************************************************************************/
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setdevicedataptr()
+ *
+ * @brief This function sets the local data structure pointer to point to the structure in the local array as given by the index.
+ *
+ * input parameters
+ * @param index    - selects the array object to point to. Must be within the array bounds, i.e. < DWT_NUM_DW_DEV
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_setdevicedataptr(unsigned int index);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getpartid()
+ *
+ * @brief This is used to return the read part ID of the device
+ *
+ * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the 32 bit part ID value as programmed in the factory
+ */
+uint32_t dwt_getpartid(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getlotid()
+ *
+ * @brief This is used to return the read lot ID of the device
+ *
+ * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the 32 bit lot ID value as programmed in the factory
+ */
+uint32_t dwt_getlotid(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readdevid()
+ *
+ * @brief This is used to return the read device type and revision information of the DW1000 device (MP part is 0xDECA0130)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the read value which for DW1000 is 0xDECA0130
+ */
+uint32_t dwt_readdevid(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_otprevision()
+ *
+ * @brief This is used to return the read OTP revision
+ *
+ * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the read OTP revision value
+ */
+uint8_t dwt_otprevision(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setfinegraintxseq()
+ *
+ * @brief This function enables/disables the fine grain TX sequencing (enabled by default).
+ *
+ * input parameters
+ * @param enable - 1 to enable fine grain TX sequencing, 0 to disable it.
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void dwt_setfinegraintxseq(int enable);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setlnapamode()
+ *
+ * @brief This is used to enable GPIO for external LNA or PA functionality - HW dependent, consult the DW1000 User Manual.
+ *        This can also be used for debug as enabling TX and RX GPIOs is quite handy to monitor DW1000's activity.
+ *
+ * NOTE: Enabling PA functionality requires that fine grain TX sequencing is deactivated. This can be done using
+ *       dwt_setfinegraintxseq().
+ *
+ * input parameters
+ * @param lna - 1 to enable LNA functionality, 0 to disable it
+ * @param pa - 1 to enable PA functionality, 0 to disable it
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setlnapamode(int lna, int pa);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setgpiodirection()
+ *
+ * @brief This is used to set GPIO direction as an input (1) or output (0)
+ *
+ * input parameters
+ * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
+ * @param direction  -   this sets the GPIO direction - see GxP0... GxP8 in the deca_regs.h file
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setgpiodirection(uint32_t gpioNum, uint32_t direction);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setgpiovalue()
+ *
+ * @brief This is used to set GPIO value as (1) or (0) only applies if the GPIO is configured as output
+ *
+ * input parameters
+ * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
+ * @param value  -   this sets the GPIO value - see GDP0... GDP8 in the deca_regs.h file
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setgpiovalue(uint32_t gpioNum, uint32_t value);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_initialise()
+ *
+ * @brief This function initiates communications with the DW1000 transceiver
+ * and reads its DEV_ID register (address 0x00) to verify the IC is one supported
+ * by this software (e.g. DW1000 32-bit device ID value is 0xDECA0130).  Then it
+ * does any initial once only device configurations needed for use and initialises
+ * as necessary any static data items belonging to this low-level driver.
+ *
+ * NOTES:
+ * 1.this function needs to be run before dwt_configuresleep, also the SPI frequency has to be < 3MHz
+ * 2.it also reads and applies LDO tune and crystal trim values from OTP memory
+ *
+ * input parameters
+ * @param config    -   specifies what configuration to load
+ *                  DWT_LOADUCODE     0x1 - load the LDE microcode from ROM - enabled accurate RX timestamp
+ *                  DWT_LOADNONE      0x0 - do not load any values from OTP memory
+ * @param drv       -   hardware specifc struct containg refernce to SPI, GPIO etc.
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_initialise(uint16_t config) ;   // TODO
+//int dwt_initialise(uint16_t config, DW1000Driver* drv) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configure()
+ *
+ * @brief This function provides the main API for the configuration of the
+ * DW1000 and this low-level driver.  The input is a pointer to the data structure
+ * of type dwt_config_t that holds all the configurable items.
+ * The dwt_config_t structure shows which ones are supported
+ *
+ * input parameters
+ * @param config    -   pointer to the configuration structure, which contains the device configuration data.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configure(dwt_config_t* config) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configuretxrf()
+ *
+ * @brief This function provides the API for the configuration of the TX spectrum
+ * including the power and pulse generator delay. The input is a pointer to the data structure
+ * of type dwt_txconfig_t that holds all the configurable items.
+ *
+ * input parameters
+ * @param config    -   pointer to the txrf configuration structure, which contains the tx rf config data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configuretxrf(dwt_txconfig_t *config) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setrxantennadelay()
+ *
+ * @brief This API function writes the antenna delay (in time units) to RX registers
+ *
+ * input parameters:
+ * @param rxDelay - this is the total (RX) antenna delay value, which
+ *                          will be programmed into the RX register
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setrxantennadelay(uint16_t antennaDly);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_settxantennadelay()
+ *
+ * @brief This API function writes the antenna delay (in time units) to TX registers
+ *
+ * input parameters:
+ * @param txDelay - this is the total (TX) antenna delay value, which
+ *                          will be programmed into the TX delay register
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_settxantennadelay(uint16_t antennaDly);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setsmarttxpower()
+ *
+ * @brief This call enables or disables the smart TX power feature.
+ *
+ * input parameters
+ * @param enable - this enables or disables the TX smart power (1 = enable, 0 = disable)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setsmarttxpower(int enable);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_writetxdata()
+ *
+ * @brief This API function writes the supplied TX data into the DW1000's
+ * TX buffer.  The input parameters are the data length in bytes and a pointer
+ * to those data bytes.
+ *
+ * input parameters
+ * @param txFrameLength  - This is the total frame length, including the two byte CRC.
+ *                         Note: this is the length of TX message (including the 2 byte CRC) - max is 1023
+ *                         standard PHR mode allows up to 127 bytes
+ *                         if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
+ *                         see dwt_configure function
+ * @param txFrameBytes   - Pointer to the user’s buffer containing the data to send.
+ * @param txBufferOffset - This specifies an offset in the DW1000’s TX Buffer at which to start writing data.
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_writetxdata(uint16_t txFrameLength, uint8_t *txFrameBytes, uint16_t txBufferOffset) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_writetxfctrl()
+ *
+ * @brief This API function configures the TX frame control register before the transmission of a frame
+ *
+ * input parameters:
+ * @param txFrameLength - this is the length of TX message (including the 2 byte CRC) - max is 1023
+ *                              NOTE: standard PHR mode allows up to 127 bytes
+ *                              if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
+ *                              see dwt_configure function
+ * @param txBufferOffset - the offset in the tx buffer to start writing the data
+ * @param ranging - 1 if this is a ranging frame, else 0
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_writetxfctrl(uint16_t txFrameLength, uint16_t txBufferOffset, int ranging);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_starttx()
+ *
+ * @brief This call initiates the transmission, input parameter indicates which TX mode is used see below
+ *
+ * input parameters:
+ * @param mode - is a bitmask for which the following values can be combined to define the operation
+ *               DWT_START_TX_IMMEDIATE (0)            - to begin transmission immediatelty.
+ *               DWT_START_TX_DELAYED   (to set bit 0) - to begin TX at pre-configured delay time
+ *               DWT_RESPONSE_EXPECTED  (to set bit 1) - to turn the receiver on automatically (after the TX) after a pre-programmed delay
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error (e.g. a delayed transmission will fail if the delayed time has passed)
+ */
+int dwt_starttx(uint8_t mode) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setdelayedtrxtime()
+ *
+ * @brief This API function configures the delayed transmit time or the delayed RX on time
+ *
+ * input parameters
+ * @param starttime - the TX/RX start time (the 32 bits should be the high 32 bits of the system time at which to send the message,
+ * or at which to turn on the receiver)
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void dwt_setdelayedtrxtime(uint32_t starttime) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtxtimestamp()
+ *
+ * @brief This is used to read the TX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ * @param timestamp - a pointer to a 5-byte buffer which will store the read TX timestamp time
+ *
+ * output parameters - the timestamp buffer will contain the value after the function call
+ *
+ * no return value
+ */
+void dwt_readtxtimestamp(uint8_t * timestamp);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtxtimestamphi32()
+ *
+ * @brief This is used to read the high 32-bits of the TX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns high 32-bits of TX timestamp
+ */
+uint32_t dwt_readtxtimestamphi32(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtxtimestamplo32()
+ *
+ * @brief This is used to read the low 32-bits of the TX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns low 32-bits of TX timestamp
+ */
+uint32_t dwt_readtxtimestamplo32(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxtimestamp()
+ *
+ * @brief This is used to read the RX timestamp (adjusted time of arrival)
+ *
+ * input parameters
+ * @param timestamp - a pointer to a 5-byte buffer which will store the read RX timestamp time
+ *
+ * output parameters - the timestamp buffer will contain the value after the function call
+ *
+ * no return value
+ */
+void dwt_readrxtimestamp(uint8_t * timestamp);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxtimestamphi32()
+ *
+ * @brief This is used to read the high 32-bits of the RX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns high 32-bits of RX timestamp
+ */
+uint32_t dwt_readrxtimestamphi32(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxtimestamplo32()
+ *
+ * @brief This is used to read the low 32-bits of the RX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns low 32-bits of RX timestamp
+ */
+uint32_t dwt_readrxtimestamplo32(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readsystimestamphi32()
+ *
+ * @brief This is used to read the high 32-bits of the system time
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns high 32-bits of system time timestamp
+ */
+uint32_t dwt_readsystimestamphi32(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readsystime()
+ *
+ * @brief This is used to read the system time
+ *
+ * input parameters
+ * @param timestamp - a pointer to a 5-byte buffer which will store the read system time
+ *
+ * output parameters
+ * @param timestamp - the timestamp buffer will contain the value after the function call
+ *
+ * no return value
+ */
+void dwt_readsystime(uint8_t * timestamp);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_forcetrxoff()
+ *
+ * @brief This is used to turn off the transceiver
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_forcetrxoff(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_syncrxbufptrs()
+ *
+ * @brief this function synchronizes rx buffer pointers
+ * need to make sure that the host/IC buffer pointers are aligned before starting RX
+ *
+ * input parameters:
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_syncrxbufptrs(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_rxenable()
+ *
+ * @brief This call turns on the receiver, can be immediate or delayed (depending on the mode parameter). In the case of a
+ * "late" error the receiver will only be turned on if the DWT_IDLE_ON_DLY_ERR is not set.
+ * The receiver will stay turned on, listening to any messages until
+ * it either receives a good frame, an error (CRC, PHY header, Reed Solomon) or  it times out (SFD, Preamble or Frame).
+ *
+ * input parameters
+ * @param mode - this can be one of the following allowed values:
+ *
+ * DWT_START_RX_IMMEDIATE      0 used to enbale receiver immediately
+ * DWT_START_RX_DELAYED        1 used to set up delayed RX, if "late" error triggers, then the RX will be enabled immediately
+ * (DWT_START_RX_DELAYED | DWT_IDLE_ON_DLY_ERR) 3 used to disable re-enabling of receiver if delayed RX failed due to "late" error
+ * (DWT_START_RX_IMMEDIATE | DWT_NO_SYNC_PTRS) 4 used to re-enable RX without trying to sync IC and host side buffer pointers, typically when
+ *                                               performing manual RX re-enabling in double buffering mode
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error (e.g. a delayed receive enable will be too far in the future if delayed time has passed)
+ */
+int dwt_rxenable(int mode);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setsniffmode()
+ *
+ * @brief enable/disable and configure SNIFF mode.
+ *
+ * SNIFF mode is a low-power reception mode where the receiver is sequenced on and off instead of being on all the time.
+ * The time spent in each state (on/off) is specified through the parameters below.
+ * See DW1000 User Manual section 4.5 "Low-Power SNIFF mode" for more details.
+ *
+ * input parameters:
+ * @param enable - 1 to enable SNIFF mode, 0 to disable. When 0, all other parameters are not taken into account.
+ * @param timeOn - duration of receiver ON phase, expressed in multiples of PAC size. The counter automatically adds 1 PAC
+ *                 size to the value set. Min value that can be set is 1 (i.e. an ON time of 2 PAC size), max value is 15.
+ * @param timeOff - duration of receiver OFF phase, expressed in multiples of 128/125 µs (~1 µs). Max value is 255.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setsniffmode(int enable, uint8_t timeOn, uint8_t timeOff);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setlowpowerlistening()
+ *
+ * @brief enable/disable low-power listening mode.
+ *
+ * Low-power listening is a feature whereby the DW1000 is predominantly in the SLEEP state but wakes periodically, (after
+ * this "long sleep"), for a very short time to sample the air for a preamble sequence. This preamble sampling "listening"
+ * phase is actually two reception phases separated by a "short sleep" time. See DW1000 User Manual section "Low-Power
+ * Listening" for more details.
+ *
+ * NOTE: Before enabling low-power listening, the following functions have to be called to fully configure it:
+ *           - dwt_configuresleep() to configure long sleep phase. "mode" parameter should at least have DWT_PRESRV_SLEEP,
+ *             DWT_CONFIG and DWT_RX_EN set and "wake" parameter should at least have both DWT_WAKE_SLPCNT and DWT_SLP_EN set.
+ *           - dwt_calibratesleepcnt() and dwt_configuresleepcnt() to define the "long sleep" phase duration.
+ *           - dwt_setsnoozetime() to define the "short sleep" phase duration.
+ *           - dwt_setpreambledetecttimeout() to define the reception phases duration.
+ *           - dwt_setinterrupt() to activate RX good frame interrupt (DWT_INT_RFCG) only.
+ *       When configured, low-power listening mode can be triggered either by putting the DW1000 to sleep (using
+ *       dwt_entersleep()) or by activating reception (using dwt_rxenable()).
+ *
+ *       Please refer to the low-power listening examples (examples 8a/8b accompanying the API distribution on Decawave's
+ *       website). They form a working example code that shows how to use low-power listening correctly.
+ *
+ * input parameters:
+ * @param enable - 1 to enable low-power listening, 0 to disable.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setlowpowerlistening(int enable);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setsnoozetime()
+ *
+ * @brief Set duration of "short sleep" phase when in low-power listening mode.
+ *
+ * input parameters:
+ * @param snooze_time - "short sleep" phase duration, expressed in multiples of 512/19.2 µs (~26.7 µs). The counter
+ *                      automatically adds 1 to the value set. The smallest working value that should be set is 1,
+ *                      i.e. giving a snooze time of 2 units (or ~53 µs).
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setsnoozetime(uint8_t snooze_time);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setdblrxbuffmode()
+ *
+ * @brief This call enables the double receive buffer mode
+ *
+ * input parameters
+ * @param enable - 1 to enable, 0 to disable the double buffer mode
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setdblrxbuffmode(int enable);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setrxtimeout()
+ *
+ * @brief This call enables RX timeout (SY_STAT_RFTO event)
+ *
+ * input parameters
+ * @param time - how long the receiver remains on from the RX enable command
+ *               The time parameter used here is in 1.0256 us (512/499.2MHz) units
+ *               If set to 0 the timeout is disabled.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setrxtimeout(uint16_t time);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setpreambledetecttimeout()
+ *
+ * @brief This call enables preamble timeout (SY_STAT_RXPTO event)
+ *
+ * input parameters
+ * @param  timeout - Preamble detection timeout, expressed in multiples of PAC size. The counter automatically adds 1 PAC
+ *                   size to the value set. Min value that can be set is 1 (i.e. a timeout of 2 PAC size).
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setpreambledetecttimeout(uint16_t timeout);
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calibratesleepcnt()
+ *
+ * @brief calibrates the local oscillator as its frequency can vary between 7 and 13kHz depending on temp and voltage
+ *
+ * NOTE: this function needs to be run before dwt_configuresleepcnt, so that we know what the counter units are
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the number of XTAL/2 cycles per low-power oscillator cycle. LP OSC frequency = 19.2 MHz/return value
+ */
+uint16_t dwt_calibratesleepcnt(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configuresleepcnt()
+ *
+ * @brief sets the sleep counter to new value, this function programs the high 16-bits of the 28-bit counter
+ *
+ * NOTE: this function needs to be run before dwt_configuresleep, also the SPI frequency has to be < 3MHz
+ *
+ * input parameters
+ * @param sleepcnt - this it value of the sleep counter to program
+ *
+ * output parameters
+ *
+ * no return value
+ */
+ void dwt_configuresleepcnt(uint16_t sleepcnt);
+
+ /*! ------------------------------------------------------------------------------------------------------------------
+  * @fn dwt_configuresleep()
+  *
+  * @brief configures the device for both DEEP_SLEEP and SLEEP modes, and on-wake mode
+  * i.e. before entering the sleep, the device should be programmed for TX or RX, then upon "waking up" the TX/RX settings
+  * will be preserved and the device can immediately perform the desired action TX/RX
+  *
+  * NOTE: e.g. Tag operation - after deep sleep, the device needs to just load the TX buffer and send the frame
+  *
+  *
+  *      mode: the array and LDE code (OTP/ROM) and LDO tune, and set sleep persist
+  *      DWT_PRESRV_SLEEP 0x0100 - preserve sleep
+  *      DWT_LOADOPSET    0x0080 - load operating parameter set on wakeup
+  *      DWT_CONFIG       0x0040 - download the AON array into the HIF (configuration download)
+  *      DWT_LOADEUI      0x0008
+  *      DWT_GOTORX       0x0002
+  *      DWT_TANDV        0x0001
+  *
+  *      wake: wake up parameters
+  *      DWT_XTAL_EN      0x10 - keep XTAL running during sleep
+  *      DWT_WAKE_SLPCNT  0x8 - wake up after sleep count
+  *      DWT_WAKE_CS      0x4 - wake up on chip select
+  *      DWT_WAKE_WK      0x2 - wake up on WAKEUP PIN
+  *      DWT_SLP_EN       0x1 - enable sleep/deep sleep functionality
+  *
+  * input parameters
+  * @param mode - config on-wake parameters
+  * @param wake - config wake up parameters
+  *
+  * output parameters
+  *
+  * no return value
+  */
+void dwt_configuresleep(uint16_t mode, uint8_t wake);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_entersleep()
+ *
+ * @brief This function puts the device into deep sleep or sleep. dwt_configuresleep() should be called first
+ * to configure the sleep and on-wake/wake-up parameters
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_entersleep(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_entersleepaftertx(int enable)
+ *
+ * @brief sets the auto TX to sleep bit. This means that after a frame
+ * transmission the device will enter deep sleep mode. The dwt_configuresleep() function
+ * needs to be called before this to configure the on-wake settings
+ *
+ * NOTE: the IRQ line has to be low/inactive (i.e. no pending events)
+ *
+ * input parameters
+ * @param enable - 1 to configure the device to enter deep sleep after TX, 0 - disables the configuration
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_entersleepaftertx(int enable);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_spicswakeup()
+ *
+ * @brief wake up the device from sleep mode using the SPI read,
+ * the device will wake up on chip select line going low if the line is held low for at least 500us.
+ * To define the length depending on the time one wants to hold
+ * the chip select line low, use the following formula:
+ *
+ *      length (bytes) = time (s) * byte_rate (Hz)
+ *
+ * where fastest byte_rate is spi_rate (Hz) / 8 if the SPI is sending the bytes back-to-back.
+ * To save time and power, a system designer could determine byte_rate value more precisely.
+ *
+ * NOTE: Alternatively the device can be waken up with WAKE_UP pin if configured for that operation
+ *
+ * input parameters
+ * @param buff   - this is a pointer to the dummy buffer which will be used in the SPI read transaction used for the WAKE UP of the device
+ * @param length - this is the length of the dummy buffer
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_spicswakeup(uint8_t *buff, uint16_t length);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setcallbacks()
+ *
+ * @brief This function is used to register the different callbacks called when one of the corresponding event occurs.
+ *
+ * NOTE: Callbacks can be undefined (set to NULL). In this case, dwt_isr() will process the event as usual but the 'null'
+ * callback will not be called.
+ *
+ * input parameters
+ * @param cbTxDone - the pointer to the TX confirmation event callback function
+ * @param cbRxOk - the pointer to the RX good frame event callback function
+ * @param cbRxTo - the pointer to the RX timeout events callback function
+ * @param cbRxErr - the pointer to the RX error events callback function
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setcallbacks(dwt_cb_t cbTxDone, dwt_cb_t cbRxOk, dwt_cb_t cbRxTo, dwt_cb_t cbRxErr);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_checkirq()
+ *
+ * @brief This function checks if the IRQ line is active - this is used instead of interrupt handler
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * return value is 1 if the IRQS bit is set and 0 otherwise
+ */
+uint8_t dwt_checkirq(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_isr()
+ *
+ * @brief This is the DW1000's general Interrupt Service Routine. It will process/report the following events:
+ *          - RXFCG (through cbRxOk callback)
+ *          - TXFRS (through cbTxDone callback)
+ *          - RXRFTO/RXPTO (through cbRxTo callback)
+ *          - RXPHE/RXFCE/RXRFSL/RXSFDTO/AFFREJ/LDEERR (through cbRxTo cbRxErr)
+ *        For all events, corresponding interrupts are cleared and necessary resets are performed. In addition, in the RXFCG case,
+ *        received frame information and frame control are read before calling the callback. If double buffering is activated, it
+ *        will also toggle between reception buffers once the reception callback processing has ended.
+ *
+ *        /!\ This version of the ISR supports double buffering but does not support automatic RX re-enabling!
+ *
+ * NOTE:  In PC based system using (Cheetah or ARM) USB to SPI converter there can be no interrupts, however we still need something
+ *        to take the place of it and operate in a polled way. In an embedded system this function should be configured to be triggered
+ *        on any of the interrupts described above.
+
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_isr(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_isr_lplisten()
+ *
+ * @brief This is the DW1000's Interrupt Service Routine to use when low-power listening scheme is implemented. It will
+ *        only process/report the RXFCG event (through cbRxOk callback).
+ *        It clears RXFCG interrupt and reads received frame information and frame control before calling the callback.
+ *
+ *        /!\ This version of the ISR is designed for single buffering case only!
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_lowpowerlistenisr(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn void dwt_setinterrupt()
+ *
+ * @brief This function enables the specified events to trigger an interrupt.
+ * The following events can be enabled:
+ * DWT_INT_TFRS         0x00000080          // frame sent
+ * DWT_INT_RFCG         0x00004000          // frame received with good CRC
+ * DWT_INT_RPHE         0x00001000          // receiver PHY header error
+ * DWT_INT_RFCE         0x00008000          // receiver CRC error
+ * DWT_INT_RFSL         0x00010000          // receiver sync loss error
+ * DWT_INT_RFTO         0x00020000          // frame wait timeout
+ * DWT_INT_RXPTO        0x00200000          // preamble detect timeout
+ * DWT_INT_SFDT         0x04000000          // SFD timeout
+ * DWT_INT_ARFE         0x20000000          // frame rejected (due to frame filtering configuration)
+ *
+ *
+ * input parameters:
+ * @param bitmask - sets the events which will generate interrupt
+ * @param enable - if set the interrupts are enabled else they are cleared
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setinterrupt( uint32_t bitmask, uint8_t enable);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setpanid()
+ *
+ * @brief This is used to set the PAN ID
+ *
+ * input parameters
+ * @param panID - this is the PAN ID
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setpanid(uint16_t panID);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setaddress16()
+ *
+ * @brief This is used to set 16-bit (short) address
+ *
+ * input parameters
+ * @param shortAddress - this sets the 16 bit short address
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setaddress16(uint16_t shortAddress);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_seteui()
+ *
+ * @brief This is used to set the EUI 64-bit (long) address
+ *
+ * input parameters
+ * @param eui64 - this is the pointer to a buffer that contains the 64bit address
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_seteui(uint8_t *eui64);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_geteui()
+ *
+ * @brief This is used to get the EUI 64-bit from the DW1000
+ *
+ * input parameters
+ * @param eui64 - this is the pointer to a buffer that will contain the read 64-bit EUI value
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_geteui(uint8_t *eui64);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_otpread()
+ *
+ * @brief This is used to read the OTP data from given address into provided array
+ *
+ * input parameters
+ * @param address - this is the OTP address to read from
+ * @param array - this is the pointer to the array into which to read the data
+ * @param length - this is the number of 32 bit words to read (array needs to be at least this length)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_otpread(uint32_t address, uint32_t *array, uint8_t length);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_enableframefilter()
+ *
+ * @brief This is used to enable the frame filtering - (the default option is to
+ * accept any data and ACK frames with correct destination address
+ *
+ * input parameters
+ * @param - bitmask - enables/disables the frame filtering options according to
+ *      DWT_FF_NOTYPE_EN        0x000   no frame types allowed
+ *      DWT_FF_COORD_EN         0x002   behave as coordinator (can receive frames with no destination address (PAN ID has to match))
+ *      DWT_FF_BEACON_EN        0x004   beacon frames allowed
+ *      DWT_FF_DATA_EN          0x008   data frames allowed
+ *      DWT_FF_ACK_EN           0x010   ack frames allowed
+ *      DWT_FF_MAC_EN           0x020   mac control frames allowed
+ *      DWT_FF_RSVD_EN          0x040   reserved frame types allowed
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_enableframefilter(uint16_t bitmask);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_enableautoack()
+ *
+ * @brief This call enables the auto-ACK feature. If the responseDelayTime (parameter) is 0, the ACK will be sent a.s.a.p.
+ * otherwise it will be sent with a programmed delay (in symbols), max is 255.
+ * NOTE: needs to have frame filtering enabled as well
+ *
+ * input parameters
+ * @param responseDelayTime - if non-zero the ACK is sent after this delay, max is 255.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_enableautoack(uint8_t responseDelayTime);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setrxaftertxdelay()
+ *
+ * @brief This sets the receiver turn on delay time after a transmission of a frame
+ *
+ * input parameters
+ * @param rxDelayTime - (20 bits) - the delay is in UWB microseconds
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setrxaftertxdelay(uint32_t rxDelayTime);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_rxreset()
+ *
+ * @brief this function resets the receiver of the DW1000
+ *
+ * input parameters:
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_rxreset(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_softreset()
+ *
+ * @brief this function resets the DW1000
+ *
+ * input parameters:
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_softreset(void) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxdata()
+ *
+ * @brief This is used to read the data from the RX buffer, from an offset location give by offset parameter
+ *
+ * input parameters
+ * @param buffer - the buffer into which the data will be read
+ * @param length - the length of data to read (in bytes)
+ * @param rxBufferOffset - the offset in the rx buffer from which to read the data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readrxdata(uint8_t *buffer, uint16_t length, uint16_t rxBufferOffset);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readaccdata()
+ *
+ * @brief This is used to read the data from the Accumulator buffer, from an offset location give by offset parameter
+ *
+ * NOTE: Because of an internal memory access delay when reading the accumulator the first octet output is a dummy octet
+ *       that should be discarded. This is true no matter what sub-index the read begins at.
+ *
+ * input parameters
+ * @param buffer - the buffer into which the data will be read
+ * @param length - the length of data to read (in bytes)
+ * @param accOffset - the offset in the acc buffer from which to read the data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readaccdata(uint8_t *buffer, uint16_t length, uint16_t rxBufferOffset);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readdiagnostics()
+ *
+ * @brief this function reads the RX signal quality diagnostic data
+ *
+ * input parameters
+ * @param diagnostics - diagnostic structure pointer, this will contain the diagnostic data read from the DW1000
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readdiagnostics(dwt_rxdiag_t * diagnostics);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_loadopsettabfromotp()
+ *
+ * @brief This is used to select which Operational Parameter Set table to load from OTP memory
+ *
+ * input parameters
+ * @param ops_sel - Operational Parameter Set table to load:
+ *                  DWT_OPSET_64LEN = 0x0 - load the operational parameter set table for 64 length preamble configuration
+ *                  DWT_OPSET_TIGHT = 0x1 - load the operational parameter set table for tight xtal offsets (<1ppm)
+ *                  DWT_OPSET_DEFLT = 0x2 - load the default operational parameter set table (this is loaded from reset)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_loadopsettabfromotp(uint8_t ops_sel);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configeventcounters()
+ *
+ * @brief This is used to enable/disable the event counter in the IC
+ *
+ * input parameters
+ * @param - enable - 1 enables (and reset), 0 disables the event counters
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configeventcounters(int enable);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readeventcounters()
+ *
+ * @brief This is used to read the event counters in the IC
+ *
+ * input parameters
+ * @param counters - pointer to the dwt_deviceentcnts_t structure which will hold the read data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readeventcounters(dwt_deviceentcnts_t *counters);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_otpwriteandverify()
+ *
+ * @brief This is used to program 32-bit value into the DW1000 OTP memory.
+ *
+ * input parameters
+ * @param value - this is the 32-bit value to be programmed into OTP
+ * @param address - this is the 16-bit OTP address into which the 32-bit value is programmed
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_otpwriteandverify(uint32_t value, uint16_t address);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setleds()
+ *
+ * @brief This is used to set up Tx/Rx GPIOs which could be used to control LEDs
+ * Note: not completely IC dependent, also needs board with LEDS fitted on right I/O lines
+ *       this function enables GPIOs 2 and 3 which are connected to LED3 and LED4 on EVB1000
+ *
+ * input parameters
+ * @param mode - this is a bit field interpreted as follows:
+ *          - bit 0: 1 to enable LEDs, 0 to disable them
+ *          - bit 1: 1 to make LEDs blink once on init. Only valid if bit 0 is set (enable LEDs)
+ *          - bit 2 to 7: reserved
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void dwt_setleds(uint8_t mode);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setxtaltrim()
+ *
+ * @brief This is used to adjust the crystal frequency
+ *
+ * input parameters:
+ * @param   value - crystal trim value (in range 0x0 to 0x1F) 31 steps (~1.5ppm per step)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setxtaltrim(uint8_t value);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getinitxtaltrim()
+ *
+ * @brief This function returns the value of XTAL trim that has been applied during initialisation (dwt_init). This can
+ *        be either the value read in OTP memory or a default value.
+ *
+ * NOTE: The value returned by this function is the initial value only! It is not updated on dwt_setxtaltrim calls.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the XTAL trim value set upon initialisation
+ */
+uint8_t dwt_getinitxtaltrim(void);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configcwmode()
+ *
+ * @brief this function sets the DW1000 to transmit cw signal at specific channel frequency
+ *
+ * input parameters:
+ * @param chan - specifies the operating channel (e.g. 1, 2, 3, 4, 5, 6 or 7)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configcwmode(uint8_t chan);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configcontinuousframemode()
+ *
+ * @brief this function sets the DW1000 to continuous tx frame mode for regulatory approvals testing.
+ *
+ * input parameters:
+ * @param framerepetitionrate - This is a 32-bit value that is used to set the interval between transmissions.
+*  The minimum value is 4. The units are approximately 8 ns. (or more precisely 512/(499.2e6*128) seconds)).
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configcontinuousframemode(uint32_t framerepetitionrate);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtempvbat()
+ *
+ * @brief this function reads the battery voltage and temperature of the MP
+ * The values read here will be the current values sampled by DW1000 AtoD converters.
+ * Note on Temperature: the temperature value needs to be converted to give the real temperature
+ * the formula is: 1.13 * reading - 113.0
+ * Note on Voltage: the voltage value needs to be converted to give the real voltage
+ * the formula is: 0.0057 * reading + 2.3
+ *
+ * NB: To correctly read the temperature this read should be done with xtal clock
+ * however that means that the receiver will be switched off, if receiver needs to be on then
+ * the timer is used to make sure the value is stable before reading
+ *
+ * input parameters:
+ * @param fastSPI - set to 1 if SPI rate > than 3MHz is used
+ *
+ * output parameters
+ *
+ * returns  (temp_raw<<8)|(vbat_raw)
+ */
+uint16_t dwt_readtempvbat(uint8_t fastSPI);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readwakeuptemp()
+ *
+ * @brief this function reads the temperature of the DW1000 that was sampled
+ * on waking from Sleep/Deepsleep. They are not current values, but read on last
+ * wakeup if DWT_TANDV bit is set in mode parameter of dwt_configuresleep
+ *
+ * input parameters:
+ *
+ * output parameters:
+ *
+ * returns: 8-bit raw temperature sensor value
+ */
+uint8_t dwt_readwakeuptemp(void) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readwakeupvbat()
+ *
+ * @brief this function reads the battery voltage of the DW1000 that was sampled
+ * on waking from Sleep/Deepsleep. They are not current values, but read on last
+ * wakeup if DWT_TANDV bit is set in mode parameter of dwt_configuresleep
+ *
+ * input parameters:
+ *
+ * output parameters:
+ *
+ * returns: 8-bit raw battery voltage sensor value
+ */
+uint8_t dwt_readwakeupvbat(void) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calcbandwidthtempadj()
+ *
+ * @brief this function determines the corrected bandwidth setting (PG_DELAY register setting)
+ * of the DW1000 which changes over temperature.
+ *
+ * input parameters:
+ * @param target_count - uint16_t - the PG count target to reach in order to correct the bandwidth
+ *
+ * output parameters:
+ *
+ * returns: (uint32) The setting to be programmed into the PG_DELAY value
+ */
+uint32_t dwt_calcbandwidthtempadj(uint16_t target_count);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calcpowertempadj()
+ *
+ * @brief this function determines the corrected power setting (TX_POWER setting) for the
+ * DW1000 which changes over temperature.
+ *
+ * input parameters:
+ * @param channel - uint8_t - the channel at which compensation of power level will be applied
+ * @param ref_powerreg - uint32_t - the TX_POWER register value recorded when reference measurements were made
+ * @param current_temperature - double - the current ambient temperature in degrees Celcius
+ * @param reference_temperature - double - the temperature at which reference measurements were made
+ * output parameters: None
+ *
+ * returns: (uint32) The corrected TX_POWER register value
+ */
+uint32_t dwt_calcpowertempadj(uint8_t channel, uint32_t ref_powerreg, double current_temperature, double reference_temperature);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calcpgcount()
+ *
+ * @brief this function calculates the value in the pulse generator counter register (PGC_STATUS) for a given PG_DELAY
+ * This is used to take a reference measurement, and the value recorded as the reference is used to adjust the
+ * bandwidth of the device when the temperature changes.
+ *
+ * input parameters:
+ * @param pgdly - uint8_t - the PG_DELAY to set (to control bandwidth), and to find the corresponding count value for
+ * output parameters: None
+ *
+ * returns: (uint16) PGC_STATUS count value calculated from the provided PG_DELAY value - used as reference for later
+ * bandwidth adjustments
+ */
+uint16_t dwt_calcpgcount(uint8_t pgdly);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_writetodevice()
+ *
+ * @brief  this function is used to write to the DW1000 device registers
+ * Notes:
+ *        1. Firstly we create a header (the first byte is a header byte)
+ *        a. check if sub index is used, if subindexing is used - set bit-6 to 1 to signify that the sub-index address follows the register index byte
+ *        b. set bit-7 (or with 0x80) for write operation
+ *        c. if extended sub address index is used (i.e. if index > 127) set bit-7 of the first sub-index byte following the first header byte
+ *
+ *        2. Write the header followed by the data bytes to the DW1000 device
+ *
+ *
+ * input parameters:
+ * @param recordNumber  - ID of register file or buffer being accessed
+ * @param index         - byte index into register file or buffer being accessed
+ * @param length        - number of bytes being written
+ * @param buffer        - pointer to buffer containing the 'length' bytes to be written
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_writetodevice
+(
+    uint16_t      recordNumber,   // input parameter - ID of register file or buffer being accessed
+    uint16_t      index,          // input parameter - byte index into register file or buffer being accessed
+    uint32_t      length,         // input parameter - number of bytes being written
+    const uint8_t *buffer         // input parameter - pointer to buffer containing the 'length' bytes to be written
+) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readfromdevice()
+ *
+ * @brief  this function is used to read from the DW1000 device registers
+ * Notes:
+ *        1. Firstly we create a header (the first byte is a header byte)
+ *        a. check if sub index is used, if subindexing is used - set bit-6 to 1 to signify that the sub-index address follows the register index byte
+ *        b. set bit-7 (or with 0x80) for write operation
+ *        c. if extended sub address index is used (i.e. if index > 127) set bit-7 of the first sub-index byte following the first header byte
+ *
+ *        2. Write the header followed by the data bytes to the DW1000 device
+ *        3. Store the read data in the input buffer
+ *
+ * input parameters:
+ * @param recordNumber  - ID of register file or buffer being accessed
+ * @param index         - byte index into register file or buffer being accessed
+ * @param length        - number of bytes being read
+ * @param buffer        - pointer to buffer in which to return the read data.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readfromdevice
+(
+    uint16_t  recordNumber,       // input parameter - ID of register file or buffer being accessed
+    uint16_t  index,              // input parameter - byte index into register file or buffer being accessed
+    uint32_t  length,             // input parameter - number of bytes being read
+    uint8_t   *buffer             // input parameter - pointer to buffer in which to return the read data.
+) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_read32bitoffsetreg()
+ *
+ * @brief  this function is used to read 32-bit value from the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ *
+ * output parameters
+ *
+ * returns 32 bit register value
+ */
+uint32_t dwt_read32bitoffsetreg(int regFileID, int regOffset) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_write32bitoffsetreg()
+ *
+ * @brief  this function is used to write 32-bit value to the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ * @param regval    - the value to write
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_write32bitoffsetreg(int regFileID, int regOffset, uint32_t regval);
+
+#define dwt_write32bitreg(x,y)  dwt_write32bitoffsetreg(x,0,y)
+#define dwt_read32bitreg(x)     dwt_read32bitoffsetreg(x,0)
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_read16bitoffsetreg()
+ *
+ * @brief  this function is used to read 16-bit value from the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ *
+ * output parameters
+ *
+ * returns 16 bit register value
+ */
+uint16_t dwt_read16bitoffsetreg(int regFileID, int regOffset);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_write16bitoffsetreg()
+ *
+ * @brief  this function is used to write 16-bit value to the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ * @param regval    - the value to write
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_write16bitoffsetreg(int regFileID, int regOffset, uint16_t regval) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_read8bitoffsetreg()
+ *
+ * @brief  this function is used to read an 8-bit value from the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ *
+ * output parameters
+ *
+ * returns 8-bit register value
+ */
+uint8_t dwt_read8bitoffsetreg(int regFileID, int regOffset);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_write8bitoffsetreg()
+ *
+ * @brief  this function is used to write an 8-bit value to the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ * @param regval    - the value to write
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_write8bitoffsetreg(int regFileID, int regOffset, uint8_t regval);
+
+
+/****************************************************************************************************************************************************
+ *
+ * Declaration of platform-dependent lower level functions.
+ *
+ ****************************************************************************************************************************************************/
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn writetospi()
+ *
+ * @brief
+ * NB: In porting this to a particular microprocessor, the implementer needs to define the two low
+ * level abstract functions to write to and read from the SPI.
+ * Low level abstract function to write to the SPI
+ * Takes two separate byte buffers for write header and write data
+ * returns 0 for success, or -1 for error
+ *
+ * Note: The body of this function is platform specific
+ *
+ * input parameters:
+ * @param headerLength  - number of bytes header being written
+ * @param headerBuffer  - pointer to buffer containing the 'headerLength' bytes of header to be written
+ * @param bodylength    - number of bytes data being written
+ * @param bodyBuffer    - pointer to buffer containing the 'bodylength' bytes od data to be written
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+extern int writetospi(uint16_t headerLength, const uint8_t *headerBuffer, uint32_t bodylength, const uint8_t *bodyBuffer);
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn readfromspi()
+ *
+ * @brief
+ * NB: In porting this to a particular microprocessor, the implementer needs to define the two low
+ * level abstract functions to write to and read from the SPI.
+ * Low level abstract function to write to the SPI
+ * Takes two separate byte buffers for write header and write data
+ * returns 0 for success, or -1 for error
+ *
+ * Note: The body of this function is platform specific
+ *
+ * input parameters:
+ * @param headerLength  - number of bytes header to write
+ * @param headerBuffer  - pointer to buffer containing the 'headerLength' bytes of header to write
+ * @param readlength    - number of bytes data being read
+ * @param readBuffer    - pointer to buffer containing to return the data (NB: size required = headerLength + readlength)
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success (and the position in the buffer at which data begins), or DWT_ERROR for error
+ */
+extern int readfromspi(uint16_t headerLength, const uint8_t *headerBuffer, uint32_t readlength, uint8_t *readBuffer);
+
+// ---------------------------------------------------------------------------
+//
+// NB: The purpose of the deca_mutex.c file is to provide for microprocessor interrupt enable/disable, this is used for
+//     controlling mutual exclusion from critical sections in the code where interrupts and background
+//     processing may interact.  The code using this is kept to a minimum and the disabling time is also
+//     kept to a minimum, so blanket interrupt disable may be the easiest way to provide this.  But at a
+//     minimum those interrupts coming from the decawave device should be disabled/re-enabled by this activity.
+//
+//     In porting this to a particular microprocessor, the implementer may choose to use #defines here
+//     to map these calls transparently to the target system.  Alternatively the appropriate code may
+//     be embedded in the functions provided in the deca_irq.c file.
+//
+// ---------------------------------------------------------------------------
+
+typedef int decaIrqStatus_t ; // Type for remembering IRQ status
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn decamutexon()
+ *
+ * @brief This function should disable interrupts. This is called at the start of a critical section
+ * It returns the IRQ state before disable, this value is used to re-enable in decamutexoff call
+ *
+ * Note: The body of this function is platform specific
+ *
+ * input parameters:
+ *
+ * output parameters
+ *
+ * returns the state of the DW1000 interrupt
+ */
+decaIrqStatus_t decamutexon(void) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn decamutexoff()
+ *
+ * @brief This function should re-enable interrupts, or at least restore their state as returned(&saved) by decamutexon
+ * This is called at the end of a critical section
+ *
+ * Note: The body of this function is platform specific
+ *
+ * input parameters:
+ * @param s - the state of the DW1000 interrupt as returned by decamutexon
+ *
+ * output parameters
+ *
+ * returns the state of the DW1000 interrupt
+ */
+void decamutexoff(decaIrqStatus_t s) ;
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn deca_sleep()
+ *
+ * @brief Wait for a given amount of time.
+ * NB: The body of this function is platform specific
+ *
+ * input parameters:
+ * @param time_ms - time to wait in milliseconds
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void deca_sleep(unsigned int time_ms);
+void Sleep(unsigned int time_ms);
+
+
+void port_EnableEXT_IRQ(void);
+void port_DisableEXT_IRQ(void);
+ITStatus port_GetEXT_IRQStatus(void);
+
+void port_set_dw1000_slowrate(void);
+void port_set_dw1000_fastrate(void);
+void port_wakeup_dw1000_fast(void);
+uint32_t portGetTickCnt(void);
+
+
+/**
+ * @brief   Pad specific IRQn handler. modify it if the PIN no. is changed
+ */
+#define DW1000_EXTI_IRQn    EXTI15_10_IRQn
+
+
+/**
+ * @brief   Flag to switch between two SPI speeds on the fly
+ */
+extern bool isHighSpeedSpi;
+
+
+/**
+ * @brief   Configuration for the Low Speed SPI interface driver to communicate with DW1000
+ */
+//extern SPIConfig moduleHalSpiUwbLsConfig;
+
+
+/**
+ * @brief   Configuration for the High Speed SPI interface driver to communicate with DW1000
+ */
+//extern SPIConfig moduleHalSpiUwbHsConfig;
+
+#endif /* defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
+
+#endif //AMIROLLD_DW1000_V1_H
diff --git a/include/DW1000/v1/deca_instance_v1.h b/include/DW1000/v1/deca_instance_v1.h
new file mode 100755
index 0000000..a861f1e
--- /dev/null
+++ b/include/DW1000/v1/deca_instance_v1.h
@@ -0,0 +1,588 @@
+/*! ----------------------------------------------------------------------------
+ *  @file    instance.h
+ *  @brief   DecaWave header for application level instance
+ *
+ * @attention
+ *
+ * Copyright 2015 (c) DecaWave Ltd, Dublin, Ireland.
+ *
+ * All rights reserved.
+ *
+ * @author DecaWave
+ */
+#ifndef __DECAINSTANCE_V1_H_
+#define DECAINSTANCE_V1_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <amiro-lld.h>
+#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
+
+#include <alld_DW1000.h>
+
+  /******************************************************************************************************************
+   ********************* NOTES on DW (MP) features/options ***********************************************************
+   *******************************************************************************************************************/
+#define DEEP_SLEEP (0) //To enable deep-sleep set this to 1
+  //DEEP_SLEEP mode can be used, for example, by a Tag instance to put the DW1000 into low-power deep-sleep mode:
+  // when the Anchor is sending the range report back to the Tag, the Tag will enter sleep after a ranging exchange is finished
+  // once it receives a report or times out, before the next poll message is sent (before next ranging exchange is started).
+
+#define CORRECT_RANGE_BIAS  (1)     // Compensate for small bias due to uneven accumulator growth at close up high power
+
+
+#define ANCTOANCTWR (1) //if set to 1 then anchor to anchor TWR will be done in the last slot
+
+#define DISCOVERY (0)     //set to 1 to enable tag discovery - tags starts by sending blinks (with own ID) and then
+                            //anchor assigns a slot to it and gives it short address
+  /******************************************************************************************************************
+   *******************************************************************************************************************
+   *******************************************************************************************************************/
+
+#define NUM_INST            1
+#define SPEED_OF_LIGHT      (299702547.0)     // in m/s in air
+#define MASK_40BIT			(0x00FFFFFFFFFF)  // DW1000 counter is 40 bits
+#define MASK_TXDTS			(0x00FFFFFFFE00)  //The TX timestamp will snap to 8 ns resolution - mask lower 9 bits.
+
+//!  callback events
+#define DWT_SIG_RX_NOERR            0
+#define DWT_SIG_TX_DONE             1       // Frame has been sent
+#define DWT_SIG_RX_OKAY             2       // Frame Received with Good CRC
+#define DWT_SIG_RX_ERROR            3       // Frame Received but CRC is wrong
+#define DWT_SIG_RX_TIMEOUT          4       // Timeout on receive has elapsed
+#define DWT_SIG_TX_AA_DONE          6       // ACK frame has been sent (as a result of auto-ACK)
+#define DWT_SIG_RX_BLINK            7       // Received ISO EUI 64 blink message
+#define DWT_SIG_RX_PHR_ERROR        8       // Error found in PHY Header
+#define DWT_SIG_RX_SYNCLOSS         9       // Un-recoverable error in Reed Solomon Decoder
+#define DWT_SIG_RX_SFDTIMEOUT       10      // Saw preamble but got no SFD within configured time
+#define DWT_SIG_RX_PTOTIMEOUT       11      // Got preamble detection timeout (no preamble detected)
+
+#define DWT_SIG_TX_PENDING          12      // TX is pending
+#define DWT_SIG_TX_ERROR            13      // TX failed
+#define DWT_SIG_RX_PENDING          14      // RX has been re-enabled
+#define DWT_SIG_DW_IDLE             15      // DW radio is in IDLE (no TX or RX pending)
+
+#define SIG_RX_UNKNOWN			99		// Received an unknown frame
+
+  //DecaRTLS frame function codes
+#define RTLS_DEMO_MSG_TAG_POLL              (0x81)          // Tag poll message
+#define RTLS_DEMO_MSG_ANCH_RESP             (0x70)          // Anchor response to poll
+#define RTLS_DEMO_MSG_ANCH_POLL				(0x71)			// Anchor to anchor poll message
+#define RTLS_DEMO_MSG_ANCH_RESP2            (0x72)          // Anchor response to poll from anchor
+#define RTLS_DEMO_MSG_ANCH_FINAL            (0x73)          // Anchor final massage back to Anchor
+#define RTLS_DEMO_MSG_TAG_FINAL             (0x82)          // Tag final massage back to Anchor
+
+
+  //lengths including the Decaranging Message Function Code byte
+#define TAG_POLL_MSG_LEN                    2				// FunctionCode(1), Range Num (1)
+#define ANCH_RESPONSE_MSG_LEN               8               // FunctionCode(1), Sleep Correction Time (2), Measured_TOF_Time(4), Range Num (1) (previous)
+#define TAG_FINAL_MSG_LEN                   33              // FunctionCode(1), Range Num (1), Poll_TxTime(5),
+  // Resp0_RxTime(5), Resp1_RxTime(5), Resp2_RxTime(5), Resp3_RxTime(5), Final_TxTime(5), Valid Response Mask (1)
+
+#define MAX_MAC_MSG_DATA_LEN                (TAG_FINAL_MSG_LEN) //max message len of the above
+
+#define STANDARD_FRAME_SIZE         127
+  //#define STANDARD_FRAME_SIZE         80
+
+#define ADDR_BYTE_SIZE_L            (8)
+#define ADDR_BYTE_SIZE_S            (2)
+
+#define FRAME_CONTROL_BYTES         2
+#define FRAME_SEQ_NUM_BYTES         1
+#define FRAME_PANID                 2
+#define FRAME_CRC					2
+#define FRAME_SOURCE_ADDRESS_S        (ADDR_BYTE_SIZE_S)
+#define FRAME_DEST_ADDRESS_S          (ADDR_BYTE_SIZE_S)
+#define FRAME_SOURCE_ADDRESS_L        (ADDR_BYTE_SIZE_L)
+#define FRAME_DEST_ADDRESS_L          (ADDR_BYTE_SIZE_L)
+#define FRAME_CTRLP					(FRAME_CONTROL_BYTES + FRAME_SEQ_NUM_BYTES + FRAME_PANID) //5
+#define FRAME_CRTL_AND_ADDRESS_L    (FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_L + FRAME_CTRLP) //21 bytes for 64-bit addresses)
+#define FRAME_CRTL_AND_ADDRESS_S    (FRAME_DEST_ADDRESS_S + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //9 bytes for 16-bit addresses)
+#define FRAME_CRTL_AND_ADDRESS_LS	(FRAME_DEST_ADDRESS_L + FRAME_SOURCE_ADDRESS_S + FRAME_CTRLP) //15 bytes for 1 16-bit address and 1 64-bit address)
+#define MAX_USER_PAYLOAD_STRING_LL     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_L-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 21 - 16 - 2 = 88
+#define MAX_USER_PAYLOAD_STRING_SS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_S-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 9 - 16 - 2 = 100
+#define MAX_USER_PAYLOAD_STRING_LS     (STANDARD_FRAME_SIZE-FRAME_CRTL_AND_ADDRESS_LS-TAG_FINAL_MSG_LEN-FRAME_CRC) //127 - 15 - 16 - 2 = 94
+
+  //NOTE: the user payload assumes that there are only 88 "free" bytes to be used for the user message (it does not scale according to the addressing modes)
+#define MAX_USER_PAYLOAD_STRING	MAX_USER_PAYLOAD_STRING_LL
+
+#define MAX_TAG_LIST_SIZE				(8)
+#define MAX_ANCHOR_LIST_SIZE			(4) //this is limited to 4 in this application
+#define NUM_EXPECTED_RESPONSES			(3) //e.g. MAX_ANCHOR_LIST_SIZE - 1
+#define NUM_EXPECTED_RESPONSES_ANC		(1) //anchors A0, A1 and A2 are involved in anchor to anchor ranging
+#define NUM_EXPECTED_RESPONSES_ANC0		(2) //anchor A0 expects response from A1 and A2
+
+#define GATEWAY_ANCHOR_ADDR				(0x8000)
+#define A1_ANCHOR_ADDR					(0x8001)
+#define A2_ANCHOR_ADDR					(0x8002)
+#define A3_ANCHOR_ADDR					(0x8003)
+
+
+  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  // NOTE: the maximum RX timeout is ~ 65ms
+  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+#define INST_DONE_WAIT_FOR_NEXT_EVENT   	1   //this signifies that the current event has been processed and instance is ready for next one
+#define INST_DONE_WAIT_FOR_NEXT_EVENT_TO    2   //this signifies that the current event has been processed and that instance is waiting for next one with a timeout
+  //which will trigger if no event coming in specified time
+#define INST_NOT_DONE_YET               	0   //this signifies that the instance is still processing the current event
+
+  //application data message byte offsets
+#define FCODE                               0               // Function code is 1st byte of messageData
+#define PTXT                                2				// Poll TX time
+#define RRXT0                               7				// A0 Response RX time
+#define RRXT1                               12				// A1 Response RX time
+#define RRXT2                               17				// A2 Response RX time
+#define RRXT3                               22				// A3 Response RX time
+#define FTXT                                27				// Final TX time
+#define VRESP                               32				// Mask of valid response times (e.g. if bit 1 = A0's response time is valid)
+#define RES_TAG_SLP0                        1               // Response tag sleep correction LSB
+#define RES_TAG_SLP1                        2               // Response tag sleep correction MSB
+#define TOFR                                3				// ToF (n-1) 4 bytes
+#define TOFRN								7				// range number 1 byte
+#define POLL_RNUM                           1               // Poll message range number
+
+  //this it the delay used for configuring the receiver on delay (wait for response delay)
+  //NOTE: this RX_RESPONSE_TURNAROUND is dependent on the microprocessor and code optimisations
+#define RX_RESPONSEX_TURNAROUND (50) //takes about 100 us for response to come back
+#define RX_RESPONSE1_TURNAROUND (200) //takes about 200 us for the 1st response to come back (from A0)
+#define RX_RESPONSE1_TURNAROUND_6M81 (300) //takes about 100 us for response to come back
+#define RX_RESPONSE1_TURNAROUND_110K (300) //takes about 100 us for response to come back
+
+  /* For TAG HAL F1 */
+  //#define RX_RESPONSE1_TURNAROUND (200) //takes about 200 us for the 1st response to come back (from A0)
+  //#define RX_RESPONSE1_TURNAROUND_6M81 (300) //takes about 100 us for response to come back
+  //#define RX_RESPONSE1_TURNAROUND_110K (18700) //takes about 100 us for response to come back
+
+  /* For ANCHOR HAL F1 */
+  //#define RX_RESPONSE1_TURNAROUND (300) //takes about 200 us for the 1st response to come back (from A0)
+  //#define RX_RESPONSE1_TURNAROUND_6M81 (300) //takes about 100 us for response to come back
+  //#define RX_RESPONSE1_TURNAROUND_110K (4700) //takes about 100 us for response to come back
+
+  //Tag will range to 3 or 4 anchors
+  //Each ranging exchange will consist of minimum of 3 messages (Poll, Response, Final)
+  //and a maximum of 6 messages (Poll, Response x 4, Final)
+  //Thus the ranging exchange will take either 28 ms for 110 kbps and 5 ms for 6.81 Mbps.
+  //NOTE: the above times are for 110k rate with 64 symb non-standard SFD and 1024 preamble length
+
+  typedef enum instanceModes{LISTENER, TAG, ANCHOR, ANCHOR_RNG, NUM_MODES} INST_MODE;
+
+  //Listener = in this mode, the instance only receives frames, does not respond
+  //Tag = Exchanges DecaRanging messages (Poll-Response-Final) with Anchor and enabling Anchor to calculate the range between the two instances
+  //Anchor = see above
+  //Anchor_Rng = the anchor (assumes a tag function) and ranges to another anchor - used in Anchor to Anchor TWR for auto positioning function
+
+#define TOF_REPORT_NUL 0
+#define TOF_REPORT_T2A 1
+#define TOF_REPORT_A2A 2
+
+#define INVALID_TOF (0xABCDFFFF)
+
+  typedef enum inst_states
+  {
+    TA_INIT, //0
+
+    TA_TXE_WAIT,                //1 - state in which the instance will enter sleep (if ranging finished) or proceed to transmit a message
+    TA_TXPOLL_WAIT_SEND,        //2 - configuration and sending of Poll message
+    TA_TXFINAL_WAIT_SEND,       //3 - configuration and sending of Final message
+    TA_TXRESPONSE_WAIT_SEND,    //4 - a place holder - response is sent from call back
+    TA_TX_WAIT_CONF,            //6 - confirmation of TX done message
+
+    TA_RXE_WAIT,                //7
+    TA_RX_WAIT_DATA,            //8
+
+    TA_SLEEP_DONE,               //9
+    TA_TXRESPONSE_SENT_POLLRX,    //10
+    TA_TXRESPONSE_SENT_RESPRX,    //11
+    TA_TXRESPONSE_SENT_TORX		  //12
+
+  } INST_STATES;
+
+
+  // This file defines data and functions for access to Parameters in the Device
+  //message structure for Poll, Response and Final message
+
+  typedef struct
+  {
+    uint8_t frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8_t seqNum;                               	//  sequence_number 02
+    uint8_t panID[2];                             	//  PAN ID 03-04
+    uint8_t destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
+    uint8_t sourceAddr[ADDR_BYTE_SIZE_L];           	//  13-20 using 64 bit addresses
+    uint8_t messageData[MAX_USER_PAYLOAD_STRING_LL] ; //  22-124 (application data and any user payload)
+    uint8_t fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+  } srd_msg_dlsl ;
+
+  typedef struct
+  {
+    uint8_t frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8_t seqNum;                               	//  sequence_number 02
+    uint8_t panID[2];                             	//  PAN ID 03-04
+    uint8_t destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
+    uint8_t sourceAddr[ADDR_BYTE_SIZE_S];           	//  07-08
+    uint8_t messageData[MAX_USER_PAYLOAD_STRING_SS] ; //  09-124 (application data and any user payload)
+    uint8_t fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+  } srd_msg_dsss ;
+
+  typedef struct
+  {
+    uint8_t frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8_t seqNum;                               	//  sequence_number 02
+    uint8_t panID[2];                             	//  PAN ID 03-04
+    uint8_t destAddr[ADDR_BYTE_SIZE_L];             	//  05-12 using 64 bit addresses
+    uint8_t sourceAddr[ADDR_BYTE_SIZE_S];           	//  13-14
+    uint8_t messageData[MAX_USER_PAYLOAD_STRING_LS] ; //  15-124 (application data and any user payload)
+    uint8_t fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+  } srd_msg_dlss ;
+
+  typedef struct
+  {
+    uint8_t frameCtrl[2];                         	//  frame control bytes 00-01
+    uint8_t seqNum;                               	//  sequence_number 02
+    uint8_t panID[2];                             	//  PAN ID 03-04
+    uint8_t destAddr[ADDR_BYTE_SIZE_S];             	//  05-06
+    uint8_t sourceAddr[ADDR_BYTE_SIZE_L];           	//  07-14 using 64 bit addresses
+    uint8_t messageData[MAX_USER_PAYLOAD_STRING_LS] ; //  15-124 (application data and any user payload)
+    uint8_t fcs[2] ;                              	//  125-126  we allow space for the CRC as it is logically part of the message. However ScenSor TX calculates and adds these bytes.
+  } srd_msg_dssl ;
+
+  typedef struct
+  {
+    uint8_t channelNumber ;       // valid range is 1 to 11
+    uint8_t preambleCode ;        // 00 = use NS code, 1 to 24 selects code
+    uint8_t pulseRepFreq ;        // NOMINAL_4M, NOMINAL_16M, or NOMINAL_64M
+    uint8_t dataRate ;            // DATA_RATE_1 (110K), DATA_RATE_2 (850K), DATA_RATE_3 (6M81)
+    uint8_t preambleLen ;         // values expected are 64, (128), (256), (512), 1024, (2048), and 4096
+    uint8_t pacSize ;
+    uint8_t nsSFD ;
+    uint16_t sfdTO;  //!< SFD timeout value (in symbols) e.g. preamble length (128) + SFD(8) - PAC + some margin ~ 135us... DWT_SFDTOC_DEF; //default value
+  } instanceConfig_t ;
+
+  typedef struct
+  {
+    uint16_t slotPeriod ; //slot period (time for 1 tag to range to 4 anchors)
+    uint16_t numSlots ; // number of slots in one superframe (number of tags supported)
+    uint16_t sfPeriod ; // superframe period in ms
+
+    uint16_t pollSleepDly ; // the minimum SLEEP time should be FRAME PERIOD so that tags don't interfere
+    uint16_t replyDly ; //response delay time (Tag or Anchor when sending Final/Response messages respectively)
+  } sfConfig_t ;
+
+  /******************************************************************************************************************
+   *******************************************************************************************************************
+   *******************************************************************************************************************/
+
+  //size of the event queue, in this application there should be at most 2 unprocessed events,
+  //i.e. if there is a transmission with wait for response then the TX callback followed by RX callback could be executed
+  //in turn and the event queued up before the instance processed the TX event.
+#define MAX_EVENT_NUMBER (6)
+
+  typedef struct
+  {
+    uint8_t  type;			// event type - if 0 there is no event in the queue
+    uint8_t  type_save;		// holds the event type - does not clear (used to show what event has been processed)
+    uint8_t  type_pend;	    // set if there is a pending event
+    uint16_t rxLength ;		// length of RX data (does not apply to TX events)
+
+    uint64_t timeStamp ;		// last timestamp (Tx or Rx) - 40 bit DW1000 time
+
+    uint32_t timeStamp32l ;		   // last tx/rx timestamp - low 32 bits of the 40 bit DW1000 time
+    uint32_t timeStamp32h ;		   // last tx/rx timestamp - high 32 bits of the 40 bit DW1000 time
+
+    uint32_t uTimeStamp ;			  //32 bit system counter (ms) - STM32 tick time (at time of IRQ)
+
+    union {
+      //holds received frame (after a good RX frame event)
+      uint8_t   frame[STANDARD_FRAME_SIZE];
+      srd_msg_dlsl rxmsg_ll ; //64 bit addresses
+      srd_msg_dssl rxmsg_sl ;
+      srd_msg_dlss rxmsg_ls ;
+      srd_msg_dsss rxmsg_ss ; //16 bit addresses
+    }msgu;
+
+    //uint32_t eventtime ;
+    //uint32_t eventtimeclr ;
+    uint8_t gotit;			//stores the instance function which processed the event (used for debug)
+  }event_data_t ;
+
+extern event_data_t dw_event_g;   // TODO
+
+  // TX power and PG delay configuration structure
+  typedef struct {
+    uint8_t PGdelay;
+
+    //TX POWER
+    //31:24     BOOST_0.125ms_PWR
+    //23:16     BOOST_0.25ms_PWR-TX_SHR_PWR
+    //15:8      BOOST_0.5ms_PWR-TX_PHR_PWR
+    //7:0       DEFAULT_PWR-TX_DATA_PWR
+    uint32_t txPwr[2]; //
+  }tx_struct;
+
+  typedef struct
+  {
+    INST_MODE mode;				//instance mode (tag or anchor)
+
+    INST_STATES testAppState ;			//state machine - current state
+    INST_STATES nextState ;				//state machine - next state
+    INST_STATES previousState ;			//state machine - previous state
+    int done ;					//done with the current event/wait for next event to arrive
+
+    //configuration structures
+    dwt_config_t    configData ;	//DW1000 channel configuration
+    dwt_txconfig_t  configTX ;		//DW1000 TX power configuration
+    uint16_t			txAntennaDelay ; //DW1000 TX antenna delay
+    uint16_t			rxAntennaDelay ; //DW1000 RX antenna delay
+    uint32_t 			txPower ;		 //DW1000 TX power
+    uint8_t txPowerChanged ;			//power has been changed - update the register on next TWR exchange
+    uint8_t antennaDelayChanged;		//antenna delay has been changed - update the register on next TWR exchange
+
+    uint16_t instanceAddress16; //contains tag/anchor address
+
+    //timeouts and delays
+    int32_t tagSleepTime_ms; //in milliseconds - defines the nominal Tag sleep time period
+    int32_t tagSleepRnd; //add an extra slot duration to sleep time to avoid collision before getting synced by anchor 0
+
+    //this is the delay used for the delayed transmit
+    uint64_t pollTx2FinalTxDelay ; //this is delay from Poll Tx time to Final Tx time in DW1000 units (40-bit)
+    uint64_t pollTx2FinalTxDelayAnc ; //this is delay from Poll Tx time to Final Tx time in DW1000 units (40-bit) for Anchor to Anchor ranging
+    uint64_t fixedReplyDelayAnc ;
+    uint32_t fixedReplyDelayAncP ;
+    int ancRespRxDelay ;
+
+    int fwtoTime_sy ;	//this is final message duration (longest out of ranging messages)
+    int fwtoTimeAnc_sy ;
+    uint32_t delayedReplyTime;		// delayed reply time of ranging-init/response/final message
+
+    uint32_t rxTimeouts ;
+
+    //message structure used for holding the data of the frame to transmit before it is written to the DW1000
+    srd_msg_dsss msg_f ; // ranging message frame with 16-bit addresses
+
+    //Tag function address/message configuration
+    uint8_t   shortAdd_idx ;				// device's 16-bit address low byte (used as index into arrays [0 - 3])
+    uint8_t   eui64[8];				// device's EUI 64-bit address
+    uint16_t  psduLength ;			// used for storing the TX frame length
+    uint8_t   frameSN;				// modulo 256 frame sequence number - it is incremented for each new frame transmission
+    uint16_t  panID ;					// panid used in the frames
+
+    //64 bit timestamps
+    //union of TX timestamps
+    union {
+      uint64_t txTimeStamp ;		   // last tx timestamp
+      uint64_t tagPollTxTime ;		   // tag's poll tx timestamp
+      uint64_t anchorRespTxTime ;	   // anchor's reponse tx timestamp
+    }txu;
+    uint64_t tagPollRxTime ;          // receive time of poll message
+
+
+    //application control parameters
+    uint8_t	wait4ack ;				// if this is set to DWT_RESPONSE_EXPECTED, then the receiver will turn on automatically after TX completion
+
+    int8_t   responseTO ;
+    uint8_t   instToSleep;			// if set the instance will go to sleep before sending the blink/poll message
+    uint8_t	stopTimer;				// stop/disable an active timer
+    uint8_t	instanceTimerEn;		// enable/start a timer
+    uint32_t	instanceWakeTime;			//
+    uint32_t  nextSleepPeriod;
+
+    uint8_t	gotTO;					// got timeout event
+
+    uint8_t   rxResponseMaskAnc;
+    uint8_t   rxResponseMask;			// bit mask - bit 0 = received response from anchor ID = 0, bit 1 from anchor ID = 1 etc...
+    uint8_t   rxResponseMaskReport;
+    uint8_t	rangeNum;				// incremented for each sequence of ranges (each slot)
+    uint8_t	rangeNumA[MAX_TAG_LIST_SIZE];				// array which holds last range number from each tag
+    uint8_t	rangeNumAnc;			// incremented for each sequence of ranges (each slot) - anchor to anchor ranging
+    uint8_t	rangeNumAAnc[MAX_ANCHOR_LIST_SIZE]; //array which holds last range number for each anchor
+    uint16_t  sframePeriod;
+    uint16_t  slotPeriod;
+    uint16_t  numSlots;
+    uint32_t  a0SlotTime;
+    uint32_t  a1SlotTime;
+    int32_t   tagSleepCorrection;
+    int32_t   tagSleepCorrection2;
+
+    //diagnostic counters/data, results and logging
+    uint32_t tof[MAX_TAG_LIST_SIZE]; //this is an array which holds last ToF from particular tag (ID 0-7)
+
+    //this is an array which holds last ToF to each anchor it should
+    uint32_t tofArray[MAX_ANCHOR_LIST_SIZE]; //contain 4 ToF to 4 anchors all relating to same range number sequence
+
+    uint32_t tofAnc[MAX_ANCHOR_LIST_SIZE]; //this is an array which holds last ToFs from particular anchors (0, 0-1, 0-2, 1-2)
+
+    //this is an array which holds last ToFs of the Anchor to Anchor ranging
+    uint32_t tofArrayAnc[MAX_ANCHOR_LIST_SIZE]; //it contains 3 ToFs relating to same range number sequence (0, 0-1, 0-2, 1-2)
+
+    int txMsgCount; //number of transmitted messages
+    int	rxMsgCount; //number of received messages
+    int lateTX; //number of "LATE" TX events
+    int lateRX; //number of "LATE" RX events
+
+    int longTermRangeCount ; //total number of ranges
+
+    int newRange;			//flag set when there is a new range to report TOF_REPORT_A2A or TOF_REPORT_T2A
+    int newRangeAncAddress; //last 4 bytes of anchor address - used for printing/range output display
+    int newRangeTagAddress; //last 4 bytes of tag address - used for printing/range output display
+    int newRangeTime;
+
+    uint8_t gatewayAnchor ; //set to TRUE = 1 if anchor address == GATEWAY_ANCHOR_ADDR
+
+    //event queue - used to store DW1000 events as they are processed by the dw_isr/callback functions
+    event_data_t dwevent[MAX_EVENT_NUMBER]; //this holds any TX/RX events and associated message data
+    event_data_t saved_dwevent; //holds an RX event while the ACK is being sent
+    uint8_t dweventIdxOut;
+    uint8_t dweventIdxIn;
+    uint8_t dweventPeek;
+    uint8_t monitor;
+    uint32_t timeofTx ;
+
+    uint8_t rxRespsIdx; //index into the array below (current tag (4bits)/seq number(4bits))
+    int8_t rxResps[256];
+
+    int dwIDLE; //set to 1 when the RST goes high after wake up (it is set in process_dwRSTn_irq)
+
+  } instance_data_t ;
+
+  //-------------------------------------------------------------------------------------------------------------
+  //
+  //	Functions used in logging/displaying range and status data
+  //
+  //-------------------------------------------------------------------------------------------------------------
+
+  // function to calculate and report the Time of Flight to the GUI/display
+  int reportTOF(int idx, uint32_t tofx);
+  void clearDistTable(int idx);
+  void setTagDist(int tidx, int aidx);
+  double getTagDist(int idx);
+
+  // clear the status/ranging data
+  void instanceclearcounts(void) ;
+
+  //-------------------------------------------------------------------------------------------------------------
+  //
+  //	Functions used in driving/controlling the ranging application
+  //
+  //-------------------------------------------------------------------------------------------------------------
+
+  void instance_close(void);
+  // Call init, then call config, then call run. call close when finished
+  // initialise the instance (application) structures and DW1000 device
+  int instance_init(void);
+  // configure the instance and DW1000 device
+  void instance_config(instanceConfig_t *config, sfConfig_t *sfconfig) ;
+
+  // configure the MAC address
+  void instancesetaddresses(uint16_t address) ;
+
+  void inst_processrxtimeout(instance_data_t *inst);
+
+  // called (periodically or from and interrupt) to process any outstanding TX/RX events and to drive the ranging application
+  int instance_run(void) ;       // returns indication of status report change
+  int testapprun(instance_data_t *inst, int message);
+
+  // calls the DW1000 interrupt handler
+#define instance_process_irq(x) 	dwt_isr()  //call device interrupt handler
+  // configure TX/RX callback functions that are called from DW1000 ISR
+  void instance_rxcallback(const dwt_cb_data_t *rxd);
+  void instance_txcallback(const dwt_cb_data_t *txd);
+  /*TODO: add callbacks */
+  void instance_rxtimeoutcallback(const dwt_cb_data_t *rxd);
+  void instance_rxerrorcallback(const dwt_cb_data_t *rxd);
+
+
+
+  // sets the Tag sleep delay time (the time Tag "sleeps" between each ranging attempt)
+  void instancesettagsleepdelay(int rangingsleep);
+  void instancesetreplydelay(int delayms);
+
+  // set/get the instance roles e.g. Tag/Anchor/Listener
+  void instancesetrole(int mode) ;                //
+  int instancegetrole(void) ;
+  // get the DW1000 device ID (e.g. 0xDECA0130 for DW1000)
+  uint32_t instancereaddeviceid(void) ;                                 // Return Device ID reg, enables validation of physical device presence
+
+  double instancegetidist(int idx);
+  double instancegetidistraw(int idx);
+  int instancegetidist_mm(int idx);
+  int instancegetidistraw_mm(int idx);
+  uint8_t instancevalidranges(void);
+  void instancecleardisttableall(void);
+
+  void instance_backtoanchor(instance_data_t *inst);
+  int instancesenddlypacket(instance_data_t *inst, int delayedTx);
+
+  int instancegetrnum(void);
+  int instancegetrnuma(int idx);
+  int instancegetrnumanc(int idx);
+  int instancegetlcount(void);
+
+  int instancenewrangeancadd(void);
+  int instancenewrangetagadd(void);
+  int instancenewrangepolltim(void);
+  int instancenewrange(void);
+  int instancenewrangetim(void);
+
+  uint64_t convertmicrosectodevicetimeu (double microsecu);
+  double convertdevicetimetosec(int32_t dt);
+
+#define DWT_PRF_64M_RFDLY   (514.462f)
+#define DWT_PRF_16M_RFDLY   (513.9067f)
+
+  /* Extern declaration while defining the data in .c file */
+  extern const uint16_t rfDelays[2];
+  extern const uint16_t rfDelaysTREK[2];
+  extern const tx_struct txSpectrumConfig[8];
+  extern instance_data_t instance_data[NUM_INST] ;
+
+
+  int instance_peekevent(void);
+
+  void instance_saveevent(event_data_t newevent, uint8_t etype);
+
+  event_data_t instance_getsavedevent(void);
+
+  void instance_putevent(event_data_t newevent, uint8_t etype);
+
+  event_data_t* instance_getevent(int x);
+
+  void instance_clearevents(void);
+
+  void instance_notify_DW1000_inIDLE(int idle);
+
+
+  // TODO: The following Functions are added in user applciation (previously on the API )
+
+  double dwt_getrangebias(uint8_t chan, float range, uint8_t prf);
+
+  uint32_t dwt_getotptxpower(uint8_t prf, uint8_t chan);
+
+  uint16_t dwt_getTREKOTPantennadelay(uint8_t anchor, uint8_t chan, uint8_t datarate);
+
+  uint16_t dwt_readantennadelay(uint8_t prf);
+
+
+  /* End of user application functions (Previously on API) */
+
+
+  // configure TX power
+  void instanceconfigtxpower(uint32_t txpower);
+  void instancesettxpower(void);
+
+  // configure the antenna delays
+  void instanceconfigantennadelays(uint16_t tx, uint16_t rx);
+  void instancesetantennadelays(void);
+  uint16_t instancetxantdly(void);
+  uint16_t instancerxantdly(void);
+
+  int instance_starttxtest(int framePeriod);
+
+#endif /* defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif   /* DECAINSTANCE_V1_H */
diff --git a/source/DW1000/v1/alld_dw1000_v1.c b/source/DW1000/v1/alld_dw1000_v1.c
new file mode 100755
index 0000000..8accea9
--- /dev/null
+++ b/source/DW1000/v1/alld_dw1000_v1.c
@@ -0,0 +1,4600 @@
+/*
+AMiRo-LLD is a compilation of low-level hardware drivers for the Autonomous Mini Robot (AMiRo) platform.
+Copyright (C) 2016..2018  Thomas Schöpping et al.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @file    deca_device.c
+ * @brief   Decawave device configuration and control functions
+ *
+ * @attention
+ *
+ * Copyright 2013 (c) Decawave Ltd, Dublin, Ireland.
+ *
+ * All rights reserved.
+ *
+ */
+
+
+#include <alld_DW1000.h>
+
+#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
+
+#include <aos_thread.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+// Defines for enable_clocks function
+#define FORCE_SYS_XTI  0
+#define ENABLE_ALL_SEQ 1
+#define FORCE_SYS_PLL  2
+#define READ_ACC_ON    7
+#define READ_ACC_OFF   8
+#define FORCE_OTP_ON   11
+#define FORCE_OTP_OFF  12
+#define FORCE_TX_PLL   13
+#define FORCE_LDE      14
+
+// Defines for ACK request bitmask in DATA and MAC COMMAND frame control (first byte) - Used to detect AAT bit wrongly set.
+#define FCTRL_ACK_REQ_MASK 0x20
+// Frame control maximum length in bytes.
+#define FCTRL_LEN_MAX 2
+
+
+/**
+ * Move to the header file <alld_dw1000_v1.h>
+*/
+//#define NUM_BR 3
+//#define NUM_PRF 2
+//#define NUM_PACS 4
+//#define NUM_BW 2            //2 bandwidths are supported
+//#define NUM_SFD 2           //supported number of SFDs - standard = 0, non-standard = 1
+//#define NUM_CH 6            //supported channels are 1, 2, 3, 4, 5, 7
+//#define NUM_CH_SUPPORTED 8  //supported channels are '0', 1, 2, 3, 4, 5, '6', 7
+//#define PCODES 25           //supported preamble codes
+
+
+typedef struct {
+    uint32_t lo32;
+    uint16_t target[NUM_PRF];
+} agc_cfg_struct ;
+
+extern const agc_cfg_struct agc_config ;
+
+//SFD threshold settings for 110k, 850k, 6.8Mb standard and non-standard
+extern const uint16_t sftsh[NUM_BR][NUM_SFD];
+
+extern const uint16_t dtune1[NUM_PRF];
+
+#define XMLPARAMS_VERSION   (1.17f)
+
+extern const uint32_t fs_pll_cfg[NUM_CH];
+extern const uint8_t fs_pll_tune[NUM_CH];
+extern const uint8_t rx_config[NUM_BW];
+extern const uint32_t tx_config[NUM_CH];
+extern const uint8_t dwnsSFDlen[NUM_BR]; //length of SFD for each of the bitrates
+extern const uint32_t digital_bb_config[NUM_PRF][NUM_PACS];
+//extern const uint8_t chan_idx[NUM_CH_SUPPORTED]; // move to header file
+extern const double txpwr_compensation[NUM_CH];
+
+#define PEAK_MULTPLIER  (0x60) //3 -> (0x3 * 32) & 0x00E0
+#define N_STD_FACTOR    (13)
+#define LDE_PARAM1      (PEAK_MULTPLIER | N_STD_FACTOR)
+
+#define LDE_PARAM3_16 (0x1607)
+#define LDE_PARAM3_64 (0x0607)
+
+#define MIXER_GAIN_STEP (0.5)
+#define DA_ATTN_STEP    (2.5)
+
+// #define DWT_API_ERROR_CHECK     // define so API checks config input parameters
+
+//-----------------------------------------
+// map the channel number to the index in the configuration arrays below
+// 0th element is chan 1, 1st is chan 2, 2nd is chan 3, 3rd is chan 4, 4th is chan 5, 5th is chan 7
+const uint8_t chan_idx[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 3, 4, 0, 5};
+
+//-----------------------------------------
+const uint32_t tx_config[NUM_CH] =
+{
+    RF_TXCTRL_CH1,
+    RF_TXCTRL_CH2,
+    RF_TXCTRL_CH3,
+    RF_TXCTRL_CH4,
+    RF_TXCTRL_CH5,
+    RF_TXCTRL_CH7,
+};
+
+//Frequency Synthesiser - PLL configuration
+const uint32_t fs_pll_cfg[NUM_CH] =
+{
+    FS_PLLCFG_CH1,
+    FS_PLLCFG_CH2,
+    FS_PLLCFG_CH3,
+    FS_PLLCFG_CH4,
+    FS_PLLCFG_CH5,
+    FS_PLLCFG_CH7
+};
+
+//Frequency Synthesiser - PLL tuning
+const uint8_t fs_pll_tune[NUM_CH] =
+{
+    FS_PLLTUNE_CH1,
+    FS_PLLTUNE_CH2,
+    FS_PLLTUNE_CH3,
+    FS_PLLTUNE_CH4,
+    FS_PLLTUNE_CH5,
+    FS_PLLTUNE_CH7
+};
+
+//bandwidth configuration
+const uint8_t rx_config[NUM_BW] =
+{
+    RF_RXCTRLH_NBW,
+    RF_RXCTRLH_WBW
+};
+
+
+const agc_cfg_struct agc_config =
+{
+    AGC_TUNE2_VAL,
+    { AGC_TUNE1_16M , AGC_TUNE1_64M }  //adc target
+};
+
+//DW non-standard SFD length for 110k, 850k and 6.81M
+const uint8_t dwnsSFDlen[NUM_BR] =
+{
+    DW_NS_SFD_LEN_110K,
+    DW_NS_SFD_LEN_850K,
+    DW_NS_SFD_LEN_6M8
+};
+
+// SFD Threshold
+const uint16_t sftsh[NUM_BR][NUM_SFD] =
+{
+    {
+        DRX_TUNE0b_110K_STD,
+        DRX_TUNE0b_110K_NSTD
+    },
+    {
+        DRX_TUNE0b_850K_STD,
+        DRX_TUNE0b_850K_NSTD
+    },
+    {
+        DRX_TUNE0b_6M8_STD,
+        DRX_TUNE0b_6M8_NSTD
+    }
+};
+
+const uint16_t dtune1[NUM_PRF] =
+{
+    DRX_TUNE1a_PRF16,
+    DRX_TUNE1a_PRF64
+};
+
+const uint32_t digital_bb_config[NUM_PRF][NUM_PACS] =
+{
+    {
+        DRX_TUNE2_PRF16_PAC8,
+        DRX_TUNE2_PRF16_PAC16,
+        DRX_TUNE2_PRF16_PAC32,
+        DRX_TUNE2_PRF16_PAC64
+    },
+    {
+        DRX_TUNE2_PRF64_PAC8,
+        DRX_TUNE2_PRF64_PAC16,
+        DRX_TUNE2_PRF64_PAC32,
+        DRX_TUNE2_PRF64_PAC64
+    }
+};
+
+const uint16_t lde_replicaCoeff[PCODES] =
+{
+    0, // No preamble code 0
+    LDE_REPC_PCODE_1,
+    LDE_REPC_PCODE_2,
+    LDE_REPC_PCODE_3,
+    LDE_REPC_PCODE_4,
+    LDE_REPC_PCODE_5,
+    LDE_REPC_PCODE_6,
+    LDE_REPC_PCODE_7,
+    LDE_REPC_PCODE_8,
+    LDE_REPC_PCODE_9,
+    LDE_REPC_PCODE_10,
+    LDE_REPC_PCODE_11,
+    LDE_REPC_PCODE_12,
+    LDE_REPC_PCODE_13,
+    LDE_REPC_PCODE_14,
+    LDE_REPC_PCODE_15,
+    LDE_REPC_PCODE_16,
+    LDE_REPC_PCODE_17,
+    LDE_REPC_PCODE_18,
+    LDE_REPC_PCODE_19,
+    LDE_REPC_PCODE_20,
+    LDE_REPC_PCODE_21,
+    LDE_REPC_PCODE_22,
+    LDE_REPC_PCODE_23,
+    LDE_REPC_PCODE_24
+};
+
+const double txpwr_compensation[NUM_CH] = {
+    0.0,
+    0.035,
+    0.0,
+    0.0,
+    0.065,
+    0.0
+};
+
+
+#define NUM_16M_OFFSET  (37)
+#define NUM_16M_OFFSETWB  (68)
+#define NUM_64M_OFFSET  (26)
+#define NUM_64M_OFFSETWB  (59)
+
+const uint8_t chan_idxnb[NUM_CH_SUPPORTED] = {0, 0, 1, 2, 0, 3, 0, 0}; //only channels 1,2,3 and 5 are in the narrow band tables
+const uint8_t chan_idxwb[NUM_CH_SUPPORTED] = {0, 0, 0, 0, 0, 0, 0, 1}; //only channels 4 and 7 are in in the wide band tables
+
+//---------------------------------------------------------------------------------------------------------------------------
+// Range Bias Correction TABLES of range values in integer units of 25 CM, for 8-bit unsigned storage, MUST END IN 255 !!!!!!
+//---------------------------------------------------------------------------------------------------------------------------
+
+// offsets to nearest centimeter for index 0, all rest are +1 cm per value
+
+#define CM_OFFSET_16M_NB    (-23)   // for normal band channels at 16 MHz PRF
+#define CM_OFFSET_16M_WB    (-28)   // for wider  band channels at 16 MHz PRF
+#define CM_OFFSET_64M_NB    (-17)   // for normal band channels at 64 MHz PRF
+#define CM_OFFSET_64M_WB    (-30)   // for wider  band channels at 64 MHz PRF
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// range25cm16PRFnb: Range Bias Correction table for narrow band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
+//---------------------------------------------------------------------------------------------------------------------------
+
+const uint8_t range25cm16PRFnb[4][NUM_16M_OFFSET] =
+{
+    // ch 1 - range25cm16PRFnb
+    {
+           1,
+           3,
+           4,
+           5,
+           7,
+           9,
+          11,
+          12,
+          13,
+          15,
+          18,
+          20,
+          23,
+          25,
+          28,
+          30,
+          33,
+          36,
+          40,
+          43,
+          47,
+          50,
+          54,
+          58,
+          63,
+          66,
+          71,
+          76,
+          82,
+          89,
+          98,
+         109,
+         127,
+         155,
+         222,
+         255,
+         255
+    },
+
+    // ch 2 - range25cm16PRFnb
+    {
+           1,
+           2,
+           4,
+           5,
+           6,
+           8,
+           9,
+          10,
+          12,
+          13,
+          15,
+          18,
+          20,
+          22,
+          24,
+          27,
+          29,
+          32,
+          35,
+          38,
+          41,
+          44,
+          47,
+          51,
+          55,
+          58,
+          62,
+          66,
+          71,
+          78,
+          85,
+          96,
+         111,
+         135,
+         194,
+         240,
+         255
+    },
+
+    // ch 3 - range25cm16PRFnb
+    {
+           1,
+           2,
+           3,
+           4,
+           5,
+           7,
+           8,
+           9,
+          10,
+          12,
+          14,
+          16,
+          18,
+          20,
+          22,
+          24,
+          26,
+          28,
+          31,
+          33,
+          36,
+          39,
+          42,
+          45,
+          49,
+          52,
+          55,
+          59,
+          63,
+          69,
+          76,
+          85,
+          98,
+         120,
+         173,
+         213,
+         255
+    },
+
+    // ch 5 - range25cm16PRFnb
+    {
+           1,
+           1,
+           2,
+           3,
+           4,
+           5,
+           6,
+           6,
+           7,
+           8,
+           9,
+          11,
+          12,
+          14,
+          15,
+          16,
+          18,
+          20,
+          21,
+          23,
+          25,
+          27,
+          29,
+          31,
+          34,
+          36,
+          38,
+          41,
+          44,
+          48,
+          53,
+          59,
+          68,
+          83,
+         120,
+         148,
+         255
+    }
+}; // end range25cm16PRFnb
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+// range25cm16PRFwb: Range Bias Correction table for wide band channels at 16 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
+//---------------------------------------------------------------------------------------------------------------------------
+
+const uint8_t range25cm16PRFwb[2][NUM_16M_OFFSETWB] =
+{
+    // ch 4 - range25cm16PRFwb
+    {
+           7,
+           7,
+           8,
+           9,
+           9,
+          10,
+          11,
+          11,
+          12,
+          13,
+          14,
+          15,
+          16,
+          17,
+          18,
+          19,
+          20,
+          21,
+          22,
+          23,
+          24,
+          26,
+          27,
+          28,
+          30,
+          31,
+          32,
+          34,
+          36,
+          38,
+          40,
+          42,
+          44,
+          46,
+          48,
+          50,
+          52,
+          55,
+          57,
+          59,
+          61,
+          63,
+          66,
+          68,
+          71,
+          74,
+          78,
+          81,
+          85,
+          89,
+          94,
+          99,
+         104,
+         110,
+         116,
+         123,
+         130,
+         139,
+         150,
+         164,
+         182,
+         207,
+         238,
+         255,
+         255,
+         255,
+         255,
+         255
+    },
+
+    // ch 7 - range25cm16PRFwb
+    {
+           4,
+           5,
+           5,
+           5,
+           6,
+           6,
+           7,
+           7,
+           7,
+           8,
+           9,
+           9,
+          10,
+          10,
+          11,
+          11,
+          12,
+          13,
+          13,
+          14,
+          15,
+          16,
+          17,
+          17,
+          18,
+          19,
+          20,
+          21,
+          22,
+          23,
+          25,
+          26,
+          27,
+          29,
+          30,
+          31,
+          32,
+          34,
+          35,
+          36,
+          38,
+          39,
+          40,
+          42,
+          44,
+          46,
+          48,
+          50,
+          52,
+          55,
+          58,
+          61,
+          64,
+          68,
+          72,
+          75,
+          80,
+          85,
+          92,
+         101,
+         112,
+         127,
+         147,
+         168,
+         182,
+         194,
+         205,
+         255
+    }
+}; // end range25cm16PRFwb
+
+//---------------------------------------------------------------------------------------------------------------------------
+// range25cm64PRFnb: Range Bias Correction table for narrow band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
+//---------------------------------------------------------------------------------------------------------------------------
+
+const uint8_t range25cm64PRFnb[4][NUM_64M_OFFSET] =
+{
+    // ch 1 - range25cm64PRFnb
+    {
+           1,
+           2,
+           2,
+           3,
+           4,
+           5,
+           7,
+          10,
+          13,
+          16,
+          19,
+          22,
+          24,
+          27,
+          30,
+          32,
+          35,
+          38,
+          43,
+          48,
+          56,
+          78,
+         101,
+         120,
+         157,
+         255
+    },
+
+    // ch 2 - range25cm64PRFnb
+    {
+           1,
+           2,
+           2,
+           3,
+           4,
+           4,
+           6,
+           9,
+          12,
+          14,
+          17,
+          19,
+          21,
+          24,
+          26,
+          28,
+          31,
+          33,
+          37,
+          42,
+          49,
+          68,
+          89,
+         105,
+         138,
+         255
+    },
+
+    // ch 3 - range25cm64PRFnb
+    {
+           1,
+           1,
+           2,
+           3,
+           3,
+           4,
+           5,
+           8,
+          10,
+          13,
+          15,
+          17,
+          19,
+          21,
+          23,
+          25,
+          27,
+          30,
+          33,
+          37,
+          44,
+          60,
+          79,
+          93,
+         122,
+         255
+    },
+
+    // ch 5 - range25cm64PRFnb
+    {
+           1,
+           1,
+           1,
+           2,
+           2,
+           3,
+           4,
+           6,
+           7,
+           9,
+          10,
+          12,
+          13,
+          15,
+          16,
+          17,
+          19,
+          21,
+          23,
+          26,
+          30,
+          42,
+          55,
+          65,
+          85,
+         255
+    }
+}; // end range25cm64PRFnb
+
+//---------------------------------------------------------------------------------------------------------------------------
+// range25cm64PRFwb: Range Bias Correction table for wide band channels at 64 MHz PRF, NB: !!!! each MUST END IN 255 !!!!
+//---------------------------------------------------------------------------------------------------------------------------
+
+const uint8_t range25cm64PRFwb[2][NUM_64M_OFFSETWB] =
+{
+    // ch 4 - range25cm64PRFwb
+    {
+           7,
+           8,
+           8,
+           9,
+           9,
+          10,
+          11,
+          12,
+          13,
+          13,
+          14,
+          15,
+          16,
+          16,
+          17,
+          18,
+          19,
+          19,
+          20,
+          21,
+          22,
+          24,
+          25,
+          27,
+          28,
+          29,
+          30,
+          32,
+          33,
+          34,
+          35,
+          37,
+          39,
+          41,
+          43,
+          45,
+          48,
+          50,
+          53,
+          56,
+          60,
+          64,
+          68,
+          74,
+          81,
+          89,
+          98,
+         109,
+         122,
+         136,
+         146,
+         154,
+         162,
+         178,
+         220,
+         249,
+         255,
+         255,
+         255
+    },
+
+    // ch 7 - range25cm64PRFwb
+    {
+           4,
+           5,
+           5,
+           5,
+           6,
+           6,
+           7,
+           7,
+           8,
+           8,
+           9,
+           9,
+          10,
+          10,
+          10,
+          11,
+          11,
+          12,
+          13,
+          13,
+          14,
+          15,
+          16,
+          16,
+          17,
+          18,
+          19,
+          19,
+          20,
+          21,
+          22,
+          23,
+          24,
+          25,
+          26,
+          28,
+          29,
+          31,
+          33,
+          35,
+          37,
+          39,
+          42,
+          46,
+          50,
+          54,
+          60,
+          67,
+          75,
+          83,
+          90,
+          95,
+         100,
+         110,
+         135,
+         153,
+         172,
+         192,
+         255
+    }
+}; // end range25cm64PRFwb
+
+
+
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * Function: dwt_getrangebias()
+ *
+ * Description: This function is used to return the range bias correction need for TWR with DW1000 units.
+ *
+ * input parameters:	
+ * @param chan  - specifies the operating channel (e.g. 1, 2, 3, 4, 5, 6 or 7) 
+ * @param range - the calculated distance before correction
+ * @param prf	- this is the PRF e.g. DWT_PRF_16M or DWT_PRF_64M
+ *
+ * output parameters
+ *
+ * returns correction needed in meters
+ */
+double dwt_getrangebias(uint8_t chan, float range, uint8_t prf)
+{
+    //first get the lookup index that corresponds to given range for a particular channel at 16M PRF
+    int i = 0 ;
+    int chanIdx ;
+    int cmoffseti ;                                 // integer number of CM offset
+
+    double mOffset ;                                // final offset result in metres
+
+    // NB: note we may get some small negitive values e.g. up to -50 cm.
+
+    int rangeint25cm = (int) (range * 4.00) ;       // convert range to integer number of 25cm values.
+
+    if (rangeint25cm > 255) rangeint25cm = 255 ;    // make sure it matches largest value in table (all tables end in 255 !!!!)
+
+    if (prf == DWT_PRF_16M)
+    {
+        switch(chan)
+        {
+            case 4:
+            case 7:
+            {
+                chanIdx = chan_idxwb[chan];
+                while (rangeint25cm > range25cm16PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
+                cmoffseti = i + CM_OFFSET_16M_WB ;                              // nearest centimeter correction
+            }
+            break;
+            default:
+            {
+                chanIdx = chan_idxnb[chan];
+                while (rangeint25cm > range25cm16PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
+                cmoffseti = i + CM_OFFSET_16M_NB ;                              // nearest centimeter correction
+            }
+        }//end of switch
+    }
+    else // 64M PRF
+    {
+        switch(chan)
+        {
+            case 4:
+            case 7:
+            {
+                chanIdx = chan_idxwb[chan];
+                while (rangeint25cm > range25cm64PRFwb[chanIdx][i]) i++ ;       // find index in table corresponding to range
+                cmoffseti = i + CM_OFFSET_64M_WB ;                              // nearest centimeter correction
+            }
+            break;
+            default:
+            {
+                chanIdx = chan_idxnb[chan];
+                while (rangeint25cm > range25cm64PRFnb[chanIdx][i]) i++ ;       // find index in table corresponding to range
+                cmoffseti = i + CM_OFFSET_64M_NB ;                              // nearest centimeter correction
+            }
+        }//end of switch
+    } // end else
+
+
+    mOffset = (float) cmoffseti ;                                       // offset result in centimmetres
+
+    mOffset *= 0.01 ;                                                   // convert to metres
+
+    return (mOffset) ;
+}
+
+
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// Internal functions for controlling and configuring the device
+//
+// -------------------------------------------------------------------------------------------------------------------
+
+// Enable and Configure specified clocks
+void _dwt_enableclocks(int clocks) ;
+// Configure the ucode (FP algorithm) parameters
+void _dwt_configlde(int prf);
+// Load ucode from OTP/ROM
+void _dwt_loaducodefromrom(void);
+// Read non-volatile memory
+uint32_t _dwt_otpread(uint32_t address);
+// Program the non-volatile memory
+uint32_t _dwt_otpprogword32(uint32_t data, uint16_t address);
+// Upload the device configuration into always on memory
+void _dwt_aonarrayupload(void);
+// -------------------------------------------------------------------------------------------------------------------
+
+/*!
+ * Static data for DW1000 DecaWave Transceiver control
+ */
+
+static dwt_local_data_t dw1000local[DWT_NUM_DW_DEV] ; // Static local device data, can be an array to support multiple DW1000 testing applications/platforms
+static dwt_local_data_t *pdw1000local = dw1000local ; // Static local data structure pointer
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setdevicedataptr()
+ *
+ * @brief This function sets the local data structure pointer to point to the structure in the local array as given by the index.
+ *
+ * input parameters
+ * @param index    - selects the array object to point to. Must be within the array bounds, i.e. < DWT_NUM_DW_DEV
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_setdevicedataptr(unsigned int index)
+{
+    // Check the index is within the array bounds
+    if (DWT_NUM_DW_DEV > index) // return error if index outside the array bounds
+    {
+        return DWT_ERROR ;
+    }
+
+    pdw1000local = &dw1000local[index];
+
+    return DWT_SUCCESS ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_initialise()
+ *
+ * @brief This function initiates communications with the DW1000 transceiver
+ * and reads its DEV_ID register (address 0x00) to verify the IC is one supported
+ * by this software (e.g. DW1000 32-bit device ID value is 0xDECA0130).  Then it
+ * does any initial once only device configurations needed for use and initialises
+ * as necessary any static data items belonging to this low-level driver.
+ *
+ * NOTES:
+ * 1.this function needs to be run before dwt_configuresleep, also the SPI frequency has to be < 3MHz
+ * 2.it also reads and applies LDO tune and crystal trim values from OTP memory
+ *
+ * input parameters
+ * @param config    -   specifies what configuration to load
+ *                  DWT_LOADUCODE     0x1 - load the LDE microcode from ROM - enabled accurate RX timestamp
+ *                  DWT_LOADNONE      0x0 - do not load any values from OTP memory
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+// OTP addresses definitions
+#define LDOTUNE_ADDRESS (0x04)
+#define PARTID_ADDRESS (0x06)
+#define LOTID_ADDRESS  (0x07)
+#define VBAT_ADDRESS   (0x08)
+#define VTEMP_ADDRESS  (0x09)
+#define XTRIM_ADDRESS  (0x1E)
+
+//int dwt_initialise(const uint16_t config, DW1000Driver* drv)
+int dwt_initialise(const uint16_t config)  // TODO:
+{
+    uint16_t otp_addr = 0;
+    uint32_t ldo_tune = 0;
+
+    pdw1000local->dblbuffon = 0; // Double buffer mode off by default
+    pdw1000local->wait4resp = 0;
+    pdw1000local->sleep_mode = 0;
+
+    pdw1000local->cbTxDone = NULL;
+    pdw1000local->cbRxOk = NULL;
+    pdw1000local->cbRxTo = NULL;
+    pdw1000local->cbRxErr = NULL;
+
+//    pdw1000local->driver = drv;  // TODO:
+
+    // Read and validate device ID return -1 if not recognised
+    if (DWT_DEVICE_ID != dwt_readdevid()) // MP IC ONLY (i.e. DW1000) FOR THIS CODE
+    {
+        return DWT_ERROR ;
+    }
+
+    // Make sure the device is completely reset before starting initialisation
+    dwt_softreset();
+
+    _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: set system clock to XTI - this is necessary to make sure the values read by _dwt_otpread are reliable
+
+    // Configure the CPLL lock detect
+    dwt_write8bitoffsetreg(EXT_SYNC_ID, EC_CTRL_OFFSET, EC_CTRL_PLLLCK);
+
+    // Read OTP revision number
+    otp_addr = _dwt_otpread(XTRIM_ADDRESS) & 0xffff;        // Read 32 bit value, XTAL trim val is in low octet-0 (5 bits)
+    pdw1000local->otprev = (otp_addr >> 8) & 0xff;            // OTP revision is next byte
+
+    // Load LDO tune from OTP and kick it if there is a value actually programmed.
+    ldo_tune = _dwt_otpread(LDOTUNE_ADDRESS);
+    if((ldo_tune & 0xFF) != 0)
+    {
+        // Kick LDO tune
+        dwt_write8bitoffsetreg(OTP_IF_ID, OTP_SF, OTP_SF_LDO_KICK); // Set load LDE kick bit
+        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDO; // LDO tune must be kicked at wake-up
+    }
+
+    // Load Part and Lot ID from OTP
+    pdw1000local->partID = _dwt_otpread(PARTID_ADDRESS);
+    pdw1000local->lotID = _dwt_otpread(LOTID_ADDRESS);
+
+    // XTAL trim value is set in OTP for DW1000 module and EVK/TREK boards but that might not be the case in a custom design
+    pdw1000local->init_xtrim = otp_addr & 0x1F;
+    if (!pdw1000local->init_xtrim) // A value of 0 means that the crystal has not been trimmed
+    {
+        pdw1000local->init_xtrim = FS_XTALT_MIDRANGE ; // Set to mid-range if no calibration value inside
+    }
+    // Configure XTAL trim
+    dwt_setxtaltrim(pdw1000local->init_xtrim);
+
+    // Load leading edge detect code
+    if(config & DWT_LOADUCODE)
+    {
+        _dwt_loaducodefromrom();
+        pdw1000local->sleep_mode |= AON_WCFG_ONW_LLDE; // microcode must be loaded at wake-up
+    }
+    else // Should disable the LDERUN enable bit in 0x36, 0x4
+    {
+        uint16_t rega = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1) ;
+        rega &= 0xFDFF ; // Clear LDERUN bit
+        dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1, rega) ;
+    }
+
+    _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing
+
+    // The 3 bits in AON CFG1 register must be cleared to ensure proper operation of the DW1000 in DEEPSLEEP mode.
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG1_OFFSET, 0x00);
+
+    // Read system register / store local copy
+    pdw1000local->sysCFGreg = dwt_read32bitreg(SYS_CFG_ID) ; // Read sysconfig register
+
+    return DWT_SUCCESS ;
+
+} // end dwt_initialise()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_otprevision()
+ *
+ * @brief This is used to return the read OTP revision
+ *
+ * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the read OTP revision value
+ */
+uint8_t dwt_otprevision(void)
+{
+    return pdw1000local->otprev ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setfinegraintxseq()
+ *
+ * @brief This function enables/disables the fine grain TX sequencing (enabled by default).
+ *
+ * input parameters
+ * @param enable - 1 to enable fine grain TX sequencing, 0 to disable it.
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void dwt_setfinegraintxseq(int enable)
+{
+    if (enable)
+    {
+        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_ENABLE);
+    }
+    else
+    {
+        dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_DISABLE);
+    }
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setlnapamode()
+ *
+ * @brief This is used to enable GPIO for external LNA or PA functionality - HW dependent, consult the DW1000 User Manual.
+ *        This can also be used for debug as enabling TX and RX GPIOs is quite handy to monitor DW1000's activity.
+ *
+ * NOTE: Enabling PA functionality requires that fine grain TX sequencing is deactivated. This can be done using
+ *       dwt_setfinegraintxseq().
+ *
+ * input parameters
+ * @param lna - 1 to enable LNA functionality, 0 to disable it
+ * @param pa - 1 to enable PA functionality, 0 to disable it
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setlnapamode(int lna, int pa)
+{
+    uint32_t gpio_mode = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
+    gpio_mode &= ~(GPIO_MSGP4_MASK | GPIO_MSGP5_MASK | GPIO_MSGP6_MASK);
+    if (lna)
+    {
+        gpio_mode |= GPIO_PIN6_EXTRXE;
+    }
+    if (pa)
+    {
+        gpio_mode |= (GPIO_PIN5_EXTTXE | GPIO_PIN4_EXTPA);
+    }
+    dwt_write32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET, gpio_mode);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setgpiodirection()
+ *
+ * @brief This is used to set GPIO direction as an input (1) or output (0)
+ *
+ * input parameters
+ * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
+ * @param direction  -   this sets the GPIO direction - see GxP0... GxP8 in the deca_regs.h file
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setgpiodirection(uint32_t gpioNum, uint32_t direction)
+{
+    uint8_t buf[GPIO_DIR_LEN];
+    uint32_t command = direction | gpioNum;
+
+    buf[0] = command & 0xff;
+    buf[1] = (command >> 8) & 0xff;
+    buf[2] = (command >> 16) & 0xff;
+
+    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DIR_OFFSET, GPIO_DIR_LEN, buf);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setgpiovalue()
+ *
+ * @brief This is used to set GPIO value as (1) or (0) only applies if the GPIO is configured as output
+ *
+ * input parameters
+ * @param gpioNum    -   this is the GPIO to configure - see GxM0... GxM8 in the deca_regs.h file
+ * @param value  -   this sets the GPIO value - see GDP0... GDP8 in the deca_regs.h file
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setgpiovalue(uint32_t gpioNum, uint32_t value)
+{
+    uint8_t buf[GPIO_DOUT_LEN];
+    uint32_t command = value | gpioNum;
+
+    buf[0] = command & 0xff;
+    buf[1] = (command >> 8) & 0xff;
+    buf[2] = (command >> 16) & 0xff;
+
+    dwt_writetodevice(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, GPIO_DOUT_LEN, buf);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getpartid()
+ *
+ * @brief This is used to return the read part ID of the device
+ *
+ * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the 32 bit part ID value as programmed in the factory
+ */
+uint32_t dwt_getpartid(void)
+{
+    return pdw1000local->partID;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getlotid()
+ *
+ * @brief This is used to return the read lot ID of the device
+ *
+ * NOTE: dwt_initialise() must be called prior to this function so that it can return a relevant value.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the 32 bit lot ID value as programmed in the factory
+ */
+uint32_t dwt_getlotid(void)
+{
+    return pdw1000local->lotID;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readdevid()
+ *
+ * @brief This is used to return the read device type and revision information of the DW1000 device (MP part is 0xDECA0130)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the read value which for DW1000 is 0xDECA0130
+ */
+uint32_t dwt_readdevid(void)
+{
+    return dwt_read32bitoffsetreg(DEV_ID_ID,0);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configuretxrf()
+ *
+ * @brief This function provides the API for the configuration of the TX spectrum
+ * including the power and pulse generator delay. The input is a pointer to the data structure
+ * of type dwt_txconfig_t that holds all the configurable items.
+ *
+ * input parameters
+ * @param config    -   pointer to the txrf configuration structure, which contains the tx rf config data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configuretxrf(dwt_txconfig_t* config)
+{
+
+    // Configure RF TX PG_DELAY
+    dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, config->PGdly);
+
+    // Configure TX power
+    dwt_write32bitreg(TX_POWER_ID, config->power);
+
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configure()
+ *
+ * @brief This function provides the main API for the configuration of the
+ * DW1000 and this low-level driver.  The input is a pointer to the data structure
+ * of type dwt_config_t that holds all the configurable items.
+ * The dwt_config_t structure shows which ones are supported
+ *
+ * input parameters
+ * @param config    -   pointer to the configuration structure, which contains the device configuration data.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configure(dwt_config_t *config)
+{
+    uint8_t nsSfd_result  = 0;
+    uint8_t useDWnsSFD = 0;
+    uint8_t chan = config->chan ;
+    uint32_t regval ;
+    uint16_t reg16 = lde_replicaCoeff[config->rxCode];
+    uint8_t prfIndex = config->prf - DWT_PRF_16M;
+    uint8_t bw = ((chan == 4) || (chan == 7)) ? 1 : 0 ; // Select wide or narrow band
+
+#ifdef DWT_API_ERROR_CHECK
+    assert(config->dataRate <= DWT_BR_6M8);
+    assert(config->rxPAC <= DWT_PAC64);
+    assert((chan >= 1) && (chan <= 7) && (chan != 6));
+    assert(((config->prf == DWT_PRF_64M) && (config->txCode >= 9) && (config->txCode <= 24))
+           || ((config->prf == DWT_PRF_16M) && (config->txCode >= 1) && (config->txCode <= 8)));
+    assert(((config->prf == DWT_PRF_64M) && (config->rxCode >= 9) && (config->rxCode <= 24))
+           || ((config->prf == DWT_PRF_16M) && (config->rxCode >= 1) && (config->rxCode <= 8)));
+    assert((config->txPreambLength == DWT_PLEN_64) || (config->txPreambLength == DWT_PLEN_128) || (config->txPreambLength == DWT_PLEN_256)
+           || (config->txPreambLength == DWT_PLEN_512) || (config->txPreambLength == DWT_PLEN_1024) || (config->txPreambLength == DWT_PLEN_1536)
+           || (config->txPreambLength == DWT_PLEN_2048) || (config->txPreambLength == DWT_PLEN_4096));
+    assert((config->phrMode == DWT_PHRMODE_STD) || (config->phrMode == DWT_PHRMODE_EXT));
+#endif
+
+    // For 110 kbps we need a special setup
+    if(DWT_BR_110K == config->dataRate)
+    {
+        pdw1000local->sysCFGreg |= SYS_CFG_RXM110K ;
+        reg16 >>= 3; // lde_replicaCoeff must be divided by 8
+    }
+    else
+    {
+        pdw1000local->sysCFGreg &= (~SYS_CFG_RXM110K) ;
+    }
+
+    pdw1000local->longFrames = config->phrMode ;
+
+    pdw1000local->sysCFGreg &= ~SYS_CFG_PHR_MODE_11;
+    pdw1000local->sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << SYS_CFG_PHR_MODE_SHFT));
+
+    dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ;
+    // Set the lde_replicaCoeff
+    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_REPC_OFFSET, reg16) ;
+
+    _dwt_configlde(prfIndex);
+
+    // Configure PLL2/RF PLL block CFG/TUNE (for a given channel)
+    dwt_write32bitoffsetreg(FS_CTRL_ID, FS_PLLCFG_OFFSET, fs_pll_cfg[chan_idx[chan]]);
+    dwt_write8bitoffsetreg(FS_CTRL_ID, FS_PLLTUNE_OFFSET, fs_pll_tune[chan_idx[chan]]);
+
+    // Configure RF RX blocks (for specified channel/bandwidth)
+    dwt_write8bitoffsetreg(RF_CONF_ID, RF_RXCTRLH_OFFSET, rx_config[bw]);
+
+    // Configure RF TX blocks (for specified channel and PRF)
+    // Configure RF TX control
+    dwt_write32bitoffsetreg(RF_CONF_ID, RF_TXCTRL_OFFSET, tx_config[chan_idx[chan]]);
+
+    // Configure the baseband parameters (for specified PRF, bit rate, PAC, and SFD settings)
+    // DTUNE0
+    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE0b_OFFSET, sftsh[config->dataRate][config->nsSFD]);
+
+    // DTUNE1
+    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1a_OFFSET, dtune1[prfIndex]);
+
+    if(config->dataRate == DWT_BR_110K)
+    {
+        dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_110K);
+    }
+    else
+    {
+        if(config->txPreambLength == DWT_PLEN_64)
+        {
+            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_6M8_PRE64);
+            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE64);
+        }
+        else
+        {
+            dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_TUNE1b_OFFSET, DRX_TUNE1b_850K_6M8);
+            dwt_write8bitoffsetreg(DRX_CONF_ID, DRX_TUNE4H_OFFSET, DRX_TUNE4H_PRE128PLUS);
+        }
+    }
+
+    // DTUNE2
+    dwt_write32bitoffsetreg(DRX_CONF_ID, DRX_TUNE2_OFFSET, digital_bb_config[prfIndex][config->rxPAC]);
+
+    // DTUNE3 (SFD timeout)
+    // Don't allow 0 - SFD timeout will always be enabled
+    if(config->sfdTO == 0)
+    {
+        config->sfdTO = DWT_SFDTOC_DEF;
+    }
+    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_SFDTOC_OFFSET, config->sfdTO);
+
+    // Configure AGC parameters
+    dwt_write32bitoffsetreg( AGC_CFG_STS_ID, 0xC, agc_config.lo32);
+    dwt_write16bitoffsetreg( AGC_CFG_STS_ID, 0x4, agc_config.target[prfIndex]);
+
+    // Set (non-standard) user SFD for improved performance,
+    if(config->nsSFD)
+    {
+        // Write non standard (DW) SFD length
+        dwt_write8bitoffsetreg(USR_SFD_ID, 0x00, dwnsSFDlen[config->dataRate]);
+        nsSfd_result = 3 ;
+        useDWnsSFD = 1 ;
+    }
+    regval =  (CHAN_CTRL_TX_CHAN_MASK & (chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel
+              (CHAN_CTRL_RX_CHAN_MASK & (chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel
+              (CHAN_CTRL_RXFPRF_MASK & (config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF
+              ((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX
+              (CHAN_CTRL_DWSFD & (useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD
+              (CHAN_CTRL_TX_PCOD_MASK & (config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code
+              (CHAN_CTRL_RX_PCOD_MASK & (config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code
+
+    dwt_write32bitreg(CHAN_CTRL_ID,regval) ;
+
+    // Set up TX Preamble Size, PRF and Data Rate
+    pdw1000local->txFCTRL = ((config->txPreambLength | config->prf) << TX_FCTRL_TXPRF_SHFT) | (config->dataRate << TX_FCTRL_TXBR_SHFT);
+    dwt_write32bitreg(TX_FCTRL_ID, pdw1000local->txFCTRL);
+
+    // The SFD transmit pattern is initialised by the DW1000 upon a user TX request, but (due to an IC issue) it is not done for an auto-ACK TX. The
+    // SYS_CTRL write below works around this issue, by simultaneously initiating and aborting a transmission, which correctly initialises the SFD
+    // after its configuration or reconfiguration.
+    // This issue is not documented at the time of writing this code. It should be in next release of DW1000 User Manual (v2.09, from July 2016).
+    dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, SYS_CTRL_TXSTRT | SYS_CTRL_TRXOFF); // Request TX start and TRX off at the same time
+} // end dwt_configure()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setrxantennadelay()
+ *
+ * @brief This API function writes the antenna delay (in time units) to RX registers
+ *
+ * input parameters:
+ * @param rxDelay - this is the total (RX) antenna delay value, which
+ *                          will be programmed into the RX register
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setrxantennadelay(uint16_t rxDelay)
+{
+    // Set the RX antenna delay for auto TX timestamp adjustment
+    dwt_write16bitoffsetreg(LDE_IF_ID, LDE_RXANTD_OFFSET, rxDelay);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_settxantennadelay()
+ *
+ * @brief This API function writes the antenna delay (in time units) to TX registers
+ *
+ * input parameters:
+ * @param txDelay - this is the total (TX) antenna delay value, which
+ *                          will be programmed into the TX delay register
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_settxantennadelay(uint16_t txDelay)
+{
+    // Set the TX antenna delay for auto TX timestamp adjustment
+    dwt_write16bitoffsetreg(TX_ANTD_ID, TX_ANTD_OFFSET, txDelay);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_writetxdata()
+ *
+ * @brief This API function writes the supplied TX data into the DW1000's
+ * TX buffer.  The input parameters are the data length in bytes and a pointer
+ * to those data bytes.
+ *
+ * input parameters
+ * @param txFrameLength  - This is the total frame length, including the two byte CRC.
+ *                         Note: this is the length of TX message (including the 2 byte CRC) - max is 1023
+ *                         standard PHR mode allows up to 127 bytes
+ *                         if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
+ *                         see dwt_configure function
+ * @param txFrameBytes   - Pointer to the user’s buffer containing the data to send.
+ * @param txBufferOffset - This specifies an offset in the DW1000’s TX Buffer at which to start writing data.
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_writetxdata(uint16_t txFrameLength, uint8_t *txFrameBytes, uint16_t txBufferOffset)
+{
+#ifdef DWT_API_ERROR_CHECK
+    assert(txFrameLength >= 2);
+    assert((pdw1000local->longFrames && (txFrameLength <= 1023)) || (txFrameLength <= 127));
+    assert((txBufferOffset + txFrameLength) <= 1024);
+#endif
+
+    if ((txBufferOffset + txFrameLength) <= 1024)
+    {
+        // Write the data to the IC TX buffer, (-2 bytes for auto generated CRC)
+        dwt_writetodevice( TX_BUFFER_ID, txBufferOffset, txFrameLength-2, txFrameBytes);
+        return DWT_SUCCESS;
+    }
+    else
+    {
+        return DWT_ERROR;
+    }
+} // end dwt_writetxdata()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_writetxfctrl()
+ *
+ * @brief This API function configures the TX frame control register before the transmission of a frame
+ *
+ * input parameters:
+ * @param txFrameLength - this is the length of TX message (including the 2 byte CRC) - max is 1023
+ *                              NOTE: standard PHR mode allows up to 127 bytes
+ *                              if > 127 is programmed, DWT_PHRMODE_EXT needs to be set in the phrMode configuration
+ *                              see dwt_configure function
+ * @param txBufferOffset - the offset in the tx buffer to start writing the data
+ * @param ranging - 1 if this is a ranging frame, else 0
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_writetxfctrl(uint16_t txFrameLength, uint16_t txBufferOffset, int ranging)
+{
+
+#ifdef DWT_API_ERROR_CHECK
+    assert((pdw1000local->longFrames && (txFrameLength <= 1023)) || (txFrameLength <= 127));
+#endif
+
+    // Write the frame length to the TX frame control register
+    // pdw1000local->txFCTRL has kept configured bit rate information
+    uint32_t reg32 = pdw1000local->txFCTRL | txFrameLength | (txBufferOffset << TX_FCTRL_TXBOFFS_SHFT) | (ranging << TX_FCTRL_TR_SHFT);
+    dwt_write32bitreg(TX_FCTRL_ID, reg32);
+} // end dwt_writetxfctrl()
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxdata()
+ *
+ * @brief This is used to read the data from the RX buffer, from an offset location give by offset parameter
+ *
+ * input parameters
+ * @param buffer - the buffer into which the data will be read
+ * @param length - the length of data to read (in bytes)
+ * @param rxBufferOffset - the offset in the rx buffer from which to read the data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readrxdata(uint8_t *buffer, uint16_t length, uint16_t rxBufferOffset)
+{
+    dwt_readfromdevice(RX_BUFFER_ID,rxBufferOffset,length,buffer) ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readaccdata()
+ *
+ * @brief This is used to read the data from the Accumulator buffer, from an offset location give by offset parameter
+ *
+ * NOTE: Because of an internal memory access delay when reading the accumulator the first octet output is a dummy octet
+ *       that should be discarded. This is true no matter what sub-index the read begins at.
+ *
+ * input parameters
+ * @param buffer - the buffer into which the data will be read
+ * @param length - the length of data to read (in bytes)
+ * @param accOffset - the offset in the acc buffer from which to read the data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readaccdata(uint8_t *buffer, uint16_t len, uint16_t accOffset)
+{
+    // Force on the ACC clocks if we are sequenced
+    _dwt_enableclocks(READ_ACC_ON);
+
+    dwt_readfromdevice(ACC_MEM_ID,accOffset,len,buffer) ;
+
+    _dwt_enableclocks(READ_ACC_OFF); // Revert clocks back
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readdiagnostics()
+ *
+ * @brief this function reads the RX signal quality diagnostic data
+ *
+ * input parameters
+ * @param diagnostics - diagnostic structure pointer, this will contain the diagnostic data read from the DW1000
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readdiagnostics(dwt_rxdiag_t *diagnostics)
+{
+    // Read the HW FP index
+    diagnostics->firstPath = dwt_read16bitoffsetreg(RX_TIME_ID, RX_TIME_FP_INDEX_OFFSET);
+
+    // LDE diagnostic data
+    diagnostics->maxNoise = dwt_read16bitoffsetreg(LDE_IF_ID, LDE_THRESH_OFFSET);
+
+    // Read all 8 bytes in one SPI transaction
+    dwt_readfromdevice(RX_FQUAL_ID, 0x0, 8, (uint8_t*)&diagnostics->stdNoise);
+
+    diagnostics->firstPathAmp1 = dwt_read16bitoffsetreg(RX_TIME_ID, RX_TIME_FP_AMPL1_OFFSET);
+
+    diagnostics->rxPreamCount = (dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXPACC_MASK) >> RX_FINFO_RXPACC_SHIFT  ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtxtimestamp()
+ *
+ * @brief This is used to read the TX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ * @param timestamp - a pointer to a 5-byte buffer which will store the read TX timestamp time
+ *
+ * output parameters - the timestamp buffer will contain the value after the function call
+ *
+ * no return value
+ */
+void dwt_readtxtimestamp(uint8_t * timestamp)
+{
+    dwt_readfromdevice(TX_TIME_ID, TX_TIME_TX_STAMP_OFFSET, TX_TIME_TX_STAMP_LEN, timestamp) ; // Read bytes directly into buffer
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtxtimestamphi32()
+ *
+ * @brief This is used to read the high 32-bits of the TX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns high 32-bits of TX timestamp
+ */
+uint32_t dwt_readtxtimestamphi32(void)
+{
+    return dwt_read32bitoffsetreg(TX_TIME_ID, 1); // Offset is 1 to get the 4 upper bytes out of 5
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtxtimestamplo32()
+ *
+ * @brief This is used to read the low 32-bits of the TX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns low 32-bits of TX timestamp
+ */
+uint32_t dwt_readtxtimestamplo32(void)
+{
+    return dwt_read32bitreg(TX_TIME_ID); // Read TX TIME as a 32-bit register to get the 4 lower bytes out of 5
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxtimestamp()
+ *
+ * @brief This is used to read the RX timestamp (adjusted time of arrival)
+ *
+ * input parameters
+ * @param timestamp - a pointer to a 5-byte buffer which will store the read RX timestamp time
+ *
+ * output parameters - the timestamp buffer will contain the value after the function call
+ *
+ * no return value
+ */
+void dwt_readrxtimestamp(uint8_t * timestamp)
+{
+    dwt_readfromdevice(RX_TIME_ID, RX_TIME_RX_STAMP_OFFSET, RX_TIME_RX_STAMP_LEN, timestamp) ; // Get the adjusted time of arrival
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxtimestamphi32()
+ *
+ * @brief This is used to read the high 32-bits of the RX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns high 32-bits of RX timestamp
+ */
+uint32_t dwt_readrxtimestamphi32(void)
+{
+    return dwt_read32bitoffsetreg(RX_TIME_ID, 1); // Offset is 1 to get the 4 upper bytes out of 5
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readrxtimestamplo32()
+ *
+ * @brief This is used to read the low 32-bits of the RX timestamp (adjusted with the programmed antenna delay)
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns low 32-bits of RX timestamp
+ */
+uint32_t dwt_readrxtimestamplo32(void)
+{
+    return dwt_read32bitreg(RX_TIME_ID); // Read RX TIME as a 32-bit register to get the 4 lower bytes out of 5
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readsystimestamphi32()
+ *
+ * @brief This is used to read the high 32-bits of the system time
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns high 32-bits of system time timestamp
+ */
+uint32_t dwt_readsystimestamphi32(void)
+{
+    return dwt_read32bitoffsetreg(SYS_TIME_ID, 1); // Offset is 1 to get the 4 upper bytes out of 5
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readsystime()
+ *
+ * @brief This is used to read the system time
+ *
+ * input parameters
+ * @param timestamp - a pointer to a 5-byte buffer which will store the read system time
+ *
+ * output parameters
+ * @param timestamp - the timestamp buffer will contain the value after the function call
+ *
+ * no return value
+ */
+void dwt_readsystime(uint8_t * timestamp)
+{
+    dwt_readfromdevice(SYS_TIME_ID, SYS_TIME_OFFSET, SYS_TIME_LEN, timestamp) ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_writetodevice()
+ *
+ * @brief  this function is used to write to the DW1000 device registers
+ * Notes:
+ *        1. Firstly we create a header (the first byte is a header byte)
+ *        a. check if sub index is used, if subindexing is used - set bit-6 to 1 to signify that the sub-index address follows the register index byte
+ *        b. set bit-7 (or with 0x80) for write operation
+ *        c. if extended sub address index is used (i.e. if index > 127) set bit-7 of the first sub-index byte following the first header byte
+ *
+ *        2. Write the header followed by the data bytes to the DW1000 device
+ *
+ *
+ * input parameters:
+ * @param recordNumber  - ID of register file or buffer being accessed
+ * @param index         - byte index into register file or buffer being accessed
+ * @param length        - number of bytes being written
+ * @param buffer        - pointer to buffer containing the 'length' bytes to be written
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_writetodevice
+(
+    uint16_t      recordNumber,
+    uint16_t      index,
+    uint32_t      length,
+    const uint8_t *buffer
+)
+{
+    uint8_t header[3] ; // Buffer to compose header in
+    int   cnt = 0; // Counter for length of header
+#ifdef DWT_API_ERROR_CHECK
+    assert(recordNumber <= 0x3F); // Record number is limited to 6-bits.
+#endif
+
+    // Write message header selecting WRITE operation and addresses as appropriate (this is one to three bytes long)
+    if (index == 0) // For index of 0, no sub-index is required
+    {
+        header[cnt++] = 0x80 | recordNumber ; // Bit-7 is WRITE operation, bit-6 zero=NO sub-addressing, bits 5-0 is reg file id
+    }
+    else
+    {
+#ifdef DWT_API_ERROR_CHECK
+        assert((index <= 0x7FFF) && ((index + length) <= 0x7FFF)); // Index and sub-addressable area are limited to 15-bits.
+#endif
+        header[cnt++] = 0xC0 | recordNumber ; // Bit-7 is WRITE operation, bit-6 one=sub-address follows, bits 5-0 is reg file id
+
+        if (index <= 127) // For non-zero index < 127, just a single sub-index byte is required
+        {
+            header[cnt++] = (uint8_t)index ; // Bit-7 zero means no extension, bits 6-0 is index.
+        }
+        else
+        {
+            header[cnt++] = 0x80 | (uint8_t)(index) ; // Bit-7 one means extended index, bits 6-0 is low seven bits of index.
+            header[cnt++] =  (uint8_t) (index >> 7) ; // 8-bit value = high eight bits of index.
+        }
+    }
+
+    // Write it to the SPI
+//    _alld_dw1000_writespi(cnt,header,length,buffer);
+    writetospi(cnt,header,length,buffer);  // TODO
+} // end dwt_writetodevice()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readfromdevice()
+ *
+ * @brief  this function is used to read from the DW1000 device registers
+ * Notes:
+ *        1. Firstly we create a header (the first byte is a header byte)
+ *        a. check if sub index is used, if subindexing is used - set bit-6 to 1 to signify that the sub-index address follows the register index byte
+ *        b. set bit-7 (or with 0x80) for write operation
+ *        c. if extended sub address index is used (i.e. if index > 127) set bit-7 of the first sub-index byte following the first header byte
+ *
+ *        2. Write the header followed by the data bytes to the DW1000 device
+ *        3. Store the read data in the input buffer
+ *
+ * input parameters:
+ * @param recordNumber  - ID of register file or buffer being accessed
+ * @param index         - byte index into register file or buffer being accessed
+ * @param length        - number of bytes being read
+ * @param buffer        - pointer to buffer in which to return the read data.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readfromdevice
+(
+    uint16_t  recordNumber,
+    uint16_t  index,
+    uint32_t  length,
+    uint8_t   *buffer
+)
+{
+    uint8_t header[3] ; // Buffer to compose header in
+    int   cnt = 0; // Counter for length of header
+#ifdef DWT_API_ERROR_CHECK
+    assert(recordNumber <= 0x3F); // Record number is limited to 6-bits.
+#endif
+
+    // Write message header selecting READ operation and addresses as appropriate (this is one to three bytes long)
+    if (index == 0) // For index of 0, no sub-index is required
+    {
+        header[cnt++] = (uint8_t) recordNumber ; // Bit-7 zero is READ operation, bit-6 zero=NO sub-addressing, bits 5-0 is reg file id
+    }
+    else
+    {
+#ifdef DWT_API_ERROR_CHECK
+        assert((index <= 0x7FFF) && ((index + length) <= 0x7FFF)); // Index and sub-addressable area are limited to 15-bits.
+#endif
+        header[cnt++] = (uint8_t)(0x40 | recordNumber) ; // Bit-7 zero is READ operation, bit-6 one=sub-address follows, bits 5-0 is reg file id
+
+        if (index <= 127) // For non-zero index < 127, just a single sub-index byte is required
+        {
+            header[cnt++] = (uint8_t) index ; // Bit-7 zero means no extension, bits 6-0 is index.
+        }
+        else
+        {
+            header[cnt++] = 0x80 | (uint8_t)(index) ; // Bit-7 one means extended index, bits 6-0 is low seven bits of index.
+            header[cnt++] =  (uint8_t) (index >> 7) ; // 8-bit value = high eight bits of index.
+        }
+    }
+
+    // Do the read from the SPI
+//    _alld_dw1000_readspi(cnt, header, length, buffer);  // result is stored in the buffer
+    readfromspi(cnt, header, length, buffer);  // TODO:
+} // end dwt_readfromdevice()
+
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_read32bitoffsetreg()
+ *
+ * @brief  this function is used to read 32-bit value from the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ *
+ * output parameters
+ *
+ * returns 32 bit register value
+ */
+uint32_t dwt_read32bitoffsetreg(int regFileID,int regOffset)
+{
+    uint32_t  regval = 0 ;
+    int     j ;
+    uint8_t   buffer[4] ;
+
+    dwt_readfromdevice(regFileID,regOffset,4,buffer); // Read 4 bytes (32-bits) register into buffer
+
+    for (j = 3 ; j >= 0 ; j --)
+    {
+        regval = (regval << 8) + buffer[j] ;
+    }
+    return regval ;
+
+} // end dwt_read32bitoffsetreg()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_read16bitoffsetreg()
+ *
+ * @brief  this function is used to read 16-bit value from the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ *
+ * output parameters
+ *
+ * returns 16 bit register value
+ */
+uint16_t dwt_read16bitoffsetreg(int regFileID,int regOffset)
+{
+    uint16_t  regval = 0 ;
+    uint8_t   buffer[2] ;
+
+    dwt_readfromdevice(regFileID,regOffset,2,buffer); // Read 2 bytes (16-bits) register into buffer
+
+    regval = (buffer[1] << 8) + buffer[0] ;
+    return regval ;
+
+} // end dwt_read16bitoffsetreg()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_read8bitoffsetreg()
+ *
+ * @brief  this function is used to read an 8-bit value from the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ *
+ * output parameters
+ *
+ * returns 8-bit register value
+ */
+uint8_t dwt_read8bitoffsetreg(int regFileID, int regOffset)
+{
+    uint8_t regval;
+
+    dwt_readfromdevice(regFileID, regOffset, 1, &regval);
+
+    return regval ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_write8bitoffsetreg()
+ *
+ * @brief  this function is used to write an 8-bit value to the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ * @param regval    - the value to write
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_write8bitoffsetreg(int regFileID, int regOffset, uint8_t regval)
+{
+    dwt_writetodevice(regFileID, regOffset, 1, &regval);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_write16bitoffsetreg()
+ *
+ * @brief  this function is used to write 16-bit value to the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ * @param regval    - the value to write
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_write16bitoffsetreg(int regFileID,int regOffset,uint16_t regval)
+{
+    uint8_t   buffer[2] ;
+
+    buffer[0] = regval & 0xFF;
+    buffer[1] = regval >> 8 ;
+
+    dwt_writetodevice(regFileID,regOffset,2,buffer);
+} // end dwt_write16bitoffsetreg()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_write32bitoffsetreg()
+ *
+ * @brief  this function is used to write 32-bit value to the DW1000 device registers
+ *
+ * input parameters:
+ * @param regFileID - ID of register file or buffer being accessed
+ * @param regOffset - the index into register file or buffer being accessed
+ * @param regval    - the value to write
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_write32bitoffsetreg(int regFileID,int regOffset,uint32_t regval)
+{
+    int     j ;
+    uint8_t   buffer[4] ;
+
+    for ( j = 0 ; j < 4 ; j++ )
+    {
+        buffer[j] = regval & 0xff ;
+        regval >>= 8 ;
+    }
+
+    dwt_writetodevice(regFileID,regOffset,4,buffer);
+} // end dwt_write32bitoffsetreg()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_enableframefilter()
+ *
+ * @brief This is used to enable the frame filtering - (the default option is to
+ * accept any data and ACK frames with correct destination address
+ *
+ * input parameters
+ * @param - bitmask - enables/disables the frame filtering options according to
+ *      DWT_FF_NOTYPE_EN        0x000   no frame types allowed
+ *      DWT_FF_COORD_EN         0x002   behave as coordinator (can receive frames with no destination address (PAN ID has to match))
+ *      DWT_FF_BEACON_EN        0x004   beacon frames allowed
+ *      DWT_FF_DATA_EN          0x008   data frames allowed
+ *      DWT_FF_ACK_EN           0x010   ack frames allowed
+ *      DWT_FF_MAC_EN           0x020   mac control frames allowed
+ *      DWT_FF_RSVD_EN          0x040   reserved frame types allowed
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_enableframefilter(uint16_t enable)
+{
+    uint32_t sysconfig = SYS_CFG_MASK & dwt_read32bitreg(SYS_CFG_ID) ; // Read sysconfig register
+
+    if(enable)
+    {
+        // Enable frame filtering and configure frame types
+        sysconfig &= ~(SYS_CFG_FF_ALL_EN); // Clear all
+        sysconfig |= (enable & SYS_CFG_FF_ALL_EN) | SYS_CFG_FFE;
+    }
+    else
+    {
+        sysconfig &= ~(SYS_CFG_FFE);
+    }
+
+    pdw1000local->sysCFGreg = sysconfig ;
+    dwt_write32bitreg(SYS_CFG_ID,sysconfig) ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setpanid()
+ *
+ * @brief This is used to set the PAN ID
+ *
+ * input parameters
+ * @param panID - this is the PAN ID
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setpanid(uint16_t panID)
+{
+    // PAN ID is high 16 bits of register
+    dwt_write16bitoffsetreg(PANADR_ID, PANADR_PAN_ID_OFFSET, panID);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setaddress16()
+ *
+ * @brief This is used to set 16-bit (short) address
+ *
+ * input parameters
+ * @param shortAddress - this sets the 16 bit short address
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setaddress16(uint16_t shortAddress)
+{
+    // Short address into low 16 bits
+    dwt_write16bitoffsetreg(PANADR_ID, PANADR_SHORT_ADDR_OFFSET, shortAddress);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_seteui()
+ *
+ * @brief This is used to set the EUI 64-bit (long) address
+ *
+ * input parameters
+ * @param eui64 - this is the pointer to a buffer that contains the 64bit address
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_seteui(uint8_t *eui64)
+{
+    dwt_writetodevice(EUI_64_ID, EUI_64_OFFSET, EUI_64_LEN, eui64);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_geteui()
+ *
+ * @brief This is used to get the EUI 64-bit from the DW1000
+ *
+ * input parameters
+ * @param eui64 - this is the pointer to a buffer that will contain the read 64-bit EUI value
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_geteui(uint8_t *eui64)
+{
+    dwt_readfromdevice(EUI_64_ID, EUI_64_OFFSET, EUI_64_LEN, eui64);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_otpread()
+ *
+ * @brief This is used to read the OTP data from given address into provided array
+ *
+ * input parameters
+ * @param address - this is the OTP address to read from
+ * @param array - this is the pointer to the array into which to read the data
+ * @param length - this is the number of 32 bit words to read (array needs to be at least this length)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_otpread(uint32_t address, uint32_t *array, uint8_t length)
+{
+    int i;
+
+    _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: Set system clock to XTAL - this is necessary to make sure the values read by _dwt_otpread are reliable
+
+    for(i=0; i<length; i++)
+    {
+        array[i] = _dwt_otpread(address + i) ;
+    }
+
+    _dwt_enableclocks(ENABLE_ALL_SEQ); // Restore system clock to PLL
+
+    return ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_otpread()
+ *
+ * @brief function to read the OTP memory. Ensure that MR,MRa,MRb are reset to 0.
+ *
+ * input parameters
+ * @param address - address to read at
+ *
+ * output parameters
+ *
+ * returns the 32bit of read data
+ */
+uint32_t _dwt_otpread(uint32_t address)
+{
+    uint32_t ret_data;
+
+    // Write the address
+    dwt_write16bitoffsetreg(OTP_IF_ID, OTP_ADDR, address);
+
+    // Perform OTP Read - Manual read mode has to be set
+    dwt_write8bitoffsetreg(OTP_IF_ID, OTP_CTRL, OTP_CTRL_OTPREAD | OTP_CTRL_OTPRDEN);
+    dwt_write8bitoffsetreg(OTP_IF_ID, OTP_CTRL, 0x00); // OTPREAD is self clearing but OTPRDEN is not
+
+    // Read read data, available 40ns after rising edge of OTP_READ
+    ret_data = dwt_read32bitoffsetreg(OTP_IF_ID, OTP_RDAT);
+
+    // Return the 32bit of read data
+    return ret_data;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_otpsetmrregs()
+ *
+ * @brief Configure the MR registers for initial programming (enable charge pump).
+ * Read margin is used to stress the read back from the
+ * programmed bit. In normal operation this is relaxed.
+ *
+ * input parameters
+ * @param mode - "0" : Reset all to 0x0:           MRA=0x0000, MRB=0x0000, MR=0x0000
+ *               "1" : Set for inital programming: MRA=0x9220, MRB=0x000E, MR=0x1024
+ *               "2" : Set for soak programming:   MRA=0x9220, MRB=0x0003, MR=0x1824
+ *               "3" : High Vpp:                   MRA=0x9220, MRB=0x004E, MR=0x1824
+ *               "4" : Low Read Margin:            MRA=0x0000, MRB=0x0003, MR=0x0000
+ *               "5" : Array Clean:                MRA=0x0049, MRB=0x0003, MR=0x0024
+ *               "4" : Very Low Read Margin:       MRA=0x0000, MRB=0x0003, MR=0x0000
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+uint32_t _dwt_otpsetmrregs(int mode)
+{
+    uint8_t rd_buf[4];
+    uint8_t wr_buf[4];
+    uint32_t mra=0,mrb=0,mr=0;
+
+    // PROGRAMME MRA
+    // Set MRA, MODE_SEL
+    wr_buf[0] = 0x03;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL+1,1,wr_buf);
+
+    // Load data
+    switch(mode&0x0f) {
+    case 0x0 :
+        mr =0x0000;
+        mra=0x0000;
+        mrb=0x0000;
+        break;
+    case 0x1 :
+        mr =0x1024;
+        mra=0x9220; // Enable CPP mon
+        mrb=0x000e;
+        break;
+    case 0x2 :
+        mr =0x1824;
+        mra=0x9220;
+        mrb=0x0003;
+        break;
+    case 0x3 :
+        mr =0x1824;
+        mra=0x9220;
+        mrb=0x004e;
+        break;
+    case 0x4 :
+        mr =0x0000;
+        mra=0x0000;
+        mrb=0x0003;
+        break;
+    case 0x5 :
+        mr =0x0024;
+        mra=0x0000;
+        mrb=0x0003;
+        break;
+    default :
+        return DWT_ERROR;
+    }
+
+    wr_buf[0] = mra & 0x00ff;
+    wr_buf[1] = (mra & 0xff00)>>8;
+    dwt_writetodevice(OTP_IF_ID, OTP_WDAT,2,wr_buf);
+
+
+    // Set WRITE_MR
+    wr_buf[0] = 0x08;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+
+    // Wait?
+
+    // Set Clear Mode sel
+    wr_buf[0] = 0x02;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+
+    // Set AUX update, write MR
+    wr_buf[0] = 0x88;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+    // Clear write MR
+    wr_buf[0] = 0x80;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+    // Clear AUX update
+    wr_buf[0] = 0x00;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+
+    ///////////////////////////////////////////
+    // PROGRAM MRB
+    // Set SLOW, MRB, MODE_SEL
+    wr_buf[0] = 0x05;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+
+    wr_buf[0] = mrb & 0x00ff;
+    wr_buf[1] = (mrb & 0xff00)>>8;
+    dwt_writetodevice(OTP_IF_ID, OTP_WDAT,2,wr_buf);
+
+    // Set WRITE_MR
+    wr_buf[0] = 0x08;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+
+    // Wait?
+
+    // Set Clear Mode sel
+    wr_buf[0] = 0x04;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+
+    // Set AUX update, write MR
+    wr_buf[0] = 0x88;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+    // Clear write MR
+    wr_buf[0] = 0x80;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+    // Clear AUX update
+    wr_buf[0] = 0x00;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+
+    ///////////////////////////////////////////
+    // PROGRAM MR
+    // Set SLOW, MODE_SEL
+    wr_buf[0] = 0x01;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+    // Load data
+
+    wr_buf[0] = mr & 0x00ff;
+    wr_buf[1] = (mr & 0xff00)>>8;
+    dwt_writetodevice(OTP_IF_ID, OTP_WDAT,2,wr_buf);
+
+    // Set WRITE_MR
+    wr_buf[0] = 0x08;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+
+    // Wait?
+    deca_sleep(10);
+    // Set Clear Mode sel
+    wr_buf[0] = 0x00;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+
+    // Read confirm mode writes.
+    // Set man override, MRA_SEL
+    wr_buf[0] = OTP_CTRL_OTPRDEN;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+    wr_buf[0] = 0x02;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+    // MRB_SEL
+    wr_buf[0] = 0x04;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+    deca_sleep(100);
+
+    // Clear mode sel
+    wr_buf[0] = 0x00;
+    dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf);
+    // Clear MAN_OVERRIDE
+    wr_buf[0] = 0x00;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf);
+
+    deca_sleep(10);
+
+    if (((mode&0x0f) == 0x1)||((mode&0x0f) == 0x2))
+    {
+        // Read status register
+        dwt_readfromdevice(OTP_IF_ID, OTP_STAT,1,rd_buf);
+    }
+
+    return DWT_SUCCESS;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_otpprogword32()
+ *
+ * @brief function to program the OTP memory. Ensure that MR,MRa,MRb are reset to 0.
+ * VNM Charge pump needs to be enabled (see _dwt_otpsetmrregs)
+ * Note the address is only 11 bits long.
+ *
+ * input parameters
+ * @param address - address to read at
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+uint32_t _dwt_otpprogword32(uint32_t data, uint16_t address)
+{
+    uint8_t rd_buf[1];
+    uint8_t wr_buf[4];
+    uint8_t otp_done;
+
+    // Read status register
+    dwt_readfromdevice(OTP_IF_ID, OTP_STAT, 1, rd_buf);
+
+    if((rd_buf[0] & 0x02) != 0x02)
+    {
+        return DWT_ERROR;
+    }
+
+    // Write the data
+    wr_buf[3] = (data>>24) & 0xff;
+    wr_buf[2] = (data>>16) & 0xff;
+    wr_buf[1] = (data>>8) & 0xff;
+    wr_buf[0] = data & 0xff;
+    dwt_writetodevice(OTP_IF_ID, OTP_WDAT, 4, wr_buf);
+
+    // Write the address [10:0]
+    wr_buf[1] = (address>>8) & 0x07;
+    wr_buf[0] = address & 0xff;
+    dwt_writetodevice(OTP_IF_ID, OTP_ADDR, 2, wr_buf);
+
+    // Enable Sequenced programming
+    wr_buf[0] = OTP_CTRL_OTPPROG;
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf);
+    wr_buf[0] = 0x00; // And clear
+    dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf);
+
+    // WAIT for status to flag PRGM OK..
+    otp_done = 0;
+    while(otp_done == 0)
+    {
+        deca_sleep(1);
+        dwt_readfromdevice(OTP_IF_ID, OTP_STAT, 1, rd_buf);
+
+        if((rd_buf[0] & 0x01) == 0x01)
+        {
+            otp_done = 1;
+        }
+    }
+
+    return DWT_SUCCESS;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_otpwriteandverify()
+ *
+ * @brief This is used to program 32-bit value into the DW1000 OTP memory.
+ *
+ * input parameters
+ * @param value - this is the 32-bit value to be programmed into OTP
+ * @param address - this is the 16-bit OTP address into which the 32-bit value is programmed
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_otpwriteandverify(uint32_t value, uint16_t address)
+{
+    int prog_ok = DWT_SUCCESS;
+    int retry = 0;
+    // Firstly set the system clock to crystal
+    _dwt_enableclocks(FORCE_SYS_XTI); //set system clock to XTI
+
+    //
+    //!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!
+    //Set the supply to 3.7V
+    //
+
+    _dwt_otpsetmrregs(1); // Set mode for programming
+
+    // For each value to program - the readback/check is done couple of times to verify it has programmed successfully
+    while(1)
+    {
+        _dwt_otpprogword32(value, address);
+
+        if(_dwt_otpread(address) == value)
+        {
+            break;
+        }
+        retry++;
+        if(retry==5)
+        {
+            break;
+        }
+    }
+
+    // Even if the above does not exit before retry reaches 5, the programming has probably been successful
+
+    _dwt_otpsetmrregs(4); // Set mode for reading
+
+    if(_dwt_otpread(address) != value) // If this does not pass please check voltage supply on VDDIO
+    {
+        prog_ok = DWT_ERROR;
+    }
+
+    _dwt_otpsetmrregs(0); // Setting OTP mode register for low RM read - resetting the device would be alternative
+
+    return prog_ok;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_aonconfigupload()
+ *
+ * @brief This function uploads always on (AON) configuration, as set in the AON_CFG0_OFFSET register.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void _dwt_aonconfigupload(void)
+{
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, AON_CTRL_UPL_CFG);
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, 0x00); // Clear the register
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_aonarrayupload()
+ *
+ * @brief This function uploads always on (AON) data array and configuration. Thus if this function is used, then _dwt_aonconfigupload
+ * is not necessary. The DW1000 will go so SLEEP straight after this if the DWT_SLP_EN has been set.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void _dwt_aonarrayupload(void)
+{
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, 0x00); // Clear the register
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, AON_CTRL_SAVE);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_entersleep()
+ *
+ * @brief This function puts the device into deep sleep or sleep. dwt_configuresleep() should be called first
+ * to configure the sleep and on-wake/wake-up parameters
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_entersleep(void)
+{
+    // Copy config to AON - upload the new configuration
+    _dwt_aonarrayupload();
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configuresleepcnt()
+ *
+ * @brief sets the sleep counter to new value, this function programs the high 16-bits of the 28-bit counter
+ *
+ * NOTE: this function needs to be run before dwt_configuresleep, also the SPI frequency has to be < 3MHz
+ *
+ * input parameters
+ * @param sleepcnt - this it value of the sleep counter to program
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configuresleepcnt(uint16_t sleepcnt)
+{
+    // Force system clock to crystal
+    _dwt_enableclocks(FORCE_SYS_XTI);
+
+    // Reset sleep configuration to make sure we don't accidentally go to sleep
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG0_OFFSET, 0x00); // NB: this write change the default LPCLKDIVA value which is not used anyway.
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG1_OFFSET, 0x00);
+
+    // Disable the sleep counter
+    _dwt_aonconfigupload();
+
+    // Set new value
+    dwt_write16bitoffsetreg(AON_ID, AON_CFG0_OFFSET + AON_CFG0_SLEEP_TIM_OFFSET, sleepcnt);
+    _dwt_aonconfigupload();
+
+    // Enable the sleep counter
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG1_OFFSET, AON_CFG1_SLEEP_CEN);
+    _dwt_aonconfigupload();
+
+    // Put system PLL back on
+    _dwt_enableclocks(ENABLE_ALL_SEQ);
+}
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calibratesleepcnt()
+ *
+ * @brief calibrates the local oscillator as its frequency can vary between 7 and 13kHz depending on temp and voltage
+ *
+ * NOTE: this function needs to be run before dwt_configuresleepcnt, so that we know what the counter units are
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the number of XTAL/2 cycles per low-power oscillator cycle. LP OSC frequency = 19.2 MHz/return value
+ */
+uint16_t dwt_calibratesleepcnt(void)
+{
+    uint16_t result;
+
+    // Enable calibration of the sleep counter
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG1_OFFSET, AON_CFG1_LPOSC_CAL);
+    _dwt_aonconfigupload();
+
+    // Disable calibration of the sleep counter
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG1_OFFSET, 0x00);
+    _dwt_aonconfigupload();
+
+    // Force system clock to crystal
+    _dwt_enableclocks(FORCE_SYS_XTI);
+
+    deca_sleep(1);
+
+    // Read the number of XTAL/2 cycles one LP oscillator cycle took.
+    // Set up address - Read upper byte first
+    dwt_write8bitoffsetreg(AON_ID, AON_ADDR_OFFSET, AON_ADDR_LPOSC_CAL_1);
+
+    // Enable manual override
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, AON_CTRL_DCA_ENAB);
+
+    // Read confirm data that was written
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, AON_CTRL_DCA_ENAB | AON_CTRL_DCA_READ);
+
+    // Read back byte from AON
+    result = dwt_read8bitoffsetreg(AON_ID, AON_RDAT_OFFSET);
+    result <<= 8;
+
+    // Set up address - Read lower byte
+    dwt_write8bitoffsetreg(AON_ID, AON_ADDR_OFFSET, AON_ADDR_LPOSC_CAL_0);
+
+    // Enable manual override
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, AON_CTRL_DCA_ENAB);
+
+    // Read confirm data that was written
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, AON_CTRL_DCA_ENAB | AON_CTRL_DCA_READ);
+
+    // Read back byte from AON
+    result |= dwt_read8bitoffsetreg(AON_ID, AON_RDAT_OFFSET);
+
+    // Disable manual override
+    dwt_write8bitoffsetreg(AON_ID, AON_CTRL_OFFSET, 0x00);
+
+    // Put system PLL back on
+    _dwt_enableclocks(ENABLE_ALL_SEQ);
+
+    // Returns the number of XTAL/2 cycles per one LP OSC cycle
+    // This can be converted into LP OSC frequency by 19.2 MHz/result
+    return result;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configuresleep()
+ *
+ * @brief configures the device for both DEEP_SLEEP and SLEEP modes, and on-wake mode
+ * i.e. before entering the sleep, the device should be programmed for TX or RX, then upon "waking up" the TX/RX settings
+ * will be preserved and the device can immediately perform the desired action TX/RX
+ *
+ * NOTE: e.g. Tag operation - after deep sleep, the device needs to just load the TX buffer and send the frame
+ *
+ *
+ *      mode: the array and LDE code (OTP/ROM) and LDO tune, and set sleep persist
+ *      DWT_PRESRV_SLEEP 0x0100 - preserve sleep
+ *      DWT_LOADOPSET    0x0080 - load operating parameter set on wakeup
+ *      DWT_CONFIG       0x0040 - download the AON array into the HIF (configuration download)
+ *      DWT_LOADEUI      0x0008
+ *      DWT_GOTORX       0x0002
+ *      DWT_TANDV        0x0001
+ *
+ *      wake: wake up parameters
+ *      DWT_XTAL_EN      0x10 - keep XTAL running during sleep
+ *      DWT_WAKE_SLPCNT  0x8 - wake up after sleep count
+ *      DWT_WAKE_CS      0x4 - wake up on chip select
+ *      DWT_WAKE_WK      0x2 - wake up on WAKEUP PIN
+ *      DWT_SLP_EN       0x1 - enable sleep/deep sleep functionality
+ *
+ * input parameters
+ * @param mode - config on-wake parameters
+ * @param wake - config wake up parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configuresleep(uint16_t mode, uint8_t wake)
+{
+    // Add predefined sleep settings before writing the mode
+    mode |= pdw1000local->sleep_mode;
+    dwt_write16bitoffsetreg(AON_ID, AON_WCFG_OFFSET, mode);
+
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG0_OFFSET, wake);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_entersleepaftertx(int enable)
+ *
+ * @brief sets the auto TX to sleep bit. This means that after a frame
+ * transmission the device will enter deep sleep mode. The dwt_configuresleep() function
+ * needs to be called before this to configure the on-wake settings
+ *
+ * NOTE: the IRQ line has to be low/inactive (i.e. no pending events)
+ *
+ * input parameters
+ * @param enable - 1 to configure the device to enter deep sleep after TX, 0 - disables the configuration
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_entersleepaftertx(int enable)
+{
+    uint32_t reg = dwt_read32bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET);
+    // Set the auto TX -> sleep bit
+    if(enable)
+    {
+        reg |= PMSC_CTRL1_ATXSLP;
+    }
+    else
+    {
+        reg &= ~(PMSC_CTRL1_ATXSLP);
+    }
+    dwt_write32bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, reg);
+}
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_spicswakeup()
+ *
+ * @brief wake up the device from sleep mode using the SPI read,
+ * the device will wake up on chip select line going low if the line is held low for at least 500us.
+ * To define the length depending on the time one wants to hold
+ * the chip select line low, use the following formula:
+ *
+ *      length (bytes) = time (s) * byte_rate (Hz)
+ *
+ * where fastest byte_rate is spi_rate (Hz) / 8 if the SPI is sending the bytes back-to-back.
+ * To save time and power, a system designer could determine byte_rate value more precisely.
+ *
+ * NOTE: Alternatively the device can be waken up with WAKE_UP pin if configured for that operation
+ *
+ * input parameters
+ * @param buff   - this is a pointer to the dummy buffer which will be used in the SPI read transaction used for the WAKE UP of the device
+ * @param length - this is the length of the dummy buffer
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error
+ */
+int dwt_spicswakeup(uint8_t *buff, uint16_t length)
+{
+    if(dwt_readdevid() != DWT_DEVICE_ID) // Device was in deep sleep (the first read fails)
+    {
+        // Need to keep chip select line low for at least 500us
+        dwt_readfromdevice(0x0, 0x0, length, buff); // Do a long read to wake up the chip (hold the chip select low)
+
+        // Need 5ms for XTAL to start and stabilise (could wait for PLL lock IRQ status bit !!!)
+        // NOTE: Polling of the STATUS register is not possible unless frequency is < 3MHz
+        deca_sleep(5);
+    }
+    else
+    {
+        return DWT_SUCCESS;
+    }
+    // DEBUG - check if still in sleep mode
+    if(dwt_readdevid() != DWT_DEVICE_ID)
+    {
+        return DWT_ERROR;
+    }
+
+    return DWT_SUCCESS;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_configlde()
+ *
+ * @brief configure LDE algorithm parameters
+ *
+ * input parameters
+ * @param prf   -   this is the PRF index (0 or 1) 0 corresponds to 16 and 1 to 64 PRF
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void _dwt_configlde(int prfIndex)
+{
+    dwt_write8bitoffsetreg(LDE_IF_ID, LDE_CFG1_OFFSET, LDE_PARAM1); // 8-bit configuration register
+
+    if(prfIndex)
+    {
+        dwt_write16bitoffsetreg( LDE_IF_ID, LDE_CFG2_OFFSET, (uint16_t) LDE_PARAM3_64); // 16-bit LDE configuration tuning register
+    }
+    else
+    {
+        dwt_write16bitoffsetreg( LDE_IF_ID, LDE_CFG2_OFFSET, (uint16_t) LDE_PARAM3_16);
+    }
+}
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_loaducodefromrom()
+ *
+ * @brief  load ucode from OTP MEMORY or ROM
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void _dwt_loaducodefromrom(void)
+{
+    // Set up clocks
+    _dwt_enableclocks(FORCE_LDE);
+
+    // Kick off the LDE load
+    dwt_write16bitoffsetreg(OTP_IF_ID, OTP_CTRL, OTP_CTRL_LDELOAD); // Set load LDE kick bit
+
+    deca_sleep(1); // Allow time for code to upload (should take up to 120 us)
+
+    // Default clocks (ENABLE_ALL_SEQ)
+    _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_loadopsettabfromotp()
+ *
+ * @brief This is used to select which Operational Parameter Set table to load from OTP memory
+ *
+ * input parameters
+ * @param ops_sel - Operational Parameter Set table to load:
+ *                  DWT_OPSET_64LEN = 0x0 - load the operational parameter set table for 64 length preamble configuration
+ *                  DWT_OPSET_TIGHT = 0x1 - load the operational parameter set table for tight xtal offsets (<1ppm)
+ *                  DWT_OPSET_DEFLT = 0x2 - load the default operational parameter set table (this is loaded from reset)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_loadopsettabfromotp(uint8_t ops_sel)
+{
+    uint16_t reg = ((ops_sel << OTP_SF_OPS_SEL_SHFT) & OTP_SF_OPS_SEL_MASK) | OTP_SF_OPS_KICK; // Select defined OPS table and trigger its loading
+
+    // Set up clocks
+    _dwt_enableclocks(FORCE_LDE);
+
+    dwt_write16bitoffsetreg(OTP_IF_ID, OTP_SF, reg);
+
+    // Default clocks (ENABLE_ALL_SEQ)
+    _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing
+
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setsmarttxpower()
+ *
+ * @brief This call enables or disables the smart TX power feature.
+ *
+ * input parameters
+ * @param enable - this enables or disables the TX smart power (1 = enable, 0 = disable)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setsmarttxpower(int enable)
+{
+    // Config system register
+    pdw1000local->sysCFGreg = dwt_read32bitreg(SYS_CFG_ID) ; // Read sysconfig register
+
+    // Disable smart power configuration
+    if(enable)
+    {
+        pdw1000local->sysCFGreg &= ~(SYS_CFG_DIS_STXP) ;
+    }
+    else
+    {
+        pdw1000local->sysCFGreg |= SYS_CFG_DIS_STXP ;
+    }
+
+    dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ;
+}
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_enableautoack()
+ *
+ * @brief This call enables the auto-ACK feature. If the responseDelayTime (parameter) is 0, the ACK will be sent a.s.a.p.
+ * otherwise it will be sent with a programmed delay (in symbols), max is 255.
+ * NOTE: needs to have frame filtering enabled as well
+ *
+ * input parameters
+ * @param responseDelayTime - if non-zero the ACK is sent after this delay, max is 255.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_enableautoack(uint8_t responseDelayTime)
+{
+    // Set auto ACK reply delay
+    dwt_write8bitoffsetreg(ACK_RESP_T_ID, ACK_RESP_T_ACK_TIM_OFFSET, responseDelayTime); // In symbols
+    // Enable auto ACK
+    pdw1000local->sysCFGreg |= SYS_CFG_AUTOACK;
+    dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setdblrxbuffmode()
+ *
+ * @brief This call enables the double receive buffer mode
+ *
+ * input parameters
+ * @param enable - 1 to enable, 0 to disable the double buffer mode
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setdblrxbuffmode(int enable)
+{
+    if(enable)
+    {
+        // Enable double RX buffer mode
+        pdw1000local->sysCFGreg &= ~SYS_CFG_DIS_DRXB;
+        pdw1000local->dblbuffon = 1;
+    }
+    else
+    {
+        // Disable double RX buffer mode
+        pdw1000local->sysCFGreg |= SYS_CFG_DIS_DRXB;
+        pdw1000local->dblbuffon = 0;
+    }
+
+    dwt_write32bitreg(SYS_CFG_ID,pdw1000local->sysCFGreg) ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setrxaftertxdelay()
+ *
+ * @brief This sets the receiver turn on delay time after a transmission of a frame
+ *
+ * input parameters
+ * @param rxDelayTime - (20 bits) - the delay is in UWB microseconds
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setrxaftertxdelay(uint32_t rxDelayTime)
+{
+    uint32_t val = dwt_read32bitreg(ACK_RESP_T_ID) ; // Read ACK_RESP_T_ID register
+
+    val &= ~(ACK_RESP_T_W4R_TIM_MASK) ; // Clear the timer (19:0)
+
+    val |= (rxDelayTime & ACK_RESP_T_W4R_TIM_MASK) ; // In UWB microseconds (e.g. turn the receiver on 20uus after TX)
+
+    dwt_write32bitreg(ACK_RESP_T_ID, val) ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setcallbacks()
+ *
+ * @brief This function is used to register the different callbacks called when one of the corresponding event occurs.
+ *
+ * NOTE: Callbacks can be undefined (set to NULL). In this case, dwt_isr() will process the event as usual but the 'null'
+ * callback will not be called.
+ *
+ * input parameters
+ * @param cbTxDone - the pointer to the TX confirmation event callback function
+ * @param cbRxOk - the pointer to the RX good frame event callback function
+ * @param cbRxTo - the pointer to the RX timeout events callback function
+ * @param cbRxErr - the pointer to the RX error events callback function
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setcallbacks(dwt_cb_t cbTxDone, dwt_cb_t cbRxOk, dwt_cb_t cbRxTo, dwt_cb_t cbRxErr)
+{
+    pdw1000local->cbTxDone = cbTxDone;
+    pdw1000local->cbRxOk = cbRxOk;
+    pdw1000local->cbRxTo = cbRxTo;
+    pdw1000local->cbRxErr = cbRxErr;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_checkirq()
+ *
+ * @brief This function checks if the IRQ line is active - this is used instead of interrupt handler
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * return value is 1 if the IRQS bit is set and 0 otherwise
+ */
+uint8_t dwt_checkirq(void)
+{
+    return (dwt_read8bitoffsetreg(SYS_STATUS_ID, SYS_STATUS_OFFSET) & SYS_STATUS_IRQS); // Reading the lower byte only is enough for this operation
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_isr()
+ *
+ * @brief This is the DW1000's general Interrupt Service Routine. It will process/report the following events:
+ *          - RXFCG (through cbRxOk callback)
+ *          - TXFRS (through cbTxDone callback)
+ *          - RXRFTO/RXPTO (through cbRxTo callback)
+ *          - RXPHE/RXFCE/RXRFSL/RXSFDTO/AFFREJ/LDEERR (through cbRxTo cbRxErr)
+ *        For all events, corresponding interrupts are cleared and necessary resets are performed. In addition, in the RXFCG case,
+ *        received frame information and frame control are read before calling the callback. If double buffering is activated, it
+ *        will also toggle between reception buffers once the reception callback processing has ended.
+ *
+ *        /!\ This version of the ISR supports double buffering but does not support automatic RX re-enabling!
+ *
+ * NOTE:  In PC based system using (Cheetah or ARM) USB to SPI converter there can be no interrupts, however we still need something
+ *        to take the place of it and operate in a polled way. In an embedded system this function should be configured to be triggered
+ *        on any of the interrupts described above.
+
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_isr(void)
+{
+    uint32_t status = pdw1000local->cbData.status = dwt_read32bitreg(SYS_STATUS_ID); // Read status register low 32bits
+
+    // Handle RX good frame event
+    if(status & SYS_STATUS_RXFCG)
+    {
+        uint16_t finfo16;
+        uint16_t len;
+
+        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_GOOD); // Clear all receive status bits
+
+        pdw1000local->cbData.rx_flags = 0;
+
+        // Read frame info - Only the first two bytes of the register are used here.
+        finfo16 = dwt_read16bitoffsetreg(RX_FINFO_ID, RX_FINFO_OFFSET);
+
+        // Report frame length - Standard frame length up to 127, extended frame length up to 1023 bytes
+        len = finfo16 & RX_FINFO_RXFL_MASK_1023;
+        if(pdw1000local->longFrames == 0)
+        {
+            len &= RX_FINFO_RXFLEN_MASK;
+        }
+        pdw1000local->cbData.datalength = len;
+
+        // Report ranging bit
+        if(finfo16 & RX_FINFO_RNG)
+        {
+            pdw1000local->cbData.rx_flags |= DWT_CB_DATA_RX_FLAG_RNG;
+        }
+
+        // Report frame control - First bytes of the received frame.
+        dwt_readfromdevice(RX_BUFFER_ID, 0, FCTRL_LEN_MAX, pdw1000local->cbData.fctrl);
+
+        // Because of a previous frame not being received properly, AAT bit can be set upon the proper reception of a frame not requesting for
+        // acknowledgement (ACK frame is not actually sent though). If the AAT bit is set, check ACK request bit in frame control to confirm (this
+        // implementation works only for IEEE802.15.4-2011 compliant frames).
+        // This issue is not documented at the time of writing this code. It should be in next release of DW1000 User Manual (v2.09, from July 2016).
+        if((status & SYS_STATUS_AAT) && ((pdw1000local->cbData.fctrl[0] & FCTRL_ACK_REQ_MASK) == 0))
+        {
+            dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_AAT); // Clear AAT status bit in register
+            pdw1000local->cbData.status &= ~SYS_STATUS_AAT; // Clear AAT status bit in callback data register copy
+            pdw1000local->wait4resp = 0;
+        }
+
+        // Call the corresponding callback if present
+        if(pdw1000local->cbRxOk != NULL)
+        {
+            pdw1000local->cbRxOk(&pdw1000local->cbData);
+        }
+
+        if (pdw1000local->dblbuffon)
+        {
+            // Toggle the Host side Receive Buffer Pointer
+            dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET, 1);
+        }
+    }
+
+    // Handle TX confirmation event
+    if(status & SYS_STATUS_TXFRS)
+    {
+        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_TX); // Clear TX event bits
+
+        // In the case where this TXFRS interrupt is due to the automatic transmission of an ACK solicited by a response (with ACK request bit set)
+        // that we receive through using wait4resp to a previous TX (and assuming that the IRQ processing of that TX has already been handled), then
+        // we need to handle the IC issue which turns on the RX again in this situation (i.e. because it is wrongly applying the wait4resp after the
+        // ACK TX).
+        // See section "Transmit and automatically wait for response" in DW1000 User Manual
+        if((status & SYS_STATUS_AAT) && pdw1000local->wait4resp)
+        {
+            dwt_forcetrxoff(); // Turn the RX off
+            dwt_rxreset(); // Reset in case we were late and a frame was already being received
+        }
+
+        // Call the corresponding callback if present
+        if(pdw1000local->cbTxDone != NULL)
+        {
+            pdw1000local->cbTxDone(&pdw1000local->cbData);
+        }
+    }
+
+    // Handle frame reception/preamble detect timeout events
+    if(status & SYS_STATUS_ALL_RX_TO)
+    {
+        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXRFTO); // Clear RX timeout event bits
+
+        pdw1000local->wait4resp = 0;
+
+        // Because of an issue with receiver restart after error conditions, an RX reset must be applied after any error or timeout event to ensure
+        // the next good frame's timestamp is computed correctly.
+        // See section "RX Message timestamp" in DW1000 User Manual.
+        dwt_forcetrxoff();
+        dwt_rxreset();
+
+        // Call the corresponding callback if present
+        if(pdw1000local->cbRxTo != NULL)
+        {
+            pdw1000local->cbRxTo(&pdw1000local->cbData);
+        }
+    }
+
+    // Handle RX errors events
+    if(status & SYS_STATUS_ALL_RX_ERR)
+    {
+        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR); // Clear RX error event bits
+
+        pdw1000local->wait4resp = 0;
+
+        // Because of an issue with receiver restart after error conditions, an RX reset must be applied after any error or timeout event to ensure
+        // the next good frame's timestamp is computed correctly.
+        // See section "RX Message timestamp" in DW1000 User Manual.
+        dwt_forcetrxoff();
+        dwt_rxreset();
+
+        // Call the corresponding callback if present
+        if(pdw1000local->cbRxErr != NULL)
+        {
+            pdw1000local->cbRxErr(&pdw1000local->cbData);
+        }
+    }
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_isr_lplisten()
+ *
+ * @brief This is the DW1000's Interrupt Service Routine to use when low-power listening scheme is implemented. It will
+ *        only process/report the RXFCG event (through cbRxOk callback).
+ *        It clears RXFCG interrupt and reads received frame information and frame control before calling the callback.
+ *
+ *        /!\ This version of the ISR is designed for single buffering case only!
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_lowpowerlistenisr(void)
+{
+    uint32_t status = pdw1000local->cbData.status = dwt_read32bitreg(SYS_STATUS_ID); // Read status register low 32bits
+    uint16_t finfo16;
+    uint16_t len;
+
+    // The only interrupt handled when in low-power listening mode is RX good frame so proceed directly to the handling of the received frame.
+
+    // Deactivate low-power listening before clearing the interrupt. If not, the DW1000 will go back to sleep as soon as the interrupt is cleared.
+    dwt_setlowpowerlistening(0);
+
+    dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_GOOD); // Clear all receive status bits
+
+    pdw1000local->cbData.rx_flags = 0;
+
+    // Read frame info - Only the first two bytes of the register are used here.
+    finfo16 = dwt_read16bitoffsetreg(RX_FINFO_ID, 0);
+
+    // Report frame length - Standard frame length up to 127, extended frame length up to 1023 bytes
+    len = finfo16 & RX_FINFO_RXFL_MASK_1023;
+    if(pdw1000local->longFrames == 0)
+    {
+        len &= RX_FINFO_RXFLEN_MASK;
+    }
+    pdw1000local->cbData.datalength = len;
+
+    // Report ranging bit
+    if(finfo16 & RX_FINFO_RNG)
+    {
+        pdw1000local->cbData.rx_flags |= DWT_CB_DATA_RX_FLAG_RNG;
+    }
+
+    // Report frame control - First bytes of the received frame.
+    dwt_readfromdevice(RX_BUFFER_ID, 0, FCTRL_LEN_MAX, pdw1000local->cbData.fctrl);
+
+    // Because of a previous frame not being received properly, AAT bit can be set upon the proper reception of a frame not requesting for
+    // acknowledgement (ACK frame is not actually sent though). If the AAT bit is set, check ACK request bit in frame control to confirm (this
+    // implementation works only for IEEE802.15.4-2011 compliant frames).
+    // This issue is not documented at the time of writing this code. It should be in next release of DW1000 User Manual (v2.09, from July 2016).
+    if((status & SYS_STATUS_AAT) && ((pdw1000local->cbData.fctrl[0] & FCTRL_ACK_REQ_MASK) == 0))
+    {
+        dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_AAT); // Clear AAT status bit in register
+        pdw1000local->cbData.status &= ~SYS_STATUS_AAT; // Clear AAT status bit in callback data register copy
+        pdw1000local->wait4resp = 0;
+    }
+
+    // Call the corresponding callback if present
+    if(pdw1000local->cbRxOk != NULL)
+    {
+        pdw1000local->cbRxOk(&pdw1000local->cbData);
+    }
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setleds()
+ *
+ * @brief This is used to set up Tx/Rx GPIOs which could be used to control LEDs
+ * Note: not completely IC dependent, also needs board with LEDS fitted on right I/O lines
+ *       this function enables GPIOs 2 and 3 which are connected to LED3 and LED4 on EVB1000
+ *
+ * input parameters
+ * @param mode - this is a bit field interpreted as follows:
+ *          - bit 0: 1 to enable LEDs, 0 to disable them
+ *          - bit 1: 1 to make LEDs blink once on init. Only valid if bit 0 is set (enable LEDs)
+ *          - bit 2 to 7: reserved
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void dwt_setleds(uint8_t mode)
+{
+    uint32_t reg;
+
+    if (mode & DWT_LEDS_ENABLE)
+    {
+        // Set up MFIO for LED output.
+        reg = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
+        reg &= ~(GPIO_MSGP2_MASK | GPIO_MSGP3_MASK);
+        reg |= (GPIO_PIN2_RXLED | GPIO_PIN3_TXLED);
+        dwt_write32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET, reg);
+
+        // Enable LP Oscillator to run from counter and turn on de-bounce clock.
+        reg = dwt_read32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET);
+        reg |= (PMSC_CTRL0_GPDCE | PMSC_CTRL0_KHZCLEN);
+        dwt_write32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, reg);
+
+        // Enable LEDs to blink and set default blink time.
+        reg = PMSC_LEDC_BLNKEN | PMSC_LEDC_BLINK_TIME_DEF;
+        // Make LEDs blink once if requested.
+        if (mode & DWT_LEDS_INIT_BLINK)
+        {
+            reg |= PMSC_LEDC_BLINK_NOW_ALL;
+        }
+        dwt_write32bitoffsetreg(PMSC_ID, PMSC_LEDC_OFFSET, reg);
+        // Clear force blink bits if needed.
+        if(mode & DWT_LEDS_INIT_BLINK)
+        {
+            reg &= ~PMSC_LEDC_BLINK_NOW_ALL;
+            dwt_write32bitoffsetreg(PMSC_ID, PMSC_LEDC_OFFSET, reg);
+        }
+    }
+    else
+    {
+        // Clear the GPIO bits that are used for LED control.
+        reg = dwt_read32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET);
+        reg &= ~(GPIO_MSGP2_MASK | GPIO_MSGP3_MASK);
+        dwt_write32bitoffsetreg(GPIO_CTRL_ID, GPIO_MODE_OFFSET, reg);
+    }
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_enableclocks()
+ *
+ * @brief function to enable/disable clocks to particular digital blocks/system
+ *
+ * input parameters
+ * @param clocks - set of clocks to enable/disable
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void _dwt_enableclocks(int clocks)
+{
+    uint8_t reg[2];
+
+    dwt_readfromdevice(PMSC_ID, PMSC_CTRL0_OFFSET, 2, reg);
+    switch(clocks)
+    {
+        case ENABLE_ALL_SEQ:
+        {
+            reg[0] = 0x00 ;
+            reg[1] = reg[1] & 0xfe;
+        }
+        break;
+        case FORCE_SYS_XTI:
+        {
+            // System and RX
+            reg[0] = 0x01 | (reg[0] & 0xfc);
+        }
+        break;
+        case FORCE_SYS_PLL:
+        {
+            // System
+            reg[0] = 0x02 | (reg[0] & 0xfc);
+        }
+        break;
+        case READ_ACC_ON:
+        {
+            reg[0] = 0x48 | (reg[0] & 0xb3);
+            reg[1] = 0x80 | reg[1];
+        }
+        break;
+        case READ_ACC_OFF:
+        {
+            reg[0] = reg[0] & 0xb3;
+            reg[1] = 0x7f & reg[1];
+        }
+        break;
+        case FORCE_OTP_ON:
+        {
+            reg[1] = 0x02 | reg[1];
+        }
+        break;
+        case FORCE_OTP_OFF:
+        {
+            reg[1] = reg[1] & 0xfd;
+        }
+        break;
+        case FORCE_TX_PLL:
+        {
+            reg[0] = 0x20 | (reg[0] & 0xcf);
+        }
+        break;
+        case FORCE_LDE:
+        {
+            reg[0] = 0x01;
+            reg[1] = 0x03;
+        }
+        break;
+        default:
+        break;
+    }
+
+
+    // Need to write lower byte separately before setting the higher byte(s)
+    dwt_writetodevice(PMSC_ID, PMSC_CTRL0_OFFSET, 1, &reg[0]);
+    dwt_writetodevice(PMSC_ID, 0x1, 1, &reg[1]);
+
+} // end _dwt_enableclocks()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_disablesequencing()
+ *
+ * @brief This function disables the TX blocks sequencing, it disables PMSC control of RF blocks, system clock is also set to XTAL
+ *
+ * input parameters none
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void _dwt_disablesequencing(void) // Disable sequencing and go to state "INIT"
+{
+    _dwt_enableclocks(FORCE_SYS_XTI); // Set system clock to XTI
+
+    dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, PMSC_CTRL1_PKTSEQ_DISABLE); // Disable PMSC ctrl of RF and RX clk blocks
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setdelayedtrxtime()
+ *
+ * @brief This API function configures the delayed transmit time or the delayed RX on time
+ *
+ * input parameters
+ * @param starttime - the TX/RX start time (the 32 bits should be the high 32 bits of the system time at which to send the message,
+ * or at which to turn on the receiver)
+ *
+ * output parameters none
+ *
+ * no return value
+ */
+void dwt_setdelayedtrxtime(uint32_t starttime)
+{
+    dwt_write32bitoffsetreg(DX_TIME_ID, 1, starttime); // Write at offset 1 as the lower 9 bits of this register are ignored
+
+} // end dwt_setdelayedtrxtime()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_starttx()
+ *
+ * @brief This call initiates the transmission, input parameter indicates which TX mode is used see below
+ *
+ * input parameters:
+ * @param mode - if 0 immediate TX (no response expected)
+ *               if 1 delayed TX (no response expected)
+ *               if 2 immediate TX (response expected - so the receiver will be automatically turned on after TX is done)
+ *               if 3 delayed TX (response expected - so the receiver will be automatically turned on after TX is done)
+ *
+ * output parameters
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error (e.g. a delayed transmission will fail if the delayed time has passed)
+ */
+int dwt_starttx(uint8_t mode)
+{
+    int retval = DWT_SUCCESS ;
+    uint8_t temp  = 0x00;
+    uint16_t checkTxOK = 0 ;
+
+    if(mode & DWT_RESPONSE_EXPECTED)
+    {
+        temp = (uint8_t)SYS_CTRL_WAIT4RESP ; // Set wait4response bit
+        dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, temp);
+        pdw1000local->wait4resp = 1;
+    }
+
+    if (mode & DWT_START_TX_DELAYED)
+    {
+        // Both SYS_CTRL_TXSTRT and SYS_CTRL_TXDLYS to correctly enable TX
+        temp |= (uint8_t)(SYS_CTRL_TXDLYS | SYS_CTRL_TXSTRT) ;
+        dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, temp);
+        checkTxOK = dwt_read16bitoffsetreg(SYS_STATUS_ID, 3); // Read at offset 3 to get the upper 2 bytes out of 5
+        if ((checkTxOK & SYS_STATUS_TXERR) == 0) // Transmit Delayed Send set over Half a Period away or Power Up error (there is enough time to send but not to power up individual blocks).
+        {
+            retval = DWT_SUCCESS ; // All okay
+        }
+        else
+        {
+            // I am taking DSHP set to Indicate that the TXDLYS was set too late for the specified DX_TIME.
+            // Remedial Action - (a) cancel delayed send
+            temp = (uint8_t)SYS_CTRL_TRXOFF; // This assumes the bit is in the lowest byte
+            dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, temp);
+            // Note event Delayed TX Time too Late
+            // Could fall through to start a normal send (below) just sending late.....
+            // ... instead return and assume return value of 1 will be used to detect and recover from the issue.
+            pdw1000local->wait4resp = 0;
+            retval = DWT_ERROR ; // Failed !
+        }
+    }
+    else
+    {
+        temp |= (uint8_t)SYS_CTRL_TXSTRT ;
+        dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, temp);
+    }
+
+    return retval;
+
+} // end dwt_starttx()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_forcetrxoff()
+ *
+ * @brief This is used to turn off the transceiver
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_forcetrxoff(void)
+{
+    decaIrqStatus_t stat ;
+    uint32_t mask;
+
+    mask = dwt_read32bitreg(SYS_MASK_ID) ; // Read set interrupt mask
+
+    // Need to beware of interrupts occurring in the middle of following read modify write cycle
+    // We can disable the radio, but before the status is cleared an interrupt can be set (e.g. the
+    // event has just happened before the radio was disabled)
+    // thus we need to disable interrupt during this operation
+    stat = decamutexon() ;
+
+    dwt_write32bitreg(SYS_MASK_ID, 0) ; // Clear interrupt mask - so we don't get any unwanted events
+
+    dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, (uint8_t)SYS_CTRL_TRXOFF) ; // Disable the radio
+
+    // Forcing Transceiver off - so we do not want to see any new events that may have happened
+    dwt_write32bitreg(SYS_STATUS_ID, (SYS_STATUS_ALL_TX | SYS_STATUS_ALL_RX_ERR | SYS_STATUS_ALL_RX_TO | SYS_STATUS_ALL_RX_GOOD));
+
+    dwt_syncrxbufptrs();
+
+    dwt_write32bitreg(SYS_MASK_ID, mask) ; // Set interrupt mask to what it was
+
+    // Enable/restore interrupts again...
+    decamutexoff(stat) ;
+    pdw1000local->wait4resp = 0;
+
+} // end deviceforcetrxoff()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_syncrxbufptrs()
+ *
+ * @brief this function synchronizes rx buffer pointers
+ * need to make sure that the host/IC buffer pointers are aligned before starting RX
+ *
+ * input parameters:
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_syncrxbufptrs(void)
+{
+    uint8_t  buff ;
+    // Need to make sure that the host/IC buffer pointers are aligned before starting RX
+    buff = dwt_read8bitoffsetreg(SYS_STATUS_ID, 3); // Read 1 byte at offset 3 to get the 4th byte out of 5
+
+    if((buff & (SYS_STATUS_ICRBP >> 24)) !=     // IC side Receive Buffer Pointer
+       ((buff & (SYS_STATUS_HSRBP>>24)) << 1) ) // Host Side Receive Buffer Pointer
+    {
+        dwt_write8bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET , 0x01) ; // We need to swap RX buffer status reg (write one to toggle internally)
+    }
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setsniffmode()
+ *
+ * @brief enable/disable and configure SNIFF mode.
+ *
+ * SNIFF mode is a low-power reception mode where the receiver is sequenced on and off instead of being on all the time.
+ * The time spent in each state (on/off) is specified through the parameters below.
+ * See DW1000 User Manual section 4.5 "Low-Power SNIFF mode" for more details.
+ *
+ * input parameters:
+ * @param enable - 1 to enable SNIFF mode, 0 to disable. When 0, all other parameters are not taken into account.
+ * @param timeOn - duration of receiver ON phase, expressed in multiples of PAC size. The counter automatically adds 1 PAC
+ *                 size to the value set. Min value that can be set is 1 (i.e. an ON time of 2 PAC size), max value is 15.
+ * @param timeOff - duration of receiver OFF phase, expressed in multiples of 128/125 µs (~1 µs). Max value is 255.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setsniffmode(int enable, uint8_t timeOn, uint8_t timeOff)
+{
+    uint32_t pmsc_reg;
+    if (enable)
+    {
+        /* Configure ON/OFF times and enable PLL2 on/off sequencing by SNIFF mode. */
+        uint16_t sniff_reg = ((timeOff << 8) | timeOn) & RX_SNIFF_MASK;
+        dwt_write16bitoffsetreg(RX_SNIFF_ID, RX_SNIFF_OFFSET, sniff_reg);
+        pmsc_reg = dwt_read32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET);
+        pmsc_reg |= PMSC_CTRL0_PLL2_SEQ_EN;
+        dwt_write32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, pmsc_reg);
+    }
+    else
+    {
+        /* Clear ON/OFF times and disable PLL2 on/off sequencing by SNIFF mode. */
+        dwt_write16bitoffsetreg(RX_SNIFF_ID, RX_SNIFF_OFFSET, 0x0000);
+        pmsc_reg = dwt_read32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET);
+        pmsc_reg &= ~PMSC_CTRL0_PLL2_SEQ_EN;
+        dwt_write32bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, pmsc_reg);
+    }
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setlowpowerlistening()
+ *
+ * @brief enable/disable low-power listening mode.
+ *
+ * Low-power listening is a feature whereby the DW1000 is predominantly in the SLEEP state but wakes periodically, (after
+ * this "long sleep"), for a very short time to sample the air for a preamble sequence. This preamble sampling "listening"
+ * phase is actually two reception phases separated by a "short sleep" time. See DW1000 User Manual section "Low-Power
+ * Listening" for more details.
+ *
+ * NOTE: Before enabling low-power listening, the following functions have to be called to fully configure it:
+ *           - dwt_configuresleep() to configure long sleep phase. "mode" parameter should at least have DWT_PRESRV_SLEEP,
+ *             DWT_CONFIG and DWT_RX_EN set and "wake" parameter should at least have both DWT_WAKE_SLPCNT and DWT_SLP_EN set.
+ *           - dwt_calibratesleepcnt() and dwt_configuresleepcnt() to define the "long sleep" phase duration.
+ *           - dwt_setsnoozetime() to define the "short sleep" phase duration.
+ *           - dwt_setpreambledetecttimeout() to define the reception phases duration.
+ *           - dwt_setinterrupt() to activate RX good frame interrupt (DWT_INT_RFCG) only.
+ *       When configured, low-power listening mode can be triggered either by putting the DW1000 to sleep (using
+ *       dwt_entersleep()) or by activating reception (using dwt_rxenable()).
+ *
+ *       Please refer to the low-power listening examples (examples 8a/8b accompanying the API distribution on Decawave's
+ *       website). They form a working example code that shows how to use low-power listening correctly.
+ *
+ * input parameters:
+ * @param enable - 1 to enable low-power listening, 0 to disable.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setlowpowerlistening(int enable)
+{
+    uint32_t pmsc_reg = dwt_read32bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET);
+    if (enable)
+    {
+        /* Configure RX to sleep and snooze features. */
+        pmsc_reg |= (PMSC_CTRL1_ARXSLP | PMSC_CTRL1_SNOZE);
+    }
+    else
+    {
+        /* Reset RX to sleep and snooze features. */
+        pmsc_reg &= ~(PMSC_CTRL1_ARXSLP | PMSC_CTRL1_SNOZE);
+    }
+    dwt_write32bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, pmsc_reg);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setsnoozetime()
+ *
+ * @brief Set duration of "short sleep" phase when in low-power listening mode.
+ *
+ * input parameters:
+ * @param snooze_time - "short sleep" phase duration, expressed in multiples of 512/19.2 µs (~26.7 µs). The counter
+ *                      automatically adds 1 to the value set. The smallest working value that should be set is 1,
+ *                      i.e. giving a snooze time of 2 units (or ~53 µs).
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setsnoozetime(uint8_t snooze_time)
+{
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_SNOZT_OFFSET, snooze_time);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_rxenable()
+ *
+ * @brief This call turns on the receiver, can be immediate or delayed (depending on the mode parameter). In the case of a
+ * "late" error the receiver will only be turned on if the DWT_IDLE_ON_DLY_ERR is not set.
+ * The receiver will stay turned on, listening to any messages until
+ * it either receives a good frame, an error (CRC, PHY header, Reed Solomon) or  it times out (SFD, Preamble or Frame).
+ *
+ * input parameters
+ * @param mode - this can be one of the following allowed values:
+ *
+ * DWT_START_RX_IMMEDIATE      0 used to enbale receiver immediately
+ * DWT_START_RX_DELAYED        1 used to set up delayed RX, if "late" error triggers, then the RX will be enabled immediately
+ * (DWT_START_RX_DELAYED | DWT_IDLE_ON_DLY_ERR) 3 used to disable re-enabling of receiver if delayed RX failed due to "late" error
+ * (DWT_START_RX_IMMEDIATE | DWT_NO_SYNC_PTRS) 4 used to re-enable RX without trying to sync IC and host side buffer pointers, typically when
+ *                                               performing manual RX re-enabling in double buffering mode
+ *
+ * returns DWT_SUCCESS for success, or DWT_ERROR for error (e.g. a delayed receive enable will be too far in the future if delayed time has passed)
+ */
+int dwt_rxenable(int mode)
+{
+    uint16_t temp ;
+    uint8_t temp1 ;
+
+    if ((mode & DWT_NO_SYNC_PTRS) == 0)
+    {
+        dwt_syncrxbufptrs();
+    }
+
+    temp = (uint16_t)SYS_CTRL_RXENAB ;
+
+    if (mode & DWT_START_RX_DELAYED)
+    {
+        temp |= (uint16_t)SYS_CTRL_RXDLYE ;
+    }
+
+    dwt_write16bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, temp);
+
+    if (mode & DWT_START_RX_DELAYED) // check for errors
+    {
+        temp1 = dwt_read8bitoffsetreg(SYS_STATUS_ID, 3); // Read 1 byte at offset 3 to get the 4th byte out of 5
+        if ((temp1 & (SYS_STATUS_HPDWARN >> 24)) != 0) // if delay has passed do immediate RX on unless DWT_IDLE_ON_DLY_ERR is true
+        {
+            dwt_forcetrxoff(); // turn the delayed receive off
+
+            if((mode & DWT_IDLE_ON_DLY_ERR) == 0) // if DWT_IDLE_ON_DLY_ERR not set then re-enable receiver
+            {
+                dwt_write16bitoffsetreg(SYS_CTRL_ID, SYS_CTRL_OFFSET, SYS_CTRL_RXENAB);
+            }
+            return DWT_ERROR; // return warning indication
+        }
+    }
+
+    return DWT_SUCCESS;
+} // end dwt_rxenable()
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setrxtimeout()
+ *
+ * @brief This call enables RX timeout (SY_STAT_RFTO event)
+ *
+ * input parameters
+ * @param time - how long the receiver remains on from the RX enable command
+ *               The time parameter used here is in 1.0256 us (512/499.2MHz) units
+ *               If set to 0 the timeout is disabled.
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setrxtimeout(uint16_t time)
+{
+    uint8_t temp ;
+
+    temp = dwt_read8bitoffsetreg(SYS_CFG_ID, 3); // Read at offset 3 to get the upper byte only
+
+    if(time > 0)
+    {
+        dwt_write16bitoffsetreg(RX_FWTO_ID, RX_FWTO_OFFSET, time) ;
+
+        temp |= (uint8_t)(SYS_CFG_RXWTOE>>24); // Shift RXWTOE mask as we read the upper byte only
+        // OR in 32bit value (1 bit set), I know this is in high byte.
+        pdw1000local->sysCFGreg |= SYS_CFG_RXWTOE;
+
+        dwt_write8bitoffsetreg(SYS_CFG_ID, 3, temp); // Write at offset 3 to write the upper byte only
+    }
+    else
+    {
+        temp &= ~((uint8_t)(SYS_CFG_RXWTOE>>24)); // Shift RXWTOE mask as we read the upper byte only
+        // AND in inverted 32bit value (1 bit clear), I know this is in high byte.
+        pdw1000local->sysCFGreg &= ~(SYS_CFG_RXWTOE);
+
+        dwt_write8bitoffsetreg(SYS_CFG_ID, 3, temp); // Write at offset 3 to write the upper byte only
+    }
+
+} // end dwt_setrxtimeout()
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setpreambledetecttimeout()
+ *
+ * @brief This call enables preamble timeout (SY_STAT_RXPTO event)
+ *
+ * input parameters
+ * @param  timeout - Preamble detection timeout, expressed in multiples of PAC size. The counter automatically adds 1 PAC
+ *                   size to the value set. Min value that can be set is 1 (i.e. a timeout of 2 PAC size).
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setpreambledetecttimeout(uint16_t timeout)
+{
+    dwt_write16bitoffsetreg(DRX_CONF_ID, DRX_PRETOC_OFFSET, timeout);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn void dwt_setinterrupt()
+ *
+ * @brief This function enables the specified events to trigger an interrupt.
+ * The following events can be enabled:
+ * DWT_INT_TFRS         0x00000080          // frame sent
+ * DWT_INT_RFCG         0x00004000          // frame received with good CRC
+ * DWT_INT_RPHE         0x00001000          // receiver PHY header error
+ * DWT_INT_RFCE         0x00008000          // receiver CRC error
+ * DWT_INT_RFSL         0x00010000          // receiver sync loss error
+ * DWT_INT_RFTO         0x00020000          // frame wait timeout
+ * DWT_INT_RXPTO        0x00200000          // preamble detect timeout
+ * DWT_INT_SFDT         0x04000000          // SFD timeout
+ * DWT_INT_ARFE         0x20000000          // frame rejected (due to frame filtering configuration)
+ *
+ *
+ * input parameters:
+ * @param bitmask - sets the events which will generate interrupt
+ * @param enable - if set the interrupts are enabled else they are cleared
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setinterrupt(uint32_t bitmask, uint8_t enable)
+{
+    decaIrqStatus_t stat ;
+    uint32_t mask ;
+
+    // Need to beware of interrupts occurring in the middle of following read modify write cycle
+    stat = decamutexon() ;
+
+    mask = dwt_read32bitreg(SYS_MASK_ID) ; // Read register
+
+    if(enable)
+    {
+        mask |= bitmask ;
+    }
+    else
+    {
+        mask &= ~bitmask ; // Clear the bit
+    }
+    dwt_write32bitreg(SYS_MASK_ID,mask) ; // New value
+
+    decamutexoff(stat) ;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configeventcounters()
+ *
+ * @brief This is used to enable/disable the event counter in the IC
+ *
+ * input parameters
+ * @param - enable - 1 enables (and reset), 0 disables the event counters
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configeventcounters(int enable)
+{
+    // Need to clear and disable, can't just clear
+    dwt_write8bitoffsetreg(DIG_DIAG_ID, EVC_CTRL_OFFSET, (uint8_t)(EVC_CLR));
+
+    if(enable)
+    {
+        dwt_write8bitoffsetreg(DIG_DIAG_ID, EVC_CTRL_OFFSET, (uint8_t)(EVC_EN)); // Enable
+    }
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readeventcounters()
+ *
+ * @brief This is used to read the event counters in the IC
+ *
+ * input parameters
+ * @param counters - pointer to the dwt_deviceentcnts_t structure which will hold the read data
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_readeventcounters(dwt_deviceentcnts_t *counters)
+{
+    uint32_t temp;
+
+    temp= dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_PHE_OFFSET); // Read sync loss (31-16), PHE (15-0)
+    counters->PHE = temp & 0xFFF;
+    counters->RSL = (temp >> 16) & 0xFFF;
+
+    temp = dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_FCG_OFFSET); // Read CRC bad (31-16), CRC good (15-0)
+    counters->CRCG = temp & 0xFFF;
+    counters->CRCB = (temp >> 16) & 0xFFF;
+
+    temp = dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_FFR_OFFSET); // Overruns (31-16), address errors (15-0)
+    counters->ARFE = temp & 0xFFF;
+    counters->OVER = (temp >> 16) & 0xFFF;
+
+    temp = dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_STO_OFFSET); // Read PTO (31-16), SFDTO (15-0)
+    counters->PTO = (temp >> 16) & 0xFFF;
+    counters->SFDTO = temp & 0xFFF;
+
+    temp = dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_FWTO_OFFSET); // Read RX TO (31-16), TXFRAME (15-0)
+    counters->TXF = (temp >> 16) & 0xFFF;
+    counters->RTO = temp & 0xFFF;
+
+    temp = dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_HPW_OFFSET); // Read half period warning events
+    counters->HPW = temp & 0xFFF;
+    counters->TXW = (temp >> 16) & 0xFFF;                       // Power-up warning events
+
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_rxreset()
+ *
+ * @brief this function resets the receiver of the DW1000
+ *
+ * input parameters:
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_rxreset(void)
+{
+    // Set RX reset
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_SOFTRESET_OFFSET, PMSC_CTRL0_RESET_RX);
+
+    // Clear RX reset
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_SOFTRESET_OFFSET, PMSC_CTRL0_RESET_CLEAR);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_softreset()
+ *
+ * @brief this function resets the DW1000
+ *
+ * input parameters:
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_softreset(void)
+{
+    _dwt_disablesequencing();
+
+    // Clear any AON auto download bits (as reset will trigger AON download)
+    dwt_write16bitoffsetreg(AON_ID, AON_WCFG_OFFSET, 0x00);
+    // Clear the wake-up configuration
+    dwt_write8bitoffsetreg(AON_ID, AON_CFG0_OFFSET, 0x00);
+    // Upload the new configuration
+    _dwt_aonarrayupload();
+
+    // Reset HIF, TX, RX and PMSC
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_SOFTRESET_OFFSET, PMSC_CTRL0_RESET_ALL);
+
+    // DW1000 needs a 10us sleep to let clk PLL lock after reset - the PLL will automatically lock after the reset
+    // Could also have polled the PLL lock flag, but then the SPI needs to be < 3MHz !! So a simple delay is easier
+    deca_sleep(1);
+
+    // Clear reset
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_SOFTRESET_OFFSET, PMSC_CTRL0_RESET_CLEAR);
+
+    pdw1000local->wait4resp = 0;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_setxtaltrim()
+ *
+ * @brief This is used to adjust the crystal frequency
+ *
+ * input parameters:
+ * @param   value - crystal trim value (in range 0x0 to 0x1F) 31 steps (~1.5ppm per step)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_setxtaltrim(uint8_t value)
+{
+    // The 3 MSb in this 8-bit register must be kept to 0b011 to avoid any malfunction.
+    uint8_t reg_val = (3 << 5) | (value & FS_XTALT_MASK);
+    dwt_write8bitoffsetreg(FS_CTRL_ID, FS_XTALT_OFFSET, reg_val);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getinitxtaltrim()
+ *
+ * @brief This function returns the value of XTAL trim that has been applied during initialisation (dwt_init). This can
+ *        be either the value read in OTP memory or a default value.
+ *
+ * NOTE: The value returned by this function is the initial value only! It is not updated on dwt_setxtaltrim calls.
+ *
+ * input parameters
+ *
+ * output parameters
+ *
+ * returns the XTAL trim value set upon initialisation
+ */
+uint8_t dwt_getinitxtaltrim(void)
+{
+    return pdw1000local->init_xtrim;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configcwmode()
+ *
+ * @brief this function sets the DW1000 to transmit cw signal at specific channel frequency
+ *
+ * input parameters:
+ * @param chan - specifies the operating channel (e.g. 1, 2, 3, 4, 5, 6 or 7)
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configcwmode(uint8_t chan)
+{
+#ifdef DWT_API_ERROR_CHECK
+    assert((chan >= 1) && (chan <= 7) && (chan != 6));
+#endif
+
+    //
+    // Disable TX/RX RF block sequencing (needed for cw frame mode)
+    //
+    _dwt_disablesequencing();
+
+    // Config RF pll (for a given channel)
+    // Configure PLL2/RF PLL block CFG/TUNE
+    dwt_write32bitoffsetreg(FS_CTRL_ID, FS_PLLCFG_OFFSET, fs_pll_cfg[chan_idx[chan]]);
+    dwt_write8bitoffsetreg(FS_CTRL_ID, FS_PLLTUNE_OFFSET, fs_pll_tune[chan_idx[chan]]);
+    // PLL wont be enabled until a TX/RX enable is issued later on
+    // Configure RF TX blocks (for specified channel and prf)
+    // Config RF TX control
+    dwt_write32bitoffsetreg(RF_CONF_ID, RF_TXCTRL_OFFSET, tx_config[chan_idx[chan]]);
+
+    //
+    // Enable RF PLL
+    //
+    dwt_write32bitreg(RF_CONF_ID, RF_CONF_TXPLLPOWEN_MASK); // Enable LDO and RF PLL blocks
+    dwt_write32bitreg(RF_CONF_ID, RF_CONF_TXALLEN_MASK); // Enable the rest of TX blocks
+
+    //
+    // Configure TX clocks
+    //
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, 0x22);
+    dwt_write8bitoffsetreg(PMSC_ID, 0x1, 0x07);
+
+    // Disable fine grain TX sequencing
+    dwt_setfinegraintxseq(0);
+
+    // Configure CW mode
+    dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGTEST_OFFSET, TC_PGTEST_CW);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_configcontinuousframemode()
+ *
+ * @brief this function sets the DW1000 to continuous tx frame mode for regulatory approvals testing.
+ *
+ * input parameters:
+ * @param framerepetitionrate - This is a 32-bit value that is used to set the interval between transmissions.
+*  The minimum value is 4. The units are approximately 8 ns. (or more precisely 512/(499.2e6*128) seconds)).
+ *
+ * output parameters
+ *
+ * no return value
+ */
+void dwt_configcontinuousframemode(uint32_t framerepetitionrate)
+{
+    //
+    // Disable TX/RX RF block sequencing (needed for continuous frame mode)
+    //
+    _dwt_disablesequencing();
+
+    //
+    // Enable RF PLL and TX blocks
+    //
+    dwt_write32bitreg(RF_CONF_ID, RF_CONF_TXPLLPOWEN_MASK); // Enable LDO and RF PLL blocks
+    dwt_write32bitreg(RF_CONF_ID, RF_CONF_TXALLEN_MASK); // Enable the rest of TX blocks
+
+    //
+    // Configure TX clocks
+    //
+    _dwt_enableclocks(FORCE_SYS_PLL);
+    _dwt_enableclocks(FORCE_TX_PLL);
+
+    // Set the frame repetition rate
+    if(framerepetitionrate < 4)
+    {
+        framerepetitionrate = 4;
+    }
+    dwt_write32bitreg(DX_TIME_ID, framerepetitionrate);
+
+    //
+    // Configure continuous frame TX
+    //
+    dwt_write8bitoffsetreg(DIG_DIAG_ID, DIAG_TMC_OFFSET, (uint8_t)(DIAG_TMC_TX_PSTM)); // Turn the tx power spectrum test mode - continuous sending of frames
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readtempvbat()
+ *
+ * @brief this function reads the battery voltage and temperature of the MP
+ * The values read here will be the current values sampled by DW1000 AtoD converters.
+ * Note on Temperature: the temperature value needs to be converted to give the real temperature
+ * the formula is: 1.13 * reading - 113.0
+ * Note on Voltage: the voltage value needs to be converted to give the real voltage
+ * the formula is: 0.0057 * reading + 2.3
+ *
+ * NB: To correctly read the temperature this read should be done with xtal clock
+ * however that means that the receiver will be switched off, if receiver needs to be on then
+ * the timer is used to make sure the value is stable before reading
+ *
+ * input parameters:
+ * @param fastSPI - set to 1 if SPI rate > than 3MHz is used
+ *
+ * output parameters
+ *
+ * returns  (temp_raw<<8)|(vbat_raw)
+ */
+uint16_t dwt_readtempvbat(uint8_t fastSPI)
+{
+    uint8_t wr_buf[2];
+    uint8_t vbat_raw;
+    uint8_t temp_raw;
+
+    // These writes should be single writes and in sequence
+    wr_buf[0] = 0x80; // Enable TLD Bias
+    dwt_writetodevice(RF_CONF_ID,0x11,1,wr_buf);
+
+    wr_buf[0] = 0x0A; // Enable TLD Bias and ADC Bias
+    dwt_writetodevice(RF_CONF_ID,0x12,1,wr_buf);
+
+    wr_buf[0] = 0x0f; // Enable Outputs (only after Biases are up and running)
+    dwt_writetodevice(RF_CONF_ID,0x12,1,wr_buf);    //
+
+    // Reading All SAR inputs
+    wr_buf[0] = 0x00;
+    dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C,1,wr_buf);
+    wr_buf[0] = 0x01; // Set SAR enable
+    dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C,1,wr_buf);
+
+    if(fastSPI == 1)
+    {
+        deca_sleep(1); // If using PLL clocks(and fast SPI rate) then this sleep is needed
+        // Read voltage and temperature.
+        dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET,2,wr_buf);
+    }
+    else //change to a slow clock
+    {
+        _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: set system clock to XTI - this is necessary to make sure the values read are reliable
+        // Read voltage and temperature.
+        dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET,2,wr_buf);
+        // Default clocks (ENABLE_ALL_SEQ)
+        _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing
+    }
+
+    vbat_raw = wr_buf[0];
+    temp_raw = wr_buf[1];
+
+    wr_buf[0] = 0x00; // Clear SAR enable
+    dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C,1,wr_buf);
+
+    return ((temp_raw<<8)|(vbat_raw));
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readwakeuptemp()
+ *
+ * @brief this function reads the temperature of the DW1000 that was sampled
+ * on waking from Sleep/Deepsleep. They are not current values, but read on last
+ * wakeup if DWT_TANDV bit is set in mode parameter of dwt_configuresleep
+ *
+ * input parameters:
+ *
+ * output parameters:
+ *
+ * returns: 8-bit raw temperature sensor value
+ */
+uint8_t dwt_readwakeuptemp(void)
+{
+    return dwt_read8bitoffsetreg(TX_CAL_ID, TC_SARL_SAR_LTEMP_OFFSET);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readwakeupvbat()
+ *
+ * @brief this function reads the battery voltage of the DW1000 that was sampled
+ * on waking from Sleep/Deepsleep. They are not current values, but read on last
+ * wakeup if DWT_TANDV bit is set in mode parameter of dwt_configuresleep
+ *
+ * input parameters:
+ *
+ * output parameters:
+ *
+ * returns: 8-bit raw battery voltage sensor value
+ */
+uint8_t dwt_readwakeupvbat(void)
+{
+    return dwt_read8bitoffsetreg(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET);
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calcbandwidthtempadj()
+ *
+ * @brief this function determines the corrected bandwidth setting (PG_DELAY register setting)
+ * of the DW1000 which changes over temperature.
+ *
+ * input parameters:
+ * @param target_count - uint16_t - the PG count target to reach in order to correct the bandwidth
+ *
+ * output parameters:
+ *
+ * returns: (uint32) The setting to be programmed into the PG_DELAY value
+ */
+uint32_t dwt_calcbandwidthtempadj(uint16_t target_count)
+{
+    int i;
+    uint32_t bit_field, curr_bw;
+    int32_t delta_count = 0;
+    uint32_t best_bw = 0;
+    uint16_t raw_count = 0;
+    int32_t delta_lowest;
+
+    // Used to store the current values of the registers so that they can be restored after
+    uint8_t old_pmsc_ctrl0;
+    uint16_t old_pmsc_ctrl1;
+    uint32_t old_rf_conf_txpow_mask;
+
+    // Record the current values of these registers, to restore later
+    old_pmsc_ctrl0 = dwt_read8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET);
+    old_pmsc_ctrl1 = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET);
+    old_rf_conf_txpow_mask = dwt_read32bitreg(RF_CONF_ID);
+
+    //  Set clock to XTAL
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, PMSC_CTRL0_SYSCLKS_19M);
+
+    //  Disable sequencing
+    dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, PMSC_CTRL1_PKTSEQ_DISABLE);
+
+    //  Turn on CLK PLL, Mix Bias and PG
+    dwt_write32bitreg(RF_CONF_ID, RF_CONF_TXPOW_MASK | RF_CONF_PGMIXBIASEN_MASK);
+
+    //  Set sys and TX clock to PLL
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, PMSC_CTRL0_SYSCLKS_125M | PMSC_CTRL0_TXCLKS_125M);
+
+    // Set the MSB high for first guess
+    curr_bw = 0x80;
+    // Set starting bit
+    bit_field = 0x80;
+    // Initial lowest delta is the maximum difference that we should allow the count value to be from the target.
+    // If the algorithm is successful, it will be overwritten by a smaller value where the count value is closer
+    // to the target
+    delta_lowest = 300;
+
+    for (i = 0; i < 7; i++)
+    {
+        // start with 0xc0 and test.
+        bit_field = bit_field >> 1;
+        curr_bw = curr_bw | bit_field;
+
+        // Write bw setting to PG_DELAY register
+        dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, curr_bw);
+
+        // Set cal direction and time
+        dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGCCTRL_OFFSET, TC_PGCCTRL_DIR_CONV | TC_PGCCTRL_TMEAS_MASK);
+
+        // Start cal
+        dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGCCTRL_OFFSET, TC_PGCCTRL_DIR_CONV | TC_PGCCTRL_TMEAS_MASK | TC_PGCCTRL_CALSTART);
+        // Allow cal to complete
+        deca_sleep(100);
+
+        // Read count value from the PG cal block
+        raw_count = dwt_read16bitoffsetreg(TX_CAL_ID, TC_PGCAL_STATUS_OFFSET) & TC_PGCAL_STATUS_DELAY_MASK;
+
+        // lets keep track of the closest value to the target in case we overshoot
+        delta_count = abs((int)raw_count - (int)target_count);
+        if (delta_count < delta_lowest)
+        {
+            delta_lowest = delta_count;
+            best_bw = curr_bw;
+        }
+
+        // Test the count results
+        if (raw_count > target_count)
+            // Count was lower, BW was lower so increase PG DELAY
+            curr_bw = curr_bw | bit_field;
+        else
+            // Count was higher
+            curr_bw = curr_bw & (~(bit_field));
+    }
+
+    // Restore old register values
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, old_pmsc_ctrl0);
+    dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, old_pmsc_ctrl1);
+    dwt_write32bitreg(RF_CONF_ID, old_rf_conf_txpow_mask);
+
+    // Returns the best PG_DELAY setting
+    return best_bw;
+}
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn _dwt_computetxpowersetting()
+ *
+ * @brief this function calculates the appropriate change to the TX_POWER register to compensate
+ * the TX power output at different temperatures.
+ *
+ * input parameters:
+ * @param ref_powerreg - uint32_t - the TX_POWER register value recorded when reference measurements were made
+ * @param power_adj - uint32_t - the adjustment in power level to be made, in 0.5dB steps
+ *
+ * output parameters:
+ *
+ * returns: (uint32) The setting to be programmed into the TX_POWER register
+ */
+uint32_t _dwt_computetxpowersetting(uint32_t ref_powerreg, int32_t power_adj)
+{
+    int32_t da_attn_change, mixer_gain_change;
+    uint8_t current_da_attn, current_mixer_gain;
+    uint8_t new_da_attn, new_mixer_gain;
+    uint32_t new_regval = 0;
+    int i;
+
+    for(i = 0; i < 4; i++)
+    {
+        da_attn_change = 0;
+        mixer_gain_change = power_adj;
+        current_da_attn = ((ref_powerreg >> (i*8)) & 0xE0) >> 5;
+        current_mixer_gain = (ref_powerreg >> (i*8)) & 0x1F;
+
+        // Mixer gain gives best performance between 4 and 20
+        while((current_mixer_gain + mixer_gain_change < 4) ||
+              (current_mixer_gain + mixer_gain_change > 20))
+        {
+            // If mixer gain goes outside bounds, adjust the DA attenuation to compensate
+            if(current_mixer_gain + mixer_gain_change > 20)
+            {
+                da_attn_change += 1;
+                mixer_gain_change -= (int) (DA_ATTN_STEP / MIXER_GAIN_STEP);
+            }
+            else if(current_mixer_gain + mixer_gain_change < 4)
+            {
+                da_attn_change += 1;
+                mixer_gain_change += (int) (DA_ATTN_STEP / MIXER_GAIN_STEP);
+            }
+        }
+
+        new_da_attn = current_da_attn + da_attn_change;
+        new_mixer_gain = current_mixer_gain + mixer_gain_change;
+
+        new_regval |= ((uint32_t) ((new_da_attn << 5) | new_mixer_gain)) << (i * 8);
+    }
+
+    return (uint32_t)new_regval;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calcpowertempadj()
+ *
+ * @brief this function determines the corrected power setting (TX_POWER setting) for the
+ * DW1000 which changes over temperature.
+ *
+ * input parameters:
+ * @param channel - uint8_t - the channel at which compensation of power level will be applied
+ * @param ref_powerreg - uint32_t - the TX_POWER register value recorded when reference measurements were made
+ * @param current_temperature - double - the current ambient temperature in degrees Celcius
+ * @param reference_temperature - double - the temperature at which reference measurements were made
+ * output parameters: None
+ *
+ * returns: (uint32) The corrected TX_POWER register value
+ */
+ uint32_t dwt_calcpowertempadj
+(
+       uint8_t channel,
+       uint32_t ref_powerreg,
+       double curr_temp,
+       double ref_temp
+)
+{
+    double delta_temp;
+    double delta_power;
+
+    // Find the temperature differential
+    delta_temp = curr_temp - ref_temp;
+
+    // Calculate the expected power differential at the current temperature
+    delta_power = delta_temp * txpwr_compensation[chan_idx[channel]];
+
+    // Adjust the TX_POWER register value
+    return _dwt_computetxpowersetting(ref_powerreg, (int32_t)(delta_power / MIXER_GAIN_STEP));
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_calcpgcount()
+ *
+ * @brief this function calculates the value in the pulse generator counter register (PGC_STATUS) for a given PG_DELAY
+ * This is used to take a reference measurement, and the value recorded as the reference is used to adjust the
+ * bandwidth of the device when the temperature changes.
+ *
+ * input parameters:
+ * @param pgdly - uint8_t - the PG_DELAY to set (to control bandwidth), and to find the corresponding count value for
+ * output parameters: None
+ *
+ * returns: (uint16) PGC_STATUS count value calculated from the provided PG_DELAY value - used as reference for later
+ * bandwidth adjustments
+ */
+uint16_t dwt_calcpgcount(uint8_t pgdly)
+{
+    // Perform PG count read ten times and take an average to smooth out any noise
+    const int NUM_SAMPLES = 10;
+    uint32_t sum_count = 0;
+    uint16_t average_count = 0, count = 0;
+    int i = 0;
+
+    // Used to store the current values of the registers so that they can be restored after
+    uint8_t old_pmsc_ctrl0;
+    uint16_t old_pmsc_ctrl1;
+    uint32_t old_rf_conf_txpow_mask;
+
+    // Record the current values of these registers, to restore later
+    old_pmsc_ctrl0 = dwt_read8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET);
+    old_pmsc_ctrl1 = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET);
+    old_rf_conf_txpow_mask = dwt_read32bitreg(RF_CONF_ID);
+
+    //  Set clock to XTAL
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, PMSC_CTRL0_SYSCLKS_19M);
+    //  Disable sequencing
+    dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, PMSC_CTRL1_PKTSEQ_DISABLE);
+    //  Turn on CLK PLL, Mix Bias and PG
+    dwt_write32bitreg(RF_CONF_ID, RF_CONF_TXPOW_MASK | RF_CONF_PGMIXBIASEN_MASK);
+    //  Set sys and TX clock to PLL
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, PMSC_CTRL0_SYSCLKS_125M | PMSC_CTRL0_TXCLKS_125M);
+
+    for(i = 0; i < NUM_SAMPLES; i++) {
+        // Write bw setting to PG_DELAY register
+        dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGDELAY_OFFSET, pgdly);
+
+        // Set cal direction and time
+        dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGCCTRL_OFFSET, TC_PGCCTRL_DIR_CONV | TC_PGCCTRL_TMEAS_MASK);
+
+        // Start cal
+        dwt_write8bitoffsetreg(TX_CAL_ID, TC_PGCCTRL_OFFSET, TC_PGCCTRL_DIR_CONV | TC_PGCCTRL_TMEAS_MASK | TC_PGCCTRL_CALSTART);
+
+        // Allow cal to complete - the TC_PGCCTRL_CALSTART bit will clear automatically
+        deca_sleep(100);
+
+        // Read count value from the PG cal block
+        count = dwt_read16bitoffsetreg(TX_CAL_ID, TC_PGCAL_STATUS_OFFSET) & TC_PGCAL_STATUS_DELAY_MASK;
+
+        sum_count += count;
+    }
+
+     // Restore old register values
+    dwt_write8bitoffsetreg(PMSC_ID, PMSC_CTRL0_OFFSET, old_pmsc_ctrl0);
+    dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET, old_pmsc_ctrl1);
+    dwt_write32bitreg(RF_CONF_ID, old_rf_conf_txpow_mask);
+
+    average_count = (int)(sum_count / NUM_SAMPLES);
+    return average_count;
+}
+
+
+/* ===============================================================================================
+   List of expected (known) device ID handled by this software
+   ===============================================================================================
+
+    0xDECA0130                               // DW1000 - MP
+
+   ===============================================================================================
+*/
+
+/****************************************************************************************************************************************************
+ *
+ * Declaration of platform-dependent lower level functions.
+ *
+ ****************************************************************************************************************************************************/
+
+/*
+ * DW1000 Hardware dependent functions: SPI, EXTI
+ */
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * Function: writetospi()
+ *
+ * Low level abstract function for DW1000 to write to the SPI
+ * Takes two separate byte buffers for write header and write data
+ * returns 0 for success, or -1 for error
+ */
+#pragma GCC optimize ("O3")
+int writetospi(uint16_t headerLength,
+               const	uint8_t *headerBuffer,
+               uint32_t bodyLength,
+               const	uint8_t *bodyBuffer)
+{
+
+    port_SPIx_clear_chip_select();
+
+    uint8_t buffer[bodyLength + 3];
+    memcpy(buffer, headerBuffer, headerLength); //copy data to buffer
+    memcpy(&buffer[headerLength], bodyBuffer, bodyLength); //copy data to buffer
+
+    apalSPITransmit(&MODULE_HAL_SPI_UWB,
+                    buffer,
+                    bodyLength + headerLength); // send header and data
+
+    port_SPIx_set_chip_select();
+
+    return 0;
+} // end writetospi()
+
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * Function: readfromspi()
+ *
+ * Low level abstract function for DW1000 to read from the SPI
+ * Takes two separate byte buffers for write header and read data
+ * returns the offset into read buffer where first byte of read data may be found,
+ * or returns -1 if there was an error
+ */
+#pragma GCC optimize ("O3")
+int readfromspi(uint16_t headerLength,
+                const uint8_t *headerBuffer,
+                uint32_t readlength,
+                uint8_t *readBuffer)
+{
+
+    apalSPITransmitAndReceive(&MODULE_HAL_SPI_UWB,
+                              headerBuffer,
+                              readBuffer,
+                              headerLength,
+                              readlength);
+
+    return 0;
+} // end readfromspi()
+
+/****************************************************************************//**
+ *
+ * 	alld_dw1000.c					IRQ section
+ *
+ *******************************************************************************/
+
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * Function: decamutexon()
+ *
+ * Description: This function should disable interrupts. This is called at the start of a critical section
+ * It returns the irq state before disable, this value is used to re-enable in decamutexoff call
+ *
+ * Note: The body of this function is platform specific
+ *
+ * input parameters:	
+ *
+ * output parameters
+ *
+ * returns the state of the DW1000 interrupt
+ */
+decaIrqStatus_t decamutexon(void)           
+{
+    decaIrqStatus_t s = port_GetEXT_IRQStatus();
+
+    if(s) {
+        port_DisableEXT_IRQ(); //disable the external interrupt line
+    }
+    return s ;   // return state before disable, value is used to re-enable in decamutexoff call
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * Function: decamutexoff()
+ *
+ * Description: This function should re-enable interrupts, or at least restore their state as returned(&saved) by decamutexon 
+ * This is called at the end of a critical section
+ *
+ * Note: The body of this function is platform specific
+ *
+ * input parameters:	
+ * @param s - the state of the DW1000 interrupt as returned by decamutexon
+ *
+ * output parameters
+ *
+ * returns the state of the DW1000 interrupt
+ */
+void decamutexoff(decaIrqStatus_t s)
+{
+//    (void) s;
+    if(s) { //need to check the port state as we can't use level sensitive interrupt on the STM ARM
+      port_EnableEXT_IRQ();
+    }
+//    return;
+}
+
+
+/*! Wrapper function to be used by decadriver. Declared in deca_device_api.h 
+ *
+ */
+
+void deca_sleep(unsigned int time_ms)
+{
+    aosThdMSleep(time_ms);
+}
+
+void Sleep(unsigned int time_ms)
+{
+    aosThdMSleep(time_ms);
+}
+
+
+void port_set_dw1000_slowrate(){ // replaced with setHighSpeed_SPI(bool speedValue) implemented in module.c
+    return;
+}
+
+void port_set_dw1000_fastrate(){ // replaced with setHighSpeed_SPI(bool speedValue) implemented in module.c
+    return;
+}
+
+void port_wakeup_dw1000_fast(){ // NOT SUPPORTED
+    return;
+}
+
+uint32_t portGetTickCnt(){
+    return chVTGetSystemTimeX();
+}
+
+//inline uint32_t portGetTickCnt(){
+//    return (uint32_t) chVTGetSystemTimeX();
+//}
+
+
+void port_DisableEXT_IRQ(void){   
+   nvicDisableVector(DW1000_EXTI_IRQn);
+
+}
+
+void port_EnableEXT_IRQ(void){    
+    nvicEnableVector(DW1000_EXTI_IRQn, STM32_IRQ_EXTI10_15_PRIORITY);
+}
+
+
+ITStatus port_GetEXT_IRQStatus(void){
+  ITStatus bitstatus = RESET;
+  //  uint32_t enablestatus = 0;
+
+  if(NVIC_GetActive(DW1000_EXTI_IRQn)|| NVIC_GetPendingIRQ(DW1000_EXTI_IRQn)){
+    //  if(NVIC_GetPendingIRQ(EXTI15_10_IRQn)){ //if the interrupt is pending (background )
+    bitstatus = SET; //Interrupt is active or panding
+  }
+  else {
+    bitstatus = RESET; //Currently there is no interrupt IRQ
+  }
+
+  return bitstatus;
+}
+
+
+
+#endif /* defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
diff --git a/source/DW1000/v1/deca_instance_common_v1.c b/source/DW1000/v1/deca_instance_common_v1.c
new file mode 100755
index 0000000..bf6defe
--- /dev/null
+++ b/source/DW1000/v1/deca_instance_common_v1.c
@@ -0,0 +1,1705 @@
+/*! ----------------------------------------------------------------------------
+ *  @file    instance_common.c
+ *  @brief   DecaWave application level common instance functions
+ *
+ * @attention
+ *
+ * Copyright 2015 (c) DecaWave Ltd, Dublin, Ireland.
+ *
+ * All rights reserved.
+ *
+ * @author DecaWave
+ */
+
+#include <alld_DW1000.h>
+
+#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
+
+#include "module.h"
+#include <string.h>
+#include <math.h>
+
+
+extern double dwt_getrangebias(uint8_t chan, float range, uint8_t prf);
+
+extern const uint16_t rfDelays[2];
+extern const uint16_t rfDelaysTREK[2];
+extern const tx_struct txSpectrumConfig[8];
+
+
+
+// -------------------------------------------------------------------------------------------------------------------
+// Deca Calibration Values
+// -------------------------------------------------------------------------------------------------------------------
+
+#define DWT_PRF_64M_RFDLY   (514.462f)
+#define DWT_PRF_16M_RFDLY   (513.9067f)
+
+// -------------------------------------------------------------------------------------------------------------------
+
+//The table below specifies the default TX spectrum configuration parameters... this has been tuned for DW EVK hardware units
+//the table is set for smart power - see below in the instance_config function how this is used when not using smart power
+const tx_struct txSpectrumConfig[8] =
+{
+    //Channel 0 ----- this is just a place holder so the next array element is channel 1
+    {
+            0x0,   //0
+            {
+                    0x0, //0
+                    0x0 //0
+            }
+    },
+    //Channel 1
+    {
+            0xc9,   //PG_DELAY
+            {
+                    0x15355575, //16M prf power
+                    0x07274767 //64M prf power
+            }
+
+    },
+    //Channel 2
+    {
+            0xc2,   //PG_DELAY
+            {
+                    0x15355575, //16M prf power
+                    0x07274767 //64M prf power
+            }
+    },
+    //Channel 3
+    {
+            0xc5,   //PG_DELAY
+            {
+                    0x0f2f4f6f, //16M prf power
+                    0x2b4b6b8b //64M prf power
+            }
+    },
+    //Channel 4
+    {
+            0x95,   //PG_DELAY
+            {
+                    0x1f1f3f5f, //16M prf power
+                    0x3a5a7a9a //64M prf power
+            }
+    },
+    //Channel 5
+    {
+            0xc0,   //PG_DELAY
+            {
+                    0x0E082848, //16M prf power
+                    0x25456585 //64M prf power
+            }
+    },
+    //Channel 6 ----- this is just a place holder so the next array element is channel 7
+    {
+            0x0,   //0
+            {
+                    0x0, //0
+                    0x0 //0
+            }
+    },
+    //Channel 7
+    {
+            0x93,   //PG_DELAY
+            {
+                    0x32527292, //16M prf power
+                    0x5171B1d1 //64M prf power
+            }
+    }
+};
+
+//these are default antenna delays for EVB1000, these can be used if there is no calibration data in the DW1000,
+//or instead of the calibration data
+const uint16_t rfDelays[2] = {
+        (uint16_t) ((DWT_PRF_16M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS),//PRF 16
+        (uint16_t) ((DWT_PRF_64M_RFDLY/ 2.0) * 1e-9 / DWT_TIME_UNITS)
+};
+
+//these are default TREK Tag/Anchor antenna delays
+const uint16_t rfDelaysTREK[2] = {
+        (uint16_t) ((514.83f/ 2.0) * 1e-9 / DWT_TIME_UNITS),//channel 2
+        (uint16_t) ((514.65f/ 2.0) * 1e-9 / DWT_TIME_UNITS) //channel 5
+};
+
+//int instance_starttxtest(int framePeriod)
+//{
+//    //define some test data for the tx buffer
+//    uint8 msg[127] = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the l";
+
+//    //NOTE: SPI frequency must be < 3MHz
+//    port_set_dw1000_slowrate();  //max SPI before PLLs configured is ~4M
+
+//    // the value here 0x1000 gives a period of 32.82 µs
+//    //this is setting 0x1000 as frame period (125MHz clock cycles) (time from Tx en - to next - Tx en)
+//    dwt_configcontinuousframemode(framePeriod);
+
+//    dwt_writetxdata(127, (uint8 *)  msg, 0) ;
+//    dwt_writetxfctrl(127, 0, 0);
+
+//    //to start the first frame - set TXSTRT
+//    dwt_starttx(DWT_START_TX_IMMEDIATE);
+
+//    //measure the power
+//    //Spectrum Analyser set:
+//    //FREQ to be channel default e.g. 3.9936 GHz for channel 2
+//    //SPAN to 1GHz
+//    //SWEEP TIME 1s
+//    //RBW and VBW 1MHz
+//    //measure channel power
+
+//    return DWT_SUCCESS ;
+//}
+
+// -------------------------------------------------------------------------------------------------------------------
+//      Data Definitions
+// -------------------------------------------------------------------------------------------------------------------
+
+instance_data_t instance_data[NUM_INST] ;
+
+static double inst_tdist[MAX_TAG_LIST_SIZE] ;
+static double inst_idist[MAX_ANCHOR_LIST_SIZE] ;
+static double inst_idistraw[MAX_ANCHOR_LIST_SIZE] ;
+
+// TODO: Instance_data declaration in .c. Not on .h (extern only)
+instance_data_t instance_data[NUM_INST] ;
+
+/* TODO: Custom data declarations */
+typedef struct
+{
+    uint32_t      deviceID ;
+    uint8_t       chan;               // added chan here - used in the reading of acc
+    uint16_t      rfrxDly;            // rf delay (delay though the RF blocks before the signal comes out of the antenna i.e. "antenna delay")
+    uint16_t      rftxDly;            // rf delay (delay though the RF blocks before the signal comes out of the antenna i.e. "antenna delay")
+    uint32_t      antennaDly;         // antenna delay read from OTP 64 PRF value is in high 16 bits and 16M PRF in low 16 bits
+    uint32_t      antennaCals[4];     // antenna delays for the TREKs (Anchor high 16-bits, Tag low 16-bits)
+    uint32_t      txPowCfg[12];       // stores the Tx power configuration read from OTP (6 channels consecutively with PRF16 then 64, e.g. Ch 1 PRF16 is index 0 and 64 index 1)
+    uint32_t      states[3] ;         //MP workaround debug states register
+    uint8_t       statescount ;
+    int           prfIndex ;
+    uint32_t      ldoTune ;           //low 32 bits of LDO tune value
+} platform_local_data_t ;
+
+static platform_local_data_t platformLocalData ; // Static local device data
+
+// -------------------------------------------------------------------------------------------------------------------
+// Functions
+// -------------------------------------------------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------------------------------------------------
+// convert microseconds to device time
+uint64_t convertmicrosectodevicetimeu (double microsecu){
+  uint64_t dt;
+  long double dtime;
+
+  dtime = (microsecu / (double) DWT_TIME_UNITS) / 1e6 ;
+
+  dt =  (uint64_t) (dtime) ;
+
+  return dt;
+}
+
+double convertdevicetimetosec(int32_t dt){
+  double f = 0;
+
+  f =  dt * DWT_TIME_UNITS ;  // seconds #define TIME_UNITS          (1.0/499.2e6/128.0) = 15.65e-12
+
+  return f ;
+}
+
+#pragma GCC optimize ("O3")
+int reportTOF(int idx, uint32_t tofx){
+  double distance ;
+  double distance_to_correct;
+  double tof ;
+  int32_t tofi ;
+
+  // check for negative results and accept them making them proper negative integers
+  tofi = (int32_t) tofx ; // make it signed
+  if (tofi > 0x7FFFFFFF){  // close up TOF may be negative
+    tofi -= 0x80000000 ;  //
+  }
+
+  // convert to seconds (as floating point)
+  tof = convertdevicetimetosec(tofi) ;          //this is divided by 4 to get single time of flight
+  inst_idistraw[idx] = distance = tof * SPEED_OF_LIGHT;
+
+#if (CORRECT_RANGE_BIAS == 1)
+  //for the 6.81Mb data rate we assume gating gain of 6dB is used,
+  //thus a different range bias needs to be applied
+  //if(inst->configData.dataRate == DWT_BR_6M8)
+  if(instance_data[0].configData.smartPowerEn){
+    //1.31 for channel 2 and 1.51 for channel 5
+    if(instance_data[0].configData.chan == 5){
+      distance_to_correct = distance/1.51;
+    }
+    else{   //channel 2
+      distance_to_correct = distance/1.31;
+    }
+  }
+  else{
+    distance_to_correct = distance;
+  }
+
+  distance = distance - dwt_getrangebias(instance_data[0].configData.chan, (float) distance_to_correct, instance_data[0].configData.prf);
+#endif
+
+  if ((distance < 0) || (distance > 20000.000))    // discard any results less than <0 cm or >20 km
+    return 0;
+
+  inst_idist[idx] = distance;
+
+  instance_data[0].longTermRangeCount++ ;                          // for computing a long term average
+
+  return 1;
+}// end of reportTOF
+
+void setTagDist(int tidx, int aidx){
+  inst_tdist[tidx] = inst_idist[aidx];
+}
+
+double getTagDist(int idx){
+  return inst_tdist[idx];
+}
+
+void clearDistTable(int idx){
+  inst_idistraw[idx] = 0;
+  inst_idist[idx] = 0;
+}
+
+void instancecleardisttableall(void){
+  int i;
+
+  for(i=0; i<MAX_ANCHOR_LIST_SIZE; i++)  {
+    inst_idistraw[i] = 0xffff;
+    inst_idist[i] = 0xffff;
+  }
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+#if NUM_INST != 1
+#error These functions assume one instance only
+#else
+
+
+// -------------------------------------------------------------------------------------------------------------------
+// Set this instance role as the Tag, Anchor or Listener
+void instancesetrole(int inst_mode){
+  // assume instance 0, for this
+  instance_data[0].mode =  inst_mode;                   // set the role
+}
+
+int instancegetrole(void){
+  return instance_data[0].mode;
+}
+
+int instancenewrange(void){
+  int x = instance_data[0].newRange;
+  instance_data[0].newRange = TOF_REPORT_NUL;
+  return x;
+}
+
+int instancenewrangeancadd(void){
+  return instance_data[0].newRangeAncAddress;
+}
+
+int instancenewrangetagadd(void){
+  return instance_data[0].newRangeTagAddress;
+}
+
+int instancenewrangetim(void){
+  return instance_data[0].newRangeTime;
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+// function to clear counts/averages/range values
+//
+void instanceclearcounts(void){
+  int instance = 0 ;
+  int i= 0 ;
+
+  instance_data[instance].rxTimeouts = 0 ;
+
+  dwt_configeventcounters(1); //enable and clear - NOTE: the counters are not preserved when in DEEP SLEEP
+
+  instance_data[instance].frameSN = 0;
+
+  instance_data[instance].longTermRangeCount  = 0;
+
+
+  for(i=0; i<MAX_ANCHOR_LIST_SIZE; i++){
+    instance_data[instance].tofArray[i] = INVALID_TOF;
+  }
+
+  for(i=0; i<MAX_TAG_LIST_SIZE; i++){
+    instance_data[instance].tof[i] = INVALID_TOF;
+  }
+
+} // end instanceclearcounts()
+
+
+// -------------------------------------------------------------------------------------------------------------------
+// function to initialise instance structures
+//
+// Returns 0 on success and -1 on error
+int instance_init(void){
+  int instance = 0 ;
+  int i;
+  int result;
+
+  instance_data[instance].mode =  ANCHOR;                                // assume listener,
+  instance_data[instance].testAppState = TA_INIT ;
+  instance_data[instance].instToSleep = FALSE;
+
+
+  // Reset the IC (might be needed if not getting here from POWER ON)
+  // ARM code: Remove soft reset here as using hard reset in the inittestapplication() in the main.c file
+  //dwt_softreset();
+
+  //this initialises DW1000 and uses specified configurations from OTP/ROM
+  result = dwt_initialise(DWT_LOADUCODE) ;
+
+  //this is platform dependent - only program if DW EVK/EVB
+  dwt_setleds(3) ; //configure the GPIOs which control the leds on EVBs
+
+  if (DWT_SUCCESS != result){
+    return (-1) ;   // device initialise has failed
+  }
+
+
+  instanceclearcounts() ;
+
+  instance_data[instance].panID = 0xdeca ;
+
+  instance_data[instance].wait4ack = 0;
+  instance_data[instance].stopTimer = 0;
+  instance_data[instance].instanceTimerEn = 0;
+
+  instance_clearevents();
+
+  //dwt_geteui(instance_data[instance].eui64);
+  memset(instance_data[instance].eui64, 0, ADDR_BYTE_SIZE_L);
+
+  instance_data[instance].tagSleepCorrection = 0;
+
+//  dwt_setautorxreenable(0); //disable auto RX re-enable
+  dwt_setdblrxbuffmode(0); //disable double RX buffer
+
+  // if using auto CRC check (DWT_INT_RFCG and DWT_INT_RFCE) are used instead of DWT_INT_RDFR flag
+  // other errors which need to be checked (as they disable receiver) are
+  //dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_SFDT | DWT_INT_RFTO /*| DWT_INT_RXPTO*/), 1);
+  dwt_setinterrupt(DWT_INT_TFRS | DWT_INT_RFCG | (DWT_INT_ARFE | DWT_INT_RFSL | DWT_INT_SFDT | DWT_INT_RPHE | DWT_INT_RFCE | DWT_INT_RFTO | DWT_INT_RXPTO), 1);
+
+  dwt_setcallbacks(instance_txcallback, instance_rxcallback, instance_rxtimeoutcallback,instance_rxerrorcallback );
+
+  instance_data[instance].monitor = 0;
+
+  instance_data[instance].lateTX = 0;
+  instance_data[instance].lateRX = 0;
+
+  instance_data[instance].responseTO = -1; //initialise
+  for(i=0; i<256; i++)  {
+    instance_data[instance].rxResps[i] = -10;
+  }
+
+  instance_data[instance].delayedReplyTime = 0;
+
+  return 0 ;
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// Return the Device ID register value, enables higher level validation of physical device presence
+//
+
+uint32_t instancereaddeviceid(void){
+  return dwt_readdevid() ;
+}
+
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// function to allow application configuration be passed into instance and affect underlying device operation
+//
+void instance_config(instanceConfig_t *config, sfConfig_t *sfConfig){
+  int instance = 0 ;
+  uint32_t power = 0;
+  uint8_t otprev ;
+
+  instance_data[instance].configData.chan = config->channelNumber ;
+  instance_data[instance].configData.rxCode =  config->preambleCode ;
+  instance_data[instance].configData.txCode = config->preambleCode ;
+  instance_data[instance].configData.prf = config->pulseRepFreq ;
+  instance_data[instance].configData.dataRate = config->dataRate ;
+  instance_data[instance].configData.txPreambLength = config->preambleLen ;
+  instance_data[instance].configData.rxPAC = config->pacSize ;
+  instance_data[instance].configData.nsSFD = config->nsSFD ;
+  instance_data[instance].configData.phrMode = DWT_PHRMODE_STD ;
+  instance_data[instance].configData.sfdTO = config->sfdTO;
+
+  //the DW1000 will automatically use gating gain for frames < 1ms duration (i.e. 6.81Mbps data rate)
+  //smartPowerEn should be set based on the frame length, but we can also use dtaa rate.
+  if(instance_data[instance].configData.dataRate == DWT_BR_6M8)  {
+    instance_data[instance].configData.smartPowerEn = 1;
+  }
+  else{
+    instance_data[instance].configData.smartPowerEn = 0;
+  }
+
+  //configure the channel parameters
+  dwt_configure(&instance_data[instance].configData) ;
+
+  instance_data[instance].configTX.PGdly = txSpectrumConfig[config->channelNumber].PGdelay ;    //Default
+
+  //firstly check if there are calibrated TX power value in the DW1000 OTP
+  power = dwt_getotptxpower(config->pulseRepFreq, instance_data[instance].configData.chan);
+
+  if((power == 0x0) || (power == 0xFFFFFFFF)) {    //if there are no calibrated values... need to use defaults
+    power = txSpectrumConfig[config->channelNumber].txPwr[config->pulseRepFreq- DWT_PRF_16M];
+  }
+
+  //Configure TX power
+  instance_data[instance].configTX.power = power;
+
+  //configure the tx spectrum parameters (power and PG delay)
+  dwt_configuretxrf(&instance_data[instance].configTX);
+
+  otprev = dwt_otprevision() ;  // this revision tells us how OTP is programmed.
+
+  if ((2 == otprev) || (3 == otprev))  {  // board is calibrated with TREK1000 with antenna delays set for each use case)
+    uint8_t mode = (instance_data[instance].mode == ANCHOR ? 1 : 0);
+    uint8_t chanindex = 0;
+
+    instance_data[instance].txAntennaDelay
+    = dwt_getTREKOTPantennadelay(mode,
+                                 instance_data[instance].configData.chan,
+                                 instance_data[instance].configData.dataRate) ;
+
+    // if nothing was actually programmed then set a reasonable value anyway
+    if ((instance_data[instance].txAntennaDelay == 0)
+        || (instance_data[instance].txAntennaDelay == 0xffff)){
+      if(instance_data[instance].configData.chan == 5){
+        chanindex = 1;
+      }
+
+      instance_data[instance].txAntennaDelay = rfDelaysTREK[chanindex];
+    }
+
+  }
+  else {  // assume it is older EVK1000 programming.
+    //get the antenna delay that was read from the OTP calibration area
+    instance_data[instance].txAntennaDelay = dwt_readantennadelay(config->pulseRepFreq) >> 1;
+
+    // if nothing was actually programmed then set a reasonable value anyway
+    if ((instance_data[instance].txAntennaDelay == 0)
+        || (instance_data[instance].txAntennaDelay == 0xffff)){
+      instance_data[instance].txAntennaDelay = rfDelays[config->pulseRepFreq - DWT_PRF_16M];
+    }
+  }
+
+  // -------------------------------------------------------------------------------------------------------------------
+  // set the antenna delay, we assume that the RX is the same as TX.
+  dwt_setrxantennadelay(instance_data[instance].txAntennaDelay);
+  dwt_settxantennadelay(instance_data[instance].txAntennaDelay);
+
+  instance_data[instance].rxAntennaDelay = instance_data[instance].txAntennaDelay;
+
+  if(config->preambleLen == DWT_PLEN_64)  {  //if preamble length is 64
+    //reduce SPI to < 3MHz
+    setHighSpeed_SPI(FALSE);  //TODO: workaround using flag to change speed
+    dwt_loadopsettabfromotp(0);
+    //increase SPI to max
+    setHighSpeed_SPI(TRUE);  //TODO: workaround using flag to change speed
+  }
+
+  instancesettagsleepdelay(sfConfig->pollSleepDly); //set the Tag sleep time
+  instance_data[instance].sframePeriod = sfConfig->sfPeriod;
+  instance_data[instance].slotPeriod = sfConfig->slotPeriod;
+  instance_data[instance].tagSleepRnd = sfConfig->slotPeriod;
+  instance_data[instance].numSlots = sfConfig->numSlots;
+
+  //last two slots are used for anchor to anchor ranging
+  instance_data[instance].a0SlotTime = (instance_data[instance].numSlots-2) * instance_data[instance].slotPeriod;
+
+  //set the default response delays
+  instancesetreplydelay(sfConfig->replyDly);
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+// function to set the tag sleep time (in ms)
+//
+void instancesettagsleepdelay(int sleepdelay) {  //sleep in ms
+  int instance = 0 ;
+  instance_data[instance].tagSleepTime_ms = sleepdelay; //subtract the micro system delays (time it takes to switch states etc.)
+}
+
+
+int instancegetrnum(void) {  //get ranging number
+  return instance_data[0].rangeNum;
+}
+
+int instancegetrnuma(int idx){  //get ranging number
+  return instance_data[0].rangeNumA[idx];
+}
+
+int instancegetrnumanc(int idx){  //get ranging number
+  return instance_data[0].rangeNumAAnc[idx];
+}
+
+int instancegetlcount(void) {  //get count of ranges used for calculation of lt avg
+  int x = instance_data[0].longTermRangeCount;
+
+  return (x);
+}
+
+double instancegetidist(int idx) {  //get instantaneous range
+  double x ;
+
+  idx &= (MAX_ANCHOR_LIST_SIZE - 1);
+
+  x = inst_idist[idx];
+
+  return (x);
+}
+
+double instancegetidistraw(int idx) { //get instantaneous range (uncorrected)
+  double x ;
+
+  idx &= (MAX_ANCHOR_LIST_SIZE - 1);
+
+  x = inst_idistraw[idx];
+
+  return (x);
+}
+
+int instancegetidist_mm(int idx) {  //get instantaneous range
+  int x ;
+
+  idx &= (MAX_ANCHOR_LIST_SIZE - 1);
+
+  x = (int)(inst_idist[idx]*1000);
+
+  return (x);
+}
+
+int instancegetidistraw_mm(int idx) {  //get instantaneous range (uncorrected)
+  int x ;
+
+  idx &= (MAX_ANCHOR_LIST_SIZE - 1);
+
+  x = (int)(inst_idistraw[idx]*1000);
+
+  return (x);
+}
+
+void instance_backtoanchor(instance_data_t *inst){
+  //stay in RX and behave as anchor
+  inst->testAppState = TA_RXE_WAIT ;
+  inst->mode = ANCHOR ;
+  dwt_setrxtimeout(0);
+  dwt_setpreambledetecttimeout(0);
+  dwt_setrxaftertxdelay(0);
+}
+
+
+#pragma GCC optimize ("O3")
+void inst_processrxtimeout(instance_data_t *inst){
+
+  //inst->responseTimeouts ++ ;
+  inst->rxTimeouts ++ ;
+  inst->done = INST_NOT_DONE_YET;
+
+  if(inst->mode == ANCHOR) { //we did not receive the final - wait for next poll
+    //only enable receiver when not using double buffering
+    inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+    dwt_setrxtimeout(0);
+  }
+
+  else if(inst->mode == TAG) {
+    //if tag times out - no response (check if we are to send a final)
+    //send the final only if it has received response from anchor 0
+    if((inst->previousState == TA_TXPOLL_WAIT_SEND) && ((inst->rxResponseMask & 0x1) == 0)) {
+      inst->instToSleep = TRUE ; //set sleep to TRUE so that tag will go to DEEP SLEEP before next ranging attempt
+      inst->testAppState = TA_TXE_WAIT ;
+      inst->nextState = TA_TXPOLL_WAIT_SEND ;
+    }
+    else if (inst->previousState == TA_TXFINAL_WAIT_SEND) {  //got here from main (error sending final - handle as timeout)
+      dwt_forcetrxoff();	//this will clear all events
+      inst->instToSleep = TRUE ;
+      // initiate the re-transmission of the poll that was not responded to
+      inst->testAppState = TA_TXE_WAIT ;
+      inst->nextState = TA_TXPOLL_WAIT_SEND ;
+    }
+    else {  //send the final
+      // initiate the re-transmission of the poll that was not responded to
+      inst->testAppState = TA_TXE_WAIT ;
+      inst->nextState = TA_TXFINAL_WAIT_SEND ;
+    }
+
+  }
+  else {  //ANCHOR_RNG
+    //no Response form the other anchor
+    if(
+        ((inst->previousState == TA_TXPOLL_WAIT_SEND)
+            && ((A1_ANCHOR_ADDR == inst->instanceAddress16) && ((inst->rxResponseMaskAnc & 0x4) == 0)))
+            ||
+            ((inst->previousState == TA_TXPOLL_WAIT_SEND)
+                && ((GATEWAY_ANCHOR_ADDR == inst->instanceAddress16) && ((inst->rxResponseMaskAnc & 0x2) == 0)))
+    )  {
+      instance_backtoanchor(inst);
+    }
+    else if (inst->previousState == TA_TXFINAL_WAIT_SEND) {  //got here from main (error ending final - handle as timeout)
+      instance_backtoanchor(inst);
+    }
+    else {  //send the final
+      // initiate the re-transmission of the poll that was not responded to
+      inst->testAppState = TA_TXE_WAIT ;
+      inst->nextState = TA_TXFINAL_WAIT_SEND ;
+    }
+  }
+
+  //timeout - disable the radio (if using SW timeout the rx will not be off)
+  //dwt_forcetrxoff() ;
+}
+
+//
+// NB: This function is called from the (TX) interrupt handler
+//
+#pragma GCC optimize ("O3")
+void instance_txcallback(const dwt_cb_data_t *txd){
+
+  (void) txd;
+  int instance = 0;
+  uint8_t txTimeStamp[5] = {0, 0, 0, 0, 0};
+//  uint8 txevent = txd->event;
+  event_data_t dw_event;
+
+  dw_event.uTimeStamp = portGetTickCnt();
+
+//  chprintf((BaseSequentialStream *)&SD2, " TX callback! \r\n");
+
+//  if(txevent == DWT_SIG_TX_DONE) {
+    //uint32_t txtimestamp = 0;
+
+    //NOTE - we can only get TX good (done) while here
+    //dwt_readtxtimestamp((uint8*) &instance_data[instance].txu.txTimeStamp);
+
+    dwt_readtxtimestamp(txTimeStamp) ;
+    dw_event.timeStamp32l = (uint32_t)txTimeStamp[0] + ((uint32_t)txTimeStamp[1] << 8) + ((uint32_t)txTimeStamp[2] << 16) + ((uint32_t)txTimeStamp[3] << 24);
+    dw_event.timeStamp = txTimeStamp[4];
+    dw_event.timeStamp <<= 32;
+    dw_event.timeStamp += dw_event.timeStamp32l;
+    dw_event.timeStamp32h = ((uint32_t)txTimeStamp[4] << 24) + (dw_event.timeStamp32l >> 8);
+
+    instance_data[instance].stopTimer = 0;
+
+    dw_event.rxLength = instance_data[instance].psduLength;
+    dw_event.type =  0;
+    dw_event.type_pend =  0;
+    dw_event.type_save = DWT_SIG_TX_DONE;
+
+    memcpy((uint8_t *)&dw_event.msgu.frame[0], (uint8_t *)&instance_data[instance].msg_f, instance_data[instance].psduLength);
+
+    instance_putevent(dw_event, DWT_SIG_TX_DONE);
+
+    instance_data[instance].txMsgCount++;
+//  }
+//  else if(txevent == DWT_SIG_TX_AA_DONE)  {
+//    //auto ACK confirmation
+//    dw_event.rxLength = 0;
+//    dw_event.type =  0;
+//    dw_event.type_save = DWT_SIG_TX_AA_DONE;
+//
+//    instance_putevent(dw_event, DWT_SIG_TX_AA_DONE);
+//
+//    //printf("TX AA time %f ecount %d\n",convertdevicetimetosecu(instance_data[instance].txu.txTimeStamp), instance_data[instance].dweventCnt);
+//  }
+
+  instance_data[instance].monitor = 0;
+}
+
+/**
+ * @brief function to re-enable the receiver and also adjust the timeout before sending the final message
+ * if it is time so send the final message, the callback will notify the application, else the receiver is
+ * automatically re-enabled
+ *
+ * this function is only used for tag when ranging to other anchors
+ */
+uint8_t tagrxreenable(uint16_t sourceAddress){
+  uint8_t type_pend = DWT_SIG_DW_IDLE;
+  uint8_t anc = sourceAddress & 0x3;
+  int instance = 0;
+
+  switch(anc){
+  //if we got Response from anchor 3 - this is the last expected response - send the final
+  case 3:
+    type_pend = DWT_SIG_DW_IDLE;
+    break;
+
+    //if we got Response from anchor 0, 1, or 2 - go back to wait for next anchor's response
+  case 0:
+  case 1:
+  case 2:
+  default:
+    if(instance_data[instance].responseTO > 0) {  //can get here as result of error frame so need to check
+      dwt_setrxtimeout((uint16_t)instance_data[instance].fwtoTime_sy * instance_data[instance].responseTO); //reconfigure the timeout
+      dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
+      type_pend = DWT_SIG_RX_PENDING ;
+    }
+    else //last response was not received (got error/frame was corrupt)
+    {
+      type_pend = DWT_SIG_DW_IDLE; //report timeout - send the final
+    }
+    break;
+  }
+
+  return type_pend;
+}
+
+/**
+ * @brief function to re-enable the receiver and also adjust the timeout before sending the final message
+ * if it is time so send the final message, the callback will notify the application, else the receiver is
+ * automatically re-enabled
+ *
+ * this function is only used for anchors (having a role of ANCHOR_RNG) when ranging to other anchors
+ */
+uint8_t ancsendfinalorrxreenable(uint16_t sourceAddress){
+  uint8_t type_pend = DWT_SIG_DW_IDLE;
+  uint8_t anc = sourceAddress & 0x3;
+  int instance = 0;
+
+  if(instance_data[instance].instanceAddress16 == GATEWAY_ANCHOR_ADDR) {
+    switch(anc) {
+    //if we got Response from anchor 1 - go back to wait for next anchor's response
+    case 1:
+      dwt_setrxtimeout((uint16_t)instance_data[instance].fwtoTime_sy); //reconfigure the timeout
+      dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
+      type_pend = DWT_SIG_RX_PENDING ;
+      break;
+
+      //if we got Response from anchor 2 - this is the last expected response - send the final
+    case 2:
+    default:
+      type_pend = DWT_SIG_DW_IDLE;
+      break;
+    }
+  }
+
+  if(instance_data[instance].instanceAddress16 == A1_ANCHOR_ADDR){
+    switch(anc)
+    {
+    //if we got Response from anchor 2 - this is the last expected response - send the final
+    case 2:
+    default:
+      type_pend = DWT_SIG_DW_IDLE;
+      break;
+    }
+  }
+  return type_pend;
+}
+
+/**
+ * @brief this function either enables the receiver (delayed)
+ *
+ **/
+void ancenablerx(void){
+  int instance = 0;
+  //subtract preamble length
+  dwt_setdelayedtrxtime(instance_data[instance].delayedReplyTime - instance_data[instance].fixedReplyDelayAncP) ;
+  if(dwt_rxenable(DWT_START_RX_DELAYED)) {  //delayed rx
+    //if the delayed RX failed - time has passed - do immediate enable
+    //led_on(LED_PC9);
+    dwt_setrxtimeout((uint16_t)instance_data[instance].fwtoTimeAnc_sy*2); //reconfigure the timeout before enable
+    //longer timeout as we cannot do delayed receive... so receiver needs to stay on for longer
+    dwt_rxenable(DWT_START_RX_IMMEDIATE);
+    dwt_setrxtimeout((uint16_t)instance_data[instance].fwtoTimeAnc_sy); //restore the timeout for next RX enable
+    instance_data[instance].lateRX++;
+    //led_off(LED_PC9);
+  }
+
+}
+
+/**
+ * @brief this function either re-enables the receiver (delayed or immediate) or transmits the response frame
+ *
+ * @param the sourceAddress is the address of the sender of the current received frame
+ * @param ancToAncTWR == 1 means that the anchor is ranging to another anchor, if == 0 then ranging to a tag
+ *
+ */
+#pragma GCC optimize ("O0")
+uint8_t anctxorrxreenable(uint16_t sourceAddress, int ancToAncTWR){
+  uint8_t type_pend = DWT_SIG_DW_IDLE;
+  int sendResp = 0;
+  int instance = 0;
+
+  if(instance_data[instance].responseTO == 0) {  //go back to RX without TO - ranging has finished. (wait for Final but no TO)
+    dwt_setrxtimeout(0); //reconfigure the timeout
+    dwt_setpreambledetecttimeout(0);
+  }
+
+  if((ancToAncTWR & 1) == 1)  {
+    if(instance_data[instance].responseTO == 1) {  //if one response left to receive (send a response now)
+      sendResp = 1;
+    }
+    //if A0 or A3 go back to RX as they do not send any responses when Anchor to Anchor ranging
+    if((instance_data[instance].gatewayAnchor)
+        || (instance_data[instance].shortAdd_idx == 3)) { //if this is anchor ID 3 do not reply to anchor poll
+      dwt_setrxtimeout(0);
+      dwt_rxenable(DWT_START_RX_IMMEDIATE);
+      return DWT_SIG_RX_PENDING ;
+    }
+  }
+
+  //configure delayed reply time (this is incremented for each received frame) it is timed from Poll rx time
+  instance_data[instance].delayedReplyTime += (instance_data[instance].fixedReplyDelayAnc >> 8);
+
+  //this checks if to send a frame
+  if((((ancToAncTWR & 1) == 0) && ((instance_data[instance].responseTO + instance_data[instance].shortAdd_idx) == NUM_EXPECTED_RESPONSES)) //it's our turn to tx
+      || (sendResp == 1)) {
+    //led_on(LED_PC9);
+    //response is expected
+    instance_data[instance].wait4ack = DWT_RESPONSE_EXPECTED; //re has/will be re-enabled
+
+    dwt_setdelayedtrxtime(instance_data[instance].delayedReplyTime) ;
+    if(dwt_starttx(DWT_START_TX_DELAYED | DWT_RESPONSE_EXPECTED)) {
+      //if TX has failed - we need to re-enable RX for the next response or final reception...
+      dwt_setrxaftertxdelay(0);
+      instance_data[instance].wait4ack = 0; //clear the flag as the TX has failed the TRX is off
+      instance_data[instance].lateTX++;
+      instance_data[instance].delayedReplyTime += 2*(instance_data[instance].fixedReplyDelayAnc >> 8); //to take into account W4R
+      ancenablerx();
+      type_pend = DWT_SIG_RX_PENDING ;
+    }
+    else {
+      instance_data[instance].delayedReplyTime += (instance_data[instance].fixedReplyDelayAnc >> 8); //to take into account W4R
+      type_pend = DWT_SIG_TX_PENDING ; // exit this interrupt and notify the application/instance that TX is in progress.
+      instance_data[instance].timeofTx = portGetTickCnt();
+      instance_data[instance].monitor = 1;
+    }
+    //led_off(LED_PC9);
+  }
+  else {  //stay in receive
+    if(sourceAddress == 0) { //we got here after RX error, as we don't need to TX, we just enable RX
+      dwt_setrxtimeout(0);
+      dwt_rxenable(DWT_START_RX_IMMEDIATE);
+    }
+    else{
+      //led_on(LED_PC9);
+      ancenablerx();
+      //led_off(LED_PC9);
+    }
+
+    type_pend = DWT_SIG_RX_PENDING ;
+  }
+  //if time to send a response
+
+  return type_pend;
+}
+
+/**
+ * @brief this function handles frame error event, it will either signal TO or re-enable the receiver
+ */
+void handle_error_unknownframe(event_data_t dw_event){
+  int instance = 0;
+  //re-enable the receiver (after error frames as we are not using auto re-enable
+  //for ranging application rx error frame is same as TO - as we are not going to get the expected frame
+  if(instance_data[instance].mode == ANCHOR){
+    //if we are participating in the ranging (i.e. Poll was received)
+    //and we get an rx error (in one of the responses)
+    //need to consider this as a timeout as we could be sending our response next and
+    //the applications needs to know to change the state
+    //
+    if(instance_data[instance].responseTO > 0){
+      instance_data[instance].responseTO--;
+
+      //send a response or re-enable rx
+      dw_event.type_pend = anctxorrxreenable(0, 0);
+      dw_event.type = 0;
+      dw_event.type_save = 0x40 | DWT_SIG_RX_TIMEOUT;
+      dw_event.rxLength = 0;
+
+      instance_putevent(dw_event, DWT_SIG_RX_TIMEOUT);
+    }
+    else{
+      dwt_setrxtimeout(0); //reconfigure the timeout
+      dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
+    }
+  }
+  else if(instance_data[instance].mode == LISTENER){
+    dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
+  }
+  else{
+    instance_data[instance].responseTO--; //got something (need to reduce timeout (for remaining responses))
+
+    dw_event.type_pend = tagrxreenable(0); //check if receiver will be re-enabled or it's time to send the final
+    dw_event.type = 0;
+    dw_event.type_save = 0x40 | DWT_SIG_RX_TIMEOUT;
+    dw_event.rxLength = 0;
+
+    instance_putevent(dw_event, DWT_SIG_RX_TIMEOUT);
+  }
+}
+
+
+/**
+ * @brief this function prepares and writes the anchor to anchor response frame into the TX buffer
+ * it is called after anchor receives a Poll from an anchor
+ */
+void ancprepareresponse2(uint16_t sourceAddress, uint8_t srcAddr_index, uint8_t fcode_index, uint8_t *frame){
+  uint16_t frameLength = 0;
+  uint8_t tof_idx = (sourceAddress) & 0x3 ;
+  int instance = 0;
+
+  instance_data[instance].psduLength = frameLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+  //set the destination address (copy source as this is a reply)
+  memcpy(&instance_data[instance].msg_f.destAddr[0], &frame[srcAddr_index], ADDR_BYTE_SIZE_S); //remember who to send the reply to (set destination address)
+  instance_data[instance].msg_f.sourceAddr[0] = instance_data[instance].eui64[0];
+  instance_data[instance].msg_f.sourceAddr[1] = instance_data[instance].eui64[1];
+  // Write calculated TOF into response message (get the previous ToF+range number from that anchor)
+  memcpy(&(instance_data[instance].msg_f.messageData[TOFR]), &instance_data[instance].tofAnc[tof_idx], 4);
+  instance_data[instance].msg_f.messageData[TOFRN] = instance_data[instance].rangeNumAAnc[tof_idx]; //get the previous range number
+
+  instance_data[instance].rangeNumAAnc[tof_idx] = 0; //clear the entry
+  instance_data[instance].rangeNumAnc = frame[POLL_RNUM + fcode_index] ;
+  instance_data[instance].msg_f.seqNum = instance_data[instance].frameSN++;
+
+  //set the delayed rx on time (the final message will be sent after this delay)
+  dwt_setrxaftertxdelay(instance_data[instance].ancRespRxDelay);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
+
+  instance_data[instance].tagSleepCorrection = 0;
+  instance_data[instance].msg_f.messageData[RES_TAG_SLP0] = 0 ;
+  instance_data[instance].msg_f.messageData[RES_TAG_SLP1] = 0 ;
+
+  instance_data[instance].msg_f.messageData[FCODE] = RTLS_DEMO_MSG_ANCH_RESP2; //message function code (specifies if message is a poll, response or other...)
+
+  //write the TX data
+  dwt_writetxfctrl(frameLength, 0, 1);
+  dwt_writetxdata(frameLength, (uint8_t *)  &instance_data[instance].msg_f, 0) ;	// write the frame data
+
+}
+
+/**
+ * @brief this function prepares and writes the anchor to tag response frame into the TX buffer
+ * it is called after anchor receives a Poll from a tag
+ */
+void ancprepareresponse(uint16_t sourceAddress, uint8_t srcAddr_index, uint8_t fcode_index, uint8_t *frame, uint32_t uTimeStamp){
+  uint16_t frameLength = 0;
+  uint8_t tof_idx = (sourceAddress) & 0x7 ;
+  int instance = 0;
+
+  instance_data[instance].psduLength = frameLength = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+  memcpy(&instance_data[instance].msg_f.destAddr[0], &frame[srcAddr_index], ADDR_BYTE_SIZE_S); //remember who to send the reply to (set destination address)
+  instance_data[instance].msg_f.sourceAddr[0] = instance_data[instance].eui64[0];
+  instance_data[instance].msg_f.sourceAddr[1] = instance_data[instance].eui64[1];
+  // Write calculated TOF into response message (get the previous ToF+range number from that tag)
+  memcpy(&(instance_data[instance].msg_f.messageData[TOFR]), &instance_data[instance].tof[tof_idx], 4);
+  instance_data[instance].msg_f.messageData[TOFRN] = instance_data[instance].rangeNumA[tof_idx]; //get the previous range number
+
+  instance_data[instance].rangeNumA[tof_idx] = 0; //clear after copy above...
+  instance_data[instance].rangeNum = frame[POLL_RNUM+fcode_index] ;
+  instance_data[instance].msg_f.seqNum = instance_data[instance].frameSN++;
+
+  //we have our range - update the own mask entry...
+  if(instance_data[instance].tof[tof_idx] != INVALID_TOF) { //check the last ToF entry is valid and copy into the current array
+    instance_data[instance].rxResponseMask = (0x1 << instance_data[instance].shortAdd_idx);
+    instance_data[instance].tofArray[instance_data[instance].shortAdd_idx] = instance_data[instance].tof[tof_idx];
+  }
+  else	{  //reset response mask
+    instance_data[instance].tofArray[instance_data[instance].shortAdd_idx] = INVALID_TOF ;
+    instance_data[instance].rxResponseMask = 0;	//reset the mask of received responses when rx poll
+  }
+  //set the delayed rx on time (the final message will be sent after this delay)
+  dwt_setrxaftertxdelay(instance_data[instance].ancRespRxDelay);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
+
+  //if this is gateway anchor - calculate the slot period correction
+  if(instance_data[instance].gatewayAnchor)  {
+    int error = 0;
+    int currentSlotTime = 0;
+    int expectedSlotTime = 0;
+    //find the time in the current superframe
+    currentSlotTime = uTimeStamp % instance_data[instance].sframePeriod;
+
+    //this is the slot time the poll should be received in (Mask 0x07 for the 8 MAX tags we support in TREK)
+    expectedSlotTime = (sourceAddress&0xFF) * instance_data[instance].slotPeriod; //
+
+    //error = expectedSlotTime - currentSlotTime
+    error = expectedSlotTime - currentSlotTime;
+
+    if(error < (-(instance_data[instance].sframePeriod>>1))) { //if error is more negative than 0.5 period, add whole period to give up to 1.5 period sleep
+      instance_data[instance].tagSleepCorrection = (instance_data[instance].sframePeriod + error);
+    }
+    else { //the minimum Sleep time will be 0.5 period
+      instance_data[instance].tagSleepCorrection = error;
+    }
+    instance_data[instance].msg_f.messageData[RES_TAG_SLP0] = instance_data[instance].tagSleepCorrection & 0xFF ;
+    instance_data[instance].msg_f.messageData[RES_TAG_SLP1] = (instance_data[instance].tagSleepCorrection >> 8) & 0xFF;
+  }
+  else {
+    instance_data[instance].tagSleepCorrection = 0;
+    instance_data[instance].msg_f.messageData[RES_TAG_SLP0] = 0 ;
+    instance_data[instance].msg_f.messageData[RES_TAG_SLP1] = 0 ;
+  }
+  instance_data[instance].msg_f.messageData[FCODE] = RTLS_DEMO_MSG_ANCH_RESP; //message function code (specifies if message is a poll, response or other...)
+
+  //write the TX data
+  dwt_writetxfctrl(frameLength, 0, 1);
+  dwt_writetxdata(frameLength, (uint8_t *)  &instance_data[instance].msg_f, 0) ;	// write the frame data
+}
+
+/**
+ * @brief this is the receive event callback handler, the received event is processed and the instance either
+ * responds by sending a response frame or re-enables the receiver to await the next frame
+ * once the immediate action is taken care of the event is queued up for application to process
+ */
+#pragma GCC optimize ("O3")
+void instance_rxcallback(const dwt_cb_data_t *rxd){
+  int instance = 0;
+  uint8_t rxTimeStamp[5]  = {0, 0, 0, 0, 0};
+
+  uint8_t rxd_event = 0;
+  uint8_t fcode_index  = 0;
+  uint8_t srcAddr_index = 0;
+  event_data_t dw_event;
+
+  //microcontroller time at which we received the frame
+  dw_event.uTimeStamp = portGetTickCnt();
+
+  //if we got a frame with a good CRC - RX OK
+  //  if(rxd->event == DWT_SIG_RX_OKAY) { // Timeout and error are handle separately in the driver itself
+  dw_event.rxLength = rxd->datalength;
+
+  //need to process the frame control bytes to figure out what type of frame we have received
+  if(((rxd->fctrl[0] == 0x41) || (rxd->fctrl[0] == 0x61))
+      &&
+      ((rxd->fctrl[1] & 0xCC) == 0x88)) {  //short address
+    fcode_index = FRAME_CRTL_AND_ADDRESS_S; //function code is in first byte after source address
+    srcAddr_index = FRAME_CTRLP + ADDR_BYTE_SIZE_S;
+    rxd_event = DWT_SIG_RX_OKAY;
+  }
+  else {
+    rxd_event = SIG_RX_UNKNOWN; //not supported - all TREK1000 frames are short addressed
+  }
+
+  //read RX timestamp
+  dwt_readrxtimestamp(rxTimeStamp) ;
+  dwt_readrxdata((uint8_t *)&dw_event.msgu.frame[0], rxd->datalength, 0);  // Read Data Frame
+  dw_event.timeStamp32l =  (uint32_t)rxTimeStamp[0] + ((uint32_t)rxTimeStamp[1] << 8) + ((uint32_t)rxTimeStamp[2] << 16) + ((uint32_t)rxTimeStamp[3] << 24);
+  dw_event.timeStamp = rxTimeStamp[4];
+  dw_event.timeStamp <<= 32;
+  dw_event.timeStamp += dw_event.timeStamp32l;
+  dw_event.timeStamp32h = ((uint32_t)rxTimeStamp[4] << 24) + (dw_event.timeStamp32l >> 8);
+
+  dw_event.type = 0; //type will be added as part of adding to event queue
+  dw_event.type_save = rxd_event;
+  dw_event.type_pend = DWT_SIG_DW_IDLE;
+
+  //if Listener then just report the received frame to the instance (application)
+  if(rxd_event == DWT_SIG_RX_OKAY) { //Process good/known frame types
+    uint16_t sourceAddress = (((uint16_t)dw_event.msgu.frame[srcAddr_index+1]) << 8) + dw_event.msgu.frame[srcAddr_index];
+
+    if(instance_data[instance].mode != LISTENER)      {
+      if(instance_data[instance].mode == TAG) //if tag got a good frame - this is probably a response, but could also be some other non-ranging frame
+        //(although due to frame filtering this is limited as non-addressed frames are filtered out)
+      {
+        instance_data[instance].responseTO--; //got 1 more response or other RX frame - need to reduce timeout (for next response)
+      }
+
+      //check if this is a TWR message (and also which one)
+      switch(dw_event.msgu.frame[fcode_index]){
+      //poll message from an anchor
+      case RTLS_DEMO_MSG_ANCH_POLL:{
+        //the anchor to anchor ranging poll frames are ignored by A0 and A3
+        if(instance_data[instance].gatewayAnchor || (instance_data[instance].instanceAddress16 > A2_ANCHOR_ADDR)){
+          //ignore poll from anchor 1 if gateway or anchor 3
+          //anchors 2 and 3 will never send polls
+          dw_event.type_pend = DWT_SIG_DW_IDLE ;
+          break;
+        }
+
+        if(instance_data[instance].mode == TAG)  {  //tag should ignore any other Polls from anchors
+          instance_data[instance].responseTO++; //as will be decremented in the function and was also decremented above
+          handle_error_unknownframe(dw_event);
+          instance_data[instance].stopTimer = 1;
+          instance_data[instance].rxMsgCount++;
+          return;
+        }
+
+        //update the response index and number of responses received tables
+        instance_data[instance].rxRespsIdx = (uint8_t) ((dw_event.msgu.frame[POLL_RNUM+fcode_index] & 0xf)
+            + (((sourceAddress&0x3) + 8) << 4));
+        instance_data[instance].rxResps[instance_data[instance].rxRespsIdx] = 0;
+        //debug LED on
+        //						led_on(LED_PC9);
+
+        //prepare the response and write it to the tx buffer
+        ancprepareresponse2(sourceAddress, srcAddr_index, fcode_index, &dw_event.msgu.frame[0]);
+
+        //A2 does not need timeout if ranging to A1
+        if(sourceAddress != A1_ANCHOR_ADDR){
+          dwt_setrxtimeout((uint16_t)instance_data[instance].fwtoTimeAnc_sy); //reconfigure the timeout for response
+        }
+
+        //set the bast reply time (the actual will be Poll rx time + instance_data[0].fixedReplyDelayAnc)
+        instance_data[instance].delayedReplyTime = dw_event.timeStamp32h ;
+        instance_data[instance].responseTO = (instance_data[instance].instanceAddress16 - sourceAddress) & 0x3; //set number of expected responses
+
+        dw_event.type_pend = anctxorrxreenable(instance_data[instance].instanceAddress16, 2+1);
+
+        instance_data[instance].tofAnc[sourceAddress & 0x3] = INVALID_TOF; //clear ToF ..
+        //debug LED off
+        //						led_off(LED_PC9);
+        break;
+      }
+
+      case RTLS_DEMO_MSG_TAG_POLL:{
+        if(instance_data[instance].mode == TAG) {  //tag should ignore any other Polls from tags
+          instance_data[instance].responseTO++; //as will be decremented in the function and was also decremented above
+          handle_error_unknownframe(dw_event);
+          instance_data[instance].stopTimer = 1;
+          instance_data[instance].rxMsgCount++;
+          return;
+        }
+        instance_data[instance].rxRespsIdx = (int8_t) ((dw_event.msgu.frame[POLL_RNUM+fcode_index] & 0xf)
+            + ((sourceAddress&0x7) << 4));
+        instance_data[instance].rxResps[instance_data[instance].rxRespsIdx] = 0;
+
+        //prepare the response and write it to the tx buffer
+        ancprepareresponse(sourceAddress, srcAddr_index, fcode_index, &dw_event.msgu.frame[0], dw_event.uTimeStamp);
+
+        dwt_setrxtimeout((uint16_t)instance_data[instance].fwtoTimeAnc_sy); //reconfigure the timeout for response
+
+        instance_data[0].delayedReplyTime = dw_event.timeStamp32h /*+ (instance_data[0].fixedReplyDelayAnc >> 8)*/ ;
+        instance_data[instance].responseTO = NUM_EXPECTED_RESPONSES; //set number of expected responses to 3 (from other anchors)
+
+        dw_event.type_pend = anctxorrxreenable(instance_data[instance].instanceAddress16, 2+0);
+
+        instance_data[instance].tof[sourceAddress & 0x7] = INVALID_TOF; //clear ToF ..
+      }
+      break;
+
+      //we got a response from a "responder" (anchor)
+      case RTLS_DEMO_MSG_ANCH_RESP:
+      case RTLS_DEMO_MSG_ANCH_RESP2:{
+
+        //we are a tag
+        if(instance_data[instance].mode == TAG){
+          uint8_t index ;
+          instance_data[instance].rxResps[instance_data[instance].rangeNum]++;
+          dw_event.type_pend = tagrxreenable(sourceAddress); //responseTO decremented above...
+          index = RRXT0 + 5*(sourceAddress & 0x3);
+
+          instance_data[instance].rxResponseMask |= (0x1 << (sourceAddress & 0x3)); //add anchor ID to the mask
+          // Write Response RX time field of Final message
+          memcpy(&(instance_data[instance].msg_f.messageData[index]), rxTimeStamp, 5);
+
+        }
+        else if (instance_data[instance].mode == ANCHOR_RNG) {  //A0 and A1 only when ranging to other anchors
+          uint8_t index ;
+          instance_data[instance].rxResps[instance_data[instance].rangeNumAnc]++;
+          dw_event.type_pend = ancsendfinalorrxreenable(sourceAddress);
+          index = RRXT0 + 5*(sourceAddress & 0x3);
+
+          instance_data[instance].rxResponseMaskAnc |= (0x1 << (sourceAddress & 0x3)); //add anchor ID to the mask
+          // Write Response RX time field of Final message
+          memcpy(&(instance_data[instance].msg_f.messageData[index]), rxTimeStamp, 5);
+        }
+        else { //normal anchor mode
+          //got a response... (check if we got a Poll with the same range number as in this response)
+          if(RTLS_DEMO_MSG_ANCH_RESP == dw_event.msgu.frame[fcode_index]){
+            if((instance_data[instance].rxResps[instance_data[instance].rxRespsIdx] >= 0) //we got the poll else ignore this response
+                && (instance_data[instance].responseTO > 0)	) {  //if responseTO == 0 we have already received all of the responses - meaning should not be here => error
+              instance_data[instance].rxResps[instance_data[instance].rxRespsIdx]++; //increment the number of responses received
+              instance_data[instance].responseTO--;
+
+              //send a response or re-enable rx
+              dw_event.type_pend = anctxorrxreenable(sourceAddress, 4+0);
+            }
+            else {  //like a timeout (error) ...
+
+              //send a response or re-enable rx
+              dwt_setrxtimeout(0); //reconfigure the timeout
+              dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
+              dw_event.type_pend = DWT_SIG_RX_PENDING ;
+            }
+          }
+          else {  //in anchor mode and got RTLS_DEMO_MSG_ANCH_RESP2
+            if((instance_data[instance].gatewayAnchor) &&
+                (instance_data[instance].rxResps[instance_data[instance].rangeNumAnc]) == 2){ //got two responses A1 and A2 this is third (A2's to A1)
+              instance_data[instance].rxResps[instance_data[instance].rangeNumAnc]++;
+              instance_data[instance].rxResponseMaskAnc |= 0x8 ;
+
+              dw_event.type_pend = anctxorrxreenable(sourceAddress, 4+1); //re-enable the RX
+            }
+            //A2 got A1's response to A0 - send A2 response (but only if we got the Poll from A0)
+            else if((instance_data[instance].instanceAddress16 == A2_ANCHOR_ADDR) &&
+                (instance_data[instance].rxResps[instance_data[instance].rxRespsIdx] >= 0) ){
+              instance_data[instance].rxResps[instance_data[instance].rxRespsIdx]++;
+              instance_data[instance].responseTO--;
+
+              dwt_setrxtimeout(0);
+              dwt_setrxaftertxdelay(0); //clear rx on delay as Final will come sooner than if we were waiting for next Response
+              dw_event.type_pend = anctxorrxreenable(sourceAddress, 1);
+            }
+            else {  // if other anchor A1, A2, A3 .. ignore these responses when in ANCHOR mode
+              dwt_setrxtimeout(0); //reconfigure the timeout
+              dwt_rxenable(DWT_START_RX_IMMEDIATE) ;
+              dw_event.type_pend = DWT_SIG_RX_PENDING ;
+            }
+          }
+        }
+
+      }
+      break;
+
+      case RTLS_DEMO_MSG_TAG_FINAL:
+      case RTLS_DEMO_MSG_ANCH_FINAL:
+        if(instance_data[instance].mode == TAG) {  //tag should ignore any other Final from anchors
+          instance_data[instance].responseTO++; //as will be decremented in the function and was also decremented above
+          handle_error_unknownframe(dw_event);
+          instance_data[instance].stopTimer = 1;
+          instance_data[instance].rxMsgCount++;
+          return;
+        }
+      break;  // TODO: fallthourgh for anchor
+//        __attribute__ ((fallthrough));
+
+        //if anchor fall into case below and process the frame
+      default: {  //process rx frame
+        dw_event.type_pend = DWT_SIG_DW_IDLE;
+      }
+      break;
+
+      }
+    }//end of if not Listener mode
+    instance_data[instance].stopTimer = 1;
+
+    instance_putevent(dw_event, rxd_event);
+
+    instance_data[instance].rxMsgCount++;
+  }
+  else { //if (rxd_event == SIG_RX_UNKNOWN) //need to re-enable the rx (got unknown frame type)
+    handle_error_unknownframe(dw_event);
+  }
+  //  }
+}
+
+
+/*TODO: Callback funtion for RX timeout (available from newer driver version) */
+#pragma GCC optimize ("O3")
+void instance_rxtimeoutcallback(const dwt_cb_data_t *rxd){
+
+    (void) rxd;
+    event_data_t dw_event;
+
+    int instance = 0;
+
+    dw_event.type_pend = DWT_SIG_DW_IDLE;
+
+    if(instance_data[instance].mode == ANCHOR) {
+        //check if anchor has received all of the responses from other anchors (it could have received only 1 or 2)
+        //it's timed out (re-enable rx or tx response)
+        if(instance_data[instance].responseTO > 0) {
+            instance_data[instance].responseTO--;
+            //send a response or re-enable rx
+            dw_event.type_pend = anctxorrxreenable(instance_data[instance].instanceAddress16, 6+0);
+//          Print_On_Uart("Re-enable RX in rxtimeout callback\r\n");
+        }
+    }
+    dw_event.type = 0;
+    dw_event.type_save = DWT_SIG_RX_TIMEOUT;
+    dw_event.rxLength = 0;
+    dw_event.timeStamp = 0;
+    dw_event.timeStamp32l = 0;
+    dw_event.timeStamp32h = 0;
+
+    instance_putevent(dw_event, DWT_SIG_RX_TIMEOUT);
+//  printf("RX timeout while in %d\n", instance_data[instance].testAppState);
+
+}
+
+
+/*TODO: Callback funtion for RX error (available from newer driver version) */
+#pragma GCC optimize ("O3")
+void instance_rxerrorcallback(const dwt_cb_data_t *rxd) {
+
+    (void) rxd;
+    event_data_t dw_event;
+
+    dw_event.uTimeStamp = portGetTickCnt();
+
+    handle_error_unknownframe(dw_event);
+}
+
+
+
+#pragma GCC optimize ("O3")
+int instance_peekevent(void){
+  int instance = 0;
+  return instance_data[instance].dwevent[instance_data[instance].dweventPeek].type; //return the type of event that is in front of the queue
+}
+
+#pragma GCC optimize ("O3")
+void instance_saveevent(event_data_t newevent, uint8_t etype){
+  int instance = 0;
+
+  instance_data[instance].saved_dwevent = newevent;
+  instance_data[instance].saved_dwevent.type = etype;
+}
+
+#pragma GCC optimize ("O3")
+event_data_t instance_getsavedevent(void){
+  int instance = 0;
+
+  return instance_data[instance].saved_dwevent;
+}
+
+#pragma GCC optimize ("O3")
+void instance_putevent(event_data_t newevent, uint8_t etype){
+  int instance = 0;
+  //newevent.eventtime = portGetTickCnt();
+  newevent.gotit = 0 ; //newevent.eventtimeclr = 0;
+
+  //copy event
+  instance_data[instance].dwevent[instance_data[instance].dweventIdxIn] = newevent;
+
+  //set type - this makes it a new event (making sure the event data is copied before event is set as new)
+  //to make sure that the get event function does not get an incomplete event
+  instance_data[instance].dwevent[instance_data[instance].dweventIdxIn].type = etype;
+
+  instance_data[instance].dweventIdxIn++;
+
+  if(MAX_EVENT_NUMBER == instance_data[instance].dweventIdxIn)
+  {
+    instance_data[instance].dweventIdxIn = 0;
+  }
+  //eventIncount++;
+
+  //printf("put %d - in %d out %d @ %d\n", newevent.type, instance_data[instance].dweventCntIn, instance_data[instance].dweventCntOut, ptime);
+}
+
+event_data_t dw_event_g;
+
+#pragma GCC optimize ("O3")
+event_data_t* instance_getevent(int x){
+  int instance = 0;
+  int indexOut = instance_data[instance].dweventIdxOut;
+
+  //dw_event_g = instance_data[instance].dwevent[instance_data[instance].dweventCntOut]; //this holds any TX/RX events
+
+  //memcpy(&dw_event_g, &instance_data[instance].dwevent[instance_data[instance].dweventCntOut], sizeof(event_data_t));
+
+  if(instance_data[instance].dwevent[indexOut].type == 0) {  //exit with "no event"
+    dw_event_g.type = 0;
+    dw_event_g.type_save = 0;
+    return &dw_event_g;
+  }
+
+  //copy the event
+  dw_event_g.type_save = instance_data[instance].dwevent[indexOut].type_save ;
+  dw_event_g.type_pend = instance_data[instance].dwevent[indexOut].type_pend ;
+  dw_event_g.rxLength = instance_data[instance].dwevent[indexOut].rxLength ;
+  dw_event_g.timeStamp = instance_data[instance].dwevent[indexOut].timeStamp ;
+  dw_event_g.timeStamp32l = instance_data[instance].dwevent[indexOut].timeStamp32l ;
+  dw_event_g.timeStamp32h = instance_data[instance].dwevent[indexOut].timeStamp32h ;
+  dw_event_g.uTimeStamp = instance_data[instance].dwevent[indexOut].uTimeStamp ;
+  //dw_event_g.eventtime = instance_data[instance].dwevent[indexOut].eventtime ;
+  //dw_event_g.eventtimeclr = instance_data[instance].dwevent[indexOut].eventtimeclr ;
+  //dw_event_g.gotit = instance_data[instance].dwevent[indexOut].gotit ;
+
+  memcpy(&dw_event_g.msgu, &instance_data[instance].dwevent[indexOut].msgu, sizeof(instance_data[instance].dwevent[indexOut].msgu));
+
+  dw_event_g.type = instance_data[instance].dwevent[indexOut].type ;
+
+
+  instance_data[instance].dwevent[indexOut].gotit = x;
+
+  //instance_data[instance].dwevent[indexOut].eventtimeclr = portGetTickCnt();
+
+  instance_data[instance].dwevent[indexOut].type = 0; //clear the event
+
+  instance_data[instance].dweventIdxOut++;
+  if(MAX_EVENT_NUMBER == instance_data[instance].dweventIdxOut){   //wrap the counter
+    instance_data[instance].dweventIdxOut = 0;
+  }
+  instance_data[instance].dweventPeek = instance_data[instance].dweventIdxOut; //set the new peek value
+
+  //if(dw_event.type) printf("get %d - in %d out %d @ %d\n", dw_event.type, instance_data[instance].dweventCntIn, instance_data[instance].dweventCntOut, ptime);
+
+  //eventOutcount++;
+
+
+  return &dw_event_g;
+}
+
+void instance_clearevents(void){
+  int i = 0;
+  int instance = 0;
+
+  for(i=0; i<MAX_EVENT_NUMBER; i++) {
+    memset(&instance_data[instance].dwevent[i], 0, sizeof(event_data_t));
+  }
+
+  instance_data[instance].dweventIdxIn = 0;
+  instance_data[instance].dweventIdxOut = 0;
+  instance_data[instance].dweventPeek = 0;
+
+  //eventOutcount = 0;
+  //eventIncount = 0;
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+#pragma GCC optimize ("O3")
+int instance_run(void){
+  int instance = 0 ;
+  int done = INST_NOT_DONE_YET;
+  int message = instance_peekevent(); //get any of the received events from ISR
+
+
+  while(done == INST_NOT_DONE_YET){
+    //int state = instance_data[instance].testAppState;
+    done = testapprun(&instance_data[instance], message) ;                                               // run the communications application
+
+    //we've processed message
+    message = 0;
+  }
+
+
+
+  if(done == INST_DONE_WAIT_FOR_NEXT_EVENT_TO) { //we are in RX and need to timeout (Tag needs to send another poll if no Rx frame)
+    if(instance_data[instance].mode == TAG) { //Tag (is either in RX or sleeping)
+      int32_t nextPeriod ;
+
+      // next period will be a positive number because correction is -0.5 to +1.5 periods, (and tagSleepTime_ms is the period)
+      nextPeriod = instance_data[instance].tagSleepRnd + instance_data[instance].tagSleepTime_ms + instance_data[instance].tagSleepCorrection;
+
+      instance_data[instance].nextSleepPeriod = (uint32_t) nextPeriod ; //set timeout time, CAST the positive period to UINT for correct wrapping.
+      instance_data[instance].tagSleepCorrection2 = instance_data[instance].tagSleepCorrection;
+      instance_data[instance].tagSleepCorrection = 0; //clear the correction
+      instance_data[instance].instanceTimerEn = 1; //start timer
+    }
+    instance_data[instance].stopTimer = 0 ; //clear the flag - timer can run if instancetimer_en set (set above)
+    instance_data[instance].done = INST_NOT_DONE_YET;
+  }
+
+  //check if timer has expired
+  if((instance_data[instance].instanceTimerEn == 1) && (instance_data[instance].stopTimer == 0))  {
+    if(instance_data[instance].mode == TAG)    {
+      if((portGetTickCnt() - instance_data[instance].instanceWakeTime) > instance_data[instance].nextSleepPeriod)      {
+        event_data_t dw_event;
+        instance_data[instance].instanceTimerEn = 0;
+        dw_event.rxLength = 0;
+        dw_event.type = 0;
+        dw_event.type_save = 0x80 | DWT_SIG_RX_TIMEOUT;
+        //printf("PC timeout DWT_SIG_RX_TIMEOUT\n");
+        instance_putevent(dw_event, DWT_SIG_RX_TIMEOUT);
+      }
+    }
+#if (ANCTOANCTWR == 1) //allow anchor to anchor ranging
+    else if(instance_data[instance].mode == ANCHOR)    {
+      uint32_t slotTime = portGetTickCnt() % instance_data[instance].sframePeriod;
+
+      if(instance_data[instance].gatewayAnchor) {
+        //if we are in the last slot - then A0 ranges to A1 and A2
+        if( slotTime >= instance_data[instance].a0SlotTime)        {
+          port_DisableEXT_IRQ(); //enable ScenSor IRQ before starting
+          //anchor0 sends poll to anchor1
+          instance_data[instance].mode = ANCHOR_RNG; //change to ranging initiator
+          dwt_forcetrxoff(); //disable DW1000
+          instance_clearevents(); //clear any events
+          //change state to send a Poll
+          instance_data[instance].testAppState = TA_TXPOLL_WAIT_SEND ;
+          instance_data[instance].msg_f.destAddr[0] = 0x1 ;
+          instance_data[instance].msg_f.destAddr[1] = (GATEWAY_ANCHOR_ADDR >> 8);
+          instance_data[instance].instanceTimerEn = 0;
+          instance_data[instance].rangeNumAnc++;
+          port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
+        }
+      }
+      else if (instance_data[instance].instanceAddress16 == A1_ANCHOR_ADDR) { //A1 ranges to A2 in the 2nd half of last slot
+        if(portGetTickCnt() >= instance_data[instance].a1SlotTime) {
+          port_DisableEXT_IRQ(); //enable ScenSor IRQ before starting
+          //anchor1 sends poll to anchor2
+          instance_data[instance].mode = ANCHOR_RNG; //change to ranging initiator
+          dwt_forcetrxoff(); //disable DW1000
+          instance_clearevents(); //clear any events
+          //change state to send a Poll
+          instance_data[instance].testAppState = TA_TXPOLL_WAIT_SEND ;
+          instance_data[instance].msg_f.destAddr[0] = 0x2 ;
+          instance_data[instance].msg_f.destAddr[1] = (GATEWAY_ANCHOR_ADDR >> 8);
+
+          instance_data[instance].instanceTimerEn = 0;
+          //instance_data[instance].a1SlotTime = 0;
+          port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
+        }
+      }
+    }
+#endif
+  }
+
+#if (ANCTOANCTWR == 1) //allow anchor to anchor ranging
+  else if (instance_data[instance].instanceTimerEn == 0){
+    if((instance_data[instance].mode == ANCHOR) && (instance_data[instance].gatewayAnchor)){
+      uint32_t slotTime = portGetTickCnt() % instance_data[instance].sframePeriod;
+      //enable the timer in 1st slot
+      if(slotTime < instance_data[instance].slotPeriod){
+        instance_data[instance].instanceTimerEn = 1;
+      }
+    }
+  }
+#endif
+  return 0 ;
+}
+
+
+void instance_close(void){
+  //wake up device from low power mode
+  //NOTE - in the ARM  code just drop chip select for 200us
+  port_SPIx_clear_chip_select();  //CS low
+  Sleep(1);   //200 us to wake up then waits 5ms for DW1000 XTAL to stabilise
+  port_SPIx_set_chip_select();  //CS high
+  Sleep(5);
+  dwt_entersleepaftertx(0); // clear the "enter deep sleep after tx" bit
+  dwt_setinterrupt(0xFFFFFFFF, 0); //don't allow any interrupts
+
+}
+
+
+void instance_notify_DW1000_inIDLE(int idle){
+  instance_data[0].dwIDLE = idle;
+}
+
+void instanceconfigtxpower(uint32_t txpower){
+  instance_data[0].txPower = txpower ;
+
+  instance_data[0].txPowerChanged = 1;
+
+}
+
+void instancesettxpower(void){
+  if(instance_data[0].txPowerChanged == 1){
+    //Configure TX power
+    dwt_write32bitreg(0x1E, instance_data[0].txPower);
+
+    instance_data[0].txPowerChanged = 0;
+  }
+}
+
+void instanceconfigantennadelays(uint16_t tx, uint16_t rx){
+  instance_data[0].txAntennaDelay = tx ;
+  instance_data[0].rxAntennaDelay = rx ;
+
+  instance_data[0].antennaDelayChanged = 1;
+}
+
+void instancesetantennadelays(void){
+  if(instance_data[0].antennaDelayChanged == 1){
+    dwt_setrxantennadelay(instance_data[0].rxAntennaDelay);
+    dwt_settxantennadelay(instance_data[0].txAntennaDelay);
+
+    instance_data[0].antennaDelayChanged = 0;
+  }
+}
+
+
+uint16_t instancetxantdly(void){
+  return instance_data[0].txAntennaDelay;
+}
+
+uint16_t instancerxantdly(void){
+  return instance_data[0].rxAntennaDelay;
+}
+
+uint8_t instancevalidranges(void){
+  uint8_t x = instance_data[0].rxResponseMaskReport;
+  instance_data[0].rxResponseMaskReport = 0; //reset mask as we have printed out the ToFs
+  return x;
+}
+#endif
+
+
+/*! TODO: the following Functions are added for user application (previously on the API )*/
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getotptxpower()
+ *
+ * @brief This API function returns the tx power value read from OTP memory as part of initialisation
+ *
+ * input parameters
+ * @param prf   -   this is the PRF e.g. DWT_PRF_16M or DWT_PRF_64M
+ * @param chan  -   this is the channel e.g. 1 to 7
+ *
+ * output parameters
+ *
+ * returns tx power value for a given PRF and channel
+ */
+uint32_t dwt_getotptxpower(uint8_t prf, uint8_t chan){
+    return platformLocalData.txPowCfg[(prf - DWT_PRF_16M) + (chan_idx[chan] * 2)];
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_getTREKOTPantennadelay()
+ *
+ * @brief This API function returns the antenna delay read from the OTP memory as part of device initialisation
+ * Note: the antenna delay will only be read if dwt_initialise is called with DWT_LOADANTDLY bit set in the config parameter
+ * The values of antenna delay are only valid for TREK use case modes.
+ *
+ * input parameters:
+ * @param anchor   - this is the mode (Tag or Anchor) if Tag set to 0, if Anchor set to 1
+ * @param chan   - this is the channel (1, 2, 3, 4, 5, 7)
+ * @param datarate   - this is the datarate DWT_BR_6M8, DWT_BR_110K or DWT_BR_850K
+ *
+ */
+uint16_t dwt_getTREKOTPantennadelay(uint8_t anchor, uint8_t chan, uint8_t datarate){
+    uint32_t dly = 0;
+
+    // 32-bit antenna delay value previously read from OTP, high 16 bits is value for Anchor mode, low 16-bits for Tag mode
+    switch(chan){
+        case 2:
+            if(datarate == DWT_BR_6M8)
+                dly = platformLocalData.antennaCals[0];
+            else if(datarate == DWT_BR_110K)
+                dly = platformLocalData.antennaCals[1];
+            break;
+        case 5:
+            if(datarate == DWT_BR_6M8)
+                dly = platformLocalData.antennaCals[2];
+            else if(datarate == DWT_BR_110K)
+                dly = platformLocalData.antennaCals[3];
+            break;
+        default:
+            dly = 0;
+            break;
+    }
+
+    return (dly >> (16*(anchor & 0x1))) & 0xFFFF;
+}
+
+/*! ------------------------------------------------------------------------------------------------------------------
+ * @fn dwt_readantennadelay()
+ *
+ * @brief This API function returns the antenna delay read from the OTP memory as part of device initialisation
+ * Note: the antenna delay will only be read if dwt_initialise is called with DWT_LOADANTDLY bit set in the config parameter
+ *
+ * input parameters:
+ * @param prf   -   this is the PRF e.g. DWT_PRF_16M or DWT_PRF_64M
+ *
+ */
+uint16_t dwt_readantennadelay(uint8_t prf){
+    // 32-bit antenna delay value previously read from OTP, high 16 bits is value for 64 MHz PRF, low 16-bits for 16 MHz PRF
+    return (platformLocalData.antennaDly >> (16*(prf-DWT_PRF_16M))) & 0xFFFF;
+}
+
+
+/* ==========================================================
+
+Notes:
+
+Previously code handled multiple instances in a single console application
+
+Now have changed it to do a single instance only. With minimal code changes...(i.e. kept [instance] index but it is always 0.
+
+Windows application should call instance_init() once and then in the "main loop" call instance_run().
+
+*/
+
+#endif /* defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
diff --git a/source/DW1000/v1/deca_instance_tag_anchor_v1.c b/source/DW1000/v1/deca_instance_tag_anchor_v1.c
new file mode 100755
index 0000000..a1ce3be
--- /dev/null
+++ b/source/DW1000/v1/deca_instance_tag_anchor_v1.c
@@ -0,0 +1,1017 @@
+/*! ----------------------------------------------------------------------------
+ *  @file    instance_tag.c
+ *  @brief   Decawave tag application state machine for TREK demo
+ *
+ * @attention
+ *
+ * Copyright 2016 (c) Decawave Ltd, Dublin, Ireland.
+ *
+ * All rights reserved.
+ *
+ * @author Decawave
+ */
+
+#include <alld_DW1000.h>
+
+#if (defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1)) || defined(__DOXYGEN__)
+
+#include <string.h>
+#include<math.h>
+#include "module.h"
+
+// -------------------------------------------------------------------------------------------------------------------
+//      Data Definitions
+// -------------------------------------------------------------------------------------------------------------------
+
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// NOTE: the maximum RX timeout is ~ 65ms
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+// -------------------------------------------------------------------------------------------------------------------
+// Functions
+// -------------------------------------------------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// function to construct the message/frame header bytes
+//
+// -------------------------------------------------------------------------------------------------------------------
+//
+void instanceconfigframeheader16(instance_data_t *inst){
+  //set frame type (0-2), SEC (3), Pending (4), ACK (5), PanIDcomp(6)
+  inst->msg_f.frameCtrl[0] = 0x1 /*frame type 0x1 == data*/ | 0x40 /*PID comp*/;
+
+  //source/dest addressing modes and frame version
+  inst->msg_f.frameCtrl[1] = 0x8 /*dest extended address (16bits)*/ | 0x80 /*src extended address (16bits)*/;
+
+  inst->msg_f.panID[0] = (inst->panID) & 0xff;
+  inst->msg_f.panID[1] = inst->panID >> 8;
+
+  inst->msg_f.seqNum = 0;
+}
+
+int instancesenddlypacket(instance_data_t *inst, int delayedTx){
+  int result = 0;
+
+  dwt_writetxfctrl(inst->psduLength, 0, 1);
+  if(delayedTx == DWT_START_TX_DELAYED){
+    dwt_setdelayedtrxtime(inst->delayedReplyTime) ; //should be high 32-bits of delayed TX TS
+  }
+
+  //begin delayed TX of frame
+  if (dwt_starttx(delayedTx | inst->wait4ack)){ // delayed start was too late
+    result = 1; //late/error
+    inst->lateTX++;
+  }
+  else {
+    inst->timeofTx = portGetTickCnt();
+    inst->monitor = 1;
+  }
+  return result;                                              // state changes
+}
+
+
+int instance_calcranges(uint32_t *array, uint16_t size, int reportRange, uint8_t* mask){
+  int i;
+  int newRange = TOF_REPORT_NUL;
+  int distance = 0;
+
+  for(i=0; i<size; i++)  {
+    uint32_t tofx = array[i];
+    if(tofx != INVALID_TOF) { //if ToF == 0 - then no new range to report
+      distance = reportTOF(i, tofx);
+    }
+
+    if(distance == 1){
+      newRange = reportRange;
+    }
+    else {
+      //clear mask
+      *mask &= ~(0x1 << i) ;
+      clearDistTable(i);
+    }
+    array[i] = INVALID_TOF;
+
+    distance = 0;
+  }
+
+  return newRange;
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// the main instance state machine (all the instance modes Tag, Anchor or Listener use the same statemachine....)
+//
+// -------------------------------------------------------------------------------------------------------------------
+//
+int testapprun(instance_data_t *inst, int message){
+
+  switch (inst->testAppState){
+  case TA_INIT :
+    // printf("TA_INIT") ;
+    switch (inst->mode) {
+    case TAG: {
+      uint16_t sleep_mode = 0;
+
+      dwt_enableframefilter(DWT_FF_DATA_EN | DWT_FF_ACK_EN); //allow data, ack frames;
+      dwt_setpanid(inst->panID);
+
+      memcpy(inst->eui64, &inst->instanceAddress16, ADDR_BYTE_SIZE_S);
+      dwt_seteui(inst->eui64);
+
+      //set source address
+      inst->newRangeTagAddress = inst->instanceAddress16 ;
+      dwt_setaddress16(inst->instanceAddress16);
+
+      //Start off by Sleeping 1st -> set instToSleep to TRUE
+      inst->nextState = TA_TXPOLL_WAIT_SEND;
+      inst->testAppState = TA_TXE_WAIT;
+      inst->instToSleep = TRUE ;
+
+      inst->rangeNum = 0;
+      inst->tagSleepCorrection = 0;
+
+      sleep_mode = (DWT_LOADUCODE|DWT_PRESRV_SLEEP|DWT_CONFIG|DWT_TANDV);
+
+      /* TODO: No need anymore since the driver handle itself */
+//      if((dwt_getldotune() != 0)) //if we need to use LDO tune value from OTP kick it after sleep
+//        sleep_mode |= DWT_LOADOPSET;
+
+      if(inst->configData.txPreambLength == DWT_PLEN_64)  //if using 64 length preamble then use the corresponding OPSet
+        sleep_mode |= DWT_LOADOPSET;
+
+#if (DEEP_SLEEP == 1)
+      dwt_configuresleep(sleep_mode, DWT_WAKE_WK|DWT_WAKE_CS|DWT_SLP_EN); //configure the on wake parameters (upload the IC config settings)
+#endif
+      instanceconfigframeheader16(inst);
+      inst->instanceWakeTime = portGetTickCnt();
+    }
+    break;
+    case ANCHOR: {
+      memcpy(inst->eui64, &inst->instanceAddress16, ADDR_BYTE_SIZE_S);
+      dwt_seteui(inst->eui64);
+
+      dwt_setpanid(inst->panID);
+
+      //set source address
+      inst->shortAdd_idx = (inst->instanceAddress16 & 0x3) ;
+      dwt_setaddress16(inst->instanceAddress16);
+
+      //if address = 0x8000
+      if(inst->instanceAddress16 == GATEWAY_ANCHOR_ADDR){
+        inst->gatewayAnchor = TRUE;
+      }
+
+      dwt_enableframefilter(DWT_FF_NOTYPE_EN); //allow data, ack frames;
+
+      // First time anchor listens we don't do a delayed RX
+      dwt_setrxaftertxdelay(0);
+      //change to next state - wait to receive a message
+      inst->testAppState = TA_RXE_WAIT ;
+
+      dwt_setrxtimeout(0);
+      dwt_setpreambledetecttimeout(0);
+      instanceconfigframeheader16(inst);
+
+    }
+    break;
+    case LISTENER:{
+      dwt_enableframefilter(DWT_FF_NOTYPE_EN); //disable frame filtering
+      dwt_setrxaftertxdelay(0); //no delay of turning on of RX
+      dwt_setrxtimeout(0);
+      dwt_setpreambledetecttimeout(0);
+      //change to next state - wait to receive a message
+      inst->testAppState = TA_RXE_WAIT ;
+    }
+    break ; // end case TA_INIT
+    default:
+      break;
+    }
+    break; // end case TA_INIT
+
+    case TA_SLEEP_DONE : {
+      event_data_t* dw_event = instance_getevent(10); //clear the event from the queue
+      // waiting for timout from application to wakup IC
+      if (dw_event->type != DWT_SIG_RX_TIMEOUT){
+        // if no pause and no wake-up timeout continu waiting for the sleep to be done.
+        inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //wait here for sleep timeout
+        break;
+      }
+
+      inst->done = INST_NOT_DONE_YET;
+      inst->instToSleep = FALSE ;
+      inst->testAppState = inst->nextState;
+      inst->nextState = 0; //clear
+      inst->instanceWakeTime = portGetTickCnt(); // Record the time count when we wake-up
+#if (DEEP_SLEEP == 1)
+      {
+        uint32 x = 0;
+
+        //wake up device from low power mode
+        //NOTE - in the ARM  code just drop chip select for 200us
+        led_on(LED_PC9);
+        port_SPIx_clear_chip_select();  //CS low
+        instance_data[0].dwIDLE = 0; //reset DW1000 IDLE flag
+
+        setup_DW1000RSTnIRQ(1); //enable RSTn IRQ
+
+        Sleep(2);   //200 us to wake up - need 2 as Sleep(1) is ~ 175 us
+//        chThdSleepMilliseconds(2);
+        //then wait 5ms for DW1000 XTAL to stabilise - instead of wait we wait for RSTn to go high
+        //Sleep(5);
+
+        //need to poll to check when the DW1000 is in IDLE, the CPLL interrupt is not reliable
+        //when RSTn goes high the DW1000 is in INIT, it will enter IDLE after PLL lock (in 5 us)
+        while(instance_data[0].dwIDLE == 0) // this variable will be sent in the IRQ (process_dwRSTn_irq)
+        {
+          //wait for DW1000 to go to IDLE state RSTn pin to go high
+          x++;
+        }
+        setup_DW1000RSTnIRQ(0); //disable RSTn IRQ
+        port_SPIx_set_chip_select();  //CS high
+
+        //!!! NOTE it takes ~35us for the DW1000 to download AON and lock the PLL and be in IDLE state
+        //do some dummy reads of the dev ID register to make sure DW1000 is in IDLE before setting LEDs
+        x = dwt_readdevid(); //dummy read... need to wait for 5 us to exit INIT state (5 SPI bytes @ ~18 MHz)
+        x = dwt_readdevid(); //dummy read... need to wait for 5 us to exit INIT state (5 SPI bytes @ ~18 MHz)
+        x = dwt_readdevid(); //dummy read... need to wait for 5 us to exit INIT state (5 SPI bytes @ ~18 MHz)
+        x = dwt_readdevid(); //dummy read... need to wait for 5 us to exit INIT state (5 SPI bytes @ ~18 MHz)
+
+        x = dwt_readdevid(); //dummy read... need to wait for 5 us to exit INIT state (5 SPI bytes @ ~18 MHz)
+        /*if(x != DWT_DEVICE_ID)
+                {
+                    x = dwt_readdevid(); //dummy read... need to wait for 5 us to exit INIT state (5 SPI bytes @ ~18 MHz)
+                }*/
+        led_off(LED_PC9);
+        //this is platform dependent - only program if DW EVK/EVB
+        dwt_setleds(1);
+
+        //MP bug - TX antenna delay needs reprogramming as it is not preserved (only RX)
+        dwt_settxantennadelay(inst->txAntennaDelay) ;
+
+        //set EUI as it will not be preserved unless the EUI is programmed and loaded from NVM
+        dwt_seteui(inst->eui64);
+      }
+#else
+      Sleep(3); //to approximate match the time spent in the #if above  //TODO: 3ms default
+#endif
+
+      instancesetantennadelays(); //this will update the antenna delay if it has changed
+      instancesettxpower(); //configure TX power if it has changed
+
+    }
+    break;
+
+    case TA_TXE_WAIT : //either go to sleep or proceed to TX a message
+      // printf("TA_TXE_WAIT") ;
+      //if we are scheduled to go to sleep before next transmission then sleep first.
+      if((inst->nextState == TA_TXPOLL_WAIT_SEND)
+          && (inst->instToSleep)  //go to sleep before sending the next poll/ starting new ranging exchange
+      ){
+        inst->rangeNum++; //increment the range number before going to sleep
+        //the app should put chip into low power state and wake up after tagSleepTime_ms time...
+        //the app could go to *_IDLE state and wait for uP to wake it up...
+        inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT_TO; //don't sleep here but kick off the Sleep timer countdown
+        inst->testAppState = TA_SLEEP_DONE; {
+#if (DEEP_SLEEP == 1)
+          //put device into low power mode
+          dwt_entersleep(); //go to sleep
+#endif
+          //DW1000 gone to sleep - report the received range
+          inst->newRange = instance_calcranges(&inst->tofArray[0], MAX_ANCHOR_LIST_SIZE, TOF_REPORT_T2A, &inst->rxResponseMask);
+          inst->rxResponseMaskReport = inst->rxResponseMask;
+          inst->rxResponseMask = 0;
+          inst->newRangeTime = portGetTickCnt() ;
+        }
+      }
+      else {  //proceed to configuration and transmission of a frame
+        inst->testAppState = inst->nextState;
+        inst->nextState = 0; //clear
+      }
+      break ; // end case TA_TXE_WAIT
+
+    case TA_TXPOLL_WAIT_SEND : {
+
+      inst->msg_f.messageData[POLL_RNUM] = (inst->mode == TAG) ? inst->rangeNum : inst->rangeNumAnc; //copy new range number
+      inst->msg_f.messageData[FCODE] = (inst->mode == TAG) ? RTLS_DEMO_MSG_TAG_POLL : RTLS_DEMO_MSG_ANCH_POLL; //message function code (specifies if message is a poll, response or other...)
+      inst->psduLength = (TAG_POLL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC);
+      inst->msg_f.seqNum = inst->frameSN++; //copy sequence number and then increment
+      inst->msg_f.sourceAddr[0] = inst->eui64[0]; //copy the address
+      inst->msg_f.sourceAddr[1] = inst->eui64[1]; //copy the address
+      inst->msg_f.destAddr[0] = 0xff;  //set the destination address (broadcast == 0xffff)
+      inst->msg_f.destAddr[1] = 0xff;  //set the destination address (broadcast == 0xffff)
+      dwt_writetxdata(inst->psduLength, (uint8_t *)  &inst->msg_f, 0) ;	// write the frame data
+
+      //set the delayed rx on time (the response message will be sent after this delay (from A0))
+      dwt_setrxaftertxdelay((uint32_t)RX_RESPONSE1_TURNAROUND);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
+
+      if(inst->mode == TAG){
+        inst->rxResps[inst->rangeNum] = 0; //reset the number of received responses
+        inst->responseTO = MAX_ANCHOR_LIST_SIZE; //expecting 4 responses
+        dwt_setrxtimeout((uint16_t)inst->fwtoTime_sy * MAX_ANCHOR_LIST_SIZE);  //configure the RX FWTO
+      }
+      else {
+        inst->rxResps[inst->rangeNumAnc] = 0; //reset number of responses
+        inst->responseTO = NUM_EXPECTED_RESPONSES_ANC0; //2 responses A1, A2
+        dwt_setrxtimeout((uint16_t)inst->fwtoTime_sy * (NUM_EXPECTED_RESPONSES_ANC0));  //units are
+      }
+
+      inst->rxResponseMask = 0;	//reset/clear the mask of received responses when tx poll
+      inst->rxResponseMaskAnc = 0;
+
+      inst->wait4ack = DWT_RESPONSE_EXPECTED; //response is expected - automatically enable the receiver
+
+      dwt_writetxfctrl(inst->psduLength, 0, 1); //write frame control
+
+      dwt_starttx(DWT_START_TX_IMMEDIATE | DWT_RESPONSE_EXPECTED); //transmit the frame
+
+      inst->testAppState = TA_TX_WAIT_CONF ;  // wait confirmation
+      inst->previousState = TA_TXPOLL_WAIT_SEND ;
+      inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set above)
+    }
+    break;
+
+    case TA_TXFINAL_WAIT_SEND : {
+      //the final has the same range number as the poll (part of the same ranging exchange)
+      inst->msg_f.messageData[POLL_RNUM] = (inst->mode == TAG) ? inst->rangeNum : inst->rangeNumAnc;
+      //the mask is sent so the anchors know whether the response RX time is valid
+      inst->msg_f.messageData[VRESP] = (inst->mode == TAG) ? inst->rxResponseMask : inst->rxResponseMaskAnc;
+      inst->msg_f.messageData[FCODE] = (inst->mode == TAG) ? RTLS_DEMO_MSG_TAG_FINAL : RTLS_DEMO_MSG_ANCH_FINAL; //message function code (specifies if message is a poll, response or other...)
+      inst->psduLength = (TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC);
+      inst->msg_f.seqNum = inst->frameSN++;
+      dwt_writetxdata(inst->psduLength, (uint8_t *)  &inst->msg_f, 0) ;	// write the frame data
+
+      inst->wait4ack = 0; //clear the flag not using wait for response as this message ends the ranging exchange
+
+      if(instancesenddlypacket(inst, DWT_START_TX_DELAYED)) {
+        // initiate the re-transmission
+        if(inst->mode == TAG){
+          inst->testAppState = TA_TXE_WAIT ; //go to TA_TXE_WAIT first to check if it's sleep time
+          inst->nextState = TA_TXPOLL_WAIT_SEND ;
+        }
+        else {
+          //A0 - failed to send Final
+          //A1 - failed to send Final
+          //go back to RX and behave as anchor
+          instance_backtoanchor(inst);
+        }
+        break; //exit this switch case...
+      }
+      else {
+        inst->testAppState = TA_TX_WAIT_CONF;                                               // wait confirmation
+        inst->previousState = TA_TXFINAL_WAIT_SEND;
+      }
+      if(inst->mode == TAG){
+        inst->instToSleep = TRUE ;
+      }
+      inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //will use RX FWTO to time out (set above)
+    }
+    break;
+
+    case TA_TX_WAIT_CONF : {
+      //printf("TA_TX_WAIT_CONF %d m%d %d states %08x %08x\n", inst->previousState, message, inst->newReportSent, dwt_read32bitreg(0x19), dwt_read32bitreg(0x0f)) ;
+
+      event_data_t* dw_event = instance_getevent(11); //get and clear this event
+
+      //NOTE: Can get the ACK before the TX confirm event for the frame requesting the ACK
+      //this happens because if polling the ISR the RX event will be processed 1st and then the TX event
+      //thus the reception of the ACK will be processed before the TX confirmation of the frame that requested it.
+      if(dw_event->type != DWT_SIG_TX_DONE) { //wait for TX done confirmation
+        if(dw_event->type != 0) {
+          if(dw_event->type == DWT_SIG_RX_TIMEOUT){   //got RX timeout - i.e. did not get the response (e.g. ACK)
+            //printf("RX timeout in TA_TX_WAIT_CONF (%d)\n", inst->previousState);
+            //we need to wait for SIG_TX_DONE and then process the timeout and re-send the frame if needed
+            inst->gotTO = 1;
+          }
+          else{
+            inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;
+          }
+        }
+
+        inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;
+        break;
+
+      }
+
+      inst->done = INST_NOT_DONE_YET;
+
+      if(inst->previousState == TA_TXFINAL_WAIT_SEND) {
+        if(inst->mode == TAG){
+          inst->testAppState = TA_TXE_WAIT ;
+          inst->nextState = TA_TXPOLL_WAIT_SEND ;
+          break;
+        }
+        else{
+          instance_backtoanchor(inst);
+        }
+      }
+      else if (inst->gotTO == 1) { //timeout
+        //printf("got TO in TA_TX_WAIT_CONF\n");
+        inst_processrxtimeout(inst);
+        inst->gotTO = 0;
+        inst->wait4ack = 0 ; //clear this
+        break;
+      }
+      else{
+        inst->txu.txTimeStamp = dw_event->timeStamp;
+
+        if(inst->previousState == TA_TXPOLL_WAIT_SEND){
+          uint64_t tagCalculatedFinalTxTime ;
+          // Embed into Final message: 40-bit pollTXTime,  40-bit respRxTime,  40-bit finalTxTime
+          if(inst->mode == TAG){
+            tagCalculatedFinalTxTime =  (inst->txu.txTimeStamp + inst->pollTx2FinalTxDelay) & MASK_TXDTS;
+          }
+          else {  //for anchor make the final half the delay ..... (this is ok, as A0 awaits 2 responses)
+            tagCalculatedFinalTxTime =  (inst->txu.txTimeStamp + inst->pollTx2FinalTxDelayAnc) & MASK_TXDTS;
+          }
+          inst->delayedReplyTime = tagCalculatedFinalTxTime >> 8; //high 32-bits
+          // Calculate Time Final message will be sent and write this field of Final message
+          // Sending time will be delayedReplyTime, snapped to ~125MHz or ~250MHz boundary by
+          // zeroing its low 9 bits, and then having the TX antenna delay added
+          // getting antenna delay from the device and add it to the Calculated TX Time
+          tagCalculatedFinalTxTime = tagCalculatedFinalTxTime + inst->txAntennaDelay;
+          tagCalculatedFinalTxTime &= MASK_40BIT;
+
+          // Write Calculated TX time field of Final message
+          memcpy(&(inst->msg_f.messageData[FTXT]), (uint8_t *)&tagCalculatedFinalTxTime, 5);
+          // Write Poll TX time field of Final message
+          memcpy(&(inst->msg_f.messageData[PTXT]), (uint8_t *)&inst->txu.tagPollTxTime, 5);
+
+          //change the w4r for the second and remaining anchors to 50 us
+          //dwt_setrxaftertxdelay((uint32)RX_RESPONSEX_TURNAROUND);  //units are 1.0256us - wait for wait4respTIM before RX on (delay RX)
+        }
+
+        if(inst->previousState == TA_TXRESPONSE_SENT_TORX) {
+          inst->previousState = TA_TXRESPONSE_WAIT_SEND ;
+        }
+        inst->testAppState = TA_RXE_WAIT ;                      // After sending, tag expects response/report, anchor waits to receive a final/new poll
+
+        message = 0;
+        //fall into the next case (turn on the RX)
+      }
+
+    }
+    // TODO: fall through to the next case statement in case of debugging
+    break ; // end case TA_TX_WAIT_CONF
+
+
+    case TA_RXE_WAIT : {
+      // printf("TA_RXE_WAIT") ;
+      if(inst->wait4ack == 0) {  //if this is set the RX will turn on automatically after TX
+        //turn RX on
+        dwt_rxenable(DWT_START_RX_IMMEDIATE) ;  // turn RX on, without delay
+      }
+      else{
+        inst->wait4ack = 0 ; //clear the flag, the next time we want to turn the RX on it might not be auto
+      }
+
+      if (inst->mode != LISTENER){
+        inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT; //using RX FWTO
+      }
+
+      inst->testAppState = TA_RX_WAIT_DATA;   // let this state handle it
+
+      // end case TA_RXE_WAIT, don't break, but fall through into the TA_RX_WAIT_DATA state to process it immediately.
+      if(message == 0) break;
+    }
+    // TODO: fall through to the next case statement in case of debugging
+    break;
+
+    case TA_RX_WAIT_DATA :                                                                     // Wait RX data
+      //printf("TA_RX_WAIT_DATA %d", message) ;
+      switch (message){
+
+      //if we have received a DWT_SIG_RX_OKAY event - this means that the message is IEEE data type - need to check frame control to know which addressing mode is used
+      case DWT_SIG_RX_OKAY : {
+        event_data_t* dw_event = instance_getevent(15); //get and clear this event
+        uint8_t  srcAddr[8] = {0,0,0,0,0,0,0,0};
+        uint8_t  dstAddr[8] = {0,0,0,0,0,0,0,0};
+        int fcode = 0;
+        int fn_code = 0;
+        //int srclen = 0;
+        //int fctrladdr_len;
+        uint8_t tof_idx  = 0;
+        uint8_t *messageData;
+
+        inst->stopTimer = 0; //clear the flag, as we have received a message
+
+        // handle 16 and 64 bit source and destination addresses
+        switch(dw_event->msgu.frame[1] & 0xCC){
+        case 0xCC: //
+          memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ll.sourceAddr[0]), ADDR_BYTE_SIZE_L);
+          memcpy(&dstAddr[0], &(dw_event->msgu.rxmsg_ll.destAddr[0]), ADDR_BYTE_SIZE_L);
+          fn_code = dw_event->msgu.rxmsg_ll.messageData[FCODE];
+          messageData = &dw_event->msgu.rxmsg_ll.messageData[0];
+          //srclen = ADDR_BYTE_SIZE_L;
+          //fctrladdr_len = FRAME_CRTL_AND_ADDRESS_L;
+          break;
+        case 0xC8: //
+          memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_sl.sourceAddr[0]), ADDR_BYTE_SIZE_L);
+          memcpy(&dstAddr[0], &(dw_event->msgu.rxmsg_sl.destAddr[0]), ADDR_BYTE_SIZE_S);
+          fn_code = dw_event->msgu.rxmsg_sl.messageData[FCODE];
+          messageData = &dw_event->msgu.rxmsg_sl.messageData[0];
+          //srclen = ADDR_BYTE_SIZE_L;
+          //fctrladdr_len = FRAME_CRTL_AND_ADDRESS_LS;
+          break;
+        case 0x8C: //
+          memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ls.sourceAddr[0]), ADDR_BYTE_SIZE_S);
+          memcpy(&dstAddr[0], &(dw_event->msgu.rxmsg_ls.destAddr[0]), ADDR_BYTE_SIZE_L);
+          fn_code = dw_event->msgu.rxmsg_ls.messageData[FCODE];
+          messageData = &dw_event->msgu.rxmsg_ls.messageData[0];
+          //srclen = ADDR_BYTE_SIZE_S;
+          //fctrladdr_len = FRAME_CRTL_AND_ADDRESS_LS;
+          break;
+        case 0x88: //
+          memcpy(&srcAddr[0], &(dw_event->msgu.rxmsg_ss.sourceAddr[0]), ADDR_BYTE_SIZE_S);
+          memcpy(&dstAddr[0], &(dw_event->msgu.rxmsg_ss.destAddr[0]), ADDR_BYTE_SIZE_S);
+          fn_code = dw_event->msgu.rxmsg_ss.messageData[FCODE];
+          messageData = &dw_event->msgu.rxmsg_ss.messageData[0];
+          //srclen = ADDR_BYTE_SIZE_S;
+          //fctrladdr_len = FRAME_CRTL_AND_ADDRESS_S;
+          break;
+        }
+
+        if((inst->instToSleep == FALSE) && (inst->mode == LISTENER)){ //update received data, and go back to receiving frames
+          //do something with message data (e.g. could extract any ToFs and print them)
+          inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+          dwt_setrxaftertxdelay(0);
+        }
+        else{
+          //process ranging messages
+          fcode = fn_code;
+          tof_idx = srcAddr[0] & 0x3 ;
+
+          switch(fcode){
+
+          case RTLS_DEMO_MSG_ANCH_POLL:
+          case RTLS_DEMO_MSG_TAG_POLL: {
+            inst->tagPollRxTime = dw_event->timeStamp ; //save Poll's Rx time
+            if(fcode == RTLS_DEMO_MSG_TAG_POLL){ //got poll from Tag
+              inst->rangeNumA[srcAddr[0]&0x7] = messageData[POLL_RNUM]; //when anchor receives a poll, we need to remember the new range number
+            }
+            else{ //got poll from Anchor (initiator)
+              inst->rangeNumAAnc[tof_idx] = messageData[POLL_RNUM]; //when anchor receives poll from another anchor - save the range number
+            }
+
+            if (A1_ANCHOR_ADDR == inst->instanceAddress16) { //this is A1
+
+              if(GATEWAY_ANCHOR_ADDR == (srcAddr[0] | ((uint32_t)(srcAddr[1] << 8)))) { //poll is from A0
+
+                //configure the time A1 will poll A2 (it should be in half slot time from now)
+                inst->a1SlotTime = dw_event->uTimeStamp + (inst->slotPeriod);
+
+                //inst->instanceTimerEn = 1; - THIS IS ENABLED BELOW AFTER FINAL
+                // - means that if final is not received then A1 will not range to A2
+              }
+            }
+
+            //the response has been sent - await TX done event
+            if(dw_event->type_pend == DWT_SIG_TX_PENDING){
+              inst->testAppState = TA_TX_WAIT_CONF;                // wait confirmation
+              inst->previousState = TA_TXRESPONSE_SENT_POLLRX ;    //wait for TX confirmation of sent response
+            }
+            //already re-enabled the receiver
+            else if (dw_event->type_pend == DWT_SIG_RX_PENDING){
+              //stay in RX wait for next frame...
+              //RX is already enabled...
+              inst->testAppState = TA_RX_WAIT_DATA ;              // wait for next frame
+            }
+            else{ //the DW1000 is idle (re-enable from the application level)
+              //stay in RX wait for next frame...
+              inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+            }
+
+
+          }
+          break; //RTLS_DEMO_MSG_TAG_POLL
+
+          case RTLS_DEMO_MSG_ANCH_RESP2:
+          case RTLS_DEMO_MSG_ANCH_RESP:{
+            uint8_t currentRangeNum = (messageData[TOFRN] + 1); //current = previous + 1
+
+            if(GATEWAY_ANCHOR_ADDR == (srcAddr[0] | ((uint32_t)(srcAddr[1] << 8)))){ //if response from gateway then use the correction factor
+              if(inst->mode == TAG){
+                // casting received bytes to int because this is a signed correction -0.5 periods to +1.5 periods
+                inst->tagSleepCorrection = (int16_t) (((uint16_t) messageData[RES_TAG_SLP1] << 8) + messageData[RES_TAG_SLP0]);
+                inst->tagSleepRnd = 0; // once we have initial response from Anchor #0 the slot correction acts and we don't need this anymore
+              }
+            }
+
+            //the response has been sent - await TX done event
+            if(dw_event->type_pend == DWT_SIG_TX_PENDING) { //anchor received response from anchor ID - 1 so is sending it's response now back to tag
+              inst->testAppState = TA_TX_WAIT_CONF;                // wait confirmation
+              inst->previousState = TA_TXRESPONSE_SENT_RESPRX ;    //wait for TX confirmation of sent response
+            }
+            //already re-enabled the receiver
+            else if(dw_event->type_pend == DWT_SIG_RX_PENDING) {
+              // stay in TA_RX_WAIT_DATA - receiver is already enabled.
+            }
+            //DW1000 idle - send the final
+            else { //if(dw_event->type_pend == DWT_SIG_DW_IDLE)
+
+              if(((TAG == inst->mode) && (inst->rxResponseMask & 0x1)) //if A0's response received send the final
+                  || ((A1_ANCHOR_ADDR == inst->instanceAddress16) && (inst->rxResponseMaskAnc & 0x4))
+                  || ((GATEWAY_ANCHOR_ADDR == inst->instanceAddress16) && (inst->rxResponseMaskAnc & 0x2)) ) { //if A1's response received
+
+                inst->testAppState = TA_TXFINAL_WAIT_SEND ; // send our response / the final
+              }
+              else { //go to sleep
+
+                if(TAG == inst->mode){
+                  inst->testAppState = TA_TXE_WAIT ; //go to TA_TXE_WAIT first to check if it's sleep time
+                  inst->nextState = TA_TXPOLL_WAIT_SEND ;
+                  inst->instToSleep = TRUE;
+                }
+                else {
+                  instance_backtoanchor(inst);
+                }
+              }
+            }
+            /*else
+                                {
+                                    //stay in RX wait for next frame...
+                                    inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+                                }*/
+
+            if(fcode == RTLS_DEMO_MSG_ANCH_RESP) { //tag to anchor mode
+              if(currentRangeNum == inst->rangeNum) { //these are the previous ranges...
+                //copy the ToF and put into array (array holds last 4 ToFs)
+                memcpy(&inst->tofArray[(srcAddr[0]&0x3)], &(messageData[TOFR]), 4);
+
+                //check if the ToF is valid, this makes sure we only report valid ToFs
+                //e.g. consider the case of reception of response from anchor a1 (we are anchor a2)
+                //if a1 got a Poll with previous Range number but got no Final, then the response will have
+                //the correct range number but the range will be INVALID_TOF
+                if(inst->tofArray[(srcAddr[0]&0x3)] != INVALID_TOF){
+                  inst->rxResponseMask |= (0x1 << (srcAddr[0]&0x3));
+                }
+
+              }
+              else {
+                if(inst->tofArray[(srcAddr[0]&0x3)] != INVALID_TOF) {
+                  inst->tofArray[(srcAddr[0]&0x3)] = INVALID_TOF;
+                }
+              }
+
+
+            }
+            else { //anchor to anchor (only gateway processes anchor to anchor ToFs)
+              //report the correct set of ranges (ranges from anchors A1, A2 need to match owns range number)
+                if((inst->gatewayAnchor)&&(currentRangeNum == inst->rangeNumAnc)) { //these are the previous ranges...
+                inst->rangeNumAAnc[0] = inst->rangeNumAnc ;
+
+                //once A0 receives A2's response then it can report the 3 ToFs.
+                if(inst->rxResps[inst->rangeNumAnc] == 3)
+                  //if(A2_ANCHOR_ADDR == (srcAddr[0] | ((uint32)(srcAddr[1] << 8))))
+                {
+                  //copy the ToF and put into array, the array should have 3 ToFs A0-A1, A0-A2 and A1-A2
+                  memcpy(&inst->tofArrayAnc[(srcAddr[0]+dstAddr[0])&0x3], &(messageData[TOFR]), 4);
+                  //calculate all anchor - anchor ranges... and report
+                  inst->newRange = instance_calcranges(&inst->tofArrayAnc[0], MAX_ANCHOR_LIST_SIZE, TOF_REPORT_A2A, &inst->rxResponseMaskAnc);
+                  inst->rxResponseMaskReport = inst->rxResponseMaskAnc;
+                  inst->rxResponseMaskAnc = 0;
+                  inst->newRangeTime = dw_event->uTimeStamp ;
+                }
+                else {
+                  //copy the ToF and put into array (array holds last 4 ToFs)
+                  memcpy(&inst->tofArrayAnc[(srcAddr[0]+dstAddr[0])&0x3], &(messageData[TOFR]), 4);
+                }
+              }
+            }
+
+          }
+          break; //RTLS_DEMO_MSG_ANCH_RESP
+
+
+          case RTLS_DEMO_MSG_ANCH_FINAL:
+          case RTLS_DEMO_MSG_TAG_FINAL: {
+            int64_t Rb, Da, Ra, Db ;
+            uint64_t tagFinalTxTime  = 0;
+            uint64_t tagFinalRxTime  = 0;
+            uint64_t tagPollTxTime  = 0;
+            uint64_t anchorRespRxTime  = 0;
+            uint64_t tof = INVALID_TOF;
+
+            double RaRbxDaDb = 0;
+            double RbyDb = 0;
+            double RayDa = 0;
+
+            uint8_t validResp = messageData[VRESP];
+            uint8_t index = RRXT0 + 5*(inst->shortAdd_idx);
+
+            if((RTLS_DEMO_MSG_TAG_FINAL == fcode) &&
+                (inst->rangeNumA[srcAddr[0]&0x7] != messageData[POLL_RNUM])) { //Final's range number needs to match Poll's or else discard this message
+              inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+              break;
+            }
+
+            if((RTLS_DEMO_MSG_ANCH_FINAL == fcode) &&
+                (((inst->rangeNumAAnc[tof_idx] != messageData[POLL_RNUM]) //Final's range number needs to match Poll's or else discard this message
+                    || inst->gatewayAnchor) //gateway can ignore the Final (from A1 to A2 exchange)
+                    || (A3_ANCHOR_ADDR == inst->instanceAddress16))) //A3 does not care about Final from A1 or A0
+            {
+              inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+              break;
+            }
+
+            if (A1_ANCHOR_ADDR == inst->instanceAddress16) { //this is A1
+              if(GATEWAY_ANCHOR_ADDR == (srcAddr[0] | ((uint32_t)(srcAddr[1] << 8)))) { //final is from A0
+                //ENABLE TIMER ONLY IF FINAL RECEIVED
+                inst->instanceTimerEn = 1;
+              }
+            }
+            //output data over USB...
+            inst->newRangeAncAddress = inst->instanceAddress16;
+
+            //if we got the final, maybe the tag did not get our response, so
+            //we can use other anchors responses/ToF if there are any.. and output..
+            //but we cannot calculate new range
+            if(((validResp & (0x1<<(inst->shortAdd_idx))) != 0)) {
+              // time of arrival of Final message
+              tagFinalRxTime = dw_event->timeStamp ; //Final's Rx time
+
+              //printf("FinalRx Timestamp: %4.15e\n", convertdevicetimetosecu(dw_event.timeStamp));
+              inst->delayedReplyTime = 0 ;
+
+              // times measured at Tag extracted from the message buffer
+              // extract 40bit times
+              memcpy(&tagPollTxTime, &(messageData[PTXT]), 5);
+              memcpy(&anchorRespRxTime, &(messageData[index]), 5);
+              memcpy(&tagFinalTxTime, &(messageData[FTXT]), 5);
+
+              // poll response round trip delay time is calculated as
+              // (anchorRespRxTime - tagPollTxTime) - (anchorRespTxTime - tagPollRxTime)
+              Ra = (int64_t)((anchorRespRxTime - tagPollTxTime) & MASK_40BIT);
+              Db = (int64_t)((inst->txu.anchorRespTxTime - inst->tagPollRxTime) & MASK_40BIT);
+
+              // response final round trip delay time is calculated as
+              // (tagFinalRxTime - anchorRespTxTime) - (tagFinalTxTime - anchorRespRxTime)
+              Rb = (int64_t)((tagFinalRxTime - inst->txu.anchorRespTxTime) & MASK_40BIT);
+              Da = (int64_t)((tagFinalTxTime - anchorRespRxTime) & MASK_40BIT);
+
+              RaRbxDaDb = (((double)Ra))*(((double)Rb))
+                                                - (((double)Da))*(((double)Db));
+
+              RbyDb = ((double)Rb + (double)Db);
+
+              RayDa = ((double)Ra + (double)Da);
+
+              tof = (int32_t) ( RaRbxDaDb/(RbyDb + RayDa) );
+            }
+
+            //tag to anchor ranging
+            if(RTLS_DEMO_MSG_TAG_FINAL == fcode) {
+              inst->newRangeTagAddress = srcAddr[0] + ((uint16_t) srcAddr[1] << 8);
+              //time-of-flight
+              inst->tof[inst->newRangeTagAddress & 0x7] = tof;
+              //calculate all tag - anchor ranges... and report
+              inst->newRange = instance_calcranges(&inst->tofArray[0], MAX_ANCHOR_LIST_SIZE, TOF_REPORT_T2A, &inst->rxResponseMask);
+              inst->rxResponseMaskReport = inst->rxResponseMask; //copy the valid mask to report
+              inst->rxResponseMask = 0;
+              //we have our range - update the own mask entry...
+              if(tof != INVALID_TOF) { //check the last ToF entry is valid and copy into the current array
+                setTagDist(srcAddr[0], inst->shortAdd_idx); //copy distance from this anchor to the tag into array
+
+                inst->rxResponseMask = (0x1 << inst->shortAdd_idx);
+                inst->tofArray[inst->shortAdd_idx] = tof;
+              }
+              inst->newRangeTime = dw_event->uTimeStamp ;
+            }
+            else { //anchor to anchor ranging
+              inst->newRangeTagAddress = srcAddr[0] + ((uint16_t) srcAddr[1] << 8);
+              //time-of-flight
+              inst->tofAnc[tof_idx] = tof;
+            }
+
+            //reset the response count
+            if(inst->rxResps[inst->rxRespsIdx] >= 0) {
+              inst->rxResps[inst->rxRespsIdx] = -1 * inst->rxResps[inst->rxRespsIdx];
+              if(inst->rxResps[inst->rxRespsIdx] == 0) //as A0 will have this as 0 when ranging to A1
+                inst->rxResps[inst->rxRespsIdx] = -1 ;
+            }
+
+            instancesetantennadelays(); //this will update the antenna delay if it has changed
+            instancesettxpower(); // configure TX power if it has changed
+
+            inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+
+          }
+          break; //RTLS_DEMO_MSG_TAG_FINAL
+
+
+          default: {
+            //only enable receiver when not using double buffering
+            inst->testAppState = TA_RXE_WAIT ;              // wait for next frame
+            dwt_setrxaftertxdelay(0);
+
+          }
+          break;
+          } //end switch (fcode)
+
+          if(dw_event->msgu.frame[0] & 0x20){
+            //as we only pass the received frame with the ACK request bit set after the ACK has been sent
+            instance_getevent(16); //get and clear the ACK sent event
+          }
+        } //end else
+
+      }
+      break ; //end of DWT_SIG_RX_OKAY
+
+      case DWT_SIG_RX_TIMEOUT :{
+
+        event_data_t* dw_event = instance_getevent(17); //get and clear this event
+
+        //printf("PD_DATA_TIMEOUT %d\n", inst->previousState) ;
+
+        //Anchor can time out and then need to send response - so will be in TX pending
+        if(dw_event->type_pend == DWT_SIG_TX_PENDING) {
+          inst->testAppState = TA_TX_WAIT_CONF;                                               // wait confirmation
+          inst->previousState = TA_TXRESPONSE_SENT_TORX ;    //wait for TX confirmation of sent response
+        }
+        else if(dw_event->type_pend == DWT_SIG_DW_IDLE) { //if timed out and back in receive then don't process as timeout
+          inst_processrxtimeout(inst);
+        }
+        //else if RX_PENDING then wait for next RX event...
+        message = 0; //clear the message as we have processed the event
+      }
+      break ;
+
+      case DWT_SIG_TX_AA_DONE: //ignore this event - just process the rx frame that was received before the ACK response
+      case 0:
+      default :{
+          if(message) { // == DWT_SIG_TX_DONE)
+          inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;
+        }
+
+        if(inst->done == INST_NOT_DONE_YET) inst->done = INST_DONE_WAIT_FOR_NEXT_EVENT;
+      }
+      break;
+
+      }
+      break ; // end case TA_RX_WAIT_DATA
+      default:
+        //printf("\nERROR - invalid state %d - what is going on??\n", inst->testAppState) ;
+        break;
+  } // end switch on testAppState
+
+  return inst->done;
+} // end testapprun()
+
+// -------------------------------------------------------------------------------------------------------------------
+#if NUM_INST != 1
+#error These functions assume one instance only
+#else
+
+
+// -------------------------------------------------------------------------------------------------------------------
+// function to set the fixed reply delay time (in us)
+//
+// This sets delay for RX to TX - Delayed Send, and for TX to RX delayed receive (wait for response) functionality,
+// and the frame wait timeout value to use.  This is a function of data rate, preamble length, and PRF
+
+extern uint8_t dwnsSFDlen[];
+
+void instancesetreplydelay(int delayus) { //delay in us
+
+  int instance = 0;
+  int margin = 3000; //2000 symbols
+  int respframe = 0;
+  int respframe_sy = 0;
+
+  //configure the rx delay receive delay time, it is dependent on the message length
+  float msgdatalen = 0;
+  float preamblelen = 0;
+  int sfdlen = 0;
+  int x = 0;
+
+  //Set the RX timeouts based on the longest expected message - the Final message
+  //Poll = 13, Response = 20, Final = 44 bytes
+  //msgdatalen = TAG_FINAL_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+  msgdatalen = ANCH_RESPONSE_MSG_LEN + FRAME_CRTL_AND_ADDRESS_S + FRAME_CRC;
+
+  x = (int) ceil(msgdatalen*8/330.0f);
+
+  msgdatalen = msgdatalen*8 + x*48;
+
+  //add some margin so we don't timeout too soon
+  margin = 0; //(TAG_FINAL_MSG_LEN - TAG_POLL_MSG_LEN);
+
+  x = (int) ceil(margin*8/330.0f);
+
+  margin = margin*8 + x*48;
+
+  //assume PHR length is 172308ns for 110k and 21539ns for 850k/6.81M
+  if(instance_data[instance].configData.dataRate == DWT_BR_110K) {
+    msgdatalen *= 8205.13f;
+    msgdatalen += 172308; // PHR length in nanoseconds
+
+    margin *= 8205.13f;
+
+  }
+  else if(instance_data[instance].configData.dataRate == DWT_BR_850K) {
+    msgdatalen *= 1025.64f;
+    msgdatalen += 21539; // PHR length in nanoseconds
+
+    margin *= 1025.64f;
+  }
+  else {
+    msgdatalen *= 128.21f;
+    msgdatalen += 21539; // PHR length in nanoseconds
+
+    margin *= 128.21f;
+  }
+
+  //SFD length is 64 for 110k (always)
+  //SFD length is 8 for 6.81M, and 16 for 850k, but can vary between 8 and 16 bytes
+  sfdlen = dwnsSFDlen[instance_data[instance].configData.dataRate];
+
+  switch (instance_data[instance].configData.txPreambLength) {
+  case DWT_PLEN_4096 : preamblelen = 4096.0f; break;
+  case DWT_PLEN_2048 : preamblelen = 2048.0f; break;
+  case DWT_PLEN_1536 : preamblelen = 1536.0f; break;
+  case DWT_PLEN_1024 : preamblelen = 1024.0f; break;
+  case DWT_PLEN_512  : preamblelen = 512.0f; break;
+  case DWT_PLEN_256  : preamblelen = 256.0f; break;
+  case DWT_PLEN_128  : preamblelen = 128.0f; break;
+  case DWT_PLEN_64   : preamblelen = 64.0f; break;
+  }
+
+  //preamble  = plen * (994 or 1018) depending on 16 or 64 PRF
+  if(instance_data[instance].configData.prf == DWT_PRF_16M) {
+    preamblelen = (sfdlen + preamblelen) * 0.99359f;
+  }
+  else {
+    preamblelen = (sfdlen + preamblelen) * 1.01763f;
+  }
+
+  respframe_sy = (16 + (int)((preamblelen + ((msgdatalen + margin)/1000.0))/ 1.0256)) ;
+
+  //this is the delay used for the delayed transmit (when sending the response, and final messages)
+  instance_data[instance].pollTx2FinalTxDelay = convertmicrosectodevicetimeu (delayus);
+  //the anchor to anchor ranging consist of A0 ranging to A1 and A2 and A1 ranging to A2
+  //as there are less messages the ranging time is shorter (thus divide by 2)
+  instance_data[instance].pollTx2FinalTxDelayAnc = convertmicrosectodevicetimeu (delayus/2 + 100);
+
+  //this is the delay the anchors 1, 2, etc.. will send the response back at...
+  //anchor 2 will have the delay set to 2 * fixedReplyDelayAnc
+  //andhor 3 will have the delay set to 3 * fixedReplyDelayAnc and so on...
+  //this delay depends on how quickly the tag can receive and process the message from previous anchor
+  //(and also the frame length of course)
+  respframe = (int)(preamblelen + (msgdatalen/1000.0)); //length of response frame (micro seconds)
+  if(instance_data[instance].configData.dataRate == DWT_BR_110K) {
+
+    //set the frame wait timeout time - total time the frame takes in symbols
+    instance_data[instance].fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_110K + 400; //add some margin because of the resp to resp RX turn on time
+
+    instance_data[instance].fwtoTimeAnc_sy = respframe_sy; //add some margin so we don't timeout too soon
+    instance_data[instance].fixedReplyDelayAnc = convertmicrosectodevicetimeu (respframe + RX_RESPONSE1_TURNAROUND_110K);
+    instance_data[instance].fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertmicrosectodevicetimeu (preamblelen)) >> 8) + 16;
+
+    instance_data[instance].ancRespRxDelay = RX_RESPONSE1_TURNAROUND_110K ;
+  }
+  else {
+
+    //set the frame wait timeout time - total time the frame takes in symbols
+    instance_data[instance].fwtoTime_sy = respframe_sy + RX_RESPONSE1_TURNAROUND_6M81; //add some margin because of the resp to resp RX turn on time
+
+    instance_data[instance].fwtoTimeAnc_sy =  respframe_sy;
+    instance_data[instance].fixedReplyDelayAnc = convertmicrosectodevicetimeu (respframe + RX_RESPONSE1_TURNAROUND_6M81);
+    instance_data[instance].fixedReplyDelayAncP = (uint32_t) (((uint64_t) convertmicrosectodevicetimeu (preamblelen)) >> 8) + 16;
+
+    instance_data[instance].ancRespRxDelay = RX_RESPONSE1_TURNAROUND_6M81 ;
+  }
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+//
+// Set Payload parameters for the instance
+//
+// -------------------------------------------------------------------------------------------------------------------
+void instancesetaddresses(uint16_t address) {
+  int instance = 0 ;
+
+  instance_data[instance].instanceAddress16 = address ;       // copy configurations
+}
+
+
+#endif
+
+
+
+
+/* ==========================================================
+
+Notes:
+
+Previously code handled multiple instances in a single console application
+
+Now have changed it to do a single instance only. With minimal code changes...(i.e. kept [instance] index but it is always 0.
+
+Windows application should call instance_init() once and then in the "main loop" call instance_run().
+
+*/
+
+
+#endif /* defined(AMIROLLD_CFG_DW1000) && (AMIROLLD_CFG_DW1000 == 1) */
