Matthias Grob & Manuel Stalder / Mbed 2 deprecated DecaWave

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
manumaet
Date:
Tue Nov 25 15:22:53 2014 +0000
Parent:
19:e94bc88c1eb0
Child:
21:23bf4399020d
Commit message:
minor changes to API, before implementing autoack and timing try

Changed in this revision

DW1000/DW1000.cpp Show annotated file Show diff for this revision Revisions of this file
DW1000/DW1000.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/DW1000/DW1000.cpp	Tue Nov 25 14:48:51 2014 +0000
+++ b/DW1000/DW1000.cpp	Tue Nov 25 15:22:53 2014 +0000
@@ -1,7 +1,8 @@
 #include "DW1000.h"
 
-DW1000::DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ) : spi(MOSI, MISO, SCLK), cs(CS), irq(IRQ) {
-    receiving = 0;                      // state in the beginning is not listening for frames
+DW1000::DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ) : irq(IRQ), spi(MOSI, MISO, SCLK), cs(CS) {
+    receiving = false;                  // state in the beginning is not listening for frames
+    sending = false;                    // state in the beginning is not sending anything
     
     deselect();                         // Chip must be deselected first
     spi.format(8,0);                    // Setup the spi for standard 8 bit data and SPI-Mode 0 (GPIO5, GPIO6 open circuit or ground on DW1000)
@@ -41,7 +42,7 @@
     writeRegister(DW1000_TX_CAL, 0x00, &buffer[4], 1);
     readRegister(DW1000_TX_CAL, 0x03, &buffer[5], 2);               // get the 8-Bit readings for Voltage and Temperature
     float Voltage = buffer[5] * 0.0057 + 2.3;
-    float Temperature = buffer[6] * 1.13 - 113.0;                   // TODO: getTemperature was always ~35 degree with better formula/calibration see instance_common.c row 391
+    //float Temperature = buffer[6] * 1.13 - 113.0;                 // TODO: getTemperature was always ~35 degree with better formula/calibration see instance_common.c row 391
     return Voltage;
 }
 
@@ -54,16 +55,14 @@
 }
 
 char* DW1000::receiveString() {
-    uint16_t framelength = 0;                                       // get framelength
-    readRegister(DW1000_RX_FINFO, 0, (uint8_t*)&framelength, 2);
-    framelength = (framelength & 0x03FF) - 2;                       // take only the right bits and subtract the 2 CRC Bytes
-    char* receive = new char[framelength];                          // get data from buffer
-    readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)receive, framelength);
+    uint16_t framelength = getFramelength();
+    char* receive = new char[framelength];                              // prepare memory for the string on the heap
+    readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)receive, framelength);  // get data from buffer
     return receive;
 }
 
 void DW1000::sendFrame(uint8_t* message, uint16_t length) {
-    if (length >= 1021) length = 1021;
+    if (length >= 1021) length = 1021;                              // check for maximim length a frame can have            TODO: 127 Byte mode?
     writeRegister(DW1000_TX_BUFFER, 0, message, length);            // fill buffer
     
     uint8_t backup = readRegister8(DW1000_TX_FCTRL, 1);             // put length of frame including 2 CRC Bytes
@@ -72,13 +71,14 @@
     writeRegister(DW1000_TX_FCTRL, 0, (uint8_t*)&length, 2);
     
     if (receiving) stopTRX();                                       // stop receiving if we are in this state
+    sending = true;
     writeRegister8(DW1000_SYS_CTRL, 0, 0x02);                       // trigger sending process by setting the TXSTRT bit
-    //if (receiving) startRX();                                       // enable receiver again if we need to preserve state          TODO: safe to do this directly ??? only after sending ended
 }
 
 void DW1000::startRX() {
+    while(sending);                                                 // block until sending finished                         TODO: the right way??
     receiving = true;
-    writeRegister8(DW1000_SYS_CTRL, 0x01, 0x01);                       // start listening for preamble by setting the RXENAB bit
+    writeRegister8(DW1000_SYS_CTRL, 0x01, 0x01);                    // start listening for preamble by setting the RXENAB bit
 }
 
 void DW1000::stopRX() {
@@ -86,27 +86,10 @@
     stopTRX();
 }
 
-void DW1000::ISR() {
-    uint64_t status = getStatus();
-    if (status & 0x4000) {
-        callbackRX(getFramelength());
-    }
-    if (status & 0x80) {
-        if (receiving) startRX();                                // enable receiver again if we need to preserve state          TODO: have to do it here??
-        callbackTX();
-    }
-}
-
-uint16_t DW1000::getFramelength() {
-    uint16_t framelength = readRegister16(DW1000_RX_FINFO, 0);                                       // get framelength TODO: get this from isr
-    framelength &= 0x03FF;
-    framelength -= 2;
-    return framelength;
-}
-
+// PRIVATE Methods ------------------------------------------------------------------------------------
 void DW1000::loadLDE() {                                            // initialise LDE algorithm LDELOAD User Manual p22
     writeRegister16(DW1000_PMSC, 0, 0x0301);                        // set clock to XTAL so OTP is reliable
-    writeRegister16(DW1000_OTP_IF, 0x06, 0x8000);                        // set LDELOAD bit in OTP
+    writeRegister16(DW1000_OTP_IF, 0x06, 0x8000);                   // set LDELOAD bit in OTP
     wait_us(150);
     writeRegister16(DW1000_PMSC, 0, 0x0200);                        // recover to PLL clock
 }
