Matthias Grob & Manuel Stalder / Mbed 2 deprecated DecaWave

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
manumaet
Date:
Mon Nov 24 16:48:03 2014 +0000
Parent:
17:8afa5f9122da
Child:
19:e94bc88c1eb0
Commit message:
many changes, sadly TX interrupt broken

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	Mon Nov 24 14:09:49 2014 +0000
+++ b/DW1000/DW1000.cpp	Mon Nov 24 16:48:03 2014 +0000
@@ -1,14 +1,16 @@
 #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;
+    receiving = 0;                      // state in the beginning is not listening for frames
     
     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)
     spi.frequency(1000000);             // with a 1MHz clock rate (worked up to 49MHz in our Test)
     
-    resetAll();                       // we can do a soft reset if we want to (only needed for debugging)
+    //resetAll();                         // we can do a soft reset if we want to (only needed for debugging)
     loadLDE();                          // important everytime DW1000 initialises/awakes otherwise the LDE algorithm must be turned of or there's receiving malfunction see User Manual LDELOAD on p22 & p158
+    
+    // Configuration TODO: make method for that
     writeRegister8(DW1000_SYS_CFG, 3, 0x20); // enable auto reenabling receiver after error
     writeRegister8(DW1000_SYS_CFG, 2, 0x03); // enable 1024 byte frames TODO: doesn't work!!
     
@@ -43,6 +45,10 @@
     return Voltage;
 }
 
+uint64_t DW1000::getStatus() {
+    return readRegister40(DW1000_SYS_STATUS, 0);
+}
+
 void DW1000::sendString(char* message) {
     sendFrame((uint8_t*)message, strlen(message)+1);
 }
@@ -65,9 +71,9 @@
     length = ((backup & 0xFC) << 8) | (length & 0x03FF);
     writeRegister(DW1000_TX_FCTRL, 0, (uint8_t*)&length, 2);
     
-    if (receiving) stopTRX();                                       // stop receiving if we are
+    if (receiving) stopTRX();                                       // stop receiving if we are in this state
     writeRegister8(DW1000_SYS_CTRL, 0, 0x02);                       // trigger sending process by setting the TXSTRT bit
-    if (receiving) startRX();                                       // enable receiver again if we need it                      TODO: safe to do this directly ??? only after sending ended
+    //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() {
@@ -81,21 +87,28 @@
 }
 
 void DW1000::ISR() {
-    uint64_t status;                                                // get the entire system status
-    readRegister(DW1000_SYS_STATUS, 0, (uint8_t*)&status, 5);
-    status &= 0xFFFFFFFFFF;                                         // only 40-Bit
-    if (status & 0x4000)
-        callbackRX();
-    if (status & 0x80)
-        ;//callbackTX();                                            // TODO: mask TX done interrupt make TX handler
+    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();
+    }
 }
 
-void DW1000::loadLDE() {
-    uint16_t ldeload[] = {0x0301, 0x8000, 0x0200};                  // initialise LDE algorithm LDELOAD User Manual p22
-    writeRegister(DW1000_PMSC, 0, (uint8_t*)&ldeload[0], 2);        // set clock to XTAL so OTP is reliable
-    writeRegister(DW1000_OTP_IF, 0x06, (uint8_t*)&ldeload[1], 2);   // set LDELOAD bit in OTP
+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;
+}
+
+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
     wait_us(150);
-    writeRegister(DW1000_PMSC, 0, (uint8_t*)&ldeload[2], 2);        // recover to PLL clock
+    writeRegister16(DW1000_PMSC, 0, 0x0200);                        // recover to PLL clock
 }
 
 void DW1000::stopTRX() {
@@ -121,39 +134,56 @@
     return result;
 }
 
+uint16_t DW1000::readRegister16(uint8_t reg, uint16_t subaddress) {
+    uint16_t result;
+    readRegister(reg, subaddress, (uint8_t*)&result, 2);
+    return result;
+}
+
+uint64_t DW1000::readRegister40(uint8_t reg, uint16_t subaddress) {
+    uint64_t result;
+    readRegister(reg, subaddress, (uint8_t*)&result, 5);
+    result &= 0xFFFFFFFFFF;                                 // only 40-Bit
+    return result;
+}
+
 void DW1000::writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer) {
     writeRegister(reg, subaddress, &buffer, 1);
 }
 
