Library to control Silicon Labs SI570 10 MHZ TO 1.4 GHZ I2C PROGRAMMABLE XO/VCXO.
Fork of SI570 by
SI570.cpp@0:dae1bf95c49e, 2010-11-09 (annotated)
- Committer:
- soldeerridder
- Date:
- Tue Nov 09 20:56:52 2010 +0000
- Revision:
- 0:dae1bf95c49e
added documentation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
soldeerridder | 0:dae1bf95c49e | 1 | /* mbed SI570 Library, for driving the SI570 programable VCXO |
soldeerridder | 0:dae1bf95c49e | 2 | * Copyright (c) 2010, Gerrit Polder, PA3BYA |
soldeerridder | 0:dae1bf95c49e | 3 | * |
soldeerridder | 0:dae1bf95c49e | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
soldeerridder | 0:dae1bf95c49e | 5 | * of this software and associated documentation files (the "Software"), to deal |
soldeerridder | 0:dae1bf95c49e | 6 | * in the Software without restriction, including without limitation the rights |
soldeerridder | 0:dae1bf95c49e | 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
soldeerridder | 0:dae1bf95c49e | 8 | * copies of the Software, and to permit persons to whom the Software is |
soldeerridder | 0:dae1bf95c49e | 9 | * furnished to do so, subject to the following conditions: |
soldeerridder | 0:dae1bf95c49e | 10 | * |
soldeerridder | 0:dae1bf95c49e | 11 | * The above copyright notice and this permission notice shall be included in |
soldeerridder | 0:dae1bf95c49e | 12 | * all copies or substantial portions of the Software. |
soldeerridder | 0:dae1bf95c49e | 13 | * |
soldeerridder | 0:dae1bf95c49e | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
soldeerridder | 0:dae1bf95c49e | 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
soldeerridder | 0:dae1bf95c49e | 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
soldeerridder | 0:dae1bf95c49e | 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
soldeerridder | 0:dae1bf95c49e | 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
soldeerridder | 0:dae1bf95c49e | 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
soldeerridder | 0:dae1bf95c49e | 20 | * THE SOFTWARE. |
soldeerridder | 0:dae1bf95c49e | 21 | */ |
soldeerridder | 0:dae1bf95c49e | 22 | |
soldeerridder | 0:dae1bf95c49e | 23 | #include "SI570.h" |
soldeerridder | 0:dae1bf95c49e | 24 | #include "mbed.h" |
soldeerridder | 0:dae1bf95c49e | 25 | |
soldeerridder | 0:dae1bf95c49e | 26 | SI570::SI570(PinName sda, PinName scl, int address) |
soldeerridder | 0:dae1bf95c49e | 27 | : _i2c(sda, scl) { |
soldeerridder | 0:dae1bf95c49e | 28 | _address = address; |
soldeerridder | 0:dae1bf95c49e | 29 | si570reset(); |
soldeerridder | 0:dae1bf95c49e | 30 | } |
soldeerridder | 0:dae1bf95c49e | 31 | |
soldeerridder | 0:dae1bf95c49e | 32 | |
soldeerridder | 0:dae1bf95c49e | 33 | |
soldeerridder | 0:dae1bf95c49e | 34 | void SI570::si570reset(void) { |
soldeerridder | 0:dae1bf95c49e | 35 | _i2c.frequency(100000); |
soldeerridder | 0:dae1bf95c49e | 36 | |
soldeerridder | 0:dae1bf95c49e | 37 | cmd[0] = 135; // reset |
soldeerridder | 0:dae1bf95c49e | 38 | cmd[1] = 0x01; // |
soldeerridder | 0:dae1bf95c49e | 39 | _i2c.write(_address, cmd, 2); // Send command string |
soldeerridder | 0:dae1bf95c49e | 40 | |
soldeerridder | 0:dae1bf95c49e | 41 | get_registers(); |
soldeerridder | 0:dae1bf95c49e | 42 | fxtal_device = (FOUT_START_UP * n1 * hsdiv) / rfreq; //MHz |
soldeerridder | 0:dae1bf95c49e | 43 | |
soldeerridder | 0:dae1bf95c49e | 44 | currentFreq = FOUT_START_UP; |
soldeerridder | 0:dae1bf95c49e | 45 | } |
soldeerridder | 0:dae1bf95c49e | 46 | |
soldeerridder | 0:dae1bf95c49e | 47 | void SI570::get_registers() { |
soldeerridder | 0:dae1bf95c49e | 48 | |
soldeerridder | 0:dae1bf95c49e | 49 | // Set pointer to location 7 (first echo) |
soldeerridder | 0:dae1bf95c49e | 50 | cmd[0] = 0x7; |
soldeerridder | 0:dae1bf95c49e | 51 | _i2c.write(_address, cmd, 1); |
soldeerridder | 0:dae1bf95c49e | 52 | |
soldeerridder | 0:dae1bf95c49e | 53 | _i2c.read(_address, buf, 6); // read the six-byte result |
soldeerridder | 0:dae1bf95c49e | 54 | |
soldeerridder | 0:dae1bf95c49e | 55 | // HS_DIV conversion |
soldeerridder | 0:dae1bf95c49e | 56 | hsdiv = ((buf[0] & 0xE0) >> 5) + 4; // get reg 7 bits 5, 6, 7 |
soldeerridder | 0:dae1bf95c49e | 57 | // hsdiv's value could be verified here to ensure that it is one |
soldeerridder | 0:dae1bf95c49e | 58 | // of the valid HS_DIV values from the datasheet. |
soldeerridder | 0:dae1bf95c49e | 59 | // n1 conversion |
soldeerridder | 0:dae1bf95c49e | 60 | n1 = (( buf[0] & 0x1F ) << 2 ) + // get reg 7 bits 0 to 4 |
soldeerridder | 0:dae1bf95c49e | 61 | (( buf[1] & 0xC0 ) >> 6 ); // add with reg 8 bits 7 and 8 |
soldeerridder | 0:dae1bf95c49e | 62 | if (n1 == 0) { |
soldeerridder | 0:dae1bf95c49e | 63 | n1 = 1; |
soldeerridder | 0:dae1bf95c49e | 64 | } else if (n1 & 1 != 0) { |
soldeerridder | 0:dae1bf95c49e | 65 | // add one to an odd number |
soldeerridder | 0:dae1bf95c49e | 66 | n1 = n1 + 1; |
soldeerridder | 0:dae1bf95c49e | 67 | } |
soldeerridder | 0:dae1bf95c49e | 68 | |
soldeerridder | 0:dae1bf95c49e | 69 | frac_bits = (( buf[2] & 0xF ) * POW_2_24 ); |
soldeerridder | 0:dae1bf95c49e | 70 | frac_bits = frac_bits + (buf[3] * POW_2_16); |
soldeerridder | 0:dae1bf95c49e | 71 | frac_bits = frac_bits + (buf[4] * 256); |
soldeerridder | 0:dae1bf95c49e | 72 | frac_bits = frac_bits + buf[5]; |
soldeerridder | 0:dae1bf95c49e | 73 | |
soldeerridder | 0:dae1bf95c49e | 74 | rfreq = frac_bits; |
soldeerridder | 0:dae1bf95c49e | 75 | rfreq = rfreq / POW_2_28; |
soldeerridder | 0:dae1bf95c49e | 76 | rfreq = rfreq + ( (( buf[1] & 0x3F ) << 4 ) + (( buf[2] & 0xF0 ) >> 4 ) ); |
soldeerridder | 0:dae1bf95c49e | 77 | } |
soldeerridder | 0:dae1bf95c49e | 78 | |
soldeerridder | 0:dae1bf95c49e | 79 | |
soldeerridder | 0:dae1bf95c49e | 80 | double SI570::get_frequency(void) { |
soldeerridder | 0:dae1bf95c49e | 81 | get_registers(); |
soldeerridder | 0:dae1bf95c49e | 82 | return (rfreq*fxtal_device)/(hsdiv*n1); |
soldeerridder | 0:dae1bf95c49e | 83 | } |
soldeerridder | 0:dae1bf95c49e | 84 | |
soldeerridder | 0:dae1bf95c49e | 85 | double SI570::get_rfreq(void) { |
soldeerridder | 0:dae1bf95c49e | 86 | get_registers(); |
soldeerridder | 0:dae1bf95c49e | 87 | return rfreq; |
soldeerridder | 0:dae1bf95c49e | 88 | } |
soldeerridder | 0:dae1bf95c49e | 89 | |
soldeerridder | 0:dae1bf95c49e | 90 | int SI570::get_n1(void) { |
soldeerridder | 0:dae1bf95c49e | 91 | get_registers(); |
soldeerridder | 0:dae1bf95c49e | 92 | return n1; |
soldeerridder | 0:dae1bf95c49e | 93 | } |
soldeerridder | 0:dae1bf95c49e | 94 | |
soldeerridder | 0:dae1bf95c49e | 95 | int SI570::get_hsdiv(void) { |
soldeerridder | 0:dae1bf95c49e | 96 | get_registers(); |
soldeerridder | 0:dae1bf95c49e | 97 | return hsdiv; |
soldeerridder | 0:dae1bf95c49e | 98 | } |
soldeerridder | 0:dae1bf95c49e | 99 | |
soldeerridder | 0:dae1bf95c49e | 100 | int SI570::set_frequency(double frequency) { |
soldeerridder | 0:dae1bf95c49e | 101 | int err; |
soldeerridder | 0:dae1bf95c49e | 102 | float diff = 1000000 * (abs(frequency - currentFreq) / currentFreq); |
soldeerridder | 0:dae1bf95c49e | 103 | if (diff < PPM) { |
soldeerridder | 0:dae1bf95c49e | 104 | err = set_frequency_small_change(frequency); |
soldeerridder | 0:dae1bf95c49e | 105 | } else { |
soldeerridder | 0:dae1bf95c49e | 106 | err = set_frequency_large_change(frequency); |
soldeerridder | 0:dae1bf95c49e | 107 | } |
soldeerridder | 0:dae1bf95c49e | 108 | return err; |
soldeerridder | 0:dae1bf95c49e | 109 | } |
soldeerridder | 0:dae1bf95c49e | 110 | |
soldeerridder | 0:dae1bf95c49e | 111 | int SI570::set_frequency_small_change(double frequency) { |
soldeerridder | 0:dae1bf95c49e | 112 | unsigned char reg135; |
soldeerridder | 0:dae1bf95c49e | 113 | unsigned int whole; |
soldeerridder | 0:dae1bf95c49e | 114 | unsigned char counter; |
soldeerridder | 0:dae1bf95c49e | 115 | int i; |
soldeerridder | 0:dae1bf95c49e | 116 | char reg[6]; |
soldeerridder | 0:dae1bf95c49e | 117 | |
soldeerridder | 0:dae1bf95c49e | 118 | rfreq = currentRfreq * frequency / currentFreq; |
soldeerridder | 0:dae1bf95c49e | 119 | |
soldeerridder | 0:dae1bf95c49e | 120 | cmd[0] = 0x8; |
soldeerridder | 0:dae1bf95c49e | 121 | _i2c.write(_address, cmd, 1); |
soldeerridder | 0:dae1bf95c49e | 122 | _i2c.read(_address, buf, 1); // read register 0x8 |
soldeerridder | 0:dae1bf95c49e | 123 | reg[1] = buf[0]; |
soldeerridder | 0:dae1bf95c49e | 124 | reg[2] = 0; |
soldeerridder | 0:dae1bf95c49e | 125 | |
soldeerridder | 0:dae1bf95c49e | 126 | // convert new RFREQ to the binary representation |
soldeerridder | 0:dae1bf95c49e | 127 | // separate the integer part |
soldeerridder | 0:dae1bf95c49e | 128 | whole = floor(rfreq); |
soldeerridder | 0:dae1bf95c49e | 129 | // get the binary representation of the fractional part |
soldeerridder | 0:dae1bf95c49e | 130 | frac_bits = floor((rfreq - whole) * POW_2_28); |
soldeerridder | 0:dae1bf95c49e | 131 | // set reg 12 to 10 making frac_bits smaller by |
soldeerridder | 0:dae1bf95c49e | 132 | // shifting off the last 8 bits everytime |
soldeerridder | 0:dae1bf95c49e | 133 | for (counter=5; counter >=3; counter--) { |
soldeerridder | 0:dae1bf95c49e | 134 | reg[counter] = frac_bits & 0xFF; |
soldeerridder | 0:dae1bf95c49e | 135 | frac_bits = frac_bits >> 8; |
soldeerridder | 0:dae1bf95c49e | 136 | } |
soldeerridder | 0:dae1bf95c49e | 137 | // set the last 4 bits of the fractional portion in reg 9 |
soldeerridder | 0:dae1bf95c49e | 138 | reg[2] = SetBits(reg[2], 0xF0, (frac_bits & 0xF)); |
soldeerridder | 0:dae1bf95c49e | 139 | // set the integer portion of RFREQ across reg 8 and 9 |
soldeerridder | 0:dae1bf95c49e | 140 | reg[2] = SetBits(reg[2], 0x0F, (whole & 0xF) << 4); |
soldeerridder | 0:dae1bf95c49e | 141 | reg[1] = SetBits(reg[1], 0xC0, (whole >> 4) & 0x3F); |
soldeerridder | 0:dae1bf95c49e | 142 | |
soldeerridder | 0:dae1bf95c49e | 143 | // Load the new frequency |
soldeerridder | 0:dae1bf95c49e | 144 | // get the current state of register 137 |
soldeerridder | 0:dae1bf95c49e | 145 | buf[0]=135; |
soldeerridder | 0:dae1bf95c49e | 146 | _i2c.write(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 147 | _i2c.read(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 148 | reg135 = buf[0]; |
soldeerridder | 0:dae1bf95c49e | 149 | |
soldeerridder | 0:dae1bf95c49e | 150 | // set the Freeze M bit in that register |
soldeerridder | 0:dae1bf95c49e | 151 | buf[0]=135; |
soldeerridder | 0:dae1bf95c49e | 152 | buf[1]=reg135 | 0x20; |
soldeerridder | 0:dae1bf95c49e | 153 | _i2c.write(_address, buf, 2); |
soldeerridder | 0:dae1bf95c49e | 154 | |
soldeerridder | 0:dae1bf95c49e | 155 | // load the new values into the device at registers 8 to 12; |
soldeerridder | 0:dae1bf95c49e | 156 | buf[0]=8; |
soldeerridder | 0:dae1bf95c49e | 157 | for (i=1;i<6;i++) { |
soldeerridder | 0:dae1bf95c49e | 158 | buf[i]=reg[i]; |
soldeerridder | 0:dae1bf95c49e | 159 | } |
soldeerridder | 0:dae1bf95c49e | 160 | _i2c.write(_address, buf, 6); |
soldeerridder | 0:dae1bf95c49e | 161 | |
soldeerridder | 0:dae1bf95c49e | 162 | // get the current state of register 135 |
soldeerridder | 0:dae1bf95c49e | 163 | buf[0]=135; |
soldeerridder | 0:dae1bf95c49e | 164 | _i2c.write(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 165 | _i2c.read(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 166 | reg135 = buf[0]; |
soldeerridder | 0:dae1bf95c49e | 167 | // clear the M bit in that register |
soldeerridder | 0:dae1bf95c49e | 168 | buf[0]=135; |
soldeerridder | 0:dae1bf95c49e | 169 | buf[1]= reg135 & 0xDF; |
soldeerridder | 0:dae1bf95c49e | 170 | _i2c.write(_address, buf, 2); |
soldeerridder | 0:dae1bf95c49e | 171 | |
soldeerridder | 0:dae1bf95c49e | 172 | return 0; |
soldeerridder | 0:dae1bf95c49e | 173 | } |
soldeerridder | 0:dae1bf95c49e | 174 | |
soldeerridder | 0:dae1bf95c49e | 175 | |
soldeerridder | 0:dae1bf95c49e | 176 | |
soldeerridder | 0:dae1bf95c49e | 177 | int SI570::set_frequency_large_change(double frequency) { |
soldeerridder | 0:dae1bf95c49e | 178 | const unsigned char HS_DIV[6] = {11, 9, 7, 6, 5, 4}; |
soldeerridder | 0:dae1bf95c49e | 179 | int i; |
soldeerridder | 0:dae1bf95c49e | 180 | // float ratio = 0; |
soldeerridder | 0:dae1bf95c49e | 181 | unsigned char counter; |
soldeerridder | 0:dae1bf95c49e | 182 | unsigned char reg137; |
soldeerridder | 0:dae1bf95c49e | 183 | char buf[7]; |
soldeerridder | 0:dae1bf95c49e | 184 | char reg[6]; |
soldeerridder | 0:dae1bf95c49e | 185 | unsigned int divider_max; |
soldeerridder | 0:dae1bf95c49e | 186 | unsigned int curr_div; |
soldeerridder | 0:dae1bf95c49e | 187 | unsigned int whole; |
soldeerridder | 0:dae1bf95c49e | 188 | unsigned char validCombo; |
soldeerridder | 0:dae1bf95c49e | 189 | float curr_n1; |
soldeerridder | 0:dae1bf95c49e | 190 | float n1_tmp; |
soldeerridder | 0:dae1bf95c49e | 191 | |
soldeerridder | 0:dae1bf95c49e | 192 | // find dividers (get the max and min divider range for the HS_DIV and N1 combo) |
soldeerridder | 0:dae1bf95c49e | 193 | divider_max = floor(FDCO_MAX / frequency); //floorf for SDCC |
soldeerridder | 0:dae1bf95c49e | 194 | curr_div = ceil(FDCO_MIN / frequency); //ceilf for SDCC |
soldeerridder | 0:dae1bf95c49e | 195 | validCombo = 0; |
soldeerridder | 0:dae1bf95c49e | 196 | while (curr_div <= divider_max) { |
soldeerridder | 0:dae1bf95c49e | 197 | //check all the HS_DIV values with the next curr_div |
soldeerridder | 0:dae1bf95c49e | 198 | for (counter=0; counter<6; counter++) { |
soldeerridder | 0:dae1bf95c49e | 199 | // get the next possible n1 value |
soldeerridder | 0:dae1bf95c49e | 200 | hsdiv = HS_DIV[counter]; |
soldeerridder | 0:dae1bf95c49e | 201 | curr_n1 = (curr_div * 1.0) / (hsdiv * 1.0); |
soldeerridder | 0:dae1bf95c49e | 202 | // determine if curr_n1 is an integer and an even number or one |
soldeerridder | 0:dae1bf95c49e | 203 | // then it will be a valid divider option for the new frequency |
soldeerridder | 0:dae1bf95c49e | 204 | n1_tmp = floor(curr_n1); |
soldeerridder | 0:dae1bf95c49e | 205 | n1_tmp = curr_n1 - n1_tmp; |
soldeerridder | 0:dae1bf95c49e | 206 | if (n1_tmp == 0.0) { |
soldeerridder | 0:dae1bf95c49e | 207 | //then curr_n1 is an integer |
soldeerridder | 0:dae1bf95c49e | 208 | n1 = (unsigned char) curr_n1; |
soldeerridder | 0:dae1bf95c49e | 209 | if ( (n1 == 1) || ((n1 & 1) == 0) ) { |
soldeerridder | 0:dae1bf95c49e | 210 | // then the calculated N1 is either 1 or an even number |
soldeerridder | 0:dae1bf95c49e | 211 | validCombo = 1; |
soldeerridder | 0:dae1bf95c49e | 212 | } |
soldeerridder | 0:dae1bf95c49e | 213 | } |
soldeerridder | 0:dae1bf95c49e | 214 | if (validCombo == 1) break; |
soldeerridder | 0:dae1bf95c49e | 215 | } |
soldeerridder | 0:dae1bf95c49e | 216 | if (validCombo == 1) break; |
soldeerridder | 0:dae1bf95c49e | 217 | //increment curr_div to find the next divider |
soldeerridder | 0:dae1bf95c49e | 218 | //since the current one was not valid |
soldeerridder | 0:dae1bf95c49e | 219 | curr_div = curr_div + 1; |
soldeerridder | 0:dae1bf95c49e | 220 | } |
soldeerridder | 0:dae1bf95c49e | 221 | |
soldeerridder | 0:dae1bf95c49e | 222 | // if(validCombo == 0) at this point then there's an error |
soldeerridder | 0:dae1bf95c49e | 223 | // in the calculation. Check if the provided frequencies |
soldeerridder | 0:dae1bf95c49e | 224 | // are valid. |
soldeerridder | 0:dae1bf95c49e | 225 | if (validCombo == 0) |
soldeerridder | 0:dae1bf95c49e | 226 | return -1; |
soldeerridder | 0:dae1bf95c49e | 227 | |
soldeerridder | 0:dae1bf95c49e | 228 | rfreq = (frequency * n1 * hsdiv) / fxtal_device; //using float |
soldeerridder | 0:dae1bf95c49e | 229 | for (counter = 0; counter < 6; counter++) { |
soldeerridder | 0:dae1bf95c49e | 230 | reg[counter] = 0; //clear registers |
soldeerridder | 0:dae1bf95c49e | 231 | } |
soldeerridder | 0:dae1bf95c49e | 232 | |
soldeerridder | 0:dae1bf95c49e | 233 | // new HS_DIV conversion |
soldeerridder | 0:dae1bf95c49e | 234 | hsdiv = hsdiv - 4; |
soldeerridder | 0:dae1bf95c49e | 235 | //reset this memory |
soldeerridder | 0:dae1bf95c49e | 236 | reg[0] = 0; |
soldeerridder | 0:dae1bf95c49e | 237 | //set the top 3 bits of reg 13 |
soldeerridder | 0:dae1bf95c49e | 238 | reg[0] = (hsdiv << 5); |
soldeerridder | 0:dae1bf95c49e | 239 | // convert new N1 to the binary representation |
soldeerridder | 0:dae1bf95c49e | 240 | if (n1 == 1) n1 = 0; |
soldeerridder | 0:dae1bf95c49e | 241 | else if ((n1 & 1) == 0) n1 = n1 - 1; //if n1 is even, subtract one |
soldeerridder | 0:dae1bf95c49e | 242 | // set reg 7 bits 0 to 4 |
soldeerridder | 0:dae1bf95c49e | 243 | reg[0] = SetBits(reg[0], 0xE0, n1 >> 2); |
soldeerridder | 0:dae1bf95c49e | 244 | // set reg 8 bits 6 and 7 |
soldeerridder | 0:dae1bf95c49e | 245 | reg[1] = (n1 & 3) << 6; |
soldeerridder | 0:dae1bf95c49e | 246 | |
soldeerridder | 0:dae1bf95c49e | 247 | // convert new RFREQ to the binary representation |
soldeerridder | 0:dae1bf95c49e | 248 | // separate the integer part |
soldeerridder | 0:dae1bf95c49e | 249 | whole = floor(rfreq); |
soldeerridder | 0:dae1bf95c49e | 250 | // get the binary representation of the fractional part |
soldeerridder | 0:dae1bf95c49e | 251 | frac_bits = floor((rfreq - whole) * POW_2_28); |
soldeerridder | 0:dae1bf95c49e | 252 | // set reg 12 to 10 making frac_bits smaller by |
soldeerridder | 0:dae1bf95c49e | 253 | // shifting off the last 8 bits everytime |
soldeerridder | 0:dae1bf95c49e | 254 | for (counter=5; counter >=3; counter--) { |
soldeerridder | 0:dae1bf95c49e | 255 | reg[counter] = frac_bits & 0xFF; |
soldeerridder | 0:dae1bf95c49e | 256 | frac_bits = frac_bits >> 8; |
soldeerridder | 0:dae1bf95c49e | 257 | } |
soldeerridder | 0:dae1bf95c49e | 258 | // set the last 4 bits of the fractional portion in reg 9 |
soldeerridder | 0:dae1bf95c49e | 259 | reg[2] = SetBits(reg[2], 0xF0, (frac_bits & 0xF)); |
soldeerridder | 0:dae1bf95c49e | 260 | // set the integer portion of RFREQ across reg 8 and 9 |
soldeerridder | 0:dae1bf95c49e | 261 | reg[2] = SetBits(reg[2], 0x0F, (whole & 0xF) << 4); |
soldeerridder | 0:dae1bf95c49e | 262 | reg[1] = SetBits(reg[1], 0xC0, (whole >> 4) & 0x3F); |
soldeerridder | 0:dae1bf95c49e | 263 | |
soldeerridder | 0:dae1bf95c49e | 264 | |
soldeerridder | 0:dae1bf95c49e | 265 | // Load the new frequency |
soldeerridder | 0:dae1bf95c49e | 266 | // get the current state of register 137 |
soldeerridder | 0:dae1bf95c49e | 267 | buf[0]=137; |
soldeerridder | 0:dae1bf95c49e | 268 | _i2c.write(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 269 | _i2c.read(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 270 | reg137 = buf[0]; |
soldeerridder | 0:dae1bf95c49e | 271 | |
soldeerridder | 0:dae1bf95c49e | 272 | // set the Freeze DCO bit in that register |
soldeerridder | 0:dae1bf95c49e | 273 | buf[0]=137; |
soldeerridder | 0:dae1bf95c49e | 274 | buf[1]=reg137 | 0x10; |
soldeerridder | 0:dae1bf95c49e | 275 | _i2c.write(_address, buf, 2); |
soldeerridder | 0:dae1bf95c49e | 276 | |
soldeerridder | 0:dae1bf95c49e | 277 | // load the new values into the device at registers 7 to 12; |
soldeerridder | 0:dae1bf95c49e | 278 | buf[0]=7; |
soldeerridder | 0:dae1bf95c49e | 279 | for (i=1;i<7;i++) { |
soldeerridder | 0:dae1bf95c49e | 280 | buf[i]=reg[i-1]; |
soldeerridder | 0:dae1bf95c49e | 281 | } |
soldeerridder | 0:dae1bf95c49e | 282 | _i2c.write(_address, buf, 7); |
soldeerridder | 0:dae1bf95c49e | 283 | |
soldeerridder | 0:dae1bf95c49e | 284 | |
soldeerridder | 0:dae1bf95c49e | 285 | // get the current state of register 137 |
soldeerridder | 0:dae1bf95c49e | 286 | buf[0]=137; |
soldeerridder | 0:dae1bf95c49e | 287 | _i2c.write(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 288 | _i2c.read(_address, buf, 1); |
soldeerridder | 0:dae1bf95c49e | 289 | reg137 = buf[0]; |
soldeerridder | 0:dae1bf95c49e | 290 | // clear the FZ_DCO bit in that register |
soldeerridder | 0:dae1bf95c49e | 291 | buf[0]=137; |
soldeerridder | 0:dae1bf95c49e | 292 | buf[1]= reg137 & 0xEF; |
soldeerridder | 0:dae1bf95c49e | 293 | _i2c.write(_address, buf, 2); |
soldeerridder | 0:dae1bf95c49e | 294 | |
soldeerridder | 0:dae1bf95c49e | 295 | |
soldeerridder | 0:dae1bf95c49e | 296 | // set the NewFreq bit, bit will clear itself once the device is ready |
soldeerridder | 0:dae1bf95c49e | 297 | buf[0]=135; |
soldeerridder | 0:dae1bf95c49e | 298 | buf[1]= 0x40; |
soldeerridder | 0:dae1bf95c49e | 299 | _i2c.write(_address, buf, 2); |
soldeerridder | 0:dae1bf95c49e | 300 | |
soldeerridder | 0:dae1bf95c49e | 301 | currentFreq = frequency; |
soldeerridder | 0:dae1bf95c49e | 302 | currentRfreq = rfreq; |
soldeerridder | 0:dae1bf95c49e | 303 | return 0; |
soldeerridder | 0:dae1bf95c49e | 304 | } |
soldeerridder | 0:dae1bf95c49e | 305 | |
soldeerridder | 0:dae1bf95c49e | 306 | |
soldeerridder | 0:dae1bf95c49e | 307 | unsigned char SI570::SetBits(unsigned char original, unsigned char reset_mask, unsigned char new_val) { |
soldeerridder | 0:dae1bf95c49e | 308 | return (( original & reset_mask ) | new_val ); |
soldeerridder | 0:dae1bf95c49e | 309 | } |
soldeerridder | 0:dae1bf95c49e | 310 |