max4146x_comp

Dependencies:   MAX14690

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 < 250 || freq > 950) {
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         char * value = (char *)malloc(17 * sizeof(char));
00446 
00447         if (value == NULL) {
00448             return -99;
00449         }
00450 
00451         int rtn_val = i2c_handler->write(I2C_ADDRESS, (char *) 0x00, 1, true);
00452         rtn_val = i2c_handler->read(I2C_ADDRESS, value, length, true);
00453         if (rtn_val != 0) {
00454             return rtn_val;
00455         }
00456 
00457         free(value);
00458 
00459         uint8_t local_data[4+length];
00460 
00461         local_data[0] = CFG7_ADDR;
00462         local_data[1] = 0x04;
00463         local_data[2] = (uint8_t)((length >> 8) | 0x80);
00464         local_data[3] = (uint8_t)((length) & 0x0FF);
00465 
00466         memcpy(&local_data[4], data, length);
00467 
00468         i2c_handler->write(I2C_ADDRESS, (const char *)local_data, sizeof(local_data), false);
00469 
00470     } else {
00471         this->io_write(data, length);
00472     }
00473 
00474     return 0;
00475 }
00476 
00477 template <class REG>
00478 int MAX4146X<REG>::io_write(uint8_t *data, uint32_t length)
00479 {
00480     //manchester array
00481     manchester_bit_array = new  unsigned char[length * 2 * 8];
00482 
00483     //bit array
00484     bits_array = new unsigned char[length * 8];
00485 
00486     //byte to bit conversion
00487     for (int i = 0; i < length; i++) {
00488         for (int j = 0; j < 8; j++) {
00489             // Mask each bit in the byte and store it
00490             if (data[i] & (mask << j)) {
00491                 bits_array[i * 8 + j] = 1;
00492             } else {
00493                 bits_array[i * 8 + j] = 0;
00494             }
00495         }
00496     }
00497 
00498     //manchester encode
00499     for (int i = 0; i < length * 8; i++) {
00500         if (bits_array[i] == 0) {
00501             //falling edge
00502             manchester_bit_array[2 * i] = 1;
00503             manchester_bit_array[2 * i + 1] = 0;
00504         } else {
00505             //rising edge
00506             manchester_bit_array[2 * i] = 0;
00507             manchester_bit_array[2 * i + 1] = 1;
00508         }
00509     }
00510 
00511     delete[] bits_array;  //delete bit array anymore not used
00512 
00513     float result = (500.0 / data_rate);
00514 
00515     bool rxFinished = false;
00516     Timer t;
00517     core_util_critical_section_enter();
00518     *this->data_sent = 0;
00519     wait_us(100);
00520     *this->data_sent = 1;
00521     wait_us(350);
00522     *this->data_sent = 0;
00523     wait_us(10);
00524     t.start();
00525     int manch_bit_counter = 0;
00526     do {
00527         if (t.read_us() >= (result * manch_bit_counter)) {
00528             if (manchester_bit_array[manch_bit_counter] == 0) {
00529                 *this->data_sent = 0;
00530             } else {
00531                 *this->data_sent = 1;
00532             }
00533 
00534             manch_bit_counter++;
00535 
00536             if (manch_bit_counter >= (length * 2 * 8)) {
00537                 rxFinished = true;
00538                 t.stop();
00539                 if (this->ssel != NULL) {
00540                     *this->ssel = 1;
00541                 }
00542             }
00543 
00544         }
00545     } while (!rxFinished);
00546     *this->data_sent = 0;
00547     core_util_critical_section_exit();
00548 
00549     delete[]  manchester_bit_array;  //manchester array clean
00550 
00551     return 0;
00552 }
00553 
00554 template <class REG>
00555 int MAX4146X<REG>::set_softreset(softreset_t softreset)
00556 {
00557     SET_BIT_FIELD(CFG8_ADDR, this->reg->reg_cfg8, this->reg->reg_cfg8.bits.softreset, softreset);
00558 
00559     return 0;
00560 }
00561 
00562 template <class REG>
00563 int MAX4146X<REG>::set_xoclkdelay(xoclkdelay_t delay)
00564 {
00565     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdelay, delay);
00566 
00567     return 0;
00568 }
00569 
00570 template <class REG>
00571 int MAX4146X<REG>::get_xoclkdelay(xoclkdelay_t *delay)
00572 {
00573     int ret;
00574 
00575     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00576     if (ret < 0) {
00577         return ret;
00578     }
00579 
00580     *delay = (xoclkdelay_t)this->reg->reg_cfg1.bits.xoclkdelay;
00581 
00582     return 0;
00583 }
00584 
00585 template <class REG>
00586 int MAX4146X<REG>::get_fifo_flags(uint8_t *fifo_flags)
00587 {
00588     return read_register(I2C6_ADDR, fifo_flags, 1);
00589 }
00590 
00591 template <class REG>
00592 int MAX4146X<REG>::get_pktcomplete(uint8_t *pktcomplete)
00593 {
00594     int ret;
00595 
00596     ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 1);
00597     if (ret < 0) {
00598         return ret;
00599     }
00600 
00601     *pktcomplete = (uint8_t)this->reg->reg_i2c4.bits.pktcomplete;
00602 
00603     return 0;
00604 }
00605 
00606 template <class REG>
00607 int MAX4146X<REG>::get_tx_pktlen(uint16_t *pktlen)
00608 {
00609     int ret;
00610 
00611     ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 2);
00612     if (ret < 0) {
00613         return ret;
00614     }
00615 
00616     *pktlen = (uint16_t)(((this->reg->reg_i2c4.bits.tx_pktlen_14_to_8) << 8) + (this->reg->reg_i2c5.raw)) ;
00617 
00618     return 0;
00619 }
00620 
00621 template <class REG>
00622 int MAX4146X<REG>::set_xoclkdiv(xoclkdiv_t div)
00623 {
00624     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdiv, div);
00625 
00626     return 0;
00627 }
00628 
00629 template <class REG>
00630 int MAX4146X<REG>::get_xoclkdiv(xoclkdiv_t* div)
00631 {
00632     int ret;
00633 
00634     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00635     if (ret < 0) {
00636         return ret;
00637     }
00638 
00639     *div = (xoclkdiv_t)this->reg->reg_cfg1.bits.xoclkdiv;
00640 
00641     return 0;
00642 }
00643 
00644 template <class REG>
00645 int MAX4146X<REG>::set_fskshape(fskshape_t shape)
00646 {
00647     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.fskshape, shape);
00648 
00649     return 0;
00650 }
00651 
00652 template <class REG>
00653 int MAX4146X<REG>::get_fskshape(fskshape_t* shape)
00654 {
00655     int ret;
00656 
00657     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00658     if (ret < 0) {
00659         return ret;
00660     }
00661 
00662     *shape = (fskshape_t)this->reg->reg_cfg1.bits.fskshape;
00663 
00664     return 0;
00665 }
00666 
00667 template <class REG>
00668 int MAX4146X<REG>::set_sync(sync_t state)
00669 {
00670     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.sync, state);
00671 
00672     return 0;
00673 }
00674 
00675 template <class REG>
00676 int MAX4146X<REG>::get_sync(sync_t* state)
00677 {
00678     int ret;
00679 
00680     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00681     if (ret < 0) {
00682         return ret;
00683     }
00684 
00685     *state = (sync_t)this->reg->reg_cfg1.bits.sync;
00686 
00687     return 0;
00688 }
00689 
00690 template <class REG>
00691 int MAX4146X<REG>::set_modmode(modmode_t mode)
00692 {
00693     SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.modmode, mode);
00694 
00695     return 0;
00696 }
00697 
00698 template <class REG>
00699 int MAX4146X<REG>::get_modmode(modmode_t* mode)
00700 {
00701     int ret;
00702 
00703     ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1);
00704     if (ret < 0) {
00705         return ret;
00706     }
00707 
00708     *mode = (modmode_t)this->reg->reg_cfg1.bits.modmode;
00709 
00710     return 0;
00711 }
00712 
00713 template <class REG>
00714 int MAX4146X<REG>::set_clkout_delay(clkout_delay_t delay)
00715 {
00716     SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.clkout_delay, delay);
00717 
00718     return 0;
00719 }
00720 
00721 template <class REG>
00722 int MAX4146X<REG>::get_clkout_delay(clkout_delay_t* delay)
00723 {
00724     int ret;
00725 
00726     ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1);
00727     if (ret < 0) {
00728         return ret;
00729     }
00730 
00731     *delay = (clkout_delay_t)this->reg->reg_cfg2.bits.clkout_delay;
00732 
00733     return 0;
00734 }
00735 
00736 template <class REG>
00737 int MAX4146X<REG>::set_bclk_postdiv(bclk_postdiv_t div)
00738 {
00739     SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.bclk_postdiv, div);
00740 
00741     return 0;
00742 }
00743 
00744 template <class REG>
00745 int MAX4146X<REG>::get_bclk_postdiv(bclk_postdiv_t* div)
00746 {
00747     int ret;
00748 
00749     ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1);
00750     if (ret < 0) {
00751         return ret;
00752     }
00753 
00754     *div = (bclk_postdiv_t)this->reg->reg_cfg2.bits.bclk_postdiv;
00755 
00756     return 0;
00757 }
00758 
00759 template <class REG>
00760 int MAX4146X<REG>::set_bclk_prediv(uint8_t prediv)
00761 {
00762     if (prediv < 3) {
00763         return -1;
00764     }
00765 
00766     SET_BIT_FIELD(CFG3_ADDR, this->reg->reg_cfg3, this->reg->reg_cfg3.bits.bclk_prediv, prediv);
00767 
00768     return 0;
00769 }
00770 
00771 template <class REG>
00772 int MAX4146X<REG>::get_bclk_prediv(uint8_t* prediv)
00773 {
00774     int ret;
00775 
00776     ret = read_register(CFG3_ADDR, (uint8_t *) & (this->reg->reg_cfg3), 1);
00777     if (ret < 0) {
00778         return ret;
00779     }
00780 
00781     *prediv = (uint8_t)this->reg->reg_cfg3.bits.bclk_prediv;
00782 
00783     return 0;
00784 }
00785 
00786 template <class REG>
00787 int MAX4146X<REG>::set_pwdn_mode(pwdn_mode_t pwdn_mode)
00788 {
00789     SET_BIT_FIELD(CFG4_ADDR, this->reg->reg_cfg4, this->reg->reg_cfg4.bits.pwdn_mode, pwdn_mode);
00790 
00791     return 0;
00792 }
00793 
00794 template <class REG>
00795 int MAX4146X<REG>::get_pwdn_mode(pwdn_mode_t* pwdn_mode)
00796 {
00797     int ret;
00798 
00799     ret = read_register(CFG4_ADDR, (uint8_t *) & (this->reg->reg_cfg4), 1);
00800     if (ret < 0) {
00801         return ret;
00802     }
00803 
00804     *pwdn_mode = (pwdn_mode_t)this->reg->reg_cfg4.bits.pwdn_mode;
00805 
00806     return 0;
00807 }
00808 
00809 template <class REG>
00810 int MAX4146X<REG>::set_tstep(uint8_t tstep)
00811 {
00812     SET_BIT_FIELD(CFG5_ADDR, this->reg->reg_cfg5, this->reg->reg_cfg5.bits.tstep, tstep);
00813 
00814     return 0;
00815 }
00816 
00817 template <class REG>
00818 int MAX4146X<REG>::get_tstep(uint8_t* tstep)
00819 {
00820     int ret;
00821 
00822     ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_cfg5), 1);
00823     if (ret < 0) {
00824         return ret;
00825     }
00826 
00827     *tstep = (uint8_t)this->reg->reg_cfg5.bits.tstep;
00828 
00829     return 0;
00830 }
00831 /*sdivarci*/
00832 template <class REG>
00833 int MAX4146X<REG>::set_i2c_txen1(i2c_txen1_t setting)
00834 {
00835     SET_BIT_FIELD(CFG6_ADDR, this->reg->reg_cfg6, this->reg->reg_cfg6.bits.i2c_txen1, setting);
00836 
00837     return 0;
00838 }
00839 
00840 template <class REG>
00841 int MAX4146X<REG>::set_i2c_txen2(i2c_txen2_t setting)
00842 {
00843     SET_BIT_FIELD(CFG7_ADDR, this->reg->reg_cfg7, this->reg->reg_cfg7.bits.i2c_txen2, setting);
00844 
00845     return 0;
00846 }
00847 
00848 template <class REG>
00849 int MAX4146X<REG>::set_i2c_data(uint8_t setting)
00850 {
00851     return write_register(I2C3_ADDR, (uint8_t *)&setting, 1);
00852 }
00853 
00854 
00855 
00856 
00857 template <class REG>
00858 int MAX4146X<REG>::set_pa_boost(pa_boost_t pa_boost)
00859 {
00860     SET_BIT_FIELD(SHDN_ADDR, this->reg->reg_shdn, this->reg->reg_shdn.bits.pa_boost, pa_boost);
00861 
00862     return 0;
00863 }
00864 
00865 template <class REG>
00866 int MAX4146X<REG>::get_pa_boost(pa_boost_t* pa_boost)
00867 {
00868     int ret;
00869 
00870     ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_shdn), 1);
00871     if (ret < 0) {
00872         return ret;
00873     }
00874 
00875     *pa_boost = (pa_boost_t)this->reg->reg_shdn.bits.pa_boost;
00876 
00877     return 0;
00878 }
00879 
00880 template <class REG>
00881 int MAX4146X<REG>::set_papwr(papwr_t papwr)
00882 {
00883     SET_BIT_FIELD(PA1_ADDR, this->reg->reg_pa1, this->reg->reg_pa1.bits.papwr, papwr);
00884 
00885     return 0;
00886 }
00887 
00888 template <class REG>
00889 int MAX4146X<REG>::get_papwr(papwr_t* papwr)
00890 {
00891     int ret;
00892 
00893     ret = read_register(PA1_ADDR, (uint8_t *) & (this->reg->reg_pa1), 1);
00894     if (ret < 0) {
00895         return ret;
00896     }
00897 
00898     *papwr = (papwr_t)this->reg->reg_pa1.bits.papwr;
00899 
00900     return 0;
00901 }
00902 
00903 template <class REG>
00904 int MAX4146X<REG>::set_pacap(pacap_t pacap)
00905 {
00906     SET_BIT_FIELD(PA2_ADDR, this->reg->reg_pa2, this->reg->reg_pa2.bits.pacap, pacap);
00907 
00908     return 0;
00909 }
00910 
00911 template <class REG>
00912 int MAX4146X<REG>::get_pacap(pacap_t* pacap)
00913 {
00914     int ret;
00915 
00916     ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_pa2), 1);
00917     if (ret < 0) {
00918         return ret;
00919     }
00920 
00921     *pacap = (pacap_t)this->reg->reg_pa2.bits.pacap;
00922 
00923     return 0;
00924 }
00925 
00926 template <class REG>
00927 int MAX4146X<REG>::set_cplin(cplin_t cplin)
00928 {
00929     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.cplin, cplin);
00930 
00931     return 0;
00932 }
00933 
00934 template <class REG>
00935 int MAX4146X<REG>::get_cplin(cplin_t* cplin)
00936 {
00937     int ret;
00938 
00939     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
00940     if (ret < 0) {
00941         return ret;
00942     }
00943 
00944     *cplin = (cplin_t)this->reg->reg_pll1.bits.cplin;
00945 
00946     return 0;
00947 }
00948 
00949 template <class REG>
00950 int MAX4146X<REG>::set_fracmode(fracmode_t fracmode)
00951 {
00952     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.fracmode, fracmode);
00953 
00954     return 0;
00955 }
00956 
00957 template <class REG>
00958 int MAX4146X<REG>::get_fracmode(fracmode_t* fracmode)
00959 {
00960     int ret;
00961 
00962     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
00963     if (ret < 0) {
00964         return ret;
00965     }
00966 
00967     *fracmode = (fracmode_t)this->reg->reg_pll1.bits.fracmode;
00968 
00969     return 0;
00970 }
00971 
00972 template <class REG>
00973 int MAX4146X<REG>::set_lodiv(lodiv_t  lodiv)
00974 {
00975     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lodiv, lodiv);
00976 
00977     return 0;
00978 }
00979 
00980 template <class REG>
00981 int MAX4146X<REG>::get_lodiv(lodiv_t * lodiv)
00982 {
00983     int ret;
00984 
00985     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
00986     if (ret < 0) {
00987         return ret;
00988     }
00989 
00990     *lodiv = (lodiv_t )this->reg->reg_pll1.bits.lodiv;
00991 
00992     return 0;
00993 }
00994 
00995 template <class REG>
00996 int MAX4146X<REG>::set_lomode(lomode_t lomode)
00997 {
00998     SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lomode, lomode);
00999 
01000     return 0;
01001 }
01002 
01003 template <class REG>
01004 int MAX4146X<REG>::get_lomode(lomode_t* lomode)
01005 {
01006     int ret;
01007 
01008     ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1);
01009     if (ret < 0) {
01010         return ret;
01011     }
01012 
01013     *lomode = (lomode_t)this->reg->reg_pll1.bits.lomode;
01014 
01015     return 0;
01016 }
01017 
01018 template <class REG>
01019 int MAX4146X<REG>::set_cpval(cpval_t cpval)
01020 {
01021 
01022     SET_BIT_FIELD(PLL2_ADDR, this->reg->reg_pll2, this->reg->reg_pll2.bits.cpval, cpval);
01023 
01024     return 0;
01025 }
01026 
01027 template <class REG>
01028 int MAX4146X<REG>::get_cpval(cpval_t* cpval)
01029 {
01030     int ret;
01031 
01032     ret = read_register(PLL2_ADDR, (uint8_t *) & (this->reg->reg_pll2), 1);
01033     if (ret < 0) {
01034         return ret;
01035     }
01036 
01037     *cpval = (cpval_t)this->reg->reg_pll2.bits.cpval;
01038 
01039     return 0;
01040 }
01041 
01042 template <class REG>
01043 int MAX4146X<REG>::set_frequency(uint32_t freq)
01044 {
01045     uint8_t value[3] = {(uint8_t)(freq >> 16), (uint8_t)(freq >> 8), (uint8_t)freq};
01046 
01047     return write_register(PLL3_ADDR, (uint8_t *)&value, 3);
01048 
01049 }
01050 
01051 template <class REG>
01052 int MAX4146X<REG>::get_frequency(uint32_t* freq)
01053 {
01054     int ret;
01055 
01056     uint8_t value[3];
01057 
01058     ret =  read_register(PLL3_ADDR, (uint8_t *)&value, 3);
01059     if (ret < 0) {
01060         return ret;
01061     }
01062 
01063     *freq = (uint32_t)((value[0] << 16) + (value[1] << 8) + value[2]);
01064 
01065     return 0;
01066 }
01067 
01068 template <class REG>
01069 int MAX4146X<REG>::set_deltaf(uint8_t deltaf)
01070 {
01071     if (deltaf > 127) {
01072         return -1;
01073     }
01074 
01075     SET_BIT_FIELD(PLL6_ADDR, this->reg->reg_pll6, this->reg->reg_pll6.bits.deltaf, deltaf);
01076 
01077     return 0;
01078 }
01079 
01080 template <class REG>
01081 int MAX4146X<REG>::get_deltaf(uint8_t* deltaf)
01082 {
01083     int ret;
01084 
01085     ret = read_register(PLL6_ADDR, (uint8_t *) & (this->reg->reg_pll6), 1);
01086     if (ret < 0) {
01087         return ret;
01088     }
01089 
01090     *deltaf = (uint8_t)this->reg->reg_pll6.bits.deltaf;
01091 
01092     return 0;
01093 }
01094 
01095 template <class REG>
01096 int MAX4146X<REG>::set_deltaf_shape(uint8_t deltaf_shape)
01097 {
01098     if (deltaf_shape > 15) {
01099         return -1;
01100     }
01101 
01102     SET_BIT_FIELD(PLL7_ADDR, this->reg->reg_pll7, this->reg->reg_pll7.bits.deltaf_shape, deltaf_shape);
01103 
01104     return 0;
01105 }
01106 
01107 template <class REG>
01108 int MAX4146X<REG>::get_deltaf_shape(uint8_t* deltaf_shape)
01109 {
01110     int ret;
01111 
01112     ret = read_register(PLL7_ADDR, (uint8_t *) & (this->reg->reg_pll7), 1);
01113     if (ret < 0) {
01114         return ret;
01115     }
01116 
01117     *deltaf_shape = (uint8_t)this->reg->reg_pll7.bits.deltaf_shape;
01118 
01119     return 0;
01120 }
01121 
01122 template <class REG>
01123 int MAX4146X<REG>::set_pktlen_mode(pktlen_mode_t pktlen_mode)
01124 {
01125     SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_mode, pktlen_mode);
01126 
01127     return 0;
01128 }
01129 
01130 template <class REG>
01131 int MAX4146X<REG>::get_pktlen_mode(pktlen_mode_t* pktlen_mode)
01132 {
01133     int ret;
01134 
01135     ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1);
01136     if (ret < 0) {
01137         return ret;
01138     }
01139 
01140     *pktlen_mode = (pktlen_mode_t)this->reg->reg_i2c1.bits.pktlen_mode;
01141 
01142     return 0;
01143 }
01144 
01145 
01146 template <class REG>
01147 int MAX4146X<REG>::set_i2c_pktlen(uint16_t pktlen)
01148 {
01149     if (pktlen > 0x7FF) {
01150         return -1;
01151     }
01152 
01153     SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_14_to_8, (uint8_t)((pktlen >> 8) & 0x07));
01154 
01155     uint8_t value = (uint8_t)(pktlen & 0xFF);
01156 
01157     return write_register(I2C2_ADDR, (uint8_t *)&value, 1);
01158 }
01159 
01160 template <class REG>
01161 int MAX4146X<REG>::get_i2c_pktlen(uint16_t* pktlen)
01162 {
01163     int ret;
01164 
01165     ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1);
01166     if (ret < 0) {
01167         return ret;
01168     }
01169 
01170     ret = read_register(I2C2_ADDR, (uint8_t *) & (this->reg->reg_i2c2), 1);
01171     if (ret < 0) {
01172         return ret;
01173     }
01174 
01175     *pktlen = (uint16_t)(((this->reg->reg_i2c1.raw & 0x7F)<<8) + (this->reg->reg_i2c2.raw &0x7F));
01176 
01177     return 0;
01178 }
01179 
01180 template <class REG>
01181 int MAX4146X<REG>::initial_programming(void)
01182 {
01183     uint8_t value = 0x80;
01184     write_register(ADDL2_ADDR, (uint8_t *)&value, 1);
01185 
01186     return write_register(CFG1_ADDR, default_register_value_1, 20);
01187 }
01188 
01189 template <>
01190 int MAX4146X<max41460_reg_map_t>::initial_programming(void)
01191 {
01192     if (this->ssel != NULL){
01193         *this->ssel = 0;
01194         wait_us(100);
01195     }
01196 
01197     int rtn = write_register(CFG1_ADDR, default_register_value_0, 17);
01198 
01199     if (this->ssel != NULL){
01200         wait_us(90);
01201         *this->ssel = 1;
01202     }
01203 
01204     return rtn;
01205 }
01206 
01207 
01208 template class MAX4146X<max41460_reg_map_t> ;
01209 template class MAX4146X<max41461_2_reg_map_t> ;
01210 template class MAX4146X<max41463_4_reg_map_t> ;
01211 
01212