max4146x_comp
Diff: max4146x/Max4146x.cpp
- Revision:
- 0:0061165683ee
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/max4146x/Max4146x.cpp Sun Oct 25 20:10:02 2020 +0000
@@ -0,0 +1,1212 @@
+/*******************************************************************************
+* 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>;
+
+