Simple driver for DWM1000 modules.

Revision:
5:c34ebc7f650c
Parent:
4:faf802b4af85
Child:
6:028891b5f03b
--- a/DW1000.cpp	Tue Mar 29 10:00:23 2016 +0000
+++ b/DW1000.cpp	Thu Mar 31 15:36:39 2016 +0000
@@ -4,13 +4,16 @@
 
 // Change this depending on whether damaged or heatlhy DWM1000 modules are used.
 const bool DWM1000_DAMAGED = true;
+//const bool DWM1000_DAMAGED = false;
 
 //#include "PC.h"
 //static PC pc(USBTX, USBRX, 115200);           // USB UART Terminal
 
-DW1000::DW1000(SPI& spi, InterruptIn& irq, PinName CS, PinName RESET)
+DW1000::DW1000(SPI& spi, InterruptIn* irq, PinName CS, PinName RESET)
 : irq(irq), spi(spi), cs(CS), reset(RESET) {
-    irq.rise(this, &DW1000::ISR);
+    if (irq != NULL) {
+        irq->rise(this, &DW1000::ISR);
+    }
 
     setCallbacks(NULL, NULL);
 
@@ -67,9 +70,11 @@
 
     writeRegister8(DW1000_SYS_CFG, 3, 0x20);    // enable auto reenabling receiver after error
 
-    irq.enable_irq();
+    if (irq != NULL) {
+        irq->enable_irq();
+    }
 
-    startRX();
+    //startRX();
 }
 
 void DW1000::setCallbacks(void (*callbackRX)(void), void (*callbackTX)(void)) {
@@ -224,6 +229,9 @@
 void DW1000::sendFrame(uint8_t* message, uint16_t length) {
     //if (length >= 1021) length = 1021;                            // check for maximim length a frame can have with 1024 Byte frames [not used, see constructor]
     if (length >= 125) length = 125;                                // check for maximim length a frame can have with 127 Byte frames
+
+    Timer timer;
+    timer.start();
     writeRegister(DW1000_TX_BUFFER, 0, message, length);            // fill buffer
     
     uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1);             // put length of frame
@@ -233,10 +241,12 @@
     
     stopTRX();                                                      // stop receiving
     writeRegister8(DW1000_SYS_CTRL, 0, 0x02);                       // trigger sending process by setting the TXSTRT bit
-    startRX();                                                      // enable receiver again
+//    startRX();                                                      // enable receiver again
 }
 
 void DW1000::sendDelayedFrame(uint8_t* message, uint16_t length, uint64_t TxTimestamp) {
+    clearSentFlag();                                                // This is necessary, otherwise we pick up the transmission time of the previous send
+
     if (TxTimestamp > CONST_2POWER40) {
         TxTimestamp -= CONST_2POWER40;
     }
@@ -250,16 +260,16 @@
     length = ((backup & 0xFC) << 8) | (length & 0x03FF);
     writeRegister16(DW1000_TX_FCTRL, 0, length);
 
-    stopTRX();                                                      // stop receiving
-
     writeRegister40(DW1000_DX_TIME, 0, TxTimestamp);                //write the timestamp on which to send the message
 
+    stopTRX();                                                      // stop receiving
     writeRegister8(DW1000_SYS_CTRL, 0, 0x02 | 0x04);                // trigger sending process by setting the TXSTRT and TXDLYS bit
-    startRX();                                                      // enable receiver again
+//    startRX();                                                      // enable receiver again
 }
 
 void DW1000::startRX() {
     writeRegister8(DW1000_SYS_CTRL, 0x01, 0x01);                    // start listening for preamble by setting the RXENAB bit
+    wait_us(16);                                                    // According to page 81 in the user manual (RXENAB bit)
 }
 
 void DW1000::stopTRX() {
@@ -280,37 +290,41 @@
 }
 
 void DW1000::hardwareReset(PinName reset_pin) {
-    // DWM1000 RESET logic.
-    if (DWM1000_DAMAGED) {
-        // The following code works for damaged DWM1000 modules.
-        // IMPORTANT: This will damage healthy DWM1000 modules!
-        DigitalInOut reset(reset_pin);
-        reset.output();
-        reset = 1;
-        wait_ms(100);
-        reset = 0;
-        wait_ms(100);
-        reset = 1;
-        wait_ms(100);
-    } else {
-        // The following code works for healthy DWM1000 modules
-        DigitalInOut reset(reset_pin);
-        reset.output();
-        reset = 0;
-        wait_ms(100);
-        reset.input();
+    DigitalInOut reset(reset_pin);
+    hardwareReset(reset);
+}
+
+void DW1000::hardwareReset(DigitalInOut& reset) {
+    if (reset.is_connected()) {
+        // DWM1000 RESET logic.
+        if (DWM1000_DAMAGED) {
+            // The following code works for damaged DWM1000 modules.
+            // IMPORTANT: This will damage healthy DWM1000 modules!
+            reset.output();
+            reset = 1;
+            wait_ms(100);
+            reset = 0;
+            wait_ms(100);
+            reset = 1;
+            wait_ms(100);
+        } else {
+            // The following code works for healthy DWM1000 modules
+            reset.output();
+            reset = 0;
+            wait_ms(100);
+            reset.input();
+        }
     }
 }
 
+void DW1000::softwareReset() {
+    stopTRX();
+    clearReceivedFlag();
+    clearSentFlag();
+}
+
 void DW1000::resetAll() {
-    if (reset.is_connected()) {
-        reset = 1;
-        wait_ms(100);
-        reset = 0;
-        wait_ms(100);
-        reset = 1;
-        wait_ms(100);
-    }
+    hardwareReset(reset);
 
     writeRegister8(DW1000_PMSC, 0, 0x01);   // set clock to XTAL
     writeRegister8(DW1000_PMSC, 3, 0x00);   // set All reset
@@ -414,11 +428,15 @@
 }
 
 void DW1000::select() {     // always called to start an SPI transmission
-    irq.disable_irq();
+    if (irq != NULL) {
+        irq->disable_irq();
+    }
     cs = 0;                 // set Cable Select pin low to start transmission
 }
 
 void DW1000::deselect() {   // always called to end an SPI transmission
     cs = 1;                 // set Cable Select pin high to stop transmission
-    irq.enable_irq();
+    if (irq != NULL) {
+        irq->enable_irq();
+    }
 }