Maxim Integrated / max4146x
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Max4146x.cpp Source File

Max4146x.cpp

00001 /*******************************************************************************
00002 * Copyright (C) 2019 Maxim Integrated Products, Inc., All rights Reserved.
00003 *
00004 * This software is protected by copyright laws of the United States and
00005 * of foreign countries. This material may also be protected by patent laws
00006 * and technology transfer regulations of the United States and of foreign
00007 * countries. This software is furnished under a license agreement and/or a
00008 * nondisclosure agreement and may only be used or reproduced in accordance
00009 * with the terms of those agreements. Dissemination of this information to
00010 * any party or parties not specified in the license agreement and/or
00011 * nondisclosure agreement is expressly prohibited.
00012 *
00013 * The above copyright notice and this permission notice shall be included
00014 * in all copies or substantial portions of the Software.
00015 *
00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00017 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00019 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00020 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00021 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00022 * OTHER DEALINGS IN THE SOFTWARE.
00023 *
00024 * Except as contained in this notice, the name of Maxim Integrated
00025 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00026 * Products, Inc. Branding Policy.
00027 *
00028 * The mere transfer of this software does not imply any licenses
00029 * of trade secrets, proprietary technology, copyrights, patents,
00030 * trademarks, maskwork rights, or any other form of intellectual
00031 * property whatsoever. Maxim Integrated Products, Inc. retains all
00032 * ownership rights.
00033 *******************************************************************************
00034 */
00035 
00036 #include "Max4146x.h"
00037 #include <iostream>
00038 
00039 using namespace std;
00040 
00041 const uint8_t default_register_value_0[17] = {0x90, 0x81, 0x03, 0x00, 0x00, 0x04, 0x80, 0x80, 0x60, 0x00,
00042                                               0x00, 0xC4, 0xDE, 0x98, 0x28, 0x04, 0x02};
00043 const uint8_t default_register_value_1[20] = {0x90, 0x81, 0x03, 0x00, 0x00, 0x04, 0x80, 0x80, 0x60, 0x00,
00044                                               0x00, 0xC4, 0xDE, 0x98, 0x28, 0x04, 0x04, 0x00, 0xFF, 0x00};
00045 
00046 template <class REG>
00047 MAX4146X<REG>::MAX4146X(REG *reg, SPI *spi, DigitalOut *cs)
00048 {
00049     operation_mode = UNINITIALIZED;
00050 
00051     if (reg == NULL) {
00052         return;
00053     }
00054 
00055     if (cs == NULL) {
00056         return;
00057     }
00058 
00059     this->reg = reg;
00060     ssel = cs;
00061 
00062     if (spi == NULL) {
00063         return;
00064     }
00065 
00066     spi_handler = spi;
00067     i2c_handler = NULL;
00068     preset_mode = 0;
00069 
00070     if (initial_programming() < 0) {
00071         return;
00072     }
00073 
00074     this->crystal_frequency = 16.0;
00075     this->center_frequency = 315.0;
00076     this->baud_rate = 5000.0;  //5 kHz
00077 
00078     operation_mode = INITIALIZED;
00079 }
00080 
00081 template <class REG>
00082 MAX4146X<REG>::MAX4146X(REG *reg, SPI *spi)
00083 {
00084     operation_mode = UNINITIALIZED;
00085 
00086     if (reg == NULL) {
00087         return;
00088     }
00089 
00090     this->reg = reg;
00091 
00092     if (spi == NULL) {
00093         return;
00094     }
00095 
00096     spi_handler = spi;
00097     i2c_handler = NULL;
00098     ssel = NULL;
00099     preset_mode = 0;
00100 
00101     if (initial_programming() < 0) {
00102         return;
00103     }
00104 
00105     this->crystal_frequency = 16.0;
00106     this->center_frequency = 315.0;
00107     this->baud_rate = 5000.0; //5 kHz
00108 
00109     operation_mode = INITIALIZED;
00110 }
00111 
00112 template <class REG>
00113 MAX4146X<REG>::MAX4146X(REG *reg, I2C *i2c)
00114 {
00115     operation_mode = UNINITIALIZED;
00116 
00117     if (reg == NULL) {
00118         return;
00119     }
00120 
00121     this->reg = reg;
00122 
00123     if (i2c == NULL) {
00124         return;
00125     }
00126 
00127     i2c_handler = i2c;
00128     spi_handler = NULL;
00129     ssel = NULL;
00130     preset_mode = 0;
00131 
00132     if (initial_programming() < 0) {
00133         return;
00134     }
00135 
00136     this->crystal_frequency = 16.0;
00137     this->center_frequency = 315.0;
00138     this->baud_rate = 5000.0;  //5 kHz
00139 
00140     operation_mode = INITIALIZED;
00141 }
00142 
00143 template <class REG>
00144 MAX4146X<REG>::MAX4146X(DigitalOut *cs)
00145 {
00146     operation_mode = UNINITIALIZED;
00147 
00148     if (cs == NULL) {
00149         return;
00150     }
00151 
00152     data_sent = cs;
00153 
00154     data_rate = 5;
00155 
00156     this->reg = NULL;
00157     this->ssel = NULL;
00158     spi_handler = NULL;
00159     i2c_handler = NULL;
00160     preset_mode = 1;
00161 
00162     operation_mode = INITIALIZED;
00163 }
00164 
00165 template <>
00166 int MAX4146X<max41460_reg_map_t>::read_register(uint8_t reg, uint8_t *value, uint8_t len)
00167 {
00168     int rtn_val = -1;
00169 
00170     if (value == NULL) {
00171         return -1;
00172     }
00173 
00174     if (this->reg == NULL) {
00175         return -1;
00176     }
00177 
00178     if (ssel != NULL) {
00179         *ssel = 0;
00180     }
00181     spi_handler->write((uint8_t)0x80 | reg);
00182     for (uint8_t i = 0; i < len; i++) {
00183         *(value++) = spi_handler->write(0x00);     // read back  data bytes
00184     }
00185     if (ssel != NULL) {
00186         *ssel = 1;
00187     }
00188     return 0;
00189 }
00190 
00191 template <class REG>
00192 int MAX4146X<REG>::read_register(uint8_t reg, uint8_t *value, uint8_t len)
00193 {
00194     int rtn_val = -1;
00195 
00196     if (value == NULL) {
00197         return -1;
00198     }
00199 
00200     if (this->reg == NULL) {
00201         return -1;
00202     }
00203 
00204     rtn_val = i2c_handler->write(I2C_ADDRESS, (const char *)&reg, 1, true);
00205     if (rtn_val != 0) {
00206         return -1;
00207     }
00208 
00209     rtn_val = i2c_handler->read(I2C_ADDRESS, (char *) value, len, false);
00210     if (rtn_val < 0) {
00211         return rtn_val;
00212     }
00213 
00214     return 0;
00215 }
00216 
00217 template <>
00218 int MAX4146X<max41460_reg_map_t>::write_register(uint8_t reg, const uint8_t *value, uint8_t len)
00219 {
00220     int rtn_val = -1;
00221     uint8_t local_data[1 + len];
00222 
00223     if (value == NULL) {
00224         return -1;
00225     }
00226 
00227     memcpy(&local_data[0], value, len);
00228 
00229     rtn_val = spi_handler->write(0x7F & reg); // write mode and adress send
00230     for (int i = 0; i < len; i++) {
00231         rtn_val = spi_handler->write(local_data[i]); // write adress
00232     }
00233     if (rtn_val != 0) {
00234         return rtn_val;
00235     }
00236 
00237     return 0;
00238 }
00239 
00240 template <class REG>
00241 int MAX4146X<REG>::write_register(uint8_t reg, const uint8_t *value, uint8_t len)
00242 {
00243     int rtn_val = -1;
00244     uint8_t local_data[1 + len];
00245 
00246     if (value == NULL) {
00247         return -1;
00248     }
00249 
00250     local_data[0] = reg;
00251 
00252     memcpy(&local_data[1], value, len);
00253 
00254     rtn_val = i2c_handler->write(I2C_ADDRESS, (const char *)local_data,
00255             sizeof(local_data));
00256     if (rtn_val != 0) {
00257         return -1;
00258     }
00259 
00260     return 0;
00261 }
00262 
00263 #define SET_BIT_FIELD(address, reg_name, bit_field_name, value)                             \
00264                 int ret;                                                                    \
00265                 ret = read_register(address, (uint8_t *)&(reg_name), 1);                    \
00266                 if (ret) {                                                                  \
00267                     return ret;                                                             \
00268                 }                                                                           \
00269                 bit_field_name = value;                                                     \
00270                 ret = write_register(address, (uint8_t *)&(reg_name), 1);                   \
00271                 if (ret) {                                                                  \
00272                     return ret;                                                             \
00273                 }
00274 
00275 template <class REG>
00276 int MAX4146X<REG>::set_crystal_frequency(float freq)
00277 {
00278     if (freq < 12.7 || freq > 19.3) {
00279         return -1;
00280     }
00281     this->crystal_frequency = freq;
00282 
00283     return 0;
00284 }
00285 
00286 template <class REG>
00287 float MAX4146X<REG>::get_crystal_frequency()
00288 {
00289     return this->crystal_frequency;
00290 }
00291 
00292 template <class REG>
00293 int MAX4146X<REG>::set_center_frequency(float freq)
00294 {
00295     if (freq < 250 || freq > 950) {
00296         return -1;
00297     }
00298 
00299     this->center_frequency = freq;
00300 
00301     uint32_t value = (uint32_t)((65536 * freq) / this->crystal_frequency); //65536 is constant defined in the datasheet
00302 
00303     return this->set_frequency(value);
00304 }
00305 
00306 template <class REG>
00307 float MAX4146X<REG>::get_center_frequency()
00308 {
00309     return this->center_frequency;
00310 }
00311 
00312 template <class REG>
00313 int MAX4146X<REG>::adjust_baudrate(float rate)
00314 {
00315     if (rate < 195.3 || rate > 200000.0) {
00316         return -1;
00317     }
00318 
00319     if (this->preset_mode == 1) {
00320         this->baud_rate = rate;
00321     }
00322 
00323     int error = 0;
00324     uint8_t prediv = 3;
00325 
00326     if (rate < 12500.0) {
00327         error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_5);
00328         prediv = (uint8_t)((50000.0 / rate) - 1);
00329     } else if (rate < 25000.0) {
00330         error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_4);
00331         prediv = (uint8_t)((100000.0 / rate) - 1);
00332     } else if (rate < 50000.0) {
00333         error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_3);
00334         prediv = (uint8_t)((200000.0 / rate) - 1);
00335     } else if (rate < 100000.0) {
00336         error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_2);
00337         prediv = (uint8_t)((400000.0 / rate) - 1);
00338     } else {
00339         error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_1);
00340         prediv = (uint8_t)((800000.0 / rate) - 1);
00341     }
00342 
00343     if (error < 0) {
00344         return -1;
00345     }
00346 
00347     return this->set_bclk_prediv(prediv);
00348 }
00349 
00350 template <class REG>
00351 float MAX4146X<REG>::get_baudrate()
00352 {
00353     return this->baud_rate;
00354 }
00355 
00356 template <class REG>
00357 int MAX4146X<REG>::adjust_frequency_deviation(float deviation)
00358 {
00359     uint8_t dev = 0;
00360 
00361     if (this->read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1) < 0) {
00362         return -1;
00363     }
00364 
00365     if (this->reg->reg_cfg1.bits.fskshape == 0) {
00366         dev = (uint8_t)(deviation * 8.192 / crystal_frequency);
00367         if (dev < 127) {
00368             return this->set_deltaf(dev);
00369         }
00370     } else {
00371         dev = (uint8_t)(deviation * 81.92 / crystal_frequency); // crystal_frequency in MHz form
00372         if (dev < 15) {
00373             return this->set_deltaf_shape(dev);
00374         }
00375     }
00376 
00377     return -1;
00378 }
00379 
00380 template <class REG>
00381 int MAX4146X<REG>::adjust_manchester_bitrate(char rate)
00382 {
00383     this->data_rate = rate;
00384 
00385     return 0;
00386 }
00387 
00388 template <class REG>
00389 char MAX4146X<REG>::get_manchester_bitrate()
00390 {
00391     return this->data_rate;
00392 }
00393 
00394 template <>
00395 int MAX4146X<max41460_reg_map_t>::send_data(uint8_t *data, uint32_t length)
00396 {
00397     if (this->preset_mode == 0) {
00398 
00399         if (ssel != NULL) {
00400             *ssel = 0;
00401         }
00402 
00403         spi_handler->write(0x7F & 0x0A); /*write mode and adress send*/
00404 
00405         spi_handler->write(0x01); /*write data SPI_EN1 clear*/
00406 
00407 
00408         if (ssel != NULL) {
00409             *ssel = 1;
00410         }
00411 
00412         wait_us(300); /* for waiting another SPI operation*/
00413 
00414         if (ssel != NULL) {
00415             *ssel = 0;
00416         }
00417 
00418         spi_handler->write(0x7F & 0x10); /*write mode and adress send*/
00419 
00420         spi_handler->write(0x03); /*write data SPI_EN2 set*/
00421 
00422         if (ssel != NULL) {
00423             *ssel = 0;
00424         }
00425 
00426         wait_us(300); /* for waiting another SPI operation*/
00427 
00428     }
00429 
00430     return this->io_write(data, length);
00431 }
00432 
00433 template <class REG>
00434 int MAX4146X<REG>::send_data(uint8_t *data, uint32_t length)
00435 {
00436     if (this->preset_mode == 0) {
00437         if (length > 32767) {
00438             return -100;
00439         }
00440 
00441         this->adjust_baudrate(this->baud_rate);
00442 
00443 //        this->set_i2c_txen1(I2C_TXEN1_DISABLE);
00444 
00445         uint8_t local_data[4+length];
00446 
00447         local_data[0] = CFG7_ADDR;
00448         local_data[1] = 0x04;
00449         local_data[2] = (uint8_t)((length >> 8) | 0x80);
00450         local_data[3] = (uint8_t)((length) & 0x0FF);
00451 
00452         memcpy(&local_data[4], data, length);
00453 
00454         i2c_handler->write(I2C_ADDRESS, (const char *)local_data, sizeof(local_data), false);
00455 
00456     } else {
00457         this->io_write(data, length);
00458     }
00459 
00460     return 0;
00461 }
00462 
00463 template <class REG>
00464 int MAX4146X<REG>::io_write(uint8_t *data, uint32_t length)
00465 {
00466     //manchester array
00467     manchester_bit_array = new  unsigned char[length * 2 * 8];
00468 
00469     //bit array
00470     bits_array = new unsigned char[length * 8];
00471 
00472     //byte to bit conversion
00473     for (int i = 0; i < length; i++) {
00474         for (int j = 0; j < 8; j++) {
00475             // Mask each bit in the byte and store it
00476             if (data[i] & (mask << j)) {
00477                 bits_array[i * 8 + j] = 1;
00478             } else {
00479                 bits_array[i * 8 + j] = 0;
00480             }
00481         }
00482     }
00483 
00484     //manchester encode
00485     for (int i = 0; i < length * 8; i++) {
00486         if (bits_array[i] == 0) {
00487             //falling edge
00488             manchester_bit_array[2 * i] = 1;
00489             manchester_bit_array[2 * i + 1] = 0;
00490         } else {
00491             //rising edge
00492             manchester_bit_array[2 * i] = 0;
00493             manchester_bit_array[2 * i + 1] = 1;
00494         }
00495     }
00496 
00497     delete[] bits_array;  //delete bit array anymore not used
00498 
00499     float result = (500.0 / data_rate);
00500 
00501     bool rxFinished = false;
00502     Timer t;
00503     core_util_critical_section_enter();
00504     *this->data_sent = 0;
00505     wait_us(100);
00506     *this->data_sent = 1;
00507     wait_us(350);
00508     *this->data_sent = 0;
00509     wait_us(10);
00510     t.start();
00511     int manch_bit_counter = 0;
00512     do {
00513         if (t.read_us() >= (result * manch_bit_counter)) {
00514             if (manchester_bit_array[manch_bit_counter] == 0) {
00515                 *this->data_sent = 0;
00516             } else {
00517                 *this->data_sent = 1;
00518             }
00519 
00520             manch_bit_counter++;
00521 
00522             if (manch_bit_counter >= (length * 2 * 8)) {
00523                 rxFinished = true;
00524                 t.stop();
00525                 if (this->ssel != NULL) {
00526                     *this->ssel = 1;
00527                 }
00528             }
00529 
00530         }
00531     } while (!rxFinished);
00532     *this->data_sent = 0;
00533     core_util_critical_section_exit();
00534 
00535     delete[]  manchester_bit_array;  //manchester array clean
00536 
00537     return 0;
00538 }
00539 
00540 template <class REG>
00541 int MAX4146X<REG>::set_softreset(softreset_t softreset)
00542 {
00543     SET_BIT_FIELD(CFG8_ADDR, this->reg->reg_cfg8, this->reg->reg_cfg8.bits.softreset, softreset);
00544 
00545     return 0;
00546 }
00547 
00548 template <class REG>
00549 int MAX4146X<REG>::set_xoclkdelay(xoclkdelay_t delay)
00550 {
00551     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdelay, delay);
00552 
00553     return 0;
00554 }
00555 
00556 template <class REG>
00557 int MAX4146X<REG>::get_xoclkdelay(xoclkdelay_t *delay)
00558 {
00559     int ret;
00560 
00561     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00562     if (ret < 0) {
00563         return ret;
00564     }
00565 
00566     *delay = (xoclkdelay_t)this->reg->reg_cfg1.bits.xoclkdelay;
00567 
00568     return 0;
00569 }
00570 
00571 template <class REG>
00572 int MAX4146X<REG>::get_fifo_flags(uint8_t *fifo_flags)
00573 {
00574     return read_register(I2C6_ADDR, fifo_flags, 1);
00575 }
00576 
00577 template <class REG>
00578 int MAX4146X<REG>::get_pktcomplete(uint8_t *pktcomplete)
00579 {
00580     int ret;
00581 
00582     ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 1);
00583     if (ret < 0) {
00584         return ret;
00585     }
00586 
00587     *pktcomplete = (uint8_t)this->reg->reg_i2c4.bits.pktcomplete;
00588 
00589     return 0;
00590 }
00591 
00592 template <class REG>
00593 int MAX4146X<REG>::get_tx_pktlen(uint16_t *pktlen)
00594 {
00595     int ret;
00596 
00597     ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 2);
00598     if (ret < 0) {
00599         return ret;
00600     }
00601 
00602     *pktlen = (uint16_t)(((this->reg->reg_i2c4.bits.tx_pktlen_14_to_8) << 8) + (this->reg->reg_i2c5.raw)) ;
00603 
00604     return 0;
00605 }
00606 
00607 template <class REG>
00608 int MAX4146X<REG>::set_xoclkdiv(xoclkdiv_t div)
00609 {
00610     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdiv, div);
00611 
00612     return 0;
00613 }
00614 
00615 template <class REG>
00616 int MAX4146X<REG>::get_xoclkdiv(xoclkdiv_t* div)
00617 {
00618     int ret;
00619 
00620     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00621     if (ret < 0) {
00622         return ret;
00623     }
00624 
00625     *div = (xoclkdiv_t)this->reg->reg_cfg1.bits.xoclkdiv;
00626 
00627     return 0;
00628 }
00629 
00630 template <class REG>
00631 int MAX4146X<REG>::set_fskshape(fskshape_t shape)
00632 {
00633     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.fskshape, shape);
00634 
00635     return 0;
00636 }
00637 
00638 template <class REG>
00639 int MAX4146X<REG>::get_fskshape(fskshape_t* shape)
00640 {
00641     int ret;
00642 
00643     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00644     if (ret < 0) {
00645         return ret;
00646     }
00647 
00648     *shape = (fskshape_t)this->reg->reg_cfg1.bits.fskshape;
00649 
00650     return 0;
00651 }
00652 
00653 template <class REG>
00654 int MAX4146X<REG>::set_sync(sync_t state)
00655 {
00656     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.sync, state);
00657 
00658     return 0;
00659 }
00660 
00661 template <class REG>
00662 int MAX4146X<REG>::get_sync(sync_t* state)
00663 {
00664     int ret;
00665 
00666     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00667     if (ret < 0) {
00668         return ret;
00669     }
00670 
00671     *state = (sync_t)this->reg->reg_cfg1.bits.sync;
00672 
00673     return 0;
00674 }
00675 
00676 template <class REG>
00677 int MAX4146X<REG>::set_modmode(modmode_t mode)
00678 {
00679     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.modmode, mode);
00680 
00681     return 0;
00682 }
00683 
00684 template <class REG>
00685 int MAX4146X<REG>::get_modmode(modmode_t* mode)
00686 {
00687     int ret;
00688 
00689     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00690     if (ret < 0) {
00691         return ret;
00692     }
00693 
00694     *mode = (modmode_t)this->reg->reg_cfg1.bits.modmode;
00695 
00696     return 0;
00697 }
00698 
00699 template <class REG>
00700 int MAX4146X<REG>::set_clkout_delay(clkout_delay_t delay)
00701 {
00702     SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.clkout_delay, delay);
00703 
00704     return 0;
00705 }
00706 
00707 template <class REG>
00708 int MAX4146X<REG>::get_clkout_delay(clkout_delay_t* delay)
00709 {
00710     int ret;
00711 
00712     ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1);
00713     if (ret < 0) {
00714         return ret;
00715     }
00716 
00717     *delay = (clkout_delay_t)this->reg->reg_cfg2.bits.clkout_delay;
00718 
00719     return 0;
00720 }
00721 
00722 template <class REG>
00723 int MAX4146X<REG>::set_bclk_postdiv(bclk_postdiv_t div)
00724 {
00725     SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.bclk_postdiv, div);
00726 
00727     return 0;
00728 }
00729 
00730 template <class REG>
00731 int MAX4146X<REG>::get_bclk_postdiv(bclk_postdiv_t* div)
00732 {
00733     int ret;
00734 
00735     ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1);
00736     if (ret < 0) {
00737         return ret;
00738     }
00739 
00740     *div = (bclk_postdiv_t)this->reg->reg_cfg2.bits.bclk_postdiv;
00741 
00742     return 0;
00743 }
00744 
00745 template <class REG>
00746 int MAX4146X<REG>::set_bclk_prediv(uint8_t prediv)
00747 {
00748     if (prediv < 3) {
00749         return -1;
00750     }
00751 
00752     SET_BIT_FIELD(CFG3_ADDR, this->reg->reg_cfg3, this->reg->reg_cfg3.bits.bclk_prediv, prediv);
00753 
00754     return 0;
00755 }
00756 
00757 template <class REG>
00758 int MAX4146X<REG>::get_bclk_prediv(uint8_t* prediv)
00759 {
00760     int ret;
00761 
00762     ret = read_register(CFG3_ADDR, (uint8_t *) & (this->reg->reg_cfg3), 1);
00763     if (ret < 0) {
00764         return ret;
00765     }
00766 
00767     *prediv = (uint8_t)this->reg->reg_cfg3.bits.bclk_prediv;
00768 
00769     return 0;
00770 }
00771 
00772 template <class REG>
00773 int MAX4146X<REG>::set_pwdn_mode(pwdn_mode_t pwdn_mode)
00774 {
00775     SET_BIT_FIELD(CFG4_ADDR, this->reg->reg_cfg4, this->reg->reg_cfg4.bits.pwdn_mode, pwdn_mode);
00776 
00777     return 0;
00778 }
00779 
00780 template <class REG>
00781 int MAX4146X<REG>::get_pwdn_mode(pwdn_mode_t* pwdn_mode)
00782 {
00783     int ret;
00784 
00785     ret = read_register(CFG4_ADDR, (uint8_t *) & (this->reg->reg_cfg4), 1);
00786     if (ret < 0) {
00787         return ret;
00788     }
00789 
00790     *pwdn_mode = (pwdn_mode_t)this->reg->reg_cfg4.bits.pwdn_mode;
00791 
00792     return 0;
00793 }
00794 
00795 template <class REG>
00796 int MAX4146X<REG>::set_tstep(uint8_t tstep)
00797 {
00798     SET_BIT_FIELD(CFG5_ADDR, this->reg->reg_cfg5, this->reg->reg_cfg5.bits.tstep, tstep);
00799 
00800     return 0;
00801 }
00802 
00803 template <class REG>
00804 int MAX4146X<REG>::get_tstep(uint8_t* tstep)
00805 {
00806     int ret;
00807 
00808     ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_cfg5), 1);
00809     if (ret < 0) {
00810         return ret;
00811     }
00812 
00813     *tstep = (uint8_t)this->reg->reg_cfg5.bits.tstep;
00814 
00815     return 0;
00816 }
00817 
00818 template <class REG>
00819 int MAX4146X<REG>::set_pa_boost(pa_boost_t pa_boost)
00820 {
00821     SET_BIT_FIELD(SHDN_ADDR, this->reg->reg_shdn, this->reg->reg_shdn.bits.pa_boost, pa_boost);
00822 
00823     return 0;
00824 }
00825 
00826 template <class REG>
00827 int MAX4146X<REG>::get_pa_boost(pa_boost_t* pa_boost)
00828 {
00829     int ret;
00830 
00831     ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_shdn), 1);
00832     if (ret < 0) {
00833         return ret;
00834     }
00835 
00836     *pa_boost = (pa_boost_t)this->reg->reg_shdn.bits.pa_boost;
00837 
00838     return 0;
00839 }
00840 
00841 template <class REG>
00842 int MAX4146X<REG>::set_papwr(papwr_t papwr)
00843 {
00844     SET_BIT_FIELD(PA1_ADDR, this->reg->reg_pa1, this->reg->reg_pa1.bits.papwr, papwr);
00845 
00846     return 0;
00847 }
00848 
00849 template <class REG>
00850 int MAX4146X<REG>::get_papwr(papwr_t* papwr)
00851 {
00852     int ret;
00853 
00854     ret = read_register(PA1_ADDR, (uint8_t *) & (this->reg->reg_pa1), 1);
00855     if (ret < 0) {
00856         return ret;
00857     }
00858 
00859     *papwr = (papwr_t)this->reg->reg_pa1.bits.papwr;
00860 
00861     return 0;
00862 }
00863 
00864 template <class REG>
00865 int MAX4146X<REG>::set_pacap(pacap_t pacap)
00866 {
00867     SET_BIT_FIELD(PA2_ADDR, this->reg->reg_pa2, this->reg->reg_pa2.bits.pacap, pacap);
00868 
00869     return 0;
00870 }
00871 
00872 template <class REG>
00873 int MAX4146X<REG>::get_pacap(pacap_t* pacap)
00874 {
00875     int ret;
00876 
00877     ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_pa2), 1);
00878     if (ret < 0) {
00879         return ret;
00880     }
00881 
00882     *pacap = (pacap_t)this->reg->reg_pa2.bits.pacap;
00883 
00884     return 0;
00885 }
00886 
00887 template <class REG>
00888 int MAX4146X<REG>::set_cplin(cplin_t cplin)
00889 {
00890     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.cplin, cplin);
00891 
00892     return 0;
00893 }
00894 
00895 template <class REG>
00896 int MAX4146X<REG>::get_cplin(cplin_t* cplin)
00897 {
00898     int ret;
00899 
00900     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
00901     if (ret < 0) {
00902         return ret;
00903     }
00904 
00905     *cplin = (cplin_t)this->reg->reg_pll1.bits.cplin;
00906 
00907     return 0;
00908 }
00909 
00910 template <class REG>
00911 int MAX4146X<REG>::set_fracmode(fracmode_t fracmode)
00912 {
00913     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.fracmode, fracmode);
00914 
00915     return 0;
00916 }
00917 
00918 template <class REG>
00919 int MAX4146X<REG>::get_fracmode(fracmode_t* fracmode)
00920 {
00921     int ret;
00922 
00923     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
00924     if (ret < 0) {
00925         return ret;
00926     }
00927 
00928     *fracmode = (fracmode_t)this->reg->reg_pll1.bits.fracmode;
00929 
00930     return 0;
00931 }
00932 
00933 template <class REG>
00934 int MAX4146X<REG>::set_lodiv(lodiv_t  lodiv)
00935 {
00936     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lodiv, lodiv);
00937 
00938     return 0;
00939 }
00940 
00941 template <class REG>
00942 int MAX4146X<REG>::get_lodiv(lodiv_t * lodiv)
00943 {
00944     int ret;
00945 
00946     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
00947     if (ret < 0) {
00948         return ret;
00949     }
00950 
00951     *lodiv = (lodiv_t )this->reg->reg_pll1.bits.lodiv;
00952 
00953     return 0;
00954 }
00955 
00956 template <class REG>
00957 int MAX4146X<REG>::set_lomode(lomode_t lomode)
00958 {
00959     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lomode, lomode);
00960 
00961     return 0;
00962 }
00963 
00964 template <class REG>
00965 int MAX4146X<REG>::get_lomode(lomode_t* lomode)
00966 {
00967     int ret;
00968 
00969     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
00970     if (ret < 0) {
00971         return ret;
00972     }
00973 
00974     *lomode = (lomode_t)this->reg->reg_pll1.bits.lomode;
00975 
00976     return 0;
00977 }
00978 
00979 template <class REG>
00980 int MAX4146X<REG>::set_cpval(cpval_t cpval)
00981 {
00982 
00983     SET_BIT_FIELD(PLL2_ADDR, this->reg->reg_pll2, this->reg->reg_pll2.bits.cpval, cpval);
00984 
00985     return 0;
00986 }
00987 
00988 template <class REG>
00989 int MAX4146X<REG>::get_cpval(cpval_t* cpval)
00990 {
00991     int ret;
00992 
00993     ret = read_register(PLL2_ADDR, (uint8_t *) & (this->reg->reg_pll2), 1);
00994     if (ret < 0) {
00995         return ret;
00996     }
00997 
00998     *cpval = (cpval_t)this->reg->reg_pll2.bits.cpval;
00999 
01000     return 0;
01001 }
01002 
01003 template <class REG>
01004 int MAX4146X<REG>::set_frequency(uint32_t freq)
01005 {
01006     uint8_t value[3] = {(uint8_t)(freq >> 16), (uint8_t)(freq >> 8), (uint8_t)freq};
01007 
01008     return write_register(PLL3_ADDR, (uint8_t *)&value, 3);
01009 
01010 }
01011 
01012 template <class REG>
01013 int MAX4146X<REG>::get_frequency(uint32_t* freq)
01014 {
01015     int ret;
01016 
01017     uint8_t value[3];
01018 
01019     ret =  read_register(PLL3_ADDR, (uint8_t *)&value, 3);
01020     if (ret < 0) {
01021         return ret;
01022     }
01023 
01024     *freq = (uint32_t)((value[0] << 16) + (value[1] << 8) + value[2]);
01025 
01026     return 0;
01027 }
01028 
01029 template <class REG>
01030 int MAX4146X<REG>::set_deltaf(uint8_t deltaf)
01031 {
01032     if (deltaf > 127) {
01033         return -1;
01034     }
01035 
01036     SET_BIT_FIELD(PLL6_ADDR, this->reg->reg_pll6, this->reg->reg_pll6.bits.deltaf, deltaf);
01037 
01038     return 0;
01039 }
01040 
01041 template <class REG>
01042 int MAX4146X<REG>::get_deltaf(uint8_t* deltaf)
01043 {
01044     int ret;
01045 
01046     ret = read_register(PLL6_ADDR, (uint8_t *) & (this->reg->reg_pll6), 1);
01047     if (ret < 0) {
01048         return ret;
01049     }
01050 
01051     *deltaf = (uint8_t)this->reg->reg_pll6.bits.deltaf;
01052 
01053     return 0;
01054 }
01055 
01056 template <class REG>
01057 int MAX4146X<REG>::set_deltaf_shape(uint8_t deltaf_shape)
01058 {
01059     if (deltaf_shape > 15) {
01060         return -1;
01061     }
01062 
01063     SET_BIT_FIELD(PLL7_ADDR, this->reg->reg_pll7, this->reg->reg_pll7.bits.deltaf_shape, deltaf_shape);
01064 
01065     return 0;
01066 }
01067 
01068 template <class REG>
01069 int MAX4146X<REG>::get_deltaf_shape(uint8_t* deltaf_shape)
01070 {
01071     int ret;
01072 
01073     ret = read_register(PLL7_ADDR, (uint8_t *) & (this->reg->reg_pll7), 1);
01074     if (ret < 0) {
01075         return ret;
01076     }
01077 
01078     *deltaf_shape = (uint8_t)this->reg->reg_pll7.bits.deltaf_shape;
01079 
01080     return 0;
01081 }
01082 
01083 template <class REG>
01084 int MAX4146X<REG>::set_pktlen_mode(pktlen_mode_t pktlen_mode)
01085 {
01086     SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_mode, pktlen_mode);
01087 
01088     return 0;
01089 }
01090 
01091 template <class REG>
01092 int MAX4146X<REG>::get_pktlen_mode(pktlen_mode_t* pktlen_mode)
01093 {
01094     int ret;
01095 
01096     ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1);
01097     if (ret < 0) {
01098         return ret;
01099     }
01100 
01101     *pktlen_mode = (pktlen_mode_t)this->reg->reg_i2c1.bits.pktlen_mode;
01102 
01103     return 0;
01104 }
01105 
01106 
01107 template <class REG>
01108 int MAX4146X<REG>::set_i2c_pktlen(uint16_t pktlen)
01109 {
01110     if (pktlen > 0x7FF) {
01111         return -1;
01112     }
01113 
01114     SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_14_to_8, (uint8_t)((pktlen >> 8) & 0x07));
01115 
01116     uint8_t value = (uint8_t)(pktlen & 0xFF);
01117 
01118     return write_register(I2C2_ADDR, (uint8_t *)&value, 1);
01119 }
01120 
01121 template <class REG>
01122 int MAX4146X<REG>::get_i2c_pktlen(uint16_t* pktlen)
01123 {
01124     int ret;
01125 
01126     ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1);
01127     if (ret < 0) {
01128         return ret;
01129     }
01130 
01131     ret = read_register(I2C2_ADDR, (uint8_t *) & (this->reg->reg_i2c2), 1);
01132     if (ret < 0) {
01133         return ret;
01134     }
01135 
01136     *pktlen = (uint16_t)(((this->reg->reg_i2c1.raw & 0x7F)<<8) + (this->reg->reg_i2c2.raw &0x7F));
01137 
01138     return 0;
01139 }
01140 
01141 template <class REG>
01142 int MAX4146X<REG>::initial_programming(void)
01143 {
01144     uint8_t value = 0x80;
01145     write_register(ADDL2_ADDR, (uint8_t *)&value, 1);
01146 
01147     return write_register(CFG1_ADDR, default_register_value_1, 20);
01148 }
01149 
01150 template <>
01151 int MAX4146X<max41460_reg_map_t>::initial_programming(void)
01152 {
01153     if (this->ssel != NULL){
01154         *this->ssel = 0;
01155         wait_us(100);
01156     }
01157 
01158     int rtn = write_register(CFG1_ADDR, default_register_value_0, 17);
01159 
01160     if (this->ssel != NULL){
01161         wait_us(90);
01162         *this->ssel = 1;
01163     }
01164 
01165     return rtn;
01166 }
01167 
01168 
01169 template class MAX4146X<max41460_reg_map_t> ;
01170 template class MAX4146X<max41461_2_reg_map_t> ;
01171 template class MAX4146X<max41463_4_reg_map_t> ;
01172 
01173