Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 18:bbc7ca7d3a95, committed 2014-11-24
- 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
--- 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*)×tamp, 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++;