MAX7032 Transceiver Mbed Driver

Max7032.cpp

Committer:
Sinan Divarci
Date:
2021-08-02
Revision:
0:65766360f6b9

File content as of revision 0:65766360f6b9:

/*******************************************************************************
 * Copyright(C) Maxim Integrated Products, Inc., All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files(the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * 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 <iostream>
#include "Max7032.h"
#include "math.h"

using namespace std;

const uint8_t rx_quick_start[Q_START_CONF_LEN] = {0xFA,0x04,0x00,0x02,0x00,0xB0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const uint8_t tx_quick_start[Q_START_CONF_LEN] = {0xFE,0x04,0x40,0x02,0x00,0xB0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0xB5,0x00,0x00};

MAX7032::MAX7032(SPI *spi, DigitalOut *cs, DigitalOut *powerPin, PinName dataPin, DigitalOut *dioPin, DigitalOut *trxPin)
{
    operation_mode = UNINITIALIZED;

    if (spi == NULL || cs == NULL || powerPin == NULL || dataPin == NULL || dioPin == NULL || trxPin == NULL)
        return;

    max7032_reg_map_t reg;

    reg_map     = &reg;
    spi_handler = spi;
    ssel        = cs;
    power_pin   = powerPin;
    data_pin    = dataPin;
    dio         = dioPin;
    trx_pin     = trxPin;
    preset_mode = 0;

    encoding            = Manchester;
    f_xtal   = 16.0f;
    f_rf    = 315.0f;
    fsk_dev = 0.05f;

    data_rate = 1.0f;
    data_read = NULL;
    data_send = NULL;

    if (initial_programming() < 0)
        return;

    operation_mode = INITIALIZED;
}

MAX7032::MAX7032(SPI *spi, DigitalOut *powerPin, PinName dataPin, DigitalOut *dioPin, DigitalOut *trxPin)
{
    operation_mode = UNINITIALIZED;

    if (spi == NULL || powerPin == NULL || dataPin == NULL || dioPin == NULL || trxPin == NULL)
        return;

    max7032_reg_map_t reg;

    reg_map     = &reg;
    spi_handler = spi;
    ssel        = NULL;
    power_pin   = powerPin;
    data_pin    = dataPin;
    dio         = dioPin;
    trx_pin     = trxPin;
    preset_mode = 0;

    encoding            = Manchester;
    f_xtal   = 16.0f;
    f_rf    = 315.0f;
    fsk_dev = 0.05f;

    data_rate = 1.0f;
    data_read = NULL;
    data_send = NULL;

    if (initial_programming() < 0)
        return;

    operation_mode = INITIALIZED;
}

MAX7032::~MAX7032()
{
    if(data_read != NULL)
        delete data_read;

    if(data_send != NULL)
        delete data_send;
}

int MAX7032::read_register(uint8_t reg, uint8_t *value)
{

    int rtn_val = 0;
//Since 3-wire spi is not supported by mbed, the read_register function must be implemented by the user.
//Here you can find an implemented read_register function for the max32630fthr.
#if defined(TARGET_MAX32630FTHR)
    if (value == NULL) {
        return -1;
    }

    if (this->reg_map == NULL) {
        return -1;
    }

    spi_handler->format(8,0);
    spi_handler->frequency(400000);

    if (ssel != NULL) {
        *ssel = 0;
    }
    spi_handler->write((uint8_t)0x80 | reg); // Set R/W bit 1 for reading
    spi_handler->write(0x00);     // dummy write command for waiting data read

    MAX7032_SPI->mstr_cfg |= MXC_F_SPIM_MSTR_CFG_THREE_WIRE_MODE;

    // Disable SPI for General Control Configuration
    MAX7032_SPI->gen_ctrl = 0;
    MAX7032_SPI->gen_ctrl |= (MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN | MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN | MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE | (1 << MXC_F_SPIM_GEN_CTRL_SIMPLE_MODE_POS)); // simple header

    MAX7032_SPI->simple_headers &= 0x0000FFFF;
    MAX7032_SPI->simple_headers |= 0x2016<<16;
    MAX7032_SPI->gen_ctrl |=MXC_F_SPIM_GEN_CTRL_START_RX_ONLY;

    if (ssel != NULL) {
        *ssel = 1;
        wait_us(5);
        *ssel = 0;
    }

    // Enable the SPI
    MAX7032_SPI->gen_ctrl |= MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN;

    volatile mxc_spim_fifo_regs_t *fifo;

    fifo = MXC_SPIM_GET_SPIM_FIFO(MXC_SPIM_GET_IDX(MAX7032_SPI));

    int avail = ((MAX7032_SPI->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) >> MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS);

    Timer *t = NULL;
    t = new Timer();

    t->start();

    while (avail < 1) {
        if (t->read_ms() > 1000) {
            rtn_val = -1;
            break;
        } else {
            avail = ((MAX7032_SPI->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) >> MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS);
        }
    }

    t->stop();

    *(value++) = fifo->rslts_8[0];

    while (MAX7032_SPI->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) {
        fifo->rslts_8[0];
    }

    MAX7032_SPI->gen_ctrl = 0;
    MAX7032_SPI->gen_ctrl |= (MXC_F_SPIM_GEN_CTRL_TX_FIFO_EN | MXC_F_SPIM_GEN_CTRL_RX_FIFO_EN | MXC_F_SPIM_GEN_CTRL_ENABLE_SCK_FB_MODE | (0 << MXC_F_SPIM_GEN_CTRL_SIMPLE_MODE_POS)); // simple header

    MAX7032_SPI->gen_ctrl |= MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN;

    if (ssel != NULL) {
        *ssel = 1;
    }

    t->~Timer();
    delete t;
#else
    if (value == NULL) {
        return -1;
    }

    if (this->reg_map == NULL) {
        return -2;
    }

    spi_handler->format(8,0);
    spi_handler->frequency(400000);

    if (ssel != NULL) {
        *ssel = 0;
    }
    spi_handler->write((uint8_t)0x80 | reg);

    spi_handler->write(0x00);     // dummy write command for waiting data read

    *(value++) = spi_handler->write(0x00);     // read back  data bytes

    if (ssel != NULL) {
        *ssel = 1;
    }
#endif
    *dio = 0;
    return rtn_val;
}

int MAX7032::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);

    if (ssel != NULL) {
        *ssel = 0;
    }

    rtn_val = spi_handler->write(0x40 | reg); // write mode and adress send
    for (int i = 0; i < len; i++) {
        rtn_val = spi_handler->write(local_data[i]); // write adress
    }

    if (ssel != NULL) {
        *ssel = 1;
    }

    *dio = 0;

    if (rtn_val < 0) {
        return rtn_val;
    }

    return 0;
}

#define SET_BIT_FIELD(address, reg_name, bit_field_name, value)                         \
        do {                                                                            \
            int ret;                                                                    \
            ret = read_register(address, (uint8_t *)&(reg_name));                       \
            if (ret) {                                                                  \
                return ret;                                                             \
            }                                                                           \
            bit_field_name = value;                                                     \
            ret = write_register(address, (uint8_t *)&(reg_name), 1);                   \
            if (ret) {                                                                  \
                return ret;                                                             \
            }                                                                           \
        } while (0)

int MAX7032::initial_programming(void)
{
    uint8_t address;

    set_power_on_off(1);

    rx_quich_start();

    set_center_freq(f_rf);
    adjust_osc_freq(f_xtal);
    set_trx_state(MAX7032::RECEIVE_MODE);

    return -1;
}

int MAX7032::rx_quich_start(void)
{
    uint8_t address;
    int ret;

    for(address = 0; address < Q_START_CONF_LEN; address++)
    {
        if(address == 4)
            continue;

        ret = write_register(address, (uint8_t *)&(rx_quick_start[address]), 1);
        if (ret) {
            return ret;
        }

//        ((max7032_dummy_t *)(&this->reg_map->power + address))->raw = rx_quick_start[address];
    }

    this->reg_map->power.raw        = rx_quick_start[POWER_ADDR];
    this->reg_map->contrl.raw       = rx_quick_start[CONTRL_ADDR];
    this->reg_map->conf0.raw        = rx_quick_start[CONF0_ADDR];
    this->reg_map->conf1.raw        = rx_quick_start[CONF1_ADDR];
    this->reg_map->osc.raw          = rx_quick_start[OSC_ADDR];
    this->reg_map->toff_upper.raw   = rx_quick_start[TOFFMSB_ADDR];
    this->reg_map->toff_lower.raw   = rx_quick_start[TOFFLSB_ADDR];
    this->reg_map->tcpu.raw         = rx_quick_start[TCPU_ADDR];
    this->reg_map->trf_upper.raw    = rx_quick_start[TRFMSB_ADDR];
    this->reg_map->trf_lower.raw    = rx_quick_start[TRFLSB_ADDR];
    this->reg_map->ton_upper.raw    = rx_quick_start[TONMSB_ADDR];
    this->reg_map->ton_lower.raw    = rx_quick_start[TONLSB_ADDR];
    this->reg_map->txlow_upper.raw  = rx_quick_start[TXLOWMSB_ADDR];
    this->reg_map->txlow_lower.raw  = rx_quick_start[TXLOWLSB_ADDR];
    this->reg_map->txhigh_upper.raw = rx_quick_start[TXHIGHMSB_ADDR];
    this->reg_map->txhigh_lower.raw = rx_quick_start[TXHIGHLSB_ADDR];

    return 0;
}

int MAX7032::tx_quich_start(void)
{
    uint8_t address;
    int ret;

    for(address = 0; address < Q_START_CONF_LEN; address++)
    {
        if(address == 4)
            continue;

        ret = write_register(address, (uint8_t *)&(tx_quick_start[address]), 1);
        if (ret) {
            return ret;
        }

//        ((max7032_dummy_t *)(&this->reg_map->power + address))->raw = tx_quick_start[address];
    }

    this->reg_map->power.raw        = tx_quick_start[POWER_ADDR];
    this->reg_map->contrl.raw       = tx_quick_start[CONTRL_ADDR];
    this->reg_map->conf0.raw        = tx_quick_start[CONF0_ADDR];
    this->reg_map->conf1.raw        = tx_quick_start[CONF1_ADDR];
    this->reg_map->osc.raw          = tx_quick_start[OSC_ADDR];
    this->reg_map->toff_upper.raw   = tx_quick_start[TOFFMSB_ADDR];
    this->reg_map->toff_lower.raw   = tx_quick_start[TOFFLSB_ADDR];
    this->reg_map->tcpu.raw         = tx_quick_start[TCPU_ADDR];
    this->reg_map->trf_upper.raw    = tx_quick_start[TRFMSB_ADDR];
    this->reg_map->trf_lower.raw    = tx_quick_start[TRFLSB_ADDR];
    this->reg_map->ton_upper.raw    = tx_quick_start[TONMSB_ADDR];
    this->reg_map->ton_lower.raw    = tx_quick_start[TONLSB_ADDR];
    this->reg_map->txlow_upper.raw  = tx_quick_start[TXLOWMSB_ADDR];
    this->reg_map->txlow_lower.raw  = tx_quick_start[TXLOWLSB_ADDR];
    this->reg_map->txhigh_upper.raw = tx_quick_start[TXHIGHMSB_ADDR];
    this->reg_map->txhigh_lower.raw = tx_quick_start[TXHIGHLSB_ADDR];
    return 0;
}

int MAX7032::set_power_on_off(uint8_t power)
{

    if (power == 0) {  // Shut down the device

        *this->power_pin = 0;

    } else { // Turn on the device

        *this->power_pin = 0;
        wait_us(1500);
        *this->power_pin = 1;
    }

    return 0;
}

int MAX7032::get_bit_field(reg_bits_t bit_field, uint8_t *val)
{
    uint8_t reg_addr, bit_pos, reg_val, reg_mask;

    reg_addr = bit_field / 8;
    bit_pos = bit_field % 8;

    int ret;
    ret = read_register(reg_addr, (uint8_t *)&(reg_val));
    if (ret) {
        return ret;
    }

    reg_mask = 0x01;
    reg_val = reg_val >> bit_pos;
    reg_val &= reg_mask;

    *val = reg_val;

    return 0;
}

int MAX7032::set_bit_field(reg_bits_t bit_field, uint8_t val)
{
    uint8_t reg_addr, bit_pos, reg_val, reg_mask;

    reg_addr = bit_field / 8;
    bit_pos = bit_field % 8;

    int ret;
    ret = read_register(reg_addr, (uint8_t *)&(reg_val));
    if (ret) {
        return ret;
    }

    reg_mask = 0x01;
    reg_mask = reg_mask << bit_pos;

    if(val == 0)
        reg_val &= ~reg_mask;
    else if(val == 1)
        reg_val |= reg_mask;
    else
        return -1;

    ret = write_register(reg_addr, (uint8_t *)&reg_val, 1);
    if (ret) {
        return ret;
    }

    if(reg_addr == POWER_ADDR)
        this->reg_map->power.raw = reg_val;
    else if(reg_addr == CONTRL_ADDR)
        this->reg_map->contrl.raw = reg_val;
    else if(reg_addr == CONF0_ADDR)
        this->reg_map->conf0.raw = reg_val;
    else if(reg_addr == CONF1_ADDR)
        this->reg_map->conf1.raw = reg_val;
    else
        return -2;

    return 0;
}

int MAX7032::set_lna(uint8_t lna)
{
    if(lna > 1)
        return -1;

    SET_BIT_FIELD(POWER_ADDR, this->reg_map->power, this->reg_map->power.bits.lna, lna);

    return 0;
}

int MAX7032::get_lna()
{
    int ret;

    ret = read_register(POWER_ADDR, (uint8_t *) & (this->reg_map->power));
    if (ret < 0)
        return ret;

    return this->reg_map->power.bits.lna;
}

int MAX7032::set_agc(uint8_t agc)
{
    if(agc > 1)
        return -1;

    SET_BIT_FIELD(POWER_ADDR, this->reg_map->power, this->reg_map->power.bits.agc, agc);

    return 0;
}

int MAX7032::get_agc()
{
    int ret;

    ret = read_register(POWER_ADDR, (uint8_t *) & (this->reg_map->power));
    if (ret < 0)
        return ret;

    return this->reg_map->power.bits.agc;
}

int MAX7032::set_mixer(uint8_t mixer)
{
    if(mixer > 1)
        return -1;

    SET_BIT_FIELD(POWER_ADDR, this->reg_map->power, this->reg_map->power.bits.mixer, mixer);

    return 0;
}

int MAX7032::get_mixer()
{
    int ret;

    ret = read_register(POWER_ADDR, (uint8_t *) & (this->reg_map->power));
    if (ret < 0)
        return ret;

    return this->reg_map->power.bits.mixer;
}

int MAX7032::set_baseb(uint8_t baseb)
{
    if(baseb > 1)
        return -1;

    SET_BIT_FIELD(POWER_ADDR, this->reg_map->power, this->reg_map->power.bits.baseb, baseb);

    return 0;
}

int MAX7032::get_baseb()
{
    int ret;

    ret = read_register(POWER_ADDR, (uint8_t *) & (this->reg_map->power));
    if (ret < 0)
        return ret;

    return this->reg_map->power.bits.baseb;
}

int MAX7032::set_pkdet(uint8_t pkdet)
{
    if(pkdet > 1)
        return -1;

    SET_BIT_FIELD(POWER_ADDR, this->reg_map->power, this->reg_map->power.bits.pkdet, pkdet);

    return 0;
}

int MAX7032::get_pkdet()
{
    int ret;

    ret = read_register(POWER_ADDR, (uint8_t *) & (this->reg_map->power));
    if (ret < 0)
        return ret;

    return this->reg_map->power.bits.pkdet;
}

int MAX7032::set_pa(uint8_t pa)
{
    if(pa > 1)
        return -1;

    SET_BIT_FIELD(POWER_ADDR, this->reg_map->power, this->reg_map->power.bits.pa, pa);

    return 0;
}

int MAX7032::get_pa()
{
    int ret;

    ret = read_register(POWER_ADDR, (uint8_t *) & (this->reg_map->power));
    if (ret < 0)
        return ret;

    return this->reg_map->power.bits.pa;
}

int MAX7032::set_rssio(uint8_t rssio)
{
    if(rssio > 1)
        return -1;

    SET_BIT_FIELD(POWER_ADDR, this->reg_map->power, this->reg_map->power.bits.rssio, rssio);

    return 0;
}

int MAX7032::get_rssio()
{
    int ret;

    ret = read_register(POWER_ADDR, (uint8_t *) & (this->reg_map->power));
    if (ret < 0)
        return ret;

    return this->reg_map->power.bits.rssio;
}


int MAX7032::set_agclk(uint8_t agclk)
{
    if(agclk > 1)
        return -1;

    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.agclk, agclk);

    if(!get_mgain())
        return -99;

    return 0;
}

int MAX7032::get_agclk()
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    return this->reg_map->contrl.bits.agclk;
}

int MAX7032::set_gain(uint8_t gain)
{
    if(gain > 1)
        return -1;

    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.gain, gain);

    if(!get_mgain())
        return -99;

    return 0;
}

int MAX7032::get_gain()
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    return this->reg_map->contrl.bits.gain;
}

int MAX7032::set_trk_en(uint8_t trk_en)
{
    if(trk_en > 1)
        return -1;

    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.trk_en, trk_en);

    return 0;
}

int MAX7032::get_trk_en()
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    return this->reg_map->contrl.bits.trk_en;
}

int MAX7032::set_pcal()
{
    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.pcal, 1);

    return 0;
}

int MAX7032::get_pcal()
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    return this->reg_map->contrl.bits.pcal;
}

int MAX7032::set_fcal()
{
    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.fcal, 1);

    return 0;
}

int MAX7032::get_fcal()
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    return this->reg_map->contrl.bits.fcal;
}

int MAX7032::set_ckout(uint8_t ckout)
{
    if(ckout > 1)
        return -1;

    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.ckout, ckout);

    return 0;
}

int MAX7032::get_ckout()
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    return this->reg_map->contrl.bits.ckout;
}

int MAX7032::set_sleep(uint8_t sleep)
{
    if(sleep > 1)
        return -1;

    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.sleep, sleep);

    return 0;
}

int MAX7032::get_sleep()
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    return this->reg_map->contrl.bits.sleep;
}

int MAX7032::set_mode(ask_fsk_sel_t ask_fsk_sel)
{
    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.mode, ask_fsk_sel);

    return 0;
}

int MAX7032::get_mode(ask_fsk_sel_t* ask_fsk_sel)
{
    int ret;

    ret = read_register(CONF0_ADDR, (uint8_t *) & (this->reg_map->conf0));
    if (ret < 0)
        return ret;

    *ask_fsk_sel = (ask_fsk_sel_t)this->reg_map->conf0.bits.mode;

    return 0;
}

int MAX7032::get_mode()
{
    int ret;

    ret = read_register(CONF0_ADDR, (uint8_t *) & (this->reg_map->conf0));
    if (ret < 0)
        return ret;

    return this->reg_map->conf0.bits.mode;
}

int MAX7032::set_t_r(uint8_t t_r)
{
    if(t_r > 1)
        return -1;

    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.t_r, t_r);

    return 0;
}

int MAX7032::get_t_r()
{
    int ret;

    ret = read_register(CONF0_ADDR, (uint8_t *) & (this->reg_map->conf0));
    if (ret < 0)
        return ret;

    return this->reg_map->conf0.bits.t_r;
}

int MAX7032::set_mgain(uint8_t mgain)
{
    if(mgain > 1)
        return -1;

    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.mgain, mgain);

    return 0;
}

int MAX7032::get_mgain()
{
    int ret;

    ret = read_register(CONF0_ADDR, (uint8_t *) & (this->reg_map->conf0));
    if (ret < 0)
        return ret;

    return this->reg_map->conf0.bits.mgain;
}

int MAX7032::set_drx(uint8_t drx)
{
    if(drx > 1)
        return -1;

    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.drx, drx);

    return 0;
}

int MAX7032::get_drx()
{
    int ret;

    ret = read_register(CONF0_ADDR, (uint8_t *) & (this->reg_map->conf0));
    if (ret < 0)
        return ret;

    return this->reg_map->conf0.bits.drx;
}


int MAX7032::set_acal(uint8_t acal)
{
    if(acal > 1)
        return -1;

    SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.acal, acal);

    return 0;
}

int MAX7032::get_acal()
{
    int ret;

    ret = read_register(CONF1_ADDR, (uint8_t *) & (this->reg_map->conf1));
    if (ret < 0)
        return ret;

    return this->reg_map->conf1.bits.acal;
}

int MAX7032::set_clkof(uint8_t clkof)
{
    if(clkof > 1)
        return -1;

    SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.clkof, clkof);

    return 0;
}

int MAX7032::get_clkof()
{
    int ret;

    ret = read_register(CONF1_ADDR, (uint8_t *) & (this->reg_map->conf1));
    if (ret < 0)
        return ret;

    return this->reg_map->conf1.bits.clkof;
}

int MAX7032::set_cdiv(uint8_t cdiv)
{
    if(cdiv > 3)
        return -1;

    SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.cdiv, cdiv);

    return 0;
}

int MAX7032::get_cdiv()
{
    int ret;

    ret = read_register(CONF1_ADDR, (uint8_t *) & (this->reg_map->conf1));
    if (ret < 0)
        return ret;

    return this->reg_map->conf1.bits.cdiv;
}

int MAX7032::set_dt(uint8_t dt)
{
    if(dt > 7)
        return -1;

    SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.dt, dt);

    return 0;
}

int MAX7032::get_dt()
{
    int ret;

    ret = read_register(CONF1_ADDR, (uint8_t *) & (this->reg_map->conf1));
    if (ret < 0)
        return ret;

    return this->reg_map->conf1.bits.dt;
}

int MAX7032::set_osc(uint8_t osc)
{
    SET_BIT_FIELD(OSC_ADDR, this->reg_map->osc, this->reg_map->osc.bits.osc, osc);

    return 0;
}

int MAX7032::get_osc()
{
    int ret;

    ret = read_register(OSC_ADDR, (uint8_t *) & (this->reg_map->osc));
    if (ret < 0)
        return ret;

    return this->reg_map->osc.bits.osc;
}

int MAX7032::set_toff(uint16_t toff)
{
    uint8_t toff_lsb, toff_msb;

    if(toff > 65535)
        return -99;

    toff_lsb = (uint8_t)(toff & 0x00FF);
    toff_msb = (uint8_t)((toff & 0xFF00) >> 8);

    SET_BIT_FIELD(TOFFMSB_ADDR, this->reg_map->toff_upper, this->reg_map->toff_upper.bits.toff_upper, toff_msb);
    SET_BIT_FIELD(TOFFLSB_ADDR, this->reg_map->toff_lower, this->reg_map->toff_lower.bits.toff_lower, toff_lsb);

    return 0;
}

uint16_t MAX7032::get_toff()
{
    uint8_t toff_lsb, toff_msb;
    uint16_t toff = 0;

    if(read_register(TOFFLSB_ADDR, (uint8_t *) & (this->reg_map->toff_lower)) < 0)
        return -1;

    if(read_register(TOFFMSB_ADDR, (uint8_t *) & (this->reg_map->toff_upper)) < 0)
        return -2;

    toff = this->reg_map->toff_upper.bits.toff_upper;
    toff = toff << 8;
    toff |= this->reg_map->toff_lower.bits.toff_lower;

    return toff;
}

int MAX7032::set_tcpu(uint8_t tcpu)
{
    SET_BIT_FIELD(TCPU_ADDR, this->reg_map->tcpu, this->reg_map->tcpu.bits.tcpu, tcpu);

    return 0;
}

uint8_t MAX7032::get_tcpu()
{
    int ret;

    ret = read_register(TCPU_ADDR, (uint8_t *) & (this->reg_map->tcpu));
    if (ret < 0)
        return ret;

    return this->reg_map->tcpu.bits.tcpu;
}

int MAX7032::set_trf(uint16_t trf)
{
    uint8_t trf_lsb, trf_msb;

    if(trf > 65535)
        return -99;

    trf_lsb = (uint8_t)(trf & 0x00FF);
    trf_msb = (uint8_t)((trf & 0xFF00) >> 8);

    SET_BIT_FIELD(TRFMSB_ADDR, this->reg_map->trf_upper, this->reg_map->trf_upper.bits.trf_upper, trf_msb);
    SET_BIT_FIELD(TRFLSB_ADDR, this->reg_map->trf_lower, this->reg_map->trf_lower.bits.trf_lower, trf_lsb);

    return 0;
}

uint16_t MAX7032::get_trf()
{
    uint8_t trf_lsb, trf_msb;
    uint16_t trf = 0;

    if(read_register(TRFLSB_ADDR, (uint8_t *) & (this->reg_map->trf_lower)) < 0)
        return -1;

    if(read_register(TRFMSB_ADDR, (uint8_t *) & (this->reg_map->trf_upper)) < 0)
        return -2;

    trf = this->reg_map->trf_upper.bits.trf_upper;
    trf = trf << 8;
    trf |= this->reg_map->trf_lower.bits.trf_lower;

    return trf;
}

int MAX7032::set_ton(uint16_t ton)
{
    uint8_t ton_lsb, ton_msb;

    if(ton > 65535)
        return -99;

    ton_lsb = (uint8_t)(ton & 0x00FF);
    ton_msb = (uint8_t)((ton & 0xFF00) >> 8);

    SET_BIT_FIELD(TONMSB_ADDR, this->reg_map->ton_upper, this->reg_map->ton_upper.bits.ton_upper, ton_msb);
    SET_BIT_FIELD(TONLSB_ADDR, this->reg_map->ton_lower, this->reg_map->ton_lower.bits.ton_lower, ton_lsb);

    return 0;
}

uint16_t MAX7032::get_ton()
{
    uint8_t ton_lsb, ton_msb;
    uint16_t ton = 0;

    if(read_register(TONLSB_ADDR, (uint8_t *) & (this->reg_map->ton_lower)) < 0)
        return -1;

    if(read_register(TONMSB_ADDR, (uint8_t *) & (this->reg_map->ton_upper)) < 0)
        return -2;

    ton = this->reg_map->ton_upper.bits.ton_upper;
    ton = ton << 8;
    ton |= this->reg_map->ton_lower.bits.ton_lower;

    return ton;
}

int MAX7032::set_txlow(int txlow_val)
{
    uint8_t tx_low_lsb, tx_low_msb;

    if(txlow_val > 65535)
        return -99;

    tx_low_lsb = (uint8_t)(txlow_val & 0x00FF);
    tx_low_msb = (uint8_t)((txlow_val & 0xFF00) >> 8);


    SET_BIT_FIELD(TXLOWLSB_ADDR, this->reg_map->txlow_lower, this->reg_map->txlow_lower.bits.txlow_lower, tx_low_lsb);
    SET_BIT_FIELD(TXLOWMSB_ADDR, this->reg_map->txlow_upper, this->reg_map->txlow_upper.bits.txlow_upper, tx_low_msb);

    return 0;
}

int MAX7032::get_txlow()
{
    uint8_t tx_low_lsb, tx_low_msb;
    uint32_t tx_low = 0;

    if(read_register(TXLOWLSB_ADDR, (uint8_t *)&tx_low_lsb) < 0)
        return -1;

    if(read_register(TXLOWMSB_ADDR, (uint8_t *)&tx_low_msb) < 0)
        return -2;

    tx_low = tx_low_msb;
    tx_low = tx_low << 8;
    tx_low |= tx_low_lsb;

    return tx_low;
}

int MAX7032::set_txhigh(int txhigh_val)
{
    uint8_t tx_high_lsb, tx_high_msb;

    if(txhigh_val > 65535)
        return -99;

    tx_high_lsb = (uint8_t)(txhigh_val & 0x00FF);
    tx_high_msb = (uint8_t)((txhigh_val & 0xFF00) >> 8);

    SET_BIT_FIELD(TXHIGHLSB_ADDR, this->reg_map->txhigh_lower, this->reg_map->txhigh_lower.bits.txhigh_lower, tx_high_lsb);
    SET_BIT_FIELD(TXHIGHMSB_ADDR, this->reg_map->txhigh_upper, this->reg_map->txhigh_upper.bits.txhigh_upper, tx_high_msb);

    return 0;
}

int MAX7032::get_txhigh()
{
    uint8_t tx_high_lsb, tx_high_msb;
    uint32_t tx_high = 0;

    if(read_register(TXHIGHLSB_ADDR, (uint8_t *)&tx_high_lsb) < 0)
        return -1;

    if(read_register(TXHIGHMSB_ADDR, (uint8_t *)&tx_high_msb) < 0)
        return -2;

    tx_high = tx_high_msb;
    tx_high = tx_high << 8;
    tx_high |= tx_high_lsb;

    return tx_high;
}

int MAX7032::get_lckd()
{
    int ret;

    ret = read_register(STATUS_ADDR, (uint8_t *) & (this->reg_map->status));
    if (ret < 0)
        return ret;

    return this->reg_map->status.bits.lckd;
}

int MAX7032::get_gains()
{
    int ret;

    ret = read_register(STATUS_ADDR, (uint8_t *) & (this->reg_map->status));
    if (ret < 0)
        return ret;

    return this->reg_map->status.bits.gains;
}

int MAX7032::get_clkon()
{
    int ret;

    ret = read_register(STATUS_ADDR, (uint8_t *) & (this->reg_map->status));
    if (ret < 0)
        return ret;

    return this->reg_map->status.bits.clkon;
}

int MAX7032::get_pcald()
{
    int ret;

    ret = read_register(STATUS_ADDR, (uint8_t *) & (this->reg_map->status));
    if (ret < 0)
        return ret;

    return this->reg_map->status.bits.pcald;
}

int MAX7032::get_fcald()
{
    int ret;

    ret = read_register(STATUS_ADDR, (uint8_t *) & (this->reg_map->status));
    if (ret < 0)
        return ret;

    return this->reg_map->status.bits.fcald;
}

int MAX7032::adjust_clockout(cdiv_t cdiv)
{
    if(cdiv == DISABLE) {
        SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.ckout, 0);
        return 0;
    }

    if(cdiv == F_XTAL) {
        SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.cdiv, 0);
    }else if(cdiv == F_XTAL_X0_5) {
        SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.cdiv, 1);
    }else if(cdiv == F_XTAL_X0_25) {
        SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.cdiv, 2);
    }else if(cdiv == F_XTAL_X0_125) {
        SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.cdiv, 3);
    }else{
        return -1;
    }

    SET_BIT_FIELD(CONTRL_ADDR, this->reg_map->contrl, this->reg_map->contrl.bits.ckout, 1);
    return 0;
}

int MAX7032::get_clockout_conf(cdiv_t *cdiv)
{
    int ret;

    ret = read_register(CONTRL_ADDR, (uint8_t *) & (this->reg_map->contrl));
    if (ret < 0)
        return ret;

    if(this->reg_map->contrl.bits.ckout == 0){
        *cdiv = DISABLE;
        return 0;
    }

    ret = read_register(CONF1_ADDR, (uint8_t *) & (this->reg_map->conf1));
    if (ret < 0)
        return ret;

    if(this->reg_map->conf1.bits.cdiv == 0)
        *cdiv = F_XTAL;
    else if(this->reg_map->conf1.bits.cdiv == 1)
        *cdiv = F_XTAL_X0_5;
    else if(this->reg_map->conf1.bits.cdiv == 2)
        *cdiv = F_XTAL_X0_25;
    else if(this->reg_map->conf1.bits.cdiv == 3)
        *cdiv = F_XTAL_X0_125;
    else
        return -1;

    return 0;
}

int MAX7032::set_ofps(uint8_t ofps)
{
    if(ofps > 3)
        return -1;

    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.ofps, ofps);

    return 0;
}

int MAX7032::get_ofps()
{
    int ret;

    ret = read_register(CONF0_ADDR, (uint8_t *) & (this->reg_map->conf0));
    if (ret < 0)
        return ret;

    return (int)this->reg_map->conf0.bits.ofps;
}

int MAX7032::set_onps(uint8_t onps)
{
    if(onps > 3)
        return -1;

    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.onps, onps);

    return 0;
}

int MAX7032::get_onps()
{
    int ret;

    ret = read_register(CONF0_ADDR, (uint8_t *) & (this->reg_map->conf0));
    if (ret < 0)
        return ret;

    return (int)this->reg_map->conf0.bits.onps;
}

int MAX7032::adjust_osc_freq(float osc_freq)
{
    uint8_t osc_reg_val;

    if (osc_freq < 12.05 || osc_freq > 18.31)
        return -99;

    osc_reg_val = (osc_freq*1000) / 100;

    if(write_register(OSC_ADDR, &osc_reg_val, 1) >= 0)
    {
        f_xtal = osc_freq;
        return 0;
    }

    return -1;
}

float MAX7032::get_osc_freq()
{
    return f_xtal;
}

int MAX7032::set_center_freq(float center_freq)
{
    uint8_t tx_low_msb, tx_low_lsb, tx_high_msb, tx_high_lsb;
    uint16_t center_freq_reg_val;
    int fsk_high, fsk_low, ask_fsk_sel;

    if (center_freq < 300 || center_freq > 450)
        return -99;

    ask_fsk_sel = this->get_mode();

    if(ask_fsk_sel < 0){
        return -98;
    }

    if(ask_fsk_sel == ASK_FSK_SEL_ASK){
        center_freq_reg_val = (uint16_t)round(((center_freq / f_xtal) - 16) * 4096);

        tx_low_lsb = (uint8_t)(center_freq_reg_val & 0x00FF);
        tx_low_msb = (uint8_t)((center_freq_reg_val & 0xFF00) >> 8);

        if(write_register(TXLOWLSB_ADDR, &tx_low_lsb, 1) < 0)
            return -1;
        if(write_register(TXLOWMSB_ADDR, &tx_low_msb, 1) < 0)
            return -2;
    }
    else{
        fsk_high = round(((center_freq + fsk_dev) / f_xtal - 16) * 4096);
        fsk_low = round(((center_freq - fsk_dev) / f_xtal - 16) * 4096);

        tx_low_lsb = ((uint)(fsk_low) & 0X00FF);
        tx_low_msb = ((uint)(fsk_low) & 0XFF00) >> 8;
        tx_high_lsb = ((uint)(fsk_high) & 0X00FF);
        tx_high_msb = ((uint)(fsk_high) & 0XFF00) >> 8;

        if(write_register(TXLOWLSB_ADDR, &tx_low_lsb, 1) < 0)
            return -3;
        if(write_register(TXLOWMSB_ADDR, &tx_low_msb, 1) < 0)
            return -4;
        if(write_register(TXHIGHLSB_ADDR, &tx_high_lsb, 1) < 0)
            return -5;
        if(write_register(TXHIGHMSB_ADDR, &tx_high_msb, 1) < 0)
            return -6;
    }

    f_rf = center_freq;

    return 0;
}

float MAX7032::get_center_freq()
{
    return f_rf;
}

int MAX7032::set_data_rate(float data_rate_set)
{
    if(encoding == Manchester){
        if(data_rate_set < 0 || data_rate_set > 33)
            return -99;
    }
    else{
        if(data_rate_set < 0 || data_rate_set > 66)
            return -99;
    }

    this->data_rate = data_rate_set;
    return 0;
}

float MAX7032::get_data_rate()
{
    return this->data_rate;
}

int MAX7032::set_fsk_dev(float fsk_dev_set)
{
    if(fsk_dev_set <= 0 || fsk_dev_set > fsk_dev_max)
        return -99;

    this->fsk_dev = fsk_dev_set;

    return set_center_freq(f_rf);
}

float MAX7032::get_fsk_dev()
{
    return this->fsk_dev;
}

int MAX7032::set_encoding(encoding_t encoding_set)
{
    this->encoding = encoding_set;
    return 0;
}

int MAX7032::get_encoding()
{
    return this->encoding;
}

int MAX7032::adjust_agc_dwell_timer(uint8_t k_val)
{
    if(k_val < 9 || k_val > 23)
        return -99;

    if(!(k_val & 0x01))
        return -98;

    k_val = (k_val - 9) / 2;

    SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.dt, k_val);
    return 0;
}

int MAX7032::adjust_agc_dwell_timer(int dwell_time)
{
    float k_val;
    uint8_t k_val_byte;

    if(dwell_time <= 0)
        return -99;

    k_val = log10(dwell_time * f_xtal) * 3.3;
    k_val_byte = (uint8_t)ceil(k_val);

    if(!(k_val_byte & 0x01))
        k_val_byte++;

    if(k_val_byte < 9)
        k_val_byte = 9;

    if(k_val_byte > 23)
        return -1;

    k_val_byte = (k_val_byte - 9) / 2;

    SET_BIT_FIELD(CONF1_ADDR, this->reg_map->conf1, this->reg_map->conf1.bits.dt, k_val_byte);
    return 0;
}

int MAX7032::get_agc_dwell_timer()
{
    int ret;
    uint8_t k_val;

    ret = read_register(CONF1_ADDR, (uint8_t *) & (this->reg_map->conf1));
    if (ret < 0)
        return ret;

    k_val = (2 * this->reg_map->conf1.bits.dt) + 9;

    return (int)(pow(2, k_val) / f_xtal);
}

int MAX7032::adjust_off_timer(timer_base_t time_base, int timer_val)
{
    uint8_t toff_msb, toff_lsb;

    if(timer_val < 1 || timer_val > 65535)
        return -99;

    toff_msb = (uint8_t)((timer_val & 0xFF00) >> 8);
    toff_lsb = (uint8_t)(timer_val & 0x00FF);

    if(write_register(TOFFMSB_ADDR, &toff_msb, 1) < 0)
        return -1;
    if(write_register(TOFFLSB_ADDR, &toff_lsb, 1) < 0)
        return -2;

    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.ofps, time_base);

    return 0;
}

int MAX7032::adjust_off_timer(int toff_time)
{
    int time_base, ton_reg_val;
    timer_base_t timer_base_param;

    if(toff_time < 7860000){  //7.86s
        time_base = 120;
        timer_base_param = US_120;
    }else if(toff_time < 31460000){  //31.46s
        time_base = 480;
        timer_base_param = US_480;
    }else if(toff_time < 126000000){  //2min 6s
        time_base = 1920;
        timer_base_param = US_1920;
    }else if(toff_time < 503000000){  //8min 23s
        time_base = 7680;
        timer_base_param = US_7680;
    }else{
        return -99;
    }

    ton_reg_val = toff_time / time_base;

    if((ton_reg_val * time_base) < toff_time)
        ton_reg_val++;

    adjust_off_timer(timer_base_param, ton_reg_val);

    return 0;
}

int MAX7032::get_off_timer()
{
    uint8_t toff_msb, toff_lsb;
    int timer_val, time_base, ret;

    time_base = this->get_ofps();

    if(time_base < 0)
        return -1;

    ret = read_register(TOFFMSB_ADDR, (uint8_t *)&toff_msb);
    if (ret < 0)
        return -2;

    ret = read_register(TOFFLSB_ADDR, (uint8_t *)&toff_lsb);
    if (ret < 0)
        return -3;

    timer_val = toff_msb;
    timer_val = timer_val << 8;
    timer_val += toff_lsb;

    if(time_base == 0)
        return timer_val * 120;
    if(time_base == 1)
        return timer_val * 480;
    if(time_base == 2)
        return timer_val * 1920;
    if(time_base == 3)
        return timer_val * 7680;

    return -4;
}

int MAX7032::adjust_on_timer(timer_base_t time_base, int timer_val)
{
    uint8_t ton_msb, ton_lsb;

    if(timer_val < 1 || timer_val > 65535)
        return -99;

    ton_msb = (uint8_t)((timer_val & 0xFF00) >> 8);
    ton_lsb = (uint8_t)(timer_val & 0x00FF);

    if(write_register(TONMSB_ADDR, &ton_msb, 1) < 0)
        return -1;
    if(write_register(TONLSB_ADDR, &ton_lsb, 1) < 0)
        return -2;

    SET_BIT_FIELD(CONF0_ADDR, this->reg_map->conf0, this->reg_map->conf0.bits.onps, time_base);

    return 0;
}

int MAX7032::adjust_on_timer(int ton_time)
{
    int time_base, ton_reg_val;
    timer_base_t timer_base_param;

    if(ton_time < 7860000){  //7.86s
        time_base = 120;
        timer_base_param = US_120;
    }else if(ton_time < 31460000){  //31.46s
        time_base = 480;
        timer_base_param = US_480;
    }else if(ton_time < 126000000){  //2min 6s
        time_base = 1920;
        timer_base_param = US_1920;
    }else if(ton_time < 503000000){  //8min 23s
        time_base = 7680;
        timer_base_param = US_7680;
    }else{
        return -99;
    }

    ton_reg_val = ton_time / time_base;

    if((ton_reg_val * time_base) < ton_time)
        ton_reg_val++;

    adjust_on_timer(timer_base_param, ton_reg_val);

    return 0;
}

int MAX7032::get_on_timer()
{
    uint8_t ton_msb, ton_lsb;
    int timer_val, time_base, ret;

    time_base = this->get_onps();

    if(time_base < 0)
        return -1;

    ret = read_register(TONMSB_ADDR, (uint8_t *)&ton_msb);
    if (ret < 0)
        return -2;

    ret = read_register(TONLSB_ADDR, (uint8_t *)&ton_lsb);
    if (ret < 0)
        return -3;

    timer_val = ton_msb;
    timer_val = timer_val << 8;
    timer_val += ton_lsb;

    if(time_base == 0)
        return timer_val * 120;
    if(time_base == 1)
        return timer_val * 480;
    if(time_base == 2)
        return timer_val * 1920;
    if(time_base == 3)
        return timer_val * 7680;

    return -4;
}

int MAX7032::adjust_cpu_recovery_timer(int tcpu_time)
{
    uint8_t tcpu;

    if(tcpu_time > 30600)
        return -99;

    tcpu =  tcpu_time / 120;

    if((tcpu * 120) < tcpu_time)
        tcpu++;

    SET_BIT_FIELD(TCPU_ADDR, this->reg_map->tcpu, this->reg_map->tcpu.bits.tcpu, tcpu);

    return 0;
}

int MAX7032::get_cpu_recovery_timer()
{
    uint8_t tcpu;
    int ret;

    ret = read_register(TCPU_ADDR, (uint8_t *)&tcpu);
    if (ret < 0)
        return -1;

    return tcpu * 120;
}

int MAX7032::adjust_rf_settling_timer(int trf_time)
{
    uint8_t trf_msb, trf_lsb;
    uint16_t timer_val;

    if(trf_time > 7864200)
        return -99;

    timer_val = trf_time / 120;

    if((timer_val*120) < trf_time)
        timer_val++;

    trf_msb = (uint8_t)((timer_val & 0xFF00) >> 8);
    trf_lsb = (uint8_t)(timer_val & 0x00FF);

    SET_BIT_FIELD(TRFMSB_ADDR, this->reg_map->trf_upper, this->reg_map->trf_upper.bits.trf_upper, trf_msb);
    SET_BIT_FIELD(TRFLSB_ADDR, this->reg_map->trf_lower, this->reg_map->trf_lower.bits.trf_lower, trf_lsb);

    return 0;
}

int MAX7032::get_rf_settling_timer()
{
    uint8_t trf_msb, trf_lsb;
    int timer_val, ret;

    ret = read_register(TRFMSB_ADDR, (uint8_t *)&trf_msb);
    if (ret < 0)
        return -1;

    ret = read_register(TRFLSB_ADDR, (uint8_t *)&trf_lsb);
    if (ret < 0)
        return -2;

    timer_val = trf_msb;
    timer_val = timer_val << 8;
    timer_val += trf_lsb;

    return timer_val * 120;
}

int MAX7032::set_trx_state(trx_state_t trx_state)
{
    if(trx_state == RECEIVE_MODE){
        if(data_send != NULL){
            delete this->data_send;
            this->data_send = NULL;
        }

        if(data_read == NULL){
            this->data_read = new DigitalIn(data_pin);
            this->data_read->mode(OpenDrain);
        }

        if( set_t_r(RECEIVE_MODE) < 0)
            return -1;

        if(trx_pin == NULL) //trx state depends on how the trx pin is connected
            return -2;

        trx_pin->write(RECEIVE_MODE);

        return 0;

    }else{
        if(data_read != NULL){
            delete this->data_read;
            this->data_read = NULL;
        }

        if(data_send == NULL){
            this->data_send = new DigitalOut(MAX7032_MBED_DATA_PIN);
            *data_send = 0;
        }

        return set_t_r(TRANSMIT_MODE);
    }
}

int MAX7032::get_trx_state()
{
    if(get_t_r())
        return TRANSMIT_MODE;

    if(trx_pin == NULL) //trx state depends on how the trx pin is connected
        return -1;

    return trx_pin->read();
}

int MAX7032::rf_transmit_data(uint8_t *data, uint8_t data_len)
{
    uint8_t *coded_data;
    uint8_t byte_idx, bit_idx;
    uint32_t bit_duration, coded_data_len, coded_data_idx, transmit_time = 0, curr_time;
    Timer timer;

    if(data == NULL)
        return -99;

    if(get_trx_state() == RECEIVE_MODE)
        return -98;

    if(encoding == Manchester){
        coded_data = new uint8_t[data_len * 2];

        if(coded_data == NULL)
            return -97;

        for(byte_idx = 0; byte_idx < data_len; byte_idx++)
        {
            for(bit_idx = 0; bit_idx < 8; bit_idx++)
            {
                if(data[byte_idx] & (0x80 >> bit_idx)){
                    coded_data[byte_idx * 2 + (bit_idx / 4)] |=  (0x80>>((bit_idx % 4) * 2));
                    coded_data[byte_idx * 2 + (bit_idx / 4)] &= ~(0x80>>((bit_idx % 4) * 2 + 1));
                } else{
                    coded_data[byte_idx * 2 + (bit_idx / 4)] &= ~(0x80>>((bit_idx % 4) * 2));
                    coded_data[byte_idx * 2 + (bit_idx / 4)] |=  (0x80>>((bit_idx % 4) * 2 + 1));
                }
            }
        }

        bit_duration = 1000 / (data_rate*2);  //us
        coded_data_len = data_len * 2;
    }
    else if(encoding == NRZ){
        coded_data = new uint8_t[data_len];

        if(coded_data == NULL)
            return -96;

        for(byte_idx = 0; byte_idx < data_len; byte_idx++)
        {
            coded_data[byte_idx] = data[byte_idx];
        }

        bit_duration = 1000 / data_rate;  //us
        coded_data_len = data_len;
    }

    timer.start();

    core_util_critical_section_enter();

    for(coded_data_idx = 0; coded_data_idx < coded_data_len; coded_data_idx++)
    {
        for(bit_idx = 0; bit_idx < 8; bit_idx++)
        {
            while(1)
            {
                curr_time = timer.read_us();
                if((curr_time - transmit_time) >= bit_duration){
                    transmit_time = curr_time;

                    if(coded_data[coded_data_idx] & (0x80 >> bit_idx))
                        *data_send = 1;
                    else
                        *data_send = 0;
                    break;
                }
            }
        }
    }

    while(1)
    {
        curr_time = timer.read_us();
        if((curr_time - transmit_time) >= bit_duration){
            *data_send = 0;
            break;
        }
    }

    core_util_critical_section_exit();

    delete coded_data;

    return 0;
}

int MAX7032::rf_receive_data(uint8_t *coded_data, uint8_t coded_data_len)
{
    uint8_t byte_idx, bit_idx;
    uint32_t   bit_duration, coded_data_idx, read_time = 0, curr_time;
    Timer timer;

    if(coded_data == NULL)
        return -99;

    if(get_trx_state() == TRANSMIT_MODE)
        return -98;

    if(encoding == Manchester){
        bit_duration = 1000 / (data_rate*4);  //us
    }else{
        bit_duration = 1000 / (data_rate*2);  //us
    }

    core_util_critical_section_enter();

    timer.start();

    for(coded_data_idx = 0; coded_data_idx < coded_data_len; coded_data_idx++)
    {
        for(bit_idx = 0; bit_idx < 8; bit_idx++)
        {
            while(1)
            {
                curr_time = timer.read_us();
                if((curr_time - read_time) >= bit_duration){
                    if(data_read->read())
                        coded_data[coded_data_idx] |=  (0x80 >> bit_idx);
                    else
                        coded_data[coded_data_idx] &= ~(0x80 >> bit_idx);

                    read_time = curr_time;
                    break;
                }
            }
        }
        core_util_critical_section_exit();
    }

    return 0;
}

int MAX7032::set_trx_pin(trx_state_t pin_state)
{
    if(trx_pin == NULL)
        return -1;

    trx_pin->write(pin_state);
    return 0;
}