DW1000 UWB driver based on work of Matthias Grob & Manuel Stalder - ETH Zürich - 2015
Diff: DW1000.cpp
- Revision:
- 15:6faab70a5b19
- Parent:
- 14:02f0912e4ce4
- Child:
- 17:1fb08dfef237
--- a/DW1000.cpp Thu Mar 30 11:32:35 2017 +0000 +++ b/DW1000.cpp Wed Nov 08 10:43:03 2017 +0000 @@ -1,7 +1,7 @@ #include "DW1000.h" - +#include "main.h" #define SPIRATE_PLL (10*1000*1000) -#define SPIRATE_OSC (2*1000*1000) +#define SPIRATE_OSC (1*1000*1000) DW1000::DW1000(PinName MOSI, PinName MISO, PinName SCLK, PinName CS, PinName IRQ) : irq(IRQ), spi(MOSI, MISO, SCLK), cs(CS) { @@ -20,6 +20,32 @@ } +void DW1000::setSPISpeed(uint32_t speed) { + spi.frequency(speed); + } + + +void DW1000::enterRFTestMode() { + writeRegister32(DW1000_RF_CONF,0,0x0009A000); + wait_ms(1); + writeRegister16(DW1000_PMSC,DWPMSC_PMSC_CTRL1,0x0000); + wait_ms(1); + writeRegister32(DW1000_TX_POWER,0,0x1f1f1f1f); + wait_ms(1); + uint32_t config = rangingSystem.readRegister32(DW1000_SYS_CFG,0); + config |= 1<<18; + writeRegister32(DW1000_SYS_CFG,0,config); + wait_ms(1); + writeRegister16(DW1000_PMSC,DWPMSC_PMSC_CTRL0,0x0222); + wait_ms(1); + writeRegister32(DW1000_PMSC,DWPMSC_PMSC_TXFSEQ,0x00000000); + wait_ms(1); + writeRegister32(DW1000_RF_CONF,0,0x005fff00); + wait_ms(1); + writeRegister8(DW1000_TX_CAL,DWTXCAL_TC_PGTEST,0x13); +} + + DW1000Setup* DW1000::getSetup() { return &systemConfig; @@ -334,6 +360,15 @@ writeRegister32(DW1000_CHAN_CTRL, 0, registerValue); } +uint8_t DW1000::readXTALTune() { + return readRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_XTALT); + } + +void DW1000::setXTALTune(uint8_t value) { + value &= 0x1f; // mask reserved bits + value |= 0x60; // set reserved bits + writeRegister8 (DW1000_FS_CTRL, DWFSCTRL_FS_XTALT,value); + } uint8_t DW1000::powerToRegValue(float powerdB) { @@ -387,7 +422,7 @@ // transmit power: 0 to 33.5 dB gain in steps of 0.5. Inputs are in 10ths of a dB (0 to 335) void DW1000::setTxPower(float normalPowerdB, float boost500, float boost250, float boost125) { - + if(normalPowerdB > 33.5) normalPowerdB = 33.5; @@ -417,7 +452,7 @@ powerReg |= powerToRegValue(boost250) << 16; powerReg |= powerToRegValue(boost125) << 24; writeRegister32(DW1000_TX_POWER,0,powerReg); - + systemConfig.setSmartTxPower(normalPowerdB,boost500,boost250,boost125); // update the systemConfig } @@ -589,7 +624,7 @@ } void DW1000::getFullQualityMetrics(uint16_t *std_noise, uint16_t *fp_amp1, uint16_t *fp_amp2, uint16_t *fp_amp3, - uint16_t *cir_pwr, uint16_t *preAmbleAcc, uint16_t *preAmbleAcc_NoSat) + uint16_t *cir_pwr, uint16_t *preAmbleAcc, uint16_t *preAmbleAcc_NoSat) { *fp_amp1 = readRegister16(DW1000_RX_TIME,7); *std_noise = readRegister16(DW1000_RX_FQUAL,0); @@ -600,11 +635,12 @@ *preAmbleAcc_NoSat = readRegister16(DW1000_DRX_CONF,DWDRX_RXPAC_NOSAT); } -void DW1000::getFullLEDMetrics(uint16_t *led_thresh, uint16_t *led_ppindx, uint16_t *led_ppampl) { +void DW1000::getFullLEDMetrics(uint16_t *led_thresh, uint16_t *led_ppindx, uint16_t *led_ppampl) +{ *led_thresh = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_THRESH); *led_ppindx = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_PPINDX); - *led_ppampl = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_PPAMPL); - } + *led_ppampl = readRegister16(DW1000_LDE_CTRL,DWLDE_LDE_PPAMPL); +} #define SQR(x) ((float)(x) * (float)(x)) @@ -922,10 +958,12 @@ void DW1000::setInterrupt(bool RX, bool TX) { writeRegister16(DW1000_SYS_MASK, 0, RX*0x4000 | TX*0x0080); // RX good frame 0x4000, TX done 0x0080 +// writeRegister32(DW1000_SYS_MASK, 0, 0x377fff0); // RX good frame 0x4000, TX done 0x0080 } void DW1000::ISR() { +// led1 = !led1; uint64_t status = getStatus(); if (status & 0x4000) { // a frame was received callbackRX.call(); @@ -1044,3 +1082,22 @@ cs = 1; // set Cable Select pin high to stop transmission irq.enable_irq(); // reenable the interrupt handler } + +void DW1000::getRxClockInfo(int32_t *offset, uint8_t* phase, uint8_t* delta) +{ + uint64_t data = readRegister40(DW1000_RX_TTCKO,0); + *phase = (data >> 32)&0x07f; + *delta = data >> 24 & 0x0ff; + int32_t RXTofs = data &0x07ffff; + if (RXTofs & 0x040000) + RXTofs |= 0xfff80000; + *offset = RXTofs; + +// uint32_t RXTTCKI = 0x01FC0000; +// if (getSetup()->getPRF() == DW1000Setup::prf16MHz) +// RXTTCKI = 0x01F00000; + +// double clockOffset = (1000000.0 * RXTofs) / RXTTCKI; +// printf("Clock offset %.4f ppm, re-sample delay %d, phase adjustment %d\n",clockOffset,RSMPDel,RCPhase); + +}