Lindholm Engineers / Mbed 2 deprecated Ultrasonic_Firmware

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TDC1000.cpp Source File

TDC1000.cpp

00001 //TDC1000.cpp
00002 //Class and functions for clearer settings of values
00003 //Created on 8 December 2015 by Eric Lindholm
00004 
00005 #include "mbed.h"
00006 #include "TDC1000.h"
00007 #include "TI_Registers.h"
00008 #include <cstring>
00009 
00010 /** TDC1000 class
00011 *   There are a total of 8 pins to the TDC1000 if you have a separate stopwatch chip.
00012 *   If you use the MCU as a stopwatch chip, which is not recommended, the number 
00013 *    increases to 11.
00014 *   The constructor for this class has 8 pin inputs and initializes a whole bunch
00015 *    of things, including the default values for a few variables.
00016 *   Pin Number on TDC1000           Function
00017 *   11                              Channel Select.  Use any digital out pin for this.
00018 *   12                              Error pin.  Requires an INTERRUPT pin in.
00019 *   15                              Enable pin.  Use any digital out pin for this.
00020 *   17                              Reset pin.  Use any digital out pin for this.
00021 *   18                              SPI serial clock (SCLK) pin.  Tie to an SPI interface.
00022 *   19                              Chip select pin.  Tied to SPI signal, but can be any digital out pin.
00023 *   20                              SPI MOSI serial pin.  Tie to an SPI interface.
00024 *   21                              SPI MISO serial pin.  Tie to an SPI interface.
00025 */
00026 TDC1000::TDC1000(PinName ChSel, PinName ERR, PinName EN, PinName RESET, PinName SCLK, PinName CS, PinName MOSI, PinName MISO):
00027         chsel(ChSel), error(ERR), en(EN), reset(RESET), tdc1000_registers(MOSI, MISO, SCLK, CS) {
00028     error.fall(this,&TDC1000::errorHandler);
00029     set_EN(true);
00030     chsel = 0;
00031     reset = 0;
00032     currentMode = 0;
00033     setClockFrequencyIn(16000000);
00034     txfreqdiv = 8;
00035     txphshiftpos = 31;
00036     timingreg = 0;
00037     numavg = 1;
00038     echoqualthld = -0.125;
00039     //t0 = (2^CLOCKIN_DIV)/fclkin
00040     t0 = 1 / ((double)fclkin);
00041     //t1 = (2^(TX_FREQ_DIV+1))/fclkin
00042     t1 = 8 / ((double)fclkin);
00043     shorttofblankperiod = 64 * t0;
00044     autozeroperiod = 64 * t0;
00045 }
00046 
00047 //readError function
00048 int TDC1000::readError() {
00049     //The address of the error register is 0x07.
00050     int errnum = tdc1000_registers.registerRead8(0x07);
00051     //Next, we clear the error register.
00052     tdc1000_registers.registerWrite(0x07, 0x03);
00053     return errnum;
00054 }
00055 
00056 //determine error
00057 void TDC1000::errorHandler() {
00058     int errnum = readError();
00059     char errorDesc[100];
00060     if(errnum & 0x04) 
00061         strcpy(errorDesc, "\nThe signal was too weak, and timeout has occurred.");
00062     if(errnum & 0x02) 
00063         strcpy(errorDesc, "\nNo signal was received at all and timeout has occurred.");
00064     if(errnum & 0x01) 
00065         strcpy(errorDesc, "\nThe signal was too large and overwhelmed the comparators.");
00066     else 
00067         strcpy(errorDesc, "\nUnknown error occurred.");
00068 }
00069 
00070 /** readToggle function
00071 *   The read a toggle setting function reads a toggle setting for the TDC1000.
00072 *   There are ...a few toggle settings for the TDC1000.
00073 *   NOTICE: a value of true does not always equal enabled...
00074 *   @param choice Choice indicates which setting you want to toggle.
00075 *   
00076 *    Use the name that is in the TI documentation, with capital letters, of that setting.
00077 *    Or, you can refer to this big chart.
00078 *   VCOM_SEL                |   Common-mode voltage reference control (default internal)
00079 *   MEAS_MODE               |   AFE measurement type (default time-of-flight)
00080 *   DAMPING                 |   Transmit burst damping (default disabled)
00081 *   CH_SWP                  |   Turns on or off automatic channel swapping in mode 2 (default disabled)
00082 *   EXT_CHSEL               |   Allows for external channel selection (default disabled)
00083 *   CH_SEL                  |   Selects the active transmit/receive pair (default channel 1)
00084 *   TEMP_MODE               |   Select which temperature measurement channels are used (default Reference, RTD1 and RTD2)
00085 *   TEMP_RTD_SEL            |   Change which type of RTD is currently connected (default PT1000)
00086 *   TEMP_CLK_DIV            |   Modify the clock divider for the temperature mode (default divide by 8)
00087 *   BLANKING                |   Adds power blanking in the standard TOF measurements (default disabled)
00088 *   RECEIVE_MODE            |   Changes receive echo mode (default: single echo)
00089 *   TRIG_EDGE_POLARITY      |   Change what the trigger edge polarity should be (default rising edge)
00090 *   PGA_CTRL                |   Turns on or off the Programmable Gain Amplifier (default active)
00091 *   LNA_CTRL                |   Turns on or off the Low-Noise Amplifier (default active)
00092 *   LNA_FB                  |   Modifies the LNA feedback mode (default capacitive feedback)
00093 *   FORCE_SHORT_TOF         |   Forces the chip to use a short TOF mode even with a large timing register (default disabled)
00094 *   ECHO_TIMEOUT            |   Turns on or off the timeout function, which means the chip will stay in receiving mode until 
00095 *                           |     it receives all of the necessary echoes (default enabled)
00096 *   CLOCKIN_DIV             |   The divisor for generating the standard waiting period (default 1)
00097 */
00098 bool TDC1000::readToggle(SettingChoice choice) {
00099     int registerIn = tdc1000_registers.registerRead8(settingAddress[choice]);
00100     bool stateOfSetting = (bool)(registerIn & settingLookUp[choice]);
00101     return stateOfSetting;
00102 }
00103 
00104 /** setToggle function
00105 *   Used for toggling a toggle setting for the TDC1000 on or off.
00106 */
00107 void TDC1000::setToggle(SettingChoice choice) {
00108     int registerIn = tdc1000_registers.registerRead8(settingAddress[choice]);
00109     int newRegisterSetting = (registerIn ^ settingLookUp[choice]); 
00110     
00111     tdc1000_registers.registerWrite(settingAddress[choice], newRegisterSetting);
00112 }
00113 
00114 //SELECT_MODE
00115 int TDC1000::readMODE_SELECT() {
00116     //The mode of the TDC1000 is the 1 and 0 bits of the config2 register.
00117     int registerInt = tdc1000_registers.registerRead8(0x02);
00118     currentMode = (registerInt & 0x03);
00119     return currentMode;
00120 }
00121 void TDC1000::setMODE_SELECT(int newMode) {
00122     int registerInt = tdc1000_registers.registerRead8(0x02);
00123     int registerPut;
00124     if((newMode < 3) && (newMode >=0)) {
00125         registerPut = (registerInt & 0xFC) + newMode;
00126         currentMode = newMode;
00127     }
00128     else {
00129         registerPut = (registerInt & 0xFC);
00130         currentMode = 0;
00131     }
00132     tdc1000_registers.registerWrite(0x02,registerPut);
00133 }
00134 
00135 //TX_FREQ_DIV
00136 int TDC1000::readTX_FREQ_DIV() {
00137     //transmit frequency = fclkin / (2 ^ (txfreqdiv + 1))
00138     //the TX_FREQ_DIV is the 7, 6, and 5 bits of the config0 register.
00139     int registerInt = tdc1000_registers.registerRead8(0x00);
00140     txfreqdiv = (registerInt & 0xE0)>>4;
00141     return txfreqdiv;
00142 }
00143 void TDC1000::setTX_FREQ_DIV(int divisor) {
00144     //read the config0 register to determine current settings
00145     int registerInt = tdc1000_registers.registerRead8(0x00);
00146     int registerPut;
00147     if((divisor < 8) && (divisor >= 0)) {
00148         registerPut = (divisor<<5) + (registerInt & 0x1F);
00149         txfreqdiv = 2<<divisor;
00150     }
00151     else {
00152         registerPut = (registerInt & 0x1F) + 0x40;
00153         txfreqdiv = 8;
00154     }
00155     tdc1000_registers.registerWrite(0x00, registerPut);
00156 }
00157 
00158 //NUMTX
00159 int TDC1000::readNUM_TX() {
00160     //the NUM_TX is the 4 thru 0 bits of the config0 register.
00161     int registerInt = tdc1000_registers.registerRead8(0x00);
00162     int numtx = (registerInt & 0x1F);
00163     return numtx;
00164 }
00165 void TDC1000::setNUM_TX(int numberOfPulses) {
00166     //the NUM_TX is the 4 thru 0 bits of the config0 register.
00167     int registerInt = tdc1000_registers.registerRead8(0x00);
00168     int registerPut;
00169     if((numberOfPulses < 32) && (numberOfPulses >= 0))
00170         registerPut = (registerInt & 0xE0) + (numberOfPulses);
00171     else
00172         registerPut = (registerInt & 0xE0) + 5;
00173     tdc1000_registers.registerWrite(0x00,registerPut);
00174 }
00175 
00176 //NUM_AVG
00177 int TDC1000::readNUM_AVG() {
00178     //the NUM_AVG is the 5 thru 3 bits of the config1 register.
00179     int registerInt = tdc1000_registers.registerRead8(0x01);
00180     numavg = (registerInt & 0x38)>>2;
00181     return numavg;
00182 }
00183 void TDC1000::setNUM_AVG(int numberToAverage) {
00184     //the NUM_AVG is the 5 thru 3 bits of the config1 register.
00185     int registerInt = tdc1000_registers.registerRead8(0x01);
00186     int registerPut;
00187     if((numberToAverage < 8) && (numberToAverage >= 0))
00188         registerPut = (registerInt & 0x07) + 0x40 + (numberToAverage)<<3;
00189     else
00190         registerPut = (registerInt & 0x07) + 0x40 ;
00191     tdc1000_registers.registerWrite(0x01,registerPut);
00192     numavg = numberToAverage;
00193 }
00194 
00195 //NUMRX
00196 int TDC1000::readNUM_RX() {
00197     //the NUM_RX is the 2 thru 0 bits of the config1 register.
00198     int registerInt = tdc1000_registers.registerRead8(0x01);
00199     int numrx = (registerInt & 0x1F);
00200     return numrx;
00201 }
00202 void TDC1000::setNUM_RX(int numberOfPulses) {
00203     //the NUM_RX is the 2 thru 0 bits of the config1 register.
00204     int registerInt = tdc1000_registers.registerRead8(0x01);
00205     int registerPut;
00206     if((numberOfPulses < 8) && (numberOfPulses >= 0))
00207         registerPut = (registerInt & 0x07) + 0x40 + (numberOfPulses);
00208     else
00209         registerPut = (registerInt & 0x07) + 0x40;
00210     tdc1000_registers.registerWrite(0x01,registerPut);
00211 }
00212 
00213 double echoThresholdArray[] = {-0.035, -0.050, -0.075, -0.125, -0.220, -0.410, -0.775, -1.500};
00214 
00215 //ECHO_QUAL_THLD
00216 int TDC1000::readECHO_QUAL_THLD() {
00217     //the ECHO_QUAL_THLD is the 2 thru 0 bits of the config3 register.
00218     int registerInt = tdc1000_registers.registerRead8(0x03);
00219     int echoqual = (registerInt & 0x07);
00220     
00221     echoqualthld = echoThresholdArray[echoqual];
00222     return echoqual;
00223 }
00224 void TDC1000::setECHO_QUAL_THLD(int tablevalue) {
00225     //the ECHO_QUAL_THLD is the 2 thru 0 bits of the config3 register.
00226     int registerInt = tdc1000_registers.registerRead8(0x03);
00227     int registerPut;
00228     if((tablevalue < 8) && (tablevalue >= 0))
00229         registerPut = (registerInt & 0x78) + (tablevalue);
00230     else
00231         registerPut = (registerInt & 0x78) + 3;
00232     tdc1000_registers.registerWrite(0x03,registerPut);
00233     echoqualthld = echoThresholdArray[tablevalue];
00234 }
00235 
00236 //TX_PH_SHIFT_POS
00237 int TDC1000::readTX_PH_SHIFT_POS() {
00238     //the TX_PH_SHIFT_POS is the 4 thru 0 bits of the config4 register.
00239     int registerInt = tdc1000_registers.registerRead8(0x04);
00240     txphshiftpos = (registerInt & 0x1F);
00241     return txphshiftpos;
00242 }
00243 void TDC1000::setTX_PH_SHIFT_POS(int newphaseshiftposition) {
00244     //the TX_PH_SHIFT_POS is the 4 thru 0 bits of the config4 register.
00245     int registerInt = tdc1000_registers.registerRead8(0x04);
00246     int registerPut;
00247     if((newphaseshiftposition < 32) && (newphaseshiftposition >= 0)) {
00248         registerPut = (registerInt & 0xE0) + (newphaseshiftposition);
00249         txphshiftpos = newphaseshiftposition;
00250     }
00251     else
00252         registerPut = (registerInt & 0xE0) + 31;
00253     tdc1000_registers.registerWrite(0x04,registerPut);
00254 }
00255 
00256 //PGA_GAIN
00257 int TDC1000::readPGA_GAIN() {
00258     //the PGA_GAIN is the 7 thru 5 bits of the TOF1 register.
00259     int registerInt = tdc1000_registers.registerRead8(0x05);
00260     int pgagain = (registerInt & 0xE0)>>5;
00261     return pgagain;
00262 }
00263 void TDC1000::setPGA_GAIN(int gain) {
00264     //the PGA_GAIN is the 7 thru 5 bits of the TOF1 register.
00265     int registerInt = tdc1000_registers.registerRead8(0x05);
00266     int registerPut;
00267     if((gain < 8) && (gain >= 0))
00268         registerPut = (registerInt & 0x1F) + (gain)<<5;
00269     else
00270         registerPut = (registerInt & 0x1F) + 0;
00271     tdc1000_registers.registerWrite(0x05,registerPut);
00272 }
00273 
00274 //TIMING_REG
00275 int TDC1000::readTIMING_REG() {
00276     //The TIMING_REG is the 2 last bits of the TOF1 register AND all of the TOF0 register.
00277     int tof1bits = tdc1000_registers.registerRead8(0x05);
00278     int tof0bits = tdc1000_registers.registerRead8(0x06);
00279     timingreg = ((tof1bits & 0x03)<<8) + (tof0bits);
00280     return timingreg;
00281 }
00282 void TDC1000::setTIMING_REG(int timereg) {
00283     //The TIMING_REG is the 2 last bits of the TOF1 register and all of the TOF0 register.
00284     int tof1bits = tdc1000_registers.registerRead8(0x05);
00285     int tof0bits;
00286     if((timereg > 1024) && (timereg >= 0)) {
00287         tof1bits = (tof1bits & 0xFC) + timereg>>8;
00288         tof0bits = (timereg & 0xFF);
00289         timingreg = timereg;
00290     }
00291     else {
00292         tof1bits = (tof1bits & 0xFC);
00293         tof0bits = 0;
00294         timingreg = 0;
00295     }
00296     tdc1000_registers.registerWrite(0x05,tof1bits);
00297     tdc1000_registers.registerWrite(0x06,tof0bits);
00298 }
00299 
00300 //SHORT_TOF_BLANK_PERIOD
00301 int TDC1000::readSHORT_TOF_BLANK_PERIOD() {
00302     //the SHORT_TOF_BLANK_PERIOD is the 5 thru 3 bits of the timeout register.
00303     int registerInt = tdc1000_registers.registerRead8(0x08);
00304     int shortblank = (registerInt & 0x38)>>3;
00305     shorttofblankperiod = (double)(4<<(shortblank + 1)) * t0;
00306     return shortblank;
00307 }
00308 void TDC1000::setSHORT_TOF_BLANK_PERIOD(int shortblank) {
00309     //the SHORT_TOF_BLANK_PERIOD is the 5 thru 3 bits of the timeout register.
00310     int registerInt = tdc1000_registers.registerRead8(0x08);
00311     int registerPut;
00312     if((shortblank < 8) && (shortblank >= 0))
00313         registerPut = (registerInt & 0x47) + (shortblank)<<3;
00314     else
00315         registerPut = (registerInt & 0x47) + 24;
00316     tdc1000_registers.registerWrite(0x08,registerPut);
00317     shorttofblankperiod = (double)(4<<(shortblank + 1)) * t0;
00318 }
00319 
00320 //TOF_TIMEOUT_CTRL
00321 int TDC1000::readTOF_TIMEOUT_CTRL() {
00322     //the TOF_TIMEOUT_CTRL is the 1 thru 0 bits of the timeout register.
00323     int registerInt = tdc1000_registers.registerRead8(0x08);
00324     int toftimeout = (registerInt & 0x03);
00325     return toftimeout;
00326 }
00327 void TDC1000::setTOF_TIMEOUT_CTRL(int toftimeout) {
00328     //the TOF_TIMEOUT_CTRL is the 1 thru 0 bits of the timeout register.
00329     int registerInt = tdc1000_registers.registerRead8(0x08);
00330     int registerPut;
00331     if((toftimeout < 4) && (toftimeout >= 0))
00332         registerPut = (registerInt & 0x7C) + (toftimeout);
00333     else
00334         registerPut = (registerInt & 0x7C) + 1;
00335     tdc1000_registers.registerWrite(0x08,registerPut);
00336 }
00337 
00338 //AUTOZERO_PERIOD
00339 int TDC1000::readAUTOZERO_PERIOD() {
00340     //the AUTOZERO_PERIOD is the 1 thru 0 bits of the clock rate register.
00341     int registerInt = tdc1000_registers.registerRead8(0x09);
00342     int autozero = (registerInt & 0x03);
00343     autozeroperiod = (double)(64<<autozero) * t0;
00344     return autozero;
00345 }
00346 void TDC1000::setAUTOZERO_PERIOD(int autozero) {
00347     //the AUTOZERO_PERIOD is the 1 thru 0 bits of the clock rate register.
00348     int registerInt = tdc1000_registers.registerRead8(0x09);
00349     int registerPut;
00350     if((autozero < 4) && (autozero >= 0))
00351         registerPut = (registerInt & 0x04) + (autozero);
00352     else
00353         registerPut = (registerInt & 0x04) + 0;
00354     tdc1000_registers.registerWrite(0x09,registerPut);
00355     autozeroperiod = (double)(64<<autozero) * t0;
00356 }
00357 
00358 //Next are functions that mess with non-register pins.
00359 //The Enable pin
00360 bool TDC1000::read_EN() {
00361     return en;
00362 }
00363 void TDC1000::set_EN(bool onOff) {
00364     if(onOff)
00365         en = 1;
00366     else
00367         en = 0;
00368 }
00369 
00370 //The reset pin
00371 void TDC1000::resetTDC1000() {
00372     //Toggle reset pin
00373     reset = 0;
00374     wait_us(10);
00375     reset = 1;
00376     wait_us(10);
00377     reset = 0;
00378     
00379     //Reset variable values
00380     currentMode = 0;
00381     txfreqdiv = 8;
00382     txphshiftpos = 31;
00383     timingreg = 0;
00384     numavg = 1;
00385     echoqualthld = -0.125;
00386     //t0 = (2^CLOCKIN_DIV)/fclkin
00387     t0 = 1 / ((double)fclkin);
00388     //t1 = (2^(TX_FREQ_DIV+1))/fclkin
00389     t1 = (double)txfreqdiv / ((double)fclkin);
00390     shorttofblankperiod = 64 * t0;
00391     autozeroperiod = 64 * t0;
00392 }
00393 
00394 //The channel select pin
00395 bool TDC1000::readChannelSelect() {
00396     return chsel;
00397 }
00398 void TDC1000::toggleChannelSelect() {
00399     if(chsel)
00400         chsel = 0;
00401     else
00402         chsel = 1;
00403 }
00404 
00405 //Functions that read setting values
00406 int TDC1000::readClockFrequencyIn() {
00407     return fclkin;
00408 }
00409 int TDC1000::readTransmitFrequencyDivision() {
00410     return txfreqdiv;
00411 }
00412 double TDC1000::readEchoQualificationThreshold() {
00413     return echoqualthld;
00414 }
00415 int TDC1000::readTransmitPhaseShiftPosition() {
00416     return txphshiftpos;
00417 }
00418 double TDC1000::readPeriod0() {
00419     return t0;
00420 }
00421 double TDC1000::readPeriod1() {
00422     return t1;
00423 }
00424 int TDC1000::readTimingRegister() {
00425     return timingreg;
00426 }
00427 int TDC1000::readNumberofCycles() {
00428     return numavg;
00429 }
00430 double TDC1000::readShortTOFBlankingPeriod() {
00431     return shorttofblankperiod;
00432 }
00433 double TDC1000::readAutoZeroPeriod() {
00434     return autozeroperiod;
00435 }
00436 
00437 //The clock frequency is not really a chip setting, but it affects a lot of things.
00438 void TDC1000::setClockFrequencyIn(int newfreq) {
00439     if(newfreq > 0) 
00440         fclkin = newfreq;
00441     else
00442         fclkin = 8000000;
00443 }