asdca
Dependencies: mbed
RFD77402.cpp@0:6d03232fcb64, 2018-04-29 (annotated)
- Committer:
- baumamer
- Date:
- Sun Apr 29 12:13:41 2018 +0000
- Revision:
- 0:6d03232fcb64
rfd777402
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
baumamer | 0:6d03232fcb64 | 1 | /* |
baumamer | 0:6d03232fcb64 | 2 | This is a library written for the RFD77402 Time of Flight sensor. |
baumamer | 0:6d03232fcb64 | 3 | SparkFun sells these at its website: www.sparkfun.com |
baumamer | 0:6d03232fcb64 | 4 | Written by Nathan Seidle @ SparkFun Electronics, June 9th, 2017 |
baumamer | 0:6d03232fcb64 | 5 | The VCSEL (vertical-cavity surface-emitting laser) Time of Flight sensor |
baumamer | 0:6d03232fcb64 | 6 | can accurately measure from 10cm to 200cm (2m) with milimeter precision. |
baumamer | 0:6d03232fcb64 | 7 | This library handles the initialization of the RFD77402 and bringing in of |
baumamer | 0:6d03232fcb64 | 8 | various readings. |
baumamer | 0:6d03232fcb64 | 9 | https://github.com/sparkfun/SparkFun_RFD77402_Arduino_Library |
baumamer | 0:6d03232fcb64 | 10 | Do you like this library? Help support SparkFun. Buy a board! |
baumamer | 0:6d03232fcb64 | 11 | Development environment specifics: |
baumamer | 0:6d03232fcb64 | 12 | Arduino IDE 1.8.1 |
baumamer | 0:6d03232fcb64 | 13 | This program is distributed in the hope that it will be useful, |
baumamer | 0:6d03232fcb64 | 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
baumamer | 0:6d03232fcb64 | 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
baumamer | 0:6d03232fcb64 | 16 | GNU General Public License for more details. |
baumamer | 0:6d03232fcb64 | 17 | You should have received a copy of the GNU General Public License |
baumamer | 0:6d03232fcb64 | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
baumamer | 0:6d03232fcb64 | 19 | */ |
baumamer | 0:6d03232fcb64 | 20 | |
baumamer | 0:6d03232fcb64 | 21 | |
baumamer | 0:6d03232fcb64 | 22 | #include "RFD77402.h" |
baumamer | 0:6d03232fcb64 | 23 | |
baumamer | 0:6d03232fcb64 | 24 | // Constructors //////////////////////////////////////////////////////////////// |
baumamer | 0:6d03232fcb64 | 25 | |
baumamer | 0:6d03232fcb64 | 26 | RFD77402::RFD77402(I2C* i2c) |
baumamer | 0:6d03232fcb64 | 27 | { |
baumamer | 0:6d03232fcb64 | 28 | this->i2c = i2c; |
baumamer | 0:6d03232fcb64 | 29 | } |
baumamer | 0:6d03232fcb64 | 30 | |
baumamer | 0:6d03232fcb64 | 31 | /** |
baumamer | 0:6d03232fcb64 | 32 | * Deletes the IRSensor object. |
baumamer | 0:6d03232fcb64 | 33 | */ |
baumamer | 0:6d03232fcb64 | 34 | RFD77402::~RFD77402() {} |
baumamer | 0:6d03232fcb64 | 35 | |
baumamer | 0:6d03232fcb64 | 36 | // Public Methods ////////////////////////////////////////////////////////////// |
baumamer | 0:6d03232fcb64 | 37 | |
baumamer | 0:6d03232fcb64 | 38 | //Sets up the sensor for constant read |
baumamer | 0:6d03232fcb64 | 39 | //Returns false if sensor does not respond |
baumamer | 0:6d03232fcb64 | 40 | bool RFD77402::init() |
baumamer | 0:6d03232fcb64 | 41 | { |
baumamer | 0:6d03232fcb64 | 42 | i2c->frequency(I2C_SPEED_STANDARD); |
baumamer | 0:6d03232fcb64 | 43 | //Bring in the user's choices |
baumamer | 0:6d03232fcb64 | 44 | uint16_t chipID = getChipID(); |
baumamer | 0:6d03232fcb64 | 45 | if (chipID < 0xAD00) return (false); //Chip ID failed. Should be 0xAD01 or 0xAD02 |
baumamer | 0:6d03232fcb64 | 46 | |
baumamer | 0:6d03232fcb64 | 47 | //Put chip into standby |
baumamer | 0:6d03232fcb64 | 48 | if (goToStandbyMode() == false) return (false); //Chip timed out before going to standby |
baumamer | 0:6d03232fcb64 | 49 | |
baumamer | 0:6d03232fcb64 | 50 | //Drive INT_PAD high |
baumamer | 0:6d03232fcb64 | 51 | uint8_t setting = readRegister(RFD77402_ICSR); |
baumamer | 0:6d03232fcb64 | 52 | setting &= 0b11110000; //clears writable bits |
baumamer | 0:6d03232fcb64 | 53 | setting |= INT_CLR_REG | INT_CLR | INT_PIN_TYPE | INT_LOHI; //change bits to enable interrupt |
baumamer | 0:6d03232fcb64 | 54 | writeRegister(RFD77402_ICSR, setting); |
baumamer | 0:6d03232fcb64 | 55 | setting = readRegister(RFD77402_INTERRUPTS); |
baumamer | 0:6d03232fcb64 | 56 | setting &= 0b00000000; //Clears bits |
baumamer | 0:6d03232fcb64 | 57 | setting |= INTSRC_DATA | INTSRC_M2H | INTSRC_H2M | INTSRC_RST; //Enables interrupt when data is ready |
baumamer | 0:6d03232fcb64 | 58 | writeRegister(RFD77402_INTERRUPTS, setting); |
baumamer | 0:6d03232fcb64 | 59 | |
baumamer | 0:6d03232fcb64 | 60 | //Configure I2C Interface |
baumamer | 0:6d03232fcb64 | 61 | writeRegister(RFD77402_CONFIGURE_I2C, 0x65); //0b.0110.0101 = Address increment, auto increment, host debug, MCPU debug |
baumamer | 0:6d03232fcb64 | 62 | |
baumamer | 0:6d03232fcb64 | 63 | //Set initialization - Magic from datasheet. Write 0x05 to 0x15 location. |
baumamer | 0:6d03232fcb64 | 64 | writeRegister16(RFD77402_CONFIGURE_PMU, 0x0500); //0b.0000.0101.0000.0000 //Patch_code_id_en, Patch_mem_en |
baumamer | 0:6d03232fcb64 | 65 | |
baumamer | 0:6d03232fcb64 | 66 | if (goToOffMode() == false) return (false); //MCPU never turned off |
baumamer | 0:6d03232fcb64 | 67 | |
baumamer | 0:6d03232fcb64 | 68 | //Read Module ID |
baumamer | 0:6d03232fcb64 | 69 | //Skipped |
baumamer | 0:6d03232fcb64 | 70 | |
baumamer | 0:6d03232fcb64 | 71 | //Read Firmware ID |
baumamer | 0:6d03232fcb64 | 72 | //Skipped |
baumamer | 0:6d03232fcb64 | 73 | |
baumamer | 0:6d03232fcb64 | 74 | //Set initialization - Magic from datasheet. Write 0x06 to 0x15 location. |
baumamer | 0:6d03232fcb64 | 75 | writeRegister16(RFD77402_CONFIGURE_PMU, 0x0600); //MCPU_Init_state, Patch_mem_en |
baumamer | 0:6d03232fcb64 | 76 | |
baumamer | 0:6d03232fcb64 | 77 | if (goToOnMode() == false) return (false); //MCPU never turned on |
baumamer | 0:6d03232fcb64 | 78 | |
baumamer | 0:6d03232fcb64 | 79 | //ToF Configuration |
baumamer | 0:6d03232fcb64 | 80 | //writeRegister16(RFD77402_CONFIGURE_A, 0xE100); //0b.1110.0001 = Peak is 0x0E, Threshold is 1. |
baumamer | 0:6d03232fcb64 | 81 | setPeak(0x0E); //Suggested values from page 20 |
baumamer | 0:6d03232fcb64 | 82 | setThreshold(0x01); |
baumamer | 0:6d03232fcb64 | 83 | |
baumamer | 0:6d03232fcb64 | 84 | writeRegister16(RFD77402_CONFIGURE_B, 0x10FF); //Set valid pixel. Set MSP430 default config. |
baumamer | 0:6d03232fcb64 | 85 | writeRegister16(RFD77402_CONFIGURE_HW_0, 0x07D0); //Set saturation threshold = 2,000. |
baumamer | 0:6d03232fcb64 | 86 | writeRegister16(RFD77402_CONFIGURE_HW_1, 0x5008); //Frequecy = 5. Low level threshold = 8. |
baumamer | 0:6d03232fcb64 | 87 | writeRegister16(RFD77402_CONFIGURE_HW_2, 0xA041); //Integration time = 10 * (6500-20)/15)+20 = 4.340ms. Plus reserved magic. |
baumamer | 0:6d03232fcb64 | 88 | writeRegister16(RFD77402_CONFIGURE_HW_3, 0x45D4); //Enable harmonic cancellation. Enable auto adjust of integration time. Plus reserved magic. |
baumamer | 0:6d03232fcb64 | 89 | |
baumamer | 0:6d03232fcb64 | 90 | if (goToStandbyMode() == false) return (false); //Error - MCPU never went to standby |
baumamer | 0:6d03232fcb64 | 91 | |
baumamer | 0:6d03232fcb64 | 92 | //Whew! We made it through power on configuration |
baumamer | 0:6d03232fcb64 | 93 | |
baumamer | 0:6d03232fcb64 | 94 | //Get the calibration data via the 0x0006 mailbox command |
baumamer | 0:6d03232fcb64 | 95 | //getCalibrationData(); //Skipped |
baumamer | 0:6d03232fcb64 | 96 | |
baumamer | 0:6d03232fcb64 | 97 | //Put device into Standby mode |
baumamer | 0:6d03232fcb64 | 98 | if (goToStandbyMode() == false) return (false); //Error - MCPU never went to standby |
baumamer | 0:6d03232fcb64 | 99 | |
baumamer | 0:6d03232fcb64 | 100 | //Now assume user will want sensor in measurement mode |
baumamer | 0:6d03232fcb64 | 101 | |
baumamer | 0:6d03232fcb64 | 102 | //Set initialization - Magic from datasheet. Write 0x05 to 0x15 location. |
baumamer | 0:6d03232fcb64 | 103 | writeRegister16(RFD77402_CONFIGURE_PMU, 0x0500); //Patch_code_id_en, Patch_mem_en |
baumamer | 0:6d03232fcb64 | 104 | |
baumamer | 0:6d03232fcb64 | 105 | if (goToOffMode() == false) return (false); //Error - MCPU never turned off |
baumamer | 0:6d03232fcb64 | 106 | |
baumamer | 0:6d03232fcb64 | 107 | //Write calibration data |
baumamer | 0:6d03232fcb64 | 108 | //Skipped |
baumamer | 0:6d03232fcb64 | 109 | |
baumamer | 0:6d03232fcb64 | 110 | //Set initialization - Magic from datasheet. Write 0x06 to 0x15 location. |
baumamer | 0:6d03232fcb64 | 111 | writeRegister16(RFD77402_CONFIGURE_PMU, 0x0600); //MCPU_Init_state, Patch_mem_en |
baumamer | 0:6d03232fcb64 | 112 | |
baumamer | 0:6d03232fcb64 | 113 | if (goToOnMode() == false) return (false); //Error - MCPU never turned on |
baumamer | 0:6d03232fcb64 | 114 | |
baumamer | 0:6d03232fcb64 | 115 | return (true); //Success! Sensor is ready for measurements |
baumamer | 0:6d03232fcb64 | 116 | } |
baumamer | 0:6d03232fcb64 | 117 | |
baumamer | 0:6d03232fcb64 | 118 | //Takes a single measurement and sets the global variables with new data |
baumamer | 0:6d03232fcb64 | 119 | //Returns zero if reading is good, otherwise return the errorCode from the result register. |
baumamer | 0:6d03232fcb64 | 120 | uint8_t RFD77402::takeMeasurement(void) |
baumamer | 0:6d03232fcb64 | 121 | { |
baumamer | 0:6d03232fcb64 | 122 | if (goToMeasurementMode() == false) return (CODE_FAILED_TIMEOUT); //Error - Timeout |
baumamer | 0:6d03232fcb64 | 123 | //New data is now available! |
baumamer | 0:6d03232fcb64 | 124 | |
baumamer | 0:6d03232fcb64 | 125 | //Read result |
baumamer | 0:6d03232fcb64 | 126 | uint16_t resultRegister = readRegister16(RFD77402_RESULT); |
baumamer | 0:6d03232fcb64 | 127 | |
baumamer | 0:6d03232fcb64 | 128 | if (resultRegister & 0x7FFF) { //Reading is valid |
baumamer | 0:6d03232fcb64 | 129 | uint8_t errorCode = (resultRegister >> 13) & 0x03; |
baumamer | 0:6d03232fcb64 | 130 | |
baumamer | 0:6d03232fcb64 | 131 | if (errorCode == 0) { |
baumamer | 0:6d03232fcb64 | 132 | distance = (resultRegister >> 2) & 0x07FF; //Distance is good. Read it. |
baumamer | 0:6d03232fcb64 | 133 | |
baumamer | 0:6d03232fcb64 | 134 | //Read confidence register |
baumamer | 0:6d03232fcb64 | 135 | uint16_t confidenceRegister = readRegister16(RFD77402_RESULT_CONFIDENCE); |
baumamer | 0:6d03232fcb64 | 136 | validPixels = confidenceRegister & 0x0F; |
baumamer | 0:6d03232fcb64 | 137 | confidenceValue = (confidenceRegister >> 4) & 0x07FF; |
baumamer | 0:6d03232fcb64 | 138 | } |
baumamer | 0:6d03232fcb64 | 139 | |
baumamer | 0:6d03232fcb64 | 140 | return (errorCode); |
baumamer | 0:6d03232fcb64 | 141 | |
baumamer | 0:6d03232fcb64 | 142 | } else { |
baumamer | 0:6d03232fcb64 | 143 | //Reading is not vald |
baumamer | 0:6d03232fcb64 | 144 | return (CODE_FAILED_NOT_NEW); //Error code for reading is not new |
baumamer | 0:6d03232fcb64 | 145 | } |
baumamer | 0:6d03232fcb64 | 146 | |
baumamer | 0:6d03232fcb64 | 147 | } |
baumamer | 0:6d03232fcb64 | 148 | |
baumamer | 0:6d03232fcb64 | 149 | //Returns the local variable to the caller |
baumamer | 0:6d03232fcb64 | 150 | uint16_t RFD77402::getDistance() |
baumamer | 0:6d03232fcb64 | 151 | { |
baumamer | 0:6d03232fcb64 | 152 | return (distance); |
baumamer | 0:6d03232fcb64 | 153 | } |
baumamer | 0:6d03232fcb64 | 154 | |
baumamer | 0:6d03232fcb64 | 155 | //Returns the number of valid pixels found when taking measurement |
baumamer | 0:6d03232fcb64 | 156 | uint8_t RFD77402::getValidPixels() |
baumamer | 0:6d03232fcb64 | 157 | { |
baumamer | 0:6d03232fcb64 | 158 | return (validPixels); |
baumamer | 0:6d03232fcb64 | 159 | } |
baumamer | 0:6d03232fcb64 | 160 | |
baumamer | 0:6d03232fcb64 | 161 | //Returns the qualitative value representing how confident the sensor is about its reported distance |
baumamer | 0:6d03232fcb64 | 162 | uint16_t RFD77402::getConfidenceValue() |
baumamer | 0:6d03232fcb64 | 163 | { |
baumamer | 0:6d03232fcb64 | 164 | return (confidenceValue); |
baumamer | 0:6d03232fcb64 | 165 | } |
baumamer | 0:6d03232fcb64 | 166 | |
baumamer | 0:6d03232fcb64 | 167 | //Read the command opcode and covert to mode |
baumamer | 0:6d03232fcb64 | 168 | uint8_t RFD77402::getMode() |
baumamer | 0:6d03232fcb64 | 169 | { |
baumamer | 0:6d03232fcb64 | 170 | return (readRegister(RFD77402_COMMAND) & 0x3F); |
baumamer | 0:6d03232fcb64 | 171 | } |
baumamer | 0:6d03232fcb64 | 172 | |
baumamer | 0:6d03232fcb64 | 173 | //Tell MCPU to go to standby mode |
baumamer | 0:6d03232fcb64 | 174 | //Return true if successful |
baumamer | 0:6d03232fcb64 | 175 | bool RFD77402::goToStandbyMode() |
baumamer | 0:6d03232fcb64 | 176 | { |
baumamer | 0:6d03232fcb64 | 177 | //Set Low Power Standby |
baumamer | 0:6d03232fcb64 | 178 | writeRegister(RFD77402_COMMAND, 0x90); //0b.1001.0000 = Go to standby mode. Set valid command. |
baumamer | 0:6d03232fcb64 | 179 | |
baumamer | 0:6d03232fcb64 | 180 | uint8_t commandReg = readRegister(RFD77402_COMMAND); |
baumamer | 0:6d03232fcb64 | 181 | |
baumamer | 0:6d03232fcb64 | 182 | |
baumamer | 0:6d03232fcb64 | 183 | //Check MCPU_ON Status |
baumamer | 0:6d03232fcb64 | 184 | for (uint8_t x = 0 ; x < 10 ; x++) { |
baumamer | 0:6d03232fcb64 | 185 | uint16_t status = readRegister16(RFD77402_DEVICE_STATUS); |
baumamer | 0:6d03232fcb64 | 186 | if ( (status & 0x001F) == 0x0000) { |
baumamer | 0:6d03232fcb64 | 187 | return (true); //MCPU is now in standby |
baumamer | 0:6d03232fcb64 | 188 | } |
baumamer | 0:6d03232fcb64 | 189 | printf("readRegister16 device status fail %d \n\r", status); |
baumamer | 0:6d03232fcb64 | 190 | wait(0.01); //Suggested timeout for status checks from datasheet |
baumamer | 0:6d03232fcb64 | 191 | } |
baumamer | 0:6d03232fcb64 | 192 | |
baumamer | 0:6d03232fcb64 | 193 | return (false); //Error - MCPU never went to standby |
baumamer | 0:6d03232fcb64 | 194 | } |
baumamer | 0:6d03232fcb64 | 195 | |
baumamer | 0:6d03232fcb64 | 196 | //Tell MCPU to go to off state |
baumamer | 0:6d03232fcb64 | 197 | //Return true if successful |
baumamer | 0:6d03232fcb64 | 198 | bool RFD77402::goToOffMode() |
baumamer | 0:6d03232fcb64 | 199 | { |
baumamer | 0:6d03232fcb64 | 200 | //Set MCPU_OFF |
baumamer | 0:6d03232fcb64 | 201 | writeRegister(RFD77402_COMMAND, 0x91); //0b.1001.0001 = Go MCPU off state. Set valid command. |
baumamer | 0:6d03232fcb64 | 202 | |
baumamer | 0:6d03232fcb64 | 203 | //Check MCPU_OFF Status |
baumamer | 0:6d03232fcb64 | 204 | for (uint8_t x = 0 ; x < 10 ; x++) { |
baumamer | 0:6d03232fcb64 | 205 | if ( (readRegister16(RFD77402_DEVICE_STATUS) & 0x001F) == 0x0010) return (true); //MCPU is now off |
baumamer | 0:6d03232fcb64 | 206 | wait(0.01); //Suggested timeout for status checks from datasheet |
baumamer | 0:6d03232fcb64 | 207 | } |
baumamer | 0:6d03232fcb64 | 208 | |
baumamer | 0:6d03232fcb64 | 209 | return (false); //Error - MCPU never turned off |
baumamer | 0:6d03232fcb64 | 210 | } |
baumamer | 0:6d03232fcb64 | 211 | |
baumamer | 0:6d03232fcb64 | 212 | //Tell MCPU to go to on state |
baumamer | 0:6d03232fcb64 | 213 | //Return true if successful |
baumamer | 0:6d03232fcb64 | 214 | bool RFD77402::goToOnMode() |
baumamer | 0:6d03232fcb64 | 215 | { |
baumamer | 0:6d03232fcb64 | 216 | //Set MCPU_ON |
baumamer | 0:6d03232fcb64 | 217 | writeRegister(RFD77402_COMMAND, 0x92); //0b.1001.0010 = Wake up MCPU to ON mode. Set valid command. |
baumamer | 0:6d03232fcb64 | 218 | |
baumamer | 0:6d03232fcb64 | 219 | //Check MCPU_ON Status |
baumamer | 0:6d03232fcb64 | 220 | for (uint8_t x = 0 ; x < 10 ; x++) { |
baumamer | 0:6d03232fcb64 | 221 | if ( (readRegister16(RFD77402_DEVICE_STATUS) & 0x001F) == 0x0018) return (true); //MCPU is now on |
baumamer | 0:6d03232fcb64 | 222 | wait(0.01); //Suggested timeout for status checks from datasheet |
baumamer | 0:6d03232fcb64 | 223 | } |
baumamer | 0:6d03232fcb64 | 224 | |
baumamer | 0:6d03232fcb64 | 225 | return (false); //Error - MCPU never turned on |
baumamer | 0:6d03232fcb64 | 226 | } |
baumamer | 0:6d03232fcb64 | 227 | |
baumamer | 0:6d03232fcb64 | 228 | //Tell MCPU to go to measurement mode |
baumamer | 0:6d03232fcb64 | 229 | //Takes a measurement. If measurement data is ready, return true |
baumamer | 0:6d03232fcb64 | 230 | bool RFD77402::goToMeasurementMode() |
baumamer | 0:6d03232fcb64 | 231 | { |
baumamer | 0:6d03232fcb64 | 232 | //Single measure command |
baumamer | 0:6d03232fcb64 | 233 | writeRegister(RFD77402_COMMAND, 0x81); //0b.1000.0001 = Single measurement. Set valid command. |
baumamer | 0:6d03232fcb64 | 234 | |
baumamer | 0:6d03232fcb64 | 235 | //Read ICSR Register - Check to see if measurement data is ready |
baumamer | 0:6d03232fcb64 | 236 | for (uint8_t x = 0 ; x < 10 ; x++) { |
baumamer | 0:6d03232fcb64 | 237 | if ( (readRegister(RFD77402_ICSR) & (1 << 4)) != 0) return (true); //Data is ready! |
baumamer | 0:6d03232fcb64 | 238 | wait(0.01); //Suggested timeout for status checks from datasheet |
baumamer | 0:6d03232fcb64 | 239 | } |
baumamer | 0:6d03232fcb64 | 240 | |
baumamer | 0:6d03232fcb64 | 241 | return (false); //Error - Timeout |
baumamer | 0:6d03232fcb64 | 242 | } |
baumamer | 0:6d03232fcb64 | 243 | |
baumamer | 0:6d03232fcb64 | 244 | //Returns the VCSEL peak 4-bit value |
baumamer | 0:6d03232fcb64 | 245 | uint8_t RFD77402::getPeak(void) |
baumamer | 0:6d03232fcb64 | 246 | { |
baumamer | 0:6d03232fcb64 | 247 | uint16_t configValue = readRegister16(RFD77402_CONFIGURE_A); |
baumamer | 0:6d03232fcb64 | 248 | return ((configValue >> 12) & 0x0F); |
baumamer | 0:6d03232fcb64 | 249 | } |
baumamer | 0:6d03232fcb64 | 250 | |
baumamer | 0:6d03232fcb64 | 251 | //Sets the VCSEL peak 4-bit value |
baumamer | 0:6d03232fcb64 | 252 | void RFD77402::setPeak(uint8_t peakValue) |
baumamer | 0:6d03232fcb64 | 253 | { |
baumamer | 0:6d03232fcb64 | 254 | uint16_t configValue = readRegister16(RFD77402_CONFIGURE_A); //Read |
baumamer | 0:6d03232fcb64 | 255 | configValue &= ~0xF000;// Zero out the peak configuration bits |
baumamer | 0:6d03232fcb64 | 256 | configValue |= (uint16_t)peakValue << 12; //Mask in user's settings |
baumamer | 0:6d03232fcb64 | 257 | writeRegister16(RFD77402_CONFIGURE_A, configValue); //Write in this new value |
baumamer | 0:6d03232fcb64 | 258 | } |
baumamer | 0:6d03232fcb64 | 259 | |
baumamer | 0:6d03232fcb64 | 260 | //Returns the VCSEL Threshold 4-bit value |
baumamer | 0:6d03232fcb64 | 261 | uint8_t RFD77402::getThreshold(void) |
baumamer | 0:6d03232fcb64 | 262 | { |
baumamer | 0:6d03232fcb64 | 263 | uint16_t configValue = readRegister16(RFD77402_CONFIGURE_A); |
baumamer | 0:6d03232fcb64 | 264 | return ((configValue >> 8) & 0x0F); |
baumamer | 0:6d03232fcb64 | 265 | } |
baumamer | 0:6d03232fcb64 | 266 | |
baumamer | 0:6d03232fcb64 | 267 | //Sets the VCSEL Threshold 4-bit value |
baumamer | 0:6d03232fcb64 | 268 | void RFD77402::setThreshold(uint8_t thresholdValue) |
baumamer | 0:6d03232fcb64 | 269 | { |
baumamer | 0:6d03232fcb64 | 270 | uint16_t configValue = readRegister16(RFD77402_CONFIGURE_A); //Read |
baumamer | 0:6d03232fcb64 | 271 | configValue &= ~0x0F00;// Zero out the threshold configuration bits |
baumamer | 0:6d03232fcb64 | 272 | configValue |= thresholdValue << 8; //Mask in user's settings |
baumamer | 0:6d03232fcb64 | 273 | writeRegister16(RFD77402_CONFIGURE_A, configValue); //Write in this new value |
baumamer | 0:6d03232fcb64 | 274 | } |
baumamer | 0:6d03232fcb64 | 275 | |
baumamer | 0:6d03232fcb64 | 276 | //Returns the VCSEL Frequency 4-bit value |
baumamer | 0:6d03232fcb64 | 277 | uint8_t RFD77402::getFrequency(void) |
baumamer | 0:6d03232fcb64 | 278 | { |
baumamer | 0:6d03232fcb64 | 279 | uint16_t configValue = readRegister16(RFD77402_CONFIGURE_HW_1); |
baumamer | 0:6d03232fcb64 | 280 | return ((configValue >> 12) & 0x0F); |
baumamer | 0:6d03232fcb64 | 281 | } |
baumamer | 0:6d03232fcb64 | 282 | |
baumamer | 0:6d03232fcb64 | 283 | //Sets the VCSEL Frequency 4-bit value |
baumamer | 0:6d03232fcb64 | 284 | void RFD77402::setFrequency(uint8_t thresholdValue) |
baumamer | 0:6d03232fcb64 | 285 | { |
baumamer | 0:6d03232fcb64 | 286 | uint16_t configValue = readRegister16(RFD77402_CONFIGURE_HW_1); //Read |
baumamer | 0:6d03232fcb64 | 287 | configValue &= ~0xF000;// Zero out the threshold configuration bits |
baumamer | 0:6d03232fcb64 | 288 | configValue |= thresholdValue << 12; //Mask in user's settings |
baumamer | 0:6d03232fcb64 | 289 | writeRegister16(RFD77402_CONFIGURE_HW_1, configValue); //Write in this new value |
baumamer | 0:6d03232fcb64 | 290 | } |
baumamer | 0:6d03232fcb64 | 291 | |
baumamer | 0:6d03232fcb64 | 292 | //Gets whatever is in the 'MCPU to Host' mailbox |
baumamer | 0:6d03232fcb64 | 293 | //Check ICSR bit 5 before reading |
baumamer | 0:6d03232fcb64 | 294 | uint16_t RFD77402::getMailbox(void) |
baumamer | 0:6d03232fcb64 | 295 | { |
baumamer | 0:6d03232fcb64 | 296 | return (readRegister16(RFD77402_MCPU_TO_HOST_MAILBOX)); |
baumamer | 0:6d03232fcb64 | 297 | } |
baumamer | 0:6d03232fcb64 | 298 | |
baumamer | 0:6d03232fcb64 | 299 | //Software reset the device |
baumamer | 0:6d03232fcb64 | 300 | void RFD77402::reset(void) |
baumamer | 0:6d03232fcb64 | 301 | { |
baumamer | 0:6d03232fcb64 | 302 | writeRegister(RFD77402_COMMAND, 1<<6); |
baumamer | 0:6d03232fcb64 | 303 | wait(100); |
baumamer | 0:6d03232fcb64 | 304 | } |
baumamer | 0:6d03232fcb64 | 305 | |
baumamer | 0:6d03232fcb64 | 306 | //Returns the chip ID |
baumamer | 0:6d03232fcb64 | 307 | //Should be 0xAD01 or higher |
baumamer | 0:6d03232fcb64 | 308 | uint16_t RFD77402::getChipID() |
baumamer | 0:6d03232fcb64 | 309 | { |
baumamer | 0:6d03232fcb64 | 310 | return(readRegister16(RFD77402_MOD_CHIP_ID)); |
baumamer | 0:6d03232fcb64 | 311 | } |
baumamer | 0:6d03232fcb64 | 312 | |
baumamer | 0:6d03232fcb64 | 313 | //Retreive 2*27 bytes from MCPU for computation of calibration parameters |
baumamer | 0:6d03232fcb64 | 314 | //This is 9.2.2 from datasheet |
baumamer | 0:6d03232fcb64 | 315 | //Reads 54 bytes into the calibration[] array |
baumamer | 0:6d03232fcb64 | 316 | //Returns true if new cal data is loaded |
baumamer | 0:6d03232fcb64 | 317 | bool RFD77402::getCalibrationData(void) |
baumamer | 0:6d03232fcb64 | 318 | { |
baumamer | 0:6d03232fcb64 | 319 | if (goToOnMode() == false) return (false); //Error - sensor timed out before getting to On Mode |
baumamer | 0:6d03232fcb64 | 320 | |
baumamer | 0:6d03232fcb64 | 321 | //Check ICSR Register and read Mailbox until it is empty |
baumamer | 0:6d03232fcb64 | 322 | uint8_t messages = 0; |
baumamer | 0:6d03232fcb64 | 323 | while (1) { |
baumamer | 0:6d03232fcb64 | 324 | if ( (readRegister(RFD77402_ICSR) & (1 << 5)) == 0) break; //Mailbox interrupt is cleared |
baumamer | 0:6d03232fcb64 | 325 | |
baumamer | 0:6d03232fcb64 | 326 | //Mailbox interrupt (Bit 5) is set so read the M2H mailbox register |
baumamer | 0:6d03232fcb64 | 327 | getMailbox(); //Throw it out. Just read to clear the register. |
baumamer | 0:6d03232fcb64 | 328 | |
baumamer | 0:6d03232fcb64 | 329 | if (messages++ > 27) return (false); //Error - Too many messages |
baumamer | 0:6d03232fcb64 | 330 | |
baumamer | 0:6d03232fcb64 | 331 | wait(10); //Suggested timeout for status checks from datasheet |
baumamer | 0:6d03232fcb64 | 332 | } |
baumamer | 0:6d03232fcb64 | 333 | |
baumamer | 0:6d03232fcb64 | 334 | //Issue mailbox command |
baumamer | 0:6d03232fcb64 | 335 | writeRegister16(RFD77402_HOST_TO_MCPU_MAILBOX, 0x0006); //Send 0x0006 mailbox command |
baumamer | 0:6d03232fcb64 | 336 | |
baumamer | 0:6d03232fcb64 | 337 | //Check to see if Mailbox can be read |
baumamer | 0:6d03232fcb64 | 338 | //Read 54 bytes of payload into the calibration[54] array |
baumamer | 0:6d03232fcb64 | 339 | for (uint8_t message = 0 ; message < 27 ; message++) { |
baumamer | 0:6d03232fcb64 | 340 | //Wait for bit to be set |
baumamer | 0:6d03232fcb64 | 341 | uint8_t x = 0; |
baumamer | 0:6d03232fcb64 | 342 | while (1) { |
baumamer | 0:6d03232fcb64 | 343 | uint8_t icsr = readRegister(RFD77402_ICSR); |
baumamer | 0:6d03232fcb64 | 344 | if ( (icsr & (1 << 5)) != 0) break; //New message in available |
baumamer | 0:6d03232fcb64 | 345 | |
baumamer | 0:6d03232fcb64 | 346 | if (x++ > 10) return (false); //Error - Timeout |
baumamer | 0:6d03232fcb64 | 347 | |
baumamer | 0:6d03232fcb64 | 348 | wait(10); //Suggested timeout for status checks from datasheet |
baumamer | 0:6d03232fcb64 | 349 | } |
baumamer | 0:6d03232fcb64 | 350 | |
baumamer | 0:6d03232fcb64 | 351 | uint16_t incoming = getMailbox(); //Get 16-bit message |
baumamer | 0:6d03232fcb64 | 352 | |
baumamer | 0:6d03232fcb64 | 353 | //Put message into larger calibrationData array |
baumamer | 0:6d03232fcb64 | 354 | calibrationData[message * 2] = incoming >> 8; |
baumamer | 0:6d03232fcb64 | 355 | calibrationData[message * 2 + 1] = incoming & 0xFF; |
baumamer | 0:6d03232fcb64 | 356 | } |
baumamer | 0:6d03232fcb64 | 357 | |
baumamer | 0:6d03232fcb64 | 358 | return(false); |
baumamer | 0:6d03232fcb64 | 359 | } |
baumamer | 0:6d03232fcb64 | 360 | |
baumamer | 0:6d03232fcb64 | 361 | //Reads two bytes from a given location from the RFD77402 |
baumamer | 0:6d03232fcb64 | 362 | uint16_t RFD77402::readRegister16(uint8_t reg) |
baumamer | 0:6d03232fcb64 | 363 | { |
baumamer | 0:6d03232fcb64 | 364 | uint8_t value[2]; |
baumamer | 0:6d03232fcb64 | 365 | uint16_t val; |
baumamer | 0:6d03232fcb64 | 366 | |
baumamer | 0:6d03232fcb64 | 367 | if (i2c->write(RFD77402_ADDR, (char*)®, 1)) { |
baumamer | 0:6d03232fcb64 | 368 | printf("readReg: write fail \n\r"); |
baumamer | 0:6d03232fcb64 | 369 | return 0x0000; //Error |
baumamer | 0:6d03232fcb64 | 370 | } |
baumamer | 0:6d03232fcb64 | 371 | |
baumamer | 0:6d03232fcb64 | 372 | if (i2c->read(RFD77402_ADDR, (char*)value, 2)) { |
baumamer | 0:6d03232fcb64 | 373 | printf("readReg: read fail \n\r"); |
baumamer | 0:6d03232fcb64 | 374 | return 0x0000; //Error |
baumamer | 0:6d03232fcb64 | 375 | } |
baumamer | 0:6d03232fcb64 | 376 | |
baumamer | 0:6d03232fcb64 | 377 | val = (value[1] << 8) | value[0]; |
baumamer | 0:6d03232fcb64 | 378 | return (val); |
baumamer | 0:6d03232fcb64 | 379 | } |
baumamer | 0:6d03232fcb64 | 380 | |
baumamer | 0:6d03232fcb64 | 381 | //Reads from a given location from the RFD77402 |
baumamer | 0:6d03232fcb64 | 382 | uint8_t RFD77402::readRegister(uint8_t reg) |
baumamer | 0:6d03232fcb64 | 383 | { |
baumamer | 0:6d03232fcb64 | 384 | uint8_t value; |
baumamer | 0:6d03232fcb64 | 385 | |
baumamer | 0:6d03232fcb64 | 386 | if (i2c->write(RFD77402_ADDR, (char*)®, 1)) { |
baumamer | 0:6d03232fcb64 | 387 | printf("readReg: write fail \n\r"); |
baumamer | 0:6d03232fcb64 | 388 | return 0xFF; //Error |
baumamer | 0:6d03232fcb64 | 389 | } |
baumamer | 0:6d03232fcb64 | 390 | |
baumamer | 0:6d03232fcb64 | 391 | if (i2c->read(RFD77402_ADDR, (char*)value, 1)) { |
baumamer | 0:6d03232fcb64 | 392 | printf("readReg: read fail \n\r"); |
baumamer | 0:6d03232fcb64 | 393 | return 0xFF; //Error |
baumamer | 0:6d03232fcb64 | 394 | } |
baumamer | 0:6d03232fcb64 | 395 | |
baumamer | 0:6d03232fcb64 | 396 | return (value); |
baumamer | 0:6d03232fcb64 | 397 | } |
baumamer | 0:6d03232fcb64 | 398 | |
baumamer | 0:6d03232fcb64 | 399 | //Write a 16 bit value to a spot in the RFD77402 |
baumamer | 0:6d03232fcb64 | 400 | void RFD77402::writeRegister16(uint8_t reg, uint16_t value) |
baumamer | 0:6d03232fcb64 | 401 | { |
baumamer | 0:6d03232fcb64 | 402 | char data[] = { |
baumamer | 0:6d03232fcb64 | 403 | reg, |
baumamer | 0:6d03232fcb64 | 404 | (char)(value & 0xFF), // value low byte |
baumamer | 0:6d03232fcb64 | 405 | (char)((value >> 8) & 0xFF) // value high byte |
baumamer | 0:6d03232fcb64 | 406 | }; |
baumamer | 0:6d03232fcb64 | 407 | |
baumamer | 0:6d03232fcb64 | 408 | if (i2c->write(RFD77402_ADDR, data, 3)) { |
baumamer | 0:6d03232fcb64 | 409 | printf("writeReg16: write fail \n\r"); |
baumamer | 0:6d03232fcb64 | 410 | } |
baumamer | 0:6d03232fcb64 | 411 | } |
baumamer | 0:6d03232fcb64 | 412 | |
baumamer | 0:6d03232fcb64 | 413 | //Write a value to a spot in the RFD77402 |
baumamer | 0:6d03232fcb64 | 414 | void RFD77402::writeRegister(uint8_t reg, uint8_t value) |
baumamer | 0:6d03232fcb64 | 415 | { |
baumamer | 0:6d03232fcb64 | 416 | char data[] = { |
baumamer | 0:6d03232fcb64 | 417 | reg, |
baumamer | 0:6d03232fcb64 | 418 | value |
baumamer | 0:6d03232fcb64 | 419 | }; |
baumamer | 0:6d03232fcb64 | 420 | |
baumamer | 0:6d03232fcb64 | 421 | if (i2c->write(RFD77402_ADDR, data, 2)){printf("write error \n\r");} |
baumamer | 0:6d03232fcb64 | 422 | } |