Sinan Divarci
/
max4146x_comp
max4146x_comp
max4146x/Max4146x.cpp
- Committer:
- sdivarci
- Date:
- 2020-10-25
- Revision:
- 0:0061165683ee
File content as of revision 0:0061165683ee:
/******************************************************************************* * Copyright (C) 2019 Maxim Integrated Products, Inc., All rights Reserved. * * This software is protected by copyright laws of the United States and * of foreign countries. This material may also be protected by patent laws * and technology transfer regulations of the United States and of foreign * countries. This software is furnished under a license agreement and/or a * nondisclosure agreement and may only be used or reproduced in accordance * with the terms of those agreements. Dissemination of this information to * any party or parties not specified in the license agreement and/or * nondisclosure agreement is expressly prohibited. * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of Maxim Integrated * Products, Inc. shall not be used except as stated in the Maxim Integrated * Products, Inc. Branding Policy. * * The mere transfer of this software does not imply any licenses * of trade secrets, proprietary technology, copyrights, patents, * trademarks, maskwork rights, or any other form of intellectual * property whatsoever. Maxim Integrated Products, Inc. retains all * ownership rights. ******************************************************************************* */ #include "Max4146x.h" #include <iostream> using namespace std; const uint8_t default_register_value_0[17] = {0x90, 0x81, 0x03, 0x00, 0x00, 0x04, 0x80, 0x80, 0x60, 0x00, 0x00, 0xC4, 0xDE, 0x98, 0x28, 0x04, 0x02}; const uint8_t default_register_value_1[20] = {0x90, 0x81, 0x03, 0x00, 0x00, 0x04, 0x80, 0x80, 0x60, 0x00, 0x00, 0xC4, 0xDE, 0x98, 0x28, 0x04, 0x04, 0x00, 0xFF, 0x00}; template <class REG> MAX4146X<REG>::MAX4146X(REG *reg, SPI *spi, DigitalOut *cs) { operation_mode = UNINITIALIZED; if (reg == NULL) { return; } if (cs == NULL) { return; } this->reg = reg; ssel = cs; if (spi == NULL) { return; } spi_handler = spi; i2c_handler = NULL; preset_mode = 0; if (initial_programming() < 0) { return; } this->crystal_frequency = 16.0; this->center_frequency = 315.0; this->baud_rate = 5000.0; //5 kHz operation_mode = INITIALIZED; } template <class REG> MAX4146X<REG>::MAX4146X(REG *reg, SPI *spi) { operation_mode = UNINITIALIZED; if (reg == NULL) { return; } this->reg = reg; if (spi == NULL) { return; } spi_handler = spi; i2c_handler = NULL; ssel = NULL; preset_mode = 0; if (initial_programming() < 0) { return; } this->crystal_frequency = 16.0; this->center_frequency = 315.0; this->baud_rate = 5000.0; //5 kHz operation_mode = INITIALIZED; } template <class REG> MAX4146X<REG>::MAX4146X(REG *reg, I2C *i2c) { operation_mode = UNINITIALIZED; if (reg == NULL) { return; } this->reg = reg; if (i2c == NULL) { return; } i2c_handler = i2c; spi_handler = NULL; ssel = NULL; preset_mode = 0; if (initial_programming() < 0) { return; } this->crystal_frequency = 16.0; this->center_frequency = 315.0; this->baud_rate = 5000.0; //5 kHz operation_mode = INITIALIZED; } template <class REG> MAX4146X<REG>::MAX4146X(DigitalOut *cs) { operation_mode = UNINITIALIZED; if (cs == NULL) { return; } data_sent = cs; data_rate = 5; this->reg = NULL; this->ssel = NULL; spi_handler = NULL; i2c_handler = NULL; preset_mode = 1; operation_mode = INITIALIZED; } template <> int MAX4146X<max41460_reg_map_t>::read_register(uint8_t reg, uint8_t *value, uint8_t len) { int rtn_val = -1; if (value == NULL) { return -1; } if (this->reg == NULL) { return -1; } if (ssel != NULL) { *ssel = 0; } spi_handler->write((uint8_t)0x80 | reg); for (uint8_t i = 0; i < len; i++) { *(value++) = spi_handler->write(0x00); // read back data bytes } if (ssel != NULL) { *ssel = 1; } return 0; } template <class REG> int MAX4146X<REG>::read_register(uint8_t reg, uint8_t *value, uint8_t len) { int rtn_val = -1; if (value == NULL) { return -1; } if (this->reg == NULL) { return -1; } rtn_val = i2c_handler->write(I2C_ADDRESS, (const char *)®, 1, true); if (rtn_val != 0) { return -1; } rtn_val = i2c_handler->read(I2C_ADDRESS, (char *) value, len, false); if (rtn_val < 0) { return rtn_val; } return 0; } template <> int MAX4146X<max41460_reg_map_t>::write_register(uint8_t reg, const uint8_t *value, uint8_t len) { int rtn_val = -1; uint8_t local_data[1 + len]; if (value == NULL) { return -1; } memcpy(&local_data[0], value, len); rtn_val = spi_handler->write(0x7F & reg); // write mode and adress send for (int i = 0; i < len; i++) { rtn_val = spi_handler->write(local_data[i]); // write adress } if (rtn_val != 0) { return rtn_val; } return 0; } template <class REG> int MAX4146X<REG>::write_register(uint8_t reg, const uint8_t *value, uint8_t len) { int rtn_val = -1; uint8_t local_data[1 + len]; if (value == NULL) { return -1; } local_data[0] = reg; memcpy(&local_data[1], value, len); rtn_val = i2c_handler->write(I2C_ADDRESS, (const char *)local_data, sizeof(local_data)); if (rtn_val != 0) { return -1; } return 0; } #define SET_BIT_FIELD(address, reg_name, bit_field_name, value) \ int ret; \ ret = read_register(address, (uint8_t *)&(reg_name), 1); \ if (ret) { \ return ret; \ } \ bit_field_name = value; \ ret = write_register(address, (uint8_t *)&(reg_name), 1); \ if (ret) { \ return ret; \ } template <class REG> int MAX4146X<REG>::set_crystal_frequency(float freq) { if (freq < 250 || freq > 950) { return -1; } this->crystal_frequency = freq; return 0; } template <class REG> float MAX4146X<REG>::get_crystal_frequency() { return this->crystal_frequency; } template <class REG> int MAX4146X<REG>::set_center_frequency(float freq) { if (freq < 250 || freq > 950) { return -1; } this->center_frequency = freq; uint32_t value = (uint32_t)((65536 * freq) / this->crystal_frequency); //65536 is constant defined in the datasheet return this->set_frequency(value); } template <class REG> float MAX4146X<REG>::get_center_frequency() { return this->center_frequency; } template <class REG> int MAX4146X<REG>::adjust_baudrate(float rate) { if (rate < 195.3 || rate > 200000.0) { return -1; } if (this->preset_mode == 1) { this->baud_rate = rate; } int error = 0; uint8_t prediv = 3; if (rate < 12500.0) { error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_5); prediv = (uint8_t)((50000.0 / rate) - 1); } else if (rate < 25000.0) { error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_4); prediv = (uint8_t)((100000.0 / rate) - 1); } else if (rate < 50000.0) { error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_3); prediv = (uint8_t)((200000.0 / rate) - 1); } else if (rate < 100000.0) { error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_2); prediv = (uint8_t)((400000.0 / rate) - 1); } else { error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_1); prediv = (uint8_t)((800000.0 / rate) - 1); } if (error < 0) { return -1; } return this->set_bclk_prediv(prediv); } template <class REG> float MAX4146X<REG>::get_baudrate() { return this->baud_rate; } template <class REG> int MAX4146X<REG>::adjust_frequency_deviation(float deviation) { uint8_t dev = 0; if (this->read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1) < 0) { return -1; } if (this->reg->reg_cfg1.bits.fskshape == 0) { dev = (uint8_t)(deviation * 8.192 / crystal_frequency); if (dev < 127) { return this->set_deltaf(dev); } } else { dev = (uint8_t)(deviation * 81.92 / crystal_frequency); // crystal_frequency in MHz form if (dev < 15) { return this->set_deltaf_shape(dev); } } return -1; } template <class REG> int MAX4146X<REG>::adjust_manchester_bitrate(char rate) { this->data_rate = rate; return 0; } template <class REG> char MAX4146X<REG>::get_manchester_bitrate() { return this->data_rate; } template <> int MAX4146X<max41460_reg_map_t>::send_data(uint8_t *data, uint32_t length) { if (this->preset_mode == 0) { if (ssel != NULL) { *ssel = 0; } spi_handler->write(0x7F & 0x0A); /*write mode and adress send*/ spi_handler->write(0x01); /*write data SPI_EN1 clear*/ if (ssel != NULL) { *ssel = 1; } wait_us(300); /* for waiting another SPI operation*/ if (ssel != NULL) { *ssel = 0; } spi_handler->write(0x7F & 0x10); /*write mode and adress send*/ spi_handler->write(0x03); /*write data SPI_EN2 set*/ if (ssel != NULL) { *ssel = 0; } wait_us(300); /* for waiting another SPI operation*/ } return this->io_write(data, length); } template <class REG> int MAX4146X<REG>::send_data(uint8_t *data, uint32_t length) { if (this->preset_mode == 0) { if (length > 32767) { return -100; } this->adjust_baudrate(this->baud_rate); // this->set_i2c_txen1(I2C_TXEN1_DISABLE); char * value = (char *)malloc(17 * sizeof(char)); if (value == NULL) { return -99; } int rtn_val = i2c_handler->write(I2C_ADDRESS, (char *) 0x00, 1, true); rtn_val = i2c_handler->read(I2C_ADDRESS, value, length, true); if (rtn_val != 0) { return rtn_val; } free(value); uint8_t local_data[4+length]; local_data[0] = CFG7_ADDR; local_data[1] = 0x04; local_data[2] = (uint8_t)((length >> 8) | 0x80); local_data[3] = (uint8_t)((length) & 0x0FF); memcpy(&local_data[4], data, length); i2c_handler->write(I2C_ADDRESS, (const char *)local_data, sizeof(local_data), false); } else { this->io_write(data, length); } return 0; } template <class REG> int MAX4146X<REG>::io_write(uint8_t *data, uint32_t length) { //manchester array manchester_bit_array = new unsigned char[length * 2 * 8]; //bit array bits_array = new unsigned char[length * 8]; //byte to bit conversion for (int i = 0; i < length; i++) { for (int j = 0; j < 8; j++) { // Mask each bit in the byte and store it if (data[i] & (mask << j)) { bits_array[i * 8 + j] = 1; } else { bits_array[i * 8 + j] = 0; } } } //manchester encode for (int i = 0; i < length * 8; i++) { if (bits_array[i] == 0) { //falling edge manchester_bit_array[2 * i] = 1; manchester_bit_array[2 * i + 1] = 0; } else { //rising edge manchester_bit_array[2 * i] = 0; manchester_bit_array[2 * i + 1] = 1; } } delete[] bits_array; //delete bit array anymore not used float result = (500.0 / data_rate); bool rxFinished = false; Timer t; core_util_critical_section_enter(); *this->data_sent = 0; wait_us(100); *this->data_sent = 1; wait_us(350); *this->data_sent = 0; wait_us(10); t.start(); int manch_bit_counter = 0; do { if (t.read_us() >= (result * manch_bit_counter)) { if (manchester_bit_array[manch_bit_counter] == 0) { *this->data_sent = 0; } else { *this->data_sent = 1; } manch_bit_counter++; if (manch_bit_counter >= (length * 2 * 8)) { rxFinished = true; t.stop(); if (this->ssel != NULL) { *this->ssel = 1; } } } } while (!rxFinished); *this->data_sent = 0; core_util_critical_section_exit(); delete[] manchester_bit_array; //manchester array clean return 0; } template <class REG> int MAX4146X<REG>::set_softreset(softreset_t softreset) { SET_BIT_FIELD(CFG8_ADDR, this->reg->reg_cfg8, this->reg->reg_cfg8.bits.softreset, softreset); return 0; } template <class REG> int MAX4146X<REG>::set_xoclkdelay(xoclkdelay_t delay) { SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdelay, delay); return 0; } template <class REG> int MAX4146X<REG>::get_xoclkdelay(xoclkdelay_t *delay) { int ret; ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); if (ret < 0) { return ret; } *delay = (xoclkdelay_t)this->reg->reg_cfg1.bits.xoclkdelay; return 0; } template <class REG> int MAX4146X<REG>::get_fifo_flags(uint8_t *fifo_flags) { return read_register(I2C6_ADDR, fifo_flags, 1); } template <class REG> int MAX4146X<REG>::get_pktcomplete(uint8_t *pktcomplete) { int ret; ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 1); if (ret < 0) { return ret; } *pktcomplete = (uint8_t)this->reg->reg_i2c4.bits.pktcomplete; return 0; } template <class REG> int MAX4146X<REG>::get_tx_pktlen(uint16_t *pktlen) { int ret; ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 2); if (ret < 0) { return ret; } *pktlen = (uint16_t)(((this->reg->reg_i2c4.bits.tx_pktlen_14_to_8) << 8) + (this->reg->reg_i2c5.raw)) ; return 0; } template <class REG> int MAX4146X<REG>::set_xoclkdiv(xoclkdiv_t div) { SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdiv, div); return 0; } template <class REG> int MAX4146X<REG>::get_xoclkdiv(xoclkdiv_t* div) { int ret; ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); if (ret < 0) { return ret; } *div = (xoclkdiv_t)this->reg->reg_cfg1.bits.xoclkdiv; return 0; } template <class REG> int MAX4146X<REG>::set_fskshape(fskshape_t shape) { SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.fskshape, shape); return 0; } template <class REG> int MAX4146X<REG>::get_fskshape(fskshape_t* shape) { int ret; ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); if (ret < 0) { return ret; } *shape = (fskshape_t)this->reg->reg_cfg1.bits.fskshape; return 0; } template <class REG> int MAX4146X<REG>::set_sync(sync_t state) { SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.sync, state); return 0; } template <class REG> int MAX4146X<REG>::get_sync(sync_t* state) { int ret; ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); if (ret < 0) { return ret; } *state = (sync_t)this->reg->reg_cfg1.bits.sync; return 0; } template <class REG> int MAX4146X<REG>::set_modmode(modmode_t mode) { SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.modmode, mode); return 0; } template <class REG> int MAX4146X<REG>::get_modmode(modmode_t* mode) { int ret; ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); if (ret < 0) { return ret; } *mode = (modmode_t)this->reg->reg_cfg1.bits.modmode; return 0; } template <class REG> int MAX4146X<REG>::set_clkout_delay(clkout_delay_t delay) { SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.clkout_delay, delay); return 0; } template <class REG> int MAX4146X<REG>::get_clkout_delay(clkout_delay_t* delay) { int ret; ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1); if (ret < 0) { return ret; } *delay = (clkout_delay_t)this->reg->reg_cfg2.bits.clkout_delay; return 0; } template <class REG> int MAX4146X<REG>::set_bclk_postdiv(bclk_postdiv_t div) { SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.bclk_postdiv, div); return 0; } template <class REG> int MAX4146X<REG>::get_bclk_postdiv(bclk_postdiv_t* div) { int ret; ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1); if (ret < 0) { return ret; } *div = (bclk_postdiv_t)this->reg->reg_cfg2.bits.bclk_postdiv; return 0; } template <class REG> int MAX4146X<REG>::set_bclk_prediv(uint8_t prediv) { if (prediv < 3) { return -1; } SET_BIT_FIELD(CFG3_ADDR, this->reg->reg_cfg3, this->reg->reg_cfg3.bits.bclk_prediv, prediv); return 0; } template <class REG> int MAX4146X<REG>::get_bclk_prediv(uint8_t* prediv) { int ret; ret = read_register(CFG3_ADDR, (uint8_t *) & (this->reg->reg_cfg3), 1); if (ret < 0) { return ret; } *prediv = (uint8_t)this->reg->reg_cfg3.bits.bclk_prediv; return 0; } template <class REG> int MAX4146X<REG>::set_pwdn_mode(pwdn_mode_t pwdn_mode) { SET_BIT_FIELD(CFG4_ADDR, this->reg->reg_cfg4, this->reg->reg_cfg4.bits.pwdn_mode, pwdn_mode); return 0; } template <class REG> int MAX4146X<REG>::get_pwdn_mode(pwdn_mode_t* pwdn_mode) { int ret; ret = read_register(CFG4_ADDR, (uint8_t *) & (this->reg->reg_cfg4), 1); if (ret < 0) { return ret; } *pwdn_mode = (pwdn_mode_t)this->reg->reg_cfg4.bits.pwdn_mode; return 0; } template <class REG> int MAX4146X<REG>::set_tstep(uint8_t tstep) { SET_BIT_FIELD(CFG5_ADDR, this->reg->reg_cfg5, this->reg->reg_cfg5.bits.tstep, tstep); return 0; } template <class REG> int MAX4146X<REG>::get_tstep(uint8_t* tstep) { int ret; ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_cfg5), 1); if (ret < 0) { return ret; } *tstep = (uint8_t)this->reg->reg_cfg5.bits.tstep; return 0; } /*sdivarci*/ template <class REG> int MAX4146X<REG>::set_i2c_txen1(i2c_txen1_t setting) { SET_BIT_FIELD(CFG6_ADDR, this->reg->reg_cfg6, this->reg->reg_cfg6.bits.i2c_txen1, setting); return 0; } template <class REG> int MAX4146X<REG>::set_i2c_txen2(i2c_txen2_t setting) { SET_BIT_FIELD(CFG7_ADDR, this->reg->reg_cfg7, this->reg->reg_cfg7.bits.i2c_txen2, setting); return 0; } template <class REG> int MAX4146X<REG>::set_i2c_data(uint8_t setting) { return write_register(I2C3_ADDR, (uint8_t *)&setting, 1); } template <class REG> int MAX4146X<REG>::set_pa_boost(pa_boost_t pa_boost) { SET_BIT_FIELD(SHDN_ADDR, this->reg->reg_shdn, this->reg->reg_shdn.bits.pa_boost, pa_boost); return 0; } template <class REG> int MAX4146X<REG>::get_pa_boost(pa_boost_t* pa_boost) { int ret; ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_shdn), 1); if (ret < 0) { return ret; } *pa_boost = (pa_boost_t)this->reg->reg_shdn.bits.pa_boost; return 0; } template <class REG> int MAX4146X<REG>::set_papwr(papwr_t papwr) { SET_BIT_FIELD(PA1_ADDR, this->reg->reg_pa1, this->reg->reg_pa1.bits.papwr, papwr); return 0; } template <class REG> int MAX4146X<REG>::get_papwr(papwr_t* papwr) { int ret; ret = read_register(PA1_ADDR, (uint8_t *) & (this->reg->reg_pa1), 1); if (ret < 0) { return ret; } *papwr = (papwr_t)this->reg->reg_pa1.bits.papwr; return 0; } template <class REG> int MAX4146X<REG>::set_pacap(pacap_t pacap) { SET_BIT_FIELD(PA2_ADDR, this->reg->reg_pa2, this->reg->reg_pa2.bits.pacap, pacap); return 0; } template <class REG> int MAX4146X<REG>::get_pacap(pacap_t* pacap) { int ret; ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_pa2), 1); if (ret < 0) { return ret; } *pacap = (pacap_t)this->reg->reg_pa2.bits.pacap; return 0; } template <class REG> int MAX4146X<REG>::set_cplin(cplin_t cplin) { SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.cplin, cplin); return 0; } template <class REG> int MAX4146X<REG>::get_cplin(cplin_t* cplin) { int ret; ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); if (ret < 0) { return ret; } *cplin = (cplin_t)this->reg->reg_pll1.bits.cplin; return 0; } template <class REG> int MAX4146X<REG>::set_fracmode(fracmode_t fracmode) { SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.fracmode, fracmode); return 0; } template <class REG> int MAX4146X<REG>::get_fracmode(fracmode_t* fracmode) { int ret; ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); if (ret < 0) { return ret; } *fracmode = (fracmode_t)this->reg->reg_pll1.bits.fracmode; return 0; } template <class REG> int MAX4146X<REG>::set_lodiv(lodiv_t lodiv) { SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lodiv, lodiv); return 0; } template <class REG> int MAX4146X<REG>::get_lodiv(lodiv_t* lodiv) { int ret; ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); if (ret < 0) { return ret; } *lodiv = (lodiv_t)this->reg->reg_pll1.bits.lodiv; return 0; } template <class REG> int MAX4146X<REG>::set_lomode(lomode_t lomode) { SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lomode, lomode); return 0; } template <class REG> int MAX4146X<REG>::get_lomode(lomode_t* lomode) { int ret; ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); if (ret < 0) { return ret; } *lomode = (lomode_t)this->reg->reg_pll1.bits.lomode; return 0; } template <class REG> int MAX4146X<REG>::set_cpval(cpval_t cpval) { SET_BIT_FIELD(PLL2_ADDR, this->reg->reg_pll2, this->reg->reg_pll2.bits.cpval, cpval); return 0; } template <class REG> int MAX4146X<REG>::get_cpval(cpval_t* cpval) { int ret; ret = read_register(PLL2_ADDR, (uint8_t *) & (this->reg->reg_pll2), 1); if (ret < 0) { return ret; } *cpval = (cpval_t)this->reg->reg_pll2.bits.cpval; return 0; } template <class REG> int MAX4146X<REG>::set_frequency(uint32_t freq) { uint8_t value[3] = {(uint8_t)(freq >> 16), (uint8_t)(freq >> 8), (uint8_t)freq}; return write_register(PLL3_ADDR, (uint8_t *)&value, 3); } template <class REG> int MAX4146X<REG>::get_frequency(uint32_t* freq) { int ret; uint8_t value[3]; ret = read_register(PLL3_ADDR, (uint8_t *)&value, 3); if (ret < 0) { return ret; } *freq = (uint32_t)((value[0] << 16) + (value[1] << 8) + value[2]); return 0; } template <class REG> int MAX4146X<REG>::set_deltaf(uint8_t deltaf) { if (deltaf > 127) { return -1; } SET_BIT_FIELD(PLL6_ADDR, this->reg->reg_pll6, this->reg->reg_pll6.bits.deltaf, deltaf); return 0; } template <class REG> int MAX4146X<REG>::get_deltaf(uint8_t* deltaf) { int ret; ret = read_register(PLL6_ADDR, (uint8_t *) & (this->reg->reg_pll6), 1); if (ret < 0) { return ret; } *deltaf = (uint8_t)this->reg->reg_pll6.bits.deltaf; return 0; } template <class REG> int MAX4146X<REG>::set_deltaf_shape(uint8_t deltaf_shape) { if (deltaf_shape > 15) { return -1; } SET_BIT_FIELD(PLL7_ADDR, this->reg->reg_pll7, this->reg->reg_pll7.bits.deltaf_shape, deltaf_shape); return 0; } template <class REG> int MAX4146X<REG>::get_deltaf_shape(uint8_t* deltaf_shape) { int ret; ret = read_register(PLL7_ADDR, (uint8_t *) & (this->reg->reg_pll7), 1); if (ret < 0) { return ret; } *deltaf_shape = (uint8_t)this->reg->reg_pll7.bits.deltaf_shape; return 0; } template <class REG> int MAX4146X<REG>::set_pktlen_mode(pktlen_mode_t pktlen_mode) { SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_mode, pktlen_mode); return 0; } template <class REG> int MAX4146X<REG>::get_pktlen_mode(pktlen_mode_t* pktlen_mode) { int ret; ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1); if (ret < 0) { return ret; } *pktlen_mode = (pktlen_mode_t)this->reg->reg_i2c1.bits.pktlen_mode; return 0; } template <class REG> int MAX4146X<REG>::set_i2c_pktlen(uint16_t pktlen) { if (pktlen > 0x7FF) { return -1; } SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_14_to_8, (uint8_t)((pktlen >> 8) & 0x07)); uint8_t value = (uint8_t)(pktlen & 0xFF); return write_register(I2C2_ADDR, (uint8_t *)&value, 1); } template <class REG> int MAX4146X<REG>::get_i2c_pktlen(uint16_t* pktlen) { int ret; ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1); if (ret < 0) { return ret; } ret = read_register(I2C2_ADDR, (uint8_t *) & (this->reg->reg_i2c2), 1); if (ret < 0) { return ret; } *pktlen = (uint16_t)(((this->reg->reg_i2c1.raw & 0x7F)<<8) + (this->reg->reg_i2c2.raw &0x7F)); return 0; } template <class REG> int MAX4146X<REG>::initial_programming(void) { uint8_t value = 0x80; write_register(ADDL2_ADDR, (uint8_t *)&value, 1); return write_register(CFG1_ADDR, default_register_value_1, 20); } template <> int MAX4146X<max41460_reg_map_t>::initial_programming(void) { if (this->ssel != NULL){ *this->ssel = 0; wait_us(100); } int rtn = write_register(CFG1_ADDR, default_register_value_0, 17); if (this->ssel != NULL){ wait_us(90); *this->ssel = 1; } return rtn; } template class MAX4146X<max41460_reg_map_t>; template class MAX4146X<max41461_2_reg_map_t>; template class MAX4146X<max41463_4_reg_map_t>;