@@ -127,6 +110,24 @@
     writeRegister8(DW1000_PMSC, 3, 0xF0);   // clear All reset
 }
 
+void DW1000::ISR() {
+    uint64_t status = getStatus();
+    if (status & 0x4000) {
+        callbackRX(getFramelength());
+    }
+    if (status & 0x80) {
+        sending = false;
+        if (receiving) startRX();                                   // enable receiver again if we need to preserve state          TODO: have to do it here??
+        callbackTX();
+    }
+}
+
+uint16_t DW1000::getFramelength() {
+    uint16_t framelength = readRegister16(DW1000_RX_FINFO, 0);      // get framelength
+    framelength = (framelength & 0x03FF) - 2;                       // take only the right bits and subtract the 2 CRC Bytes
+    return framelength;
+}
+
 // SPI Interface ------------------------------------------------------------------------------------
 uint8_t DW1000::readRegister8(uint8_t reg, uint16_t subaddress) {
     uint8_t result;
--- a/DW1000/DW1000.h	Tue Nov 25 14:48:51 2014 +0000
+++ b/DW1000/DW1000.h	Tue Nov 25 15:22:53 2014 +0000
@@ -53,7 +53,7 @@
 
 class DW1000 {
     public:            
-        DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ);                           // constructor, uses SPI class
+        DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ);              // constructor, uses SPI class
 
         // Device API
         uint32_t getDeviceID();                                                                 // gets the Device ID which should be 0xDECA0130 (good for testing SPI!)
@@ -70,6 +70,7 @@
         
     //private:
         bool receiving;                                                                         // holds if we need to preserve a receiving state after sending
+        bool sending;                                                                           // holds if we are currently in a sending process so we can't receive at the moment
 
         void loadLDE();                                                                         // load the leading edge detection algorithm to RAM, [IMPORTANT because receiving malfunction may occur] see User Manual LDELOAD on p22 & p158
         void stopTRX();                                                                         // disable tranceiver go back to idle mode
@@ -78,7 +79,7 @@
 
         // Interrupt
         InterruptIn irq;                                                                        // Pin used to handle Events from DW1000 by an Interrupthandler
-        void (*callbackRX) (int framelength);                                                                  // function pointer to callback which is called when successfull RX took place
+        void (*callbackRX) (int framelength);                                                   // function pointer to callback which is called when successfull RX took place
         void (*callbackTX) ();                                                                  // function pointer to callback which is called when successfull TX took place
         void ISR();                                                                             // interrupt handling method (also calls according callback methods)
         uint16_t getFramelength();                                                              // to get the framelength of the received frame from the PHY header
--- a/main.cpp	Tue Nov 25 14:48:51 2014 +0000
+++ b/main.cpp	Tue Nov 25 15:22:53 2014 +0000
@@ -11,7 +11,7 @@
 uint64_t timestamp_old = 0;
 
 void callbackRX(int framelength) {
-    if(framelength<200) {
+    if (framelength<200) {
         char* receive = dw.receiveString();                             // receive a string
         pc.printf("Received: \"%s\" %d ", receive, framelength);
         delete[] receive;
@@ -24,8 +24,7 @@
     uint64_t difference = timestamp - timestamp_old;
     timestamp_old = timestamp;
     //pc.printf("Timestamp: %lld\r\n", difference);
-    pc.printf("Timestamp: %fs", difference*timeunit);       // TODO: gives some wrong values because of timer overflow
-    pc.printf("\r\n");
+    pc.printf("Timestamp: %fs\r\n", difference*timeunit);       // TODO: gives some wrong values because of timer overflow
     dw.startRX();
 }
 
@@ -40,22 +39,17 @@
 }
 
 int main() {
-    pc.printf("DecaWave 0.1\r\nup and running!\r\n");
-    
-    dw.setEUI(0xFAEDCD01FAEDCD01);                  // basic methods called to check if we have a slave
+    pc.printf("DecaWave 0.1\r\nup and running!\r\n");  
+    dw.setEUI(0xFAEDCD01FAEDCD01);                  // basic methods called to check if we have a working SPI connection
     pc.printf("%d DEVICE_ID register: 0x%X\r\n", i, dw.getDeviceID());
     pc.printf("%d EUI register: %016llX\r\n", i, dw.getEUI());
     pc.printf("%d Voltage: %f\r\n", i, dw.getVoltage());
     
-    uint32_t conf = 0;     // read System Configuration
-    dw.readRegister(DW1000_SYS_CFG, 0, (uint8_t*)&conf, 4);
-    pc.printf("%d System Configuration: %X\r\n", i, conf);
-    
     dw.callbackRX = &callbackRX;        // TODO: must not jump to NULL & setter
     dw.callbackTX = &callbackTX;
     
     // Receiver initialisation
-    dw.writeRegister16(DW1000_SYS_MASK, 0, 0x4080); // RX only good frame 0x4000, RX all frames 0x2000, TX done 0x0080
+    dw.writeRegister16(DW1000_SYS_MASK, 0, 0x4080); // TODO: RX only good frame 0x4000, RX all frames 0x2000, TX done 0x0080
     dw.startRX();
     
     while(1) {