+void DW1000::writeRegister16(uint8_t reg, uint16_t subaddress, uint16_t buffer) {
+    writeRegister(reg, subaddress, (uint8_t*)&buffer, 2);
+}
+
 void DW1000::readRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) {
     setupTransaction(reg, subaddress, false);
-    for(int i=0; i<length; i++)     // get data
+    for(int i=0; i<length; i++)                             // get data
         buffer[i] = spi.write(0x00);
     deselect();
 }
 
 void DW1000::writeRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length) {
     setupTransaction(reg, subaddress, true);
-    for(int i=0; i<length; i++)     // put data
+    for(int i=0; i<length; i++)                             // put data
         spi.write(buffer[i]);
     deselect();
 }
 
 void DW1000::setupTransaction(uint8_t reg, uint16_t subaddress, bool write) {
-    reg |=  (write * DW1000_WRITE_FLAG);
+    reg |=  (write * DW1000_WRITE_FLAG);                                        // set read/write flag
     select();
     if (subaddress > 0) {                                                       // there's a subadress, we need to set flag and send second header byte
         spi.write(reg | DW1000_SUBADDRESS_FLAG);
-        if (subaddress > 127) {                                                 // sub address too long, we need to set flag and send third header byte
-            spi.write((uint8_t)(subaddress & 0x7F) | DW1000_2_SUBADDRESS_FLAG);
+        if (subaddress > 0x7F) {                                                // sub address too long, we need to set flag and send third header byte
+            spi.write((uint8_t)(subaddress & 0x7F) | DW1000_2_SUBADDRESS_FLAG); // and 
             spi.write((uint8_t)(subaddress >> 7));
         } else {
             spi.write((uint8_t)subaddress);
         }
     } else {
-        spi.write(reg);
+        spi.write(reg);                                                         // say which register address we want to access
     }
 }
 
-void DW1000::select() { cs = 0; }    // set CS low to start transmission
-void DW1000::deselect() { cs = 1; }    // set CS high to stop transmission
\ No newline at end of file
+void DW1000::select() { cs = 0; }   // set CS low to start transmission
+void DW1000::deselect() { cs = 1; } // set CS high to stop transmission
\ No newline at end of file
--- a/DW1000/DW1000.h	Mon Nov 24 14:09:49 2014 +0000
+++ b/DW1000/DW1000.h	Mon Nov 24 16:48:03 2014 +0000
@@ -60,6 +60,7 @@
         uint64_t getEUI();                                                                      // gets 64 bit Extended Unique Identifier according to IEEE standard
         void setEUI(uint64_t EUI);                                                              // sets 64 bit Extended Unique Identifier according to IEEE standard
         float getVoltage();                                                                     // gets the current chip voltage measurement form the A/D converter
+        uint64_t getStatus();                                                                   // get the 40 bit device status
         
         void sendString(char* message);                                                         // to send String with arbitrary length
         char* receiveString();                                                                  // to receive char string with arbitrary length (ATTENTION! you have to delete the returned memory location like "client delete[] receivedMessage;")
@@ -77,15 +78,20 @@
 
         // 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 (*callbackTX) ();                                                                  // function pointer to callback which is called when successfull TX took place
         void ISR();                                                                             // interrupt handling method (also calls according callback methods)
-        void (*callbackRX) ();                                                                  // pointer to callback which is called when successfull RX took place
+        uint16_t getFramelength();                                                              // to get the framelength of the received frame from the PHY header
         
         // SPI Inteface
         SPI spi;                                                                                // SPI Bus
         DigitalOut cs;                                                                          // Slave selector for SPI-Bus (here explicitly needed to start and end SPI transactions also usable to wake up DW1000)
         
-        uint8_t readRegister8(uint8_t reg, uint16_t subaddress);                                // expressive to read just one byte
-        void writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer);                  // expressive to write just one byte
+        uint8_t readRegister8(uint8_t reg, uint16_t subaddress);                                // expressive methods to read or write the number of bits written in the name
+        uint16_t readRegister16(uint8_t reg, uint16_t subaddress);
+        uint64_t readRegister40(uint8_t reg, uint16_t subaddress);
+        void writeRegister8(uint8_t reg, uint16_t subaddress, uint8_t buffer);
+        void writeRegister16(uint8_t reg, uint16_t subaddress, uint16_t buffer);
         
         void readRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length);
         void writeRegister(uint8_t reg, uint16_t subaddress, uint8_t *buffer, int length);
