Vadim Kimlaychuk / AD5933
Committer:
vadimk
Date:
Fri Aug 20 23:27:15 2021 +0300
Revision:
7:0e8dabae876c
Parent:
6:6b9fc31d51b0
Child:
8:20576c73ba85
fix frequency sweep bugs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dipi 2:93dd1ebfedea 1 /* ---------------------------------------------------------------------------------
dipi 2:93dd1ebfedea 2 Copyright 2015 Marijn Billiet
dipi 2:93dd1ebfedea 3
dipi 2:93dd1ebfedea 4 Licensed under the Apache License, Version 2.0 (the "License");
dipi 2:93dd1ebfedea 5 you may not use this file except in compliance with the License.
dipi 2:93dd1ebfedea 6 You may obtain a copy of the License at
dipi 2:93dd1ebfedea 7
dipi 2:93dd1ebfedea 8 http://www.apache.org/licenses/LICENSE-2.0
dipi 2:93dd1ebfedea 9
dipi 2:93dd1ebfedea 10 Unless required by applicable law or agreed to in writing, software
dipi 2:93dd1ebfedea 11 distributed under the License is distributed on an "AS IS" BASIS,
dipi 2:93dd1ebfedea 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
dipi 2:93dd1ebfedea 13 See the License for the specific language governing permissions and
dipi 2:93dd1ebfedea 14 limitations under the License.
dipi 2:93dd1ebfedea 15 --------------------------------------------------------------------------------- */
dipi 2:93dd1ebfedea 16
dipi 0:6a71184e6f66 17 #include "ad5933.h"
dipi 0:6a71184e6f66 18 #include "mbed.h"
dipi 0:6a71184e6f66 19
dipi 0:6a71184e6f66 20 // Define Command bytes
dipi 0:6a71184e6f66 21 #define INIT_FREQ 0x10 // initialise startfreq
dipi 0:6a71184e6f66 22 #define INIT_SWEEP 0x20 // initialise sweep
dipi 0:6a71184e6f66 23 #define INCR_FREQ 0x30 // increment frequency
dipi 0:6a71184e6f66 24 #define REPE_FREQ 0x40 // repeat frequency
dipi 0:6a71184e6f66 25 #define STANDBY 0xB0 // standby
dipi 6:6b9fc31d51b0 26 #define POWERDOWN 0xA0 // PowerDown modus
dipi 0:6a71184e6f66 27 #define MEAS_TEMP 0x90 // temperature
dipi 0:6a71184e6f66 28
dipi 0:6a71184e6f66 29 #define WRITE_CMD 0x1A // adress + write command
dipi 0:6a71184e6f66 30 #define READ_CMD 0x1B // adress + read command
dipi 0:6a71184e6f66 31
vadimk 7:0e8dabae876c 32 #define CLOCK_FREQ 16000000 // internal clock frequency in Hz
dipi 6:6b9fc31d51b0 33 #define I2C_FREQ 400000
dipi 6:6b9fc31d51b0 34
dipi 6:6b9fc31d51b0 35 #define WAITTIME 1800 // time to wait before polling for response
vadimk 7:0e8dabae876c 36 #define POW_2_27 134217728 // 2 to the power of 27
dipi 0:6a71184e6f66 37
dipi 0:6a71184e6f66 38 AD5933::AD5933(PinName sda, PinName scl, bool extClk) : sCom(sda, scl)
dipi 0:6a71184e6f66 39 {
dipi 6:6b9fc31d51b0 40 sCom.frequency(I2C_FREQ);
dipi 5:2dc8c3f02788 41 PGAandVoltout = 0x00;
dipi 0:6a71184e6f66 42 _extClk = extClk;
dipi 0:6a71184e6f66 43 }
dipi 0:6a71184e6f66 44
dipi 0:6a71184e6f66 45 bool AD5933::gotoAdressPointer(uint8_t Adress)
dipi 0:6a71184e6f66 46 {
dipi 0:6a71184e6f66 47 sCom.start();
dipi 0:6a71184e6f66 48 bool output = (sCom.write(WRITE_CMD) + sCom.write(0xB0) + sCom.write(Adress)) == 3;
dipi 0:6a71184e6f66 49 sCom.stop();
dipi 0:6a71184e6f66 50 return output;
dipi 0:6a71184e6f66 51 }
dipi 0:6a71184e6f66 52
dipi 0:6a71184e6f66 53 bool AD5933::setRegister(uint8_t RegisterAdress, uint8_t RegisterValue)
dipi 0:6a71184e6f66 54 {
dipi 0:6a71184e6f66 55 sCom.start();
dipi 5:2dc8c3f02788 56 bool output = (sCom.write(WRITE_CMD) + sCom.write(RegisterAdress) + sCom.write(RegisterValue)) == 3;
dipi 0:6a71184e6f66 57 sCom.stop();
dipi 0:6a71184e6f66 58 return output;
dipi 0:6a71184e6f66 59 }
dipi 0:6a71184e6f66 60
dipi 0:6a71184e6f66 61 bool AD5933::writeBlock(uint8_t ByteArray[], uint8_t sizeArray)
dipi 0:6a71184e6f66 62 {
dipi 0:6a71184e6f66 63 sCom.start();
dipi 0:6a71184e6f66 64 bool output = (sCom.write(WRITE_CMD) + sCom.write(0xA0) + sCom.write(sizeArray)) == 3;
dipi 0:6a71184e6f66 65 for(uint8_t i = 0; i<sizeArray; i++) {
dipi 0:6a71184e6f66 66 output = sCom.write(ByteArray[i]) == 1 && output;
dipi 0:6a71184e6f66 67 }
dipi 0:6a71184e6f66 68 sCom.stop();
dipi 0:6a71184e6f66 69 return output;
dipi 0:6a71184e6f66 70 }
dipi 0:6a71184e6f66 71
dipi 0:6a71184e6f66 72 uint8_t AD5933::getRegister(uint8_t RegisterAdress)
dipi 0:6a71184e6f66 73 {
dipi 0:6a71184e6f66 74 gotoAdressPointer(RegisterAdress);
dipi 0:6a71184e6f66 75
dipi 0:6a71184e6f66 76 uint8_t output = 0xFF;
dipi 0:6a71184e6f66 77 sCom.start();
dipi 0:6a71184e6f66 78 if(sCom.write(READ_CMD) == 1)
dipi 0:6a71184e6f66 79 output = sCom.read(0);
dipi 0:6a71184e6f66 80 sCom.stop();
dipi 0:6a71184e6f66 81 return output;
dipi 0:6a71184e6f66 82 }
dipi 0:6a71184e6f66 83
dipi 0:6a71184e6f66 84 bool AD5933::readBlock(uint8_t* ByteArray, uint8_t sizeArray)
dipi 0:6a71184e6f66 85 {
dipi 0:6a71184e6f66 86 sCom.start();
dipi 0:6a71184e6f66 87 bool output = (sCom.write(WRITE_CMD) + sCom.write(0xA1) + sCom.write(sizeArray)) == 3;
dipi 0:6a71184e6f66 88 sCom.start();
dipi 0:6a71184e6f66 89 output = output && (sCom.write(READ_CMD) == 1);
dipi 0:6a71184e6f66 90 for(uint8_t i = 0; i<sizeArray-1; i++) {
dipi 0:6a71184e6f66 91 ByteArray[i] = sCom.read(1);
dipi 0:6a71184e6f66 92 }
dipi 0:6a71184e6f66 93 ByteArray[sizeArray-1] = sCom.read(0);
dipi 0:6a71184e6f66 94 sCom.stop();
dipi 0:6a71184e6f66 95 return output;
dipi 0:6a71184e6f66 96 }
dipi 0:6a71184e6f66 97
dipi 0:6a71184e6f66 98 bool AD5933::setControlReg(uint8_t Command)
dipi 0:6a71184e6f66 99 {
dipi 0:6a71184e6f66 100 return setRegister(0x80, PGAandVoltout | Command);
dipi 0:6a71184e6f66 101 }
dipi 0:6a71184e6f66 102
dipi 0:6a71184e6f66 103 bool AD5933::setFrequencySweepParam(unsigned int startFreq, unsigned int stepFreq, unsigned int nrOfSteps)
dipi 0:6a71184e6f66 104 {
vadimk 7:0e8dabae876c 105 unsigned int startFreqCode = (unsigned int)((double) startFreq * 4 / CLOCK_FREQ * POW_2_27);
vadimk 7:0e8dabae876c 106 unsigned int stepFreqCode = (unsigned int)((double) stepFreq * 4 / CLOCK_FREQ * POW_2_27);
dipi 0:6a71184e6f66 107
dipi 5:2dc8c3f02788 108 bool output = setRegister(0x82,(startFreqCode >> 16));
dipi 5:2dc8c3f02788 109 output &= setRegister(0x83,(startFreqCode >> 8));
dipi 5:2dc8c3f02788 110 output &= setRegister(0x84,(startFreqCode));
dipi 5:2dc8c3f02788 111 output &= setRegister(0x85,(stepFreqCode >> 16));
dipi 5:2dc8c3f02788 112 output &= setRegister(0x86,(stepFreqCode >> 8));
dipi 5:2dc8c3f02788 113 output &= setRegister(0x87,(stepFreqCode));
dipi 5:2dc8c3f02788 114 output &= setRegister(0x88,(nrOfSteps >> 8));
dipi 5:2dc8c3f02788 115 output &= setRegister(0x89,nrOfSteps);
dipi 5:2dc8c3f02788 116
dipi 6:6b9fc31d51b0 117 return output;
dipi 6:6b9fc31d51b0 118 }
dipi 6:6b9fc31d51b0 119
dipi 6:6b9fc31d51b0 120 bool AD5933::initFrequencySweepParam(unsigned int startFreq, unsigned int stepFreq, unsigned int nrOfSteps, unsigned int nrOfCycles, bool PGA, int RangeNr)
dipi 6:6b9fc31d51b0 121 {
dipi 6:6b9fc31d51b0 122 bool output = setFrequencySweepParam(startFreq, stepFreq, nrOfSteps);
dipi 6:6b9fc31d51b0 123 output &= setSettlingTime(nrOfCycles);
vadimk 7:0e8dabae876c 124 output &= setAnalogCircuit(PGA, RangeNr);
dipi 6:6b9fc31d51b0 125 output &= standby();
dipi 6:6b9fc31d51b0 126 output &= setControlReg(INIT_FREQ);
vadimk 7:0e8dabae876c 127 wait_us(WAITTIME);
dipi 6:6b9fc31d51b0 128 output &= setControlReg(INIT_SWEEP);
dipi 6:6b9fc31d51b0 129 wait_us(WAITTIME);
dipi 6:6b9fc31d51b0 130
dipi 5:2dc8c3f02788 131 return output;
dipi 0:6a71184e6f66 132 }
dipi 0:6a71184e6f66 133
dipi 0:6a71184e6f66 134 bool AD5933::setSettlingTime(unsigned int nrOfCycles)
dipi 0:6a71184e6f66 135 {
dipi 5:2dc8c3f02788 136 bool output = true;
dipi 6:6b9fc31d51b0 137
dipi 0:6a71184e6f66 138 if (nrOfCycles > 1022) {
dipi 5:2dc8c3f02788 139 output &= setRegister(0x8A,((nrOfCycles/4) >> 8) | 0x06);
dipi 5:2dc8c3f02788 140 output &= setRegister(0x8B,(nrOfCycles/4));
dipi 0:6a71184e6f66 141 } else if(nrOfCycles > 511) {
dipi 5:2dc8c3f02788 142 output &= setRegister(0x8A,((nrOfCycles/4) >> 8) | 0x02);
dipi 5:2dc8c3f02788 143 output &= setRegister(0x8B,(nrOfCycles/2));
dipi 0:6a71184e6f66 144 } else {
dipi 5:2dc8c3f02788 145 output &= setRegister(0x8A,0x00);
dipi 5:2dc8c3f02788 146 output &= setRegister(0x8B,nrOfCycles);
dipi 0:6a71184e6f66 147 }
dipi 5:2dc8c3f02788 148 return output;
dipi 0:6a71184e6f66 149 }
dipi 0:6a71184e6f66 150
dipi 0:6a71184e6f66 151 bool AD5933::setAnalogCircuit(bool PGA, int RangeNr)
dipi 0:6a71184e6f66 152 {
dipi 0:6a71184e6f66 153 if(PGA)
dipi 0:6a71184e6f66 154 PGAandVoltout = 0x01;
dipi 0:6a71184e6f66 155 else
dipi 0:6a71184e6f66 156 PGAandVoltout = 0x00;
dipi 0:6a71184e6f66 157
dipi 0:6a71184e6f66 158 switch(RangeNr) {
dipi 5:2dc8c3f02788 159 case 1:
dipi 5:2dc8c3f02788 160 PGAandVoltout |= 0x00;
vadimk 7:0e8dabae876c 161 break;
dipi 0:6a71184e6f66 162 case 2:
dipi 0:6a71184e6f66 163 PGAandVoltout |= 0x06;
dipi 0:6a71184e6f66 164 break;
dipi 0:6a71184e6f66 165 case 3:
dipi 0:6a71184e6f66 166 PGAandVoltout |= 0x04;
dipi 0:6a71184e6f66 167 break;
dipi 0:6a71184e6f66 168 case 4:
dipi 0:6a71184e6f66 169 PGAandVoltout |= 0x02;
dipi 0:6a71184e6f66 170 break;
dipi 0:6a71184e6f66 171 }
dipi 6:6b9fc31d51b0 172
dipi 6:6b9fc31d51b0 173 uint8_t data = 0x00;
dipi 6:6b9fc31d51b0 174 if(_extClk)
dipi 6:6b9fc31d51b0 175 data |= 0x08;
dipi 6:6b9fc31d51b0 176
dipi 6:6b9fc31d51b0 177 bool output = setRegister(0x81, data);
dipi 6:6b9fc31d51b0 178 output &= setRegister(0x80,PGAandVoltout);
dipi 6:6b9fc31d51b0 179
dipi 6:6b9fc31d51b0 180 return output;
dipi 0:6a71184e6f66 181 }
dipi 0:6a71184e6f66 182
dipi 0:6a71184e6f66 183 bool AD5933::reset()
dipi 0:6a71184e6f66 184 {
dipi 0:6a71184e6f66 185 uint8_t data = 0x10;
dipi 0:6a71184e6f66 186 if(_extClk)
dipi 0:6a71184e6f66 187 data |= 0x08;
dipi 0:6a71184e6f66 188
dipi 0:6a71184e6f66 189 return setRegister(0x81, data);
dipi 0:6a71184e6f66 190 }
dipi 0:6a71184e6f66 191
dipi 4:1ecb56465953 192 bool AD5933::standby()
dipi 4:1ecb56465953 193 {
dipi 4:1ecb56465953 194 return setControlReg(STANDBY);
dipi 6:6b9fc31d51b0 195 }
dipi 4:1ecb56465953 196
dipi 6:6b9fc31d51b0 197 bool AD5933::powerdown()
dipi 6:6b9fc31d51b0 198 {
dipi 6:6b9fc31d51b0 199 return setControlReg(POWERDOWN);
dipi 4:1ecb56465953 200 }
dipi 4:1ecb56465953 201
vadimk 7:0e8dabae876c 202 uint8_t AD5933::Measure(bool increment)
dipi 0:6a71184e6f66 203 {
dipi 6:6b9fc31d51b0 204 if(increment) {
dipi 0:6a71184e6f66 205 setControlReg(INCR_FREQ);
dipi 0:6a71184e6f66 206 return getData();
dipi 0:6a71184e6f66 207 } else {
dipi 0:6a71184e6f66 208 setControlReg(REPE_FREQ);
dipi 0:6a71184e6f66 209 return getData();
dipi 0:6a71184e6f66 210 }
dipi 0:6a71184e6f66 211 }
dipi 0:6a71184e6f66 212
vadimk 7:0e8dabae876c 213 uint8_t AD5933::getData()
dipi 0:6a71184e6f66 214 {
dipi 0:6a71184e6f66 215 uint8_t data[4];
vadimk 7:0e8dabae876c 216 uint8_t status = getRegister(0x8F) & 0x0F;
vadimk 7:0e8dabae876c 217
vadimk 7:0e8dabae876c 218 while ((status & 0x02) == 0) { // pull status register until valid real/img data
vadimk 7:0e8dabae876c 219 status = getRegister(0x8F) & 0x0F;
vadimk 7:0e8dabae876c 220 }
dipi 2:93dd1ebfedea 221
vadimk 7:0e8dabae876c 222 gotoAdressPointer(0x94);
vadimk 7:0e8dabae876c 223 readBlock(data, 4);
dipi 2:93dd1ebfedea 224
dipi 3:b844dd14179c 225 real = data[0] << 8 | data[1];
dipi 3:b844dd14179c 226 imaginary = data[2] << 8 | data[3];
vadimk 7:0e8dabae876c 227 return status;
dipi 0:6a71184e6f66 228 }
dipi 3:b844dd14179c 229
dipi 3:b844dd14179c 230 float AD5933::getTemperature()
dipi 3:b844dd14179c 231 {
dipi 3:b844dd14179c 232 int i = 0;
dipi 3:b844dd14179c 233 uint8_t data[2];
dipi 6:6b9fc31d51b0 234
dipi 4:1ecb56465953 235 setControlReg(MEAS_TEMP);
dipi 6:6b9fc31d51b0 236 wait_us(WAITTIME);
dipi 3:b844dd14179c 237
dipi 5:2dc8c3f02788 238 while(((getRegister(0x8F) & 0x01) != 0x01) && i < 10) {
dipi 6:6b9fc31d51b0 239 wait_us(500);
dipi 3:b844dd14179c 240 i++;
dipi 3:b844dd14179c 241 }
dipi 5:2dc8c3f02788 242 if(i == 10)
dipi 5:2dc8c3f02788 243 return -1;
dipi 3:b844dd14179c 244
dipi 3:b844dd14179c 245 gotoAdressPointer(0x92);
dipi 3:b844dd14179c 246 readBlock(data, 2);
dipi 3:b844dd14179c 247
dipi 3:b844dd14179c 248 if((data[0] >> 6) & 1) {
dipi 3:b844dd14179c 249 //negative temperature
dipi 3:b844dd14179c 250 return (((data[0] << 8 | data[1]) - 16384)/32.0) ;
dipi 3:b844dd14179c 251 } else {
dipi 3:b844dd14179c 252 return ((data[0] << 8 | data[1])/32.0) ;
dipi 3:b844dd14179c 253 }
dipi 3:b844dd14179c 254 }