--- a/main.cpp	Mon Nov 24 14:09:49 2014 +0000
+++ b/main.cpp	Mon Nov 24 16:48:03 2014 +0000
@@ -10,18 +10,7 @@
 char message[1200] = "";
 uint64_t timestamp_old = 0;
 
-//#define PINGPONG
-
-void Interrupthandler() {
-    /*uint8_t frameready = 0;
-    dw.readRegister(DW1000_SYS_STATUS, 1, &frameready, 1);
-    pc.printf("Interrupt status: %X\r\n", frameready);*/
-    
-    uint16_t framelength = 0;                                       // get framelength TODO: just for debugging of string
-    dw.readRegister(DW1000_RX_FINFO, 0, (uint8_t*)&framelength, 2);
-    framelength &= 0x03FF;
-    framelength -= 2;
-    
+void callbackRX(int framelength) {
     if(framelength<200) {
         char* receive = dw.receiveString();                             // receive a string
         pc.printf("Received: \"%s\" %d ", receive, framelength);
@@ -29,14 +18,9 @@
     } else
         pc.printf("Received! %d ", framelength);
     
-    uint64_t status;
-    dw.readRegister(DW1000_SYS_STATUS, 0, (uint8_t*)&status, 5);
-    status &= 0xFFFFFFFFFF;                                      // only 40-Bit
-    pc.printf("Status: %010llX  ", status);
+    pc.printf("Status: %010llX  ", dw.getStatus());
     
-    uint64_t timestamp;
-    dw.readRegister(DW1000_RX_TIME, 0, (uint8_t*)&timestamp, 5);
-    timestamp &= 0xFFFFFFFFFF;                                      // only 40-Bit
+    uint64_t timestamp = dw.readRegister40(DW1000_RX_TIME, 0);
     uint64_t difference = timestamp - timestamp_old;
     timestamp_old = timestamp;
     //pc.printf("Timestamp: %lld\r\n", difference);
@@ -45,6 +29,16 @@
     dw.startRX();
 }
 
+void callbackTX() {
+    char messagecheck[1200];
+    dw.readRegister(DW1000_TX_BUFFER, 0, (uint8_t*)messagecheck, strlen(message)+1);
+    if (i < 200)
+        pc.printf("%d Sent: \"%s\" %d ", i, messagecheck, strlen(message)+1);
+    else
+        pc.printf("%d Sent! %d ", i, strlen(message)+1);
+    pc.printf("Status: %010llX\r\n", dw.getStatus());
+}
+
 int main() {
     pc.printf("DecaWave 0.1\r\nup and running!\r\n");
     
@@ -57,37 +51,27 @@
     dw.readRegister(DW1000_SYS_CFG, 0, (uint8_t*)&conf, 4);
     pc.printf("%d System Configuration: %X\r\n", i, conf);
     
-    dw.callbackRX = &Interrupthandler;
+    dw.callbackRX = &callbackRX;        // TODO: must not jump to NULL & setter
+    dw.callbackTX = &callbackTX;
     
     // Receiver initialisation
-    uint8_t dataframereadyinterrupt = 0x40; // only good frame 0x40 all frames 0x20
-    dw.writeRegister(DW1000_SYS_MASK, 1, &dataframereadyinterrupt, 1);
+    dw.writeRegister16(DW1000_SYS_MASK, 0, 0x4080); // RX only good frame 0x4000, RX all frames 0x2000, TX done 0x0080
     dw.startRX();
     
     while(1) {
-#if 1
+#if 0
         if(i < 1200) {
             message[i] = 48+ (i%10);
             message[i+1] = '\0';
         }
         
         //wait(0.1);
-        char messagecheck[1200];
         dw.sendString(message);
-        wait_us(10000);
-        dw.readRegister(DW1000_TX_BUFFER, 0, (uint8_t*)messagecheck, strlen(message)+1);
-        if (i < 200)
-            pc.printf("%d Sent: \"%s\" %d\r\n", i, messagecheck, strlen(message)+1);
-        else
-            pc.printf("%d Sent! %d\r\n", i, strlen(message)+1);
         
 #endif
 #if 0
         pc.printf("%d Waiting...  ", i);
-        uint64_t status;
-        dw.readRegister(DW1000_SYS_STATUS, 0, (uint8_t*)&status, 5);
-        status &= 0xFFFFFFFFFF;                                      // only 40-Bit
-        pc.printf("Status: %010llX\r\n", status);
+        pc.printf("Status: %010llX  ", dw.getStatus());
         wait(5);
 #endif
         i++;