MAX4147X RF Receiver Mbed Driver
Fork of MAX4147X by
Max4147x.cpp
- Committer:
- Sinan Divarci
- Date:
- 2021-08-02
- Revision:
- 0:dc5ded118d7c
File content as of revision 0:dc5ded118d7c:
/******************************************************************************* * 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 "Max4147x.h" #include <iostream> using namespace std; const uint8_t default_register_value_0[Q_CONF_LEN] = {0x46,0x26,0x08,0x24,0xA7,0x09,0x0A,0x1F,0x00,0x13,0xAC,0xCD,0x0F,0x00,0x00}; const uint8_t default_register_value_1[Q_CONF_LEN] = {0x44,0x26,0x18,0x24,0x00,0x00,0x00,0x1E,0x00,0x13,0xAC,0xCD,0x0F,0x00,0x00}; float bit_rate_min_max[10][2] = {{0.25, 103}, {0.125, 51.5}, {0.0625, 25.75}, {0.03125, 12.875}, {0.015625, 6.4375}, {0.125, 51.5}, {0.0625, 25.75}, {0.3125, 12.875}, {0.015625, 6.4375}, {0.0078125, 3.21875}}; const int mu1_conf[10] = {-81, -93, -102, -110, -118, -90, -102, -110, -118, -125}; const char ath_tc_conf[8] = {0x14, 0x12, 0x10, 0x0D, 0x09, 0x07, 0x05, 0x04}; const char ath_gc_conf[10] = {0x0B, 0x09, 0x08, 0x07, 0x06, 0x0A, 0x07, 0x06, 0x05, 0x04}; const char nominal_fsk_conf[14] = {80, 57, 44, 40, 29, 22, 20, 14, 11, 10, 7, 5, 3, 2}; const char chf_sel_demod_fsk_conf[14][2] = {{0, 0}, {0, 1}, {0, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}, {3, 4}, {3, 5}, {4, 4}, {4, 5}, {4, 6}}; template <class REG> MAX4147X<REG>::MAX4147X(REG *reg, SPI *spi, DigitalOut *cs, DigitalOut *powerPin, DigitalIn *dataPin) { operation_mode = UNINITIALIZED; if (reg == NULL || spi == NULL || cs == NULL || powerPin == NULL || dataPin == NULL) return; reg_map = reg; spi_handler = spi; ssel = cs; power_pin = powerPin; data_read = dataPin; i2c_handler = NULL; preset_mode = 0; encoding = Manchester; crystal_frequency = 16.0f; center_frequency = 315.0f; baud_rate = 2.0f; baud_rate_ratio = 1.0f; if (initial_programming() < 0) return; operation_mode = INITIALIZED; } template <class REG> MAX4147X<REG>::MAX4147X(REG *reg, SPI *spi, DigitalOut *powerPin, DigitalIn *dataPin) { operation_mode = UNINITIALIZED; if (reg == NULL || spi == NULL || powerPin == NULL || dataPin == NULL) return; reg_map = reg; spi_handler = spi; ssel = NULL; power_pin = powerPin; data_read = dataPin; i2c_handler = NULL; preset_mode = 0; encoding = Manchester; crystal_frequency = 16.0f; center_frequency = 315.0f; baud_rate = 2.0f; baud_rate_ratio = 1.0f; if (initial_programming() < 0) return; operation_mode = INITIALIZED; } template <class REG> MAX4147X<REG>::MAX4147X(REG *reg, I2C *i2c, DigitalOut *powerPin, DigitalIn *dataPin) { operation_mode = UNINITIALIZED; if (reg == NULL || i2c == NULL || powerPin == NULL || dataPin == NULL) return; reg_map = reg; spi_handler = NULL; ssel = NULL; power_pin = powerPin; data_read = dataPin; i2c_handler = i2c; preset_mode = 0; encoding = Manchester; crystal_frequency = 16.0f; center_frequency = 315.0f; baud_rate = 2.0f; baud_rate_ratio = 1.0f; if (initial_programming() < 0) return; operation_mode = INITIALIZED; } template <> int MAX4147X<max41470_reg_map_t>::read_register(uint8_t reg, uint8_t *value, uint8_t len) { int rtn_val = 0; uint8_t readed_byte_cnt = 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 MAX4147X_SPI->mstr_cfg |= MXC_F_SPIM_MSTR_CFG_THREE_WIRE_MODE; // Disable SPI for General Control Configuration MAX4147X_SPI->gen_ctrl = 0; MAX4147X_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 MAX4147X_SPI->simple_headers &= 0x0000FFFF; MAX4147X_SPI->simple_headers |= 0x2016<<16; MAX4147X_SPI->gen_ctrl |=MXC_F_SPIM_GEN_CTRL_START_RX_ONLY; // Enable the SPI MAX4147X_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(MAX4147X_SPI)); int avail = ((MAX4147X_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(); while(readed_byte_cnt < len) { t->start(); while (avail < 1) { if (t->read_ms() > 1000) { rtn_val = -1; break; } else { avail = ((MAX4147X_SPI->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) >> MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS); } } t->stop(); for (int i = 0; i < avail; i++) { *(value++) = fifo->rslts_8[i]; readed_byte_cnt++; } while (MAX4147X_SPI->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) { fifo->rslts_8[0]; } } MAX4147X_SPI->gen_ctrl = 0; MAX4147X_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 MAX4147X_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 for (uint8_t i = 0; i < len; i++) { *(value++) = spi_handler->write(0x00); // read back data bytes } if (ssel != NULL) { *ssel = 1; } #endif return rtn_val; } template <class REG> int MAX4147X<REG>::read_register(uint8_t reg, uint8_t *value, uint8_t len) { int rtn_val; if (value == NULL) { return -1; } if (this->reg_map == NULL) { return -2; } rtn_val = i2c_handler->write(MAX4147X_I2C_ADDRESS, (const char *)®, 1, true); if (rtn_val != 0) { return -3; } rtn_val = i2c_handler->read(MAX4147X_I2C_ADDRESS, (char *) value, len, false); if (rtn_val < 0) { return -4; } return 0; } template <> int MAX4147X<max41470_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); if (ssel != NULL) { *ssel = 0; } 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 (ssel != NULL) { *ssel = 1; } if (rtn_val != 0) { return rtn_val; } return 0; } template <class REG> int MAX4147X<REG>::write_register(uint8_t reg, const uint8_t *value, uint8_t len) { int rtn_val; 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(MAX4147X_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 MAX4147X<REG>::set_rssi_dt(rssi_dt_t rssi_dt) { SET_BIT_FIELD(DEMOD_ADDR, this->reg_map->reg_demod, this->reg_map->reg_demod.bits.rssi_dt, rssi_dt); return 0; } template <class REG> int MAX4147X<REG>::get_rssi_dt(rssi_dt_t* rssi_dt) { int ret; ret = read_register(DEMOD_ADDR, (uint8_t *) & (this->reg_map->reg_demod), 1); if (ret < 0) { return ret; } *rssi_dt = (rssi_dt_t)this->reg_map->reg_demod.bits.rssi_dt; return 0; } template <class REG> int MAX4147X<REG>::set_demod_fsk(demod_fsk_t demod_fsk) { SET_BIT_FIELD(DEMOD_ADDR, this->reg_map->reg_demod, this->reg_map->reg_demod.bits.demod_fsk, demod_fsk); return 0; } template <class REG> int MAX4147X<REG>::get_demod_fsk(demod_fsk_t* demod_fsk) { int ret; ret = read_register(DEMOD_ADDR, (uint8_t *) & (this->reg_map->reg_demod), 1); if (ret < 0) { return ret; } *demod_fsk = (demod_fsk_t)this->reg_map->reg_demod.bits.demod_fsk; return 0; } template <class REG> int MAX4147X<REG>::set_demod_tctrl(demod_tctrl_t demod_tctrl) { SET_BIT_FIELD(DEMOD_ADDR, this->reg_map->reg_demod, this->reg_map->reg_demod.bits.demod_tctrl, demod_tctrl); return 0; } template <class REG> int MAX4147X<REG>::get_demod_tctrl(demod_tctrl_t* demod_tctrl) { int ret; ret = read_register(DEMOD_ADDR, (uint8_t *) & (this->reg_map->reg_demod), 1); if (ret < 0) { return ret; } *demod_tctrl = (demod_tctrl_t)this->reg_map->reg_demod.bits.demod_tctrl; return 0; } template <class REG> int MAX4147X<REG>::set_agc_threl(uint8_t agc_threl) { SET_BIT_FIELD(AGC_ADDR, this->reg_map->reg_agc, this->reg_map->reg_agc.bits.agc_threl, agc_threl); return 0; } template <class REG> int MAX4147X<REG>::get_agc_threl(uint8_t* agc_threl) { int ret; ret = read_register(AGC_ADDR, (uint8_t *) & (this->reg_map->reg_agc), 1); if (ret < 0) { return ret; } *agc_threl = (uint8_t)this->reg_map->reg_agc.bits.agc_threl; return 0; } template <class REG> int MAX4147X<REG>::set_agc_en_bo(agc_en_bo_t agc_op_mode) { SET_BIT_FIELD(AGC_ADDR, this->reg_map->reg_agc, this->reg_map->reg_agc.bits.agc_en_bo, agc_op_mode); return 0; } template <class REG> int MAX4147X<REG>::get_agc_en_bo(agc_en_bo_t* agc_op_mode) { int ret; ret = read_register(AGC_ADDR, (uint8_t *) & (this->reg_map->reg_agc), 1); if (ret < 0) { return ret; } *agc_op_mode = (agc_en_bo_t)this->reg_map->reg_agc.bits.agc_en_bo; return 0; } template <class REG> int MAX4147X<REG>::set_ask_fsk_sel(ask_fsk_sel_t ask_fsk_sel) { SET_BIT_FIELD(IF_CHF_SEL_ADDR, this->reg_map->reg_if_chf_sel, this->reg_map->reg_if_chf_sel.bits.ask_fsk_sel, ask_fsk_sel); return 0; } template <class REG> int MAX4147X<REG>::get_ask_fsk_sel(ask_fsk_sel_t* ask_fsk_sel) { int ret; ret = read_register(IF_CHF_SEL_ADDR, (uint8_t *) & (this->reg_map->reg_if_chf_sel), 1); if (ret < 0) { return ret; } *ask_fsk_sel = (ask_fsk_sel_t)this->reg_map->reg_if_chf_sel.bits.ask_fsk_sel; return 0; } template <class REG> int MAX4147X<REG>::set_if_sel(if_sel_t if_sel) { SET_BIT_FIELD(IF_CHF_SEL_ADDR, this->reg_map->reg_if_chf_sel, this->reg_map->reg_if_chf_sel.bits.if_sel, if_sel); return 0; } template <class REG> int MAX4147X<REG>::get_if_sel(if_sel_t* if_sel) { int ret; ret = read_register(IF_CHF_SEL_ADDR, (uint8_t *) & (this->reg_map->reg_if_chf_sel), 1); if (ret < 0) { return ret; } *if_sel = (if_sel_t)this->reg_map->reg_if_chf_sel.bits.if_sel; return 0; } template <class REG> int MAX4147X<REG>::set_chf_sel(chf_sel_t chf_sel) { SET_BIT_FIELD(IF_CHF_SEL_ADDR, this->reg_map->reg_if_chf_sel, this->reg_map->reg_if_chf_sel.bits.chf_sel, chf_sel); return 0; } template <class REG> int MAX4147X<REG>::get_chf_sel(chf_sel_t* chf_sel) { int ret; ret = read_register(IF_CHF_SEL_ADDR, (uint8_t *) & (this->reg_map->reg_if_chf_sel), 1); if (ret < 0) { return ret; } *chf_sel = (chf_sel_t)this->reg_map->reg_if_chf_sel.bits.chf_sel; return 0; } template <class REG> int MAX4147X<REG>::set_ld_buf(ld_buf_t ld_buf) { SET_BIT_FIELD(PDF_CFG_ADDR, this->reg_map->reg_pdf_cfg, this->reg_map->reg_pdf_cfg.bits.ld_buf, ld_buf); return 0; } template <class REG> int MAX4147X<REG>::get_ld_buf(ld_buf_t* ld_buf) { int ret; ret = read_register(PDF_CFG_ADDR, (uint8_t *) & (this->reg_map->reg_pdf_cfg), 1); if (ret < 0) { return ret; } *ld_buf = (ld_buf_t)this->reg_map->reg_pdf_cfg.bits.ld_buf; return 0; } template <class REG> int MAX4147X<REG>::set_ld_bw(ld_bw_t ld_bw) { SET_BIT_FIELD(PDF_CFG_ADDR, this->reg_map->reg_pdf_cfg, this->reg_map->reg_pdf_cfg.bits.ld_bw, ld_bw); return 0; } template <class REG> int MAX4147X<REG>::get_ld_bw(ld_bw_t* ld_bw) { int ret; ret = read_register(PDF_CFG_ADDR, (uint8_t *) & (this->reg_map->reg_pdf_cfg), 1); if (ret < 0) { return ret; } *ld_bw = (ld_bw_t)this->reg_map->reg_pdf_cfg.bits.ld_bw; return 0; } template <class REG> int MAX4147X<REG>::set_src_lg(src_lg_t src_lg) { SET_BIT_FIELD(PDF_CFG_ADDR, this->reg_map->reg_pdf_cfg, this->reg_map->reg_pdf_cfg.bits.src_lg, src_lg); return 0; } template <class REG> int MAX4147X<REG>::get_src_lg(src_lg_t* src_lg) { int ret; ret = read_register(PDF_CFG_ADDR, (uint8_t *) & (this->reg_map->reg_pdf_cfg), 1); if (ret < 0) { return ret; } *src_lg = (src_lg_t)this->reg_map->reg_pdf_cfg.bits.src_lg; return 0; } template <class REG> int MAX4147X<REG>::set_src_sm(src_sm_t src_sm) { SET_BIT_FIELD(PDF_CFG_ADDR, this->reg_map->reg_pdf_cfg, this->reg_map->reg_pdf_cfg.bits.src_sm, src_sm); return 0; } template <class REG> int MAX4147X<REG>::get_src_sm(src_sm_t* src_sm) { int ret; ret = read_register(PDF_CFG_ADDR, (uint8_t *) & (this->reg_map->reg_pdf_cfg), 1); if (ret < 0) { return ret; } *src_sm = (src_sm_t)this->reg_map->reg_pdf_cfg.bits.src_sm; return 0; } template <class REG> int MAX4147X<REG>::set_ath_lb(uint8_t ath_lb) { SET_BIT_FIELD(ATH_CFG1_ADDR, this->reg_map->reg_ath_cfg1, this->reg_map->reg_ath_cfg1.bits.ath_lb, ath_lb); return 0; } template <class REG> int MAX4147X<REG>::get_ath_lb(uint8_t* ath_lb) { int ret; ret = read_register(ATH_CFG1_ADDR, (uint8_t *) & (this->reg_map->reg_ath_cfg1), 1); if (ret < 0) { return ret; } *ath_lb = (uint8_t)this->reg_map->reg_ath_cfg1.bits.ath_lb; return 0; } template <class REG> int MAX4147X<REG>::set_ath_dt(ath_dt_t ath_dt) { SET_BIT_FIELD(ATH_CFG2_ADDR, this->reg_map->reg_ath_cfg2, this->reg_map->reg_ath_cfg2.bits.ath_dt, ath_dt); return 0; } template <class REG> int MAX4147X<REG>::get_ath_dt(ath_dt_t* ath_dt) { int ret; ret = read_register(ATH_CFG2_ADDR, (uint8_t *) & (this->reg_map->reg_ath_cfg2), 1); if (ret < 0) { return ret; } *ath_dt = (ath_dt_t)this->reg_map->reg_ath_cfg2.bits.ath_dt; return 0; } template <class REG> int MAX4147X<REG>::set_ath_tc(uint8_t ath_tc) { SET_BIT_FIELD(ATH_CFG2_ADDR, this->reg_map->reg_ath_cfg2, this->reg_map->reg_ath_cfg2.bits.ath_tc, ath_tc); return 0; } template <class REG> int MAX4147X<REG>::get_ath_tc(uint8_t* ath_tc) { int ret; ret = read_register(ATH_CFG2_ADDR, (uint8_t *) & (this->reg_map->reg_ath_cfg2), 1); if (ret < 0) { return ret; } *ath_tc = (uint8_t)this->reg_map->reg_ath_cfg2.bits.ath_tc; return 0; } template <class REG> int MAX4147X<REG>::set_ath_type(ath_type_t ath_type) { SET_BIT_FIELD(ATH_CFG3_ADDR, this->reg_map->reg_ath_cfg3, this->reg_map->reg_ath_cfg3.bits.ath_type, ath_type); return 0; } template <class REG> int MAX4147X<REG>::get_ath_type(ath_type_t* ath_type) { int ret; ret = read_register(ATH_CFG3_ADDR, (uint8_t *) & (this->reg_map->reg_ath_cfg3), 1); if (ret < 0) { return ret; } *ath_type = (ath_type_t)this->reg_map->reg_ath_cfg3.bits.ath_type; return 0; } template <class REG> int MAX4147X<REG>::set_ath_bw(ath_bw_t ath_bw) { SET_BIT_FIELD(ATH_CFG3_ADDR, this->reg_map->reg_ath_cfg3, this->reg_map->reg_ath_cfg3.bits.ath_bw, ath_bw); return 0; } template <class REG> int MAX4147X<REG>::get_ath_bw(ath_bw_t* ath_bw) { int ret; ret = read_register(ATH_CFG3_ADDR, (uint8_t *) & (this->reg_map->reg_ath_cfg3), 1); if (ret < 0) { return ret; } *ath_bw = (ath_bw_t)this->reg_map->reg_ath_cfg3.bits.ath_bw; return 0; } template <class REG> int MAX4147X<REG>::set_ath_gc(uint8_t ath_gc) { SET_BIT_FIELD(ATH_CFG3_ADDR, this->reg_map->reg_ath_cfg3, this->reg_map->reg_ath_cfg3.bits.ath_gc, ath_gc); return 0; } template <class REG> int MAX4147X<REG>::get_ath_gc(uint8_t* ath_gc) { int ret; ret = read_register(ATH_CFG3_ADDR, (uint8_t *) & (this->reg_map->reg_ath_cfg3), 1); if (ret < 0) { return ret; } *ath_gc = (uint8_t)this->reg_map->reg_ath_cfg3.bits.ath_gc; return 0; } template <class REG> int MAX4147X<REG>::set_afc_mo(afc_mo_t afc_mo) { SET_BIT_FIELD(AFC_CFG1_ADDR, this->reg_map->reg_afc_cfg1, this->reg_map->reg_afc_cfg1.bits.afc_mo, afc_mo); return 0; } template <class REG> int MAX4147X<REG>::get_afc_mo(afc_mo_t* afc_mo) { int ret; ret = read_register(AFC_CFG1_ADDR, (uint8_t *) & (this->reg_map->reg_afc_cfg1), 1); if (ret < 0) { return ret; } *afc_mo = (afc_mo_t)this->reg_map->reg_afc_cfg1.bits.afc_mo; return 0; } template <class REG> int MAX4147X<REG>::set_afc_lg(afc_lg_t afc_lg) { SET_BIT_FIELD(AFC_CFG1_ADDR, this->reg_map->reg_afc_cfg1, this->reg_map->reg_afc_cfg1.bits.afc_lg, afc_lg); return 0; } template <class REG> int MAX4147X<REG>::get_afc_lg(afc_lg_t* afc_lg) { int ret; ret = read_register(AFC_CFG1_ADDR, (uint8_t *) & (this->reg_map->reg_afc_cfg1), 1); if (ret < 0) { return ret; } *afc_lg = (afc_lg_t)this->reg_map->reg_afc_cfg1.bits.afc_lg; return 0; } template <class REG> int MAX4147X<REG>::set_pad_freeze_afc(pad_freeze_afc_t pad_freeze_afc) { SET_BIT_FIELD(AFC_CFG2_ADDR, this->reg_map->reg_afc_cfg2, this->reg_map->reg_afc_cfg2.bits.pad_freeze_afc, pad_freeze_afc); return 0; } template <class REG> int MAX4147X<REG>::get_pad_freeze_afc(pad_freeze_afc_t* pad_freeze_afc) { int ret; ret = read_register(AFC_CFG2_ADDR, (uint8_t *) & (this->reg_map->reg_afc_cfg2), 1); if (ret < 0) { return ret; } *pad_freeze_afc = (pad_freeze_afc_t)this->reg_map->reg_afc_cfg2.bits.pad_freeze_afc; return 0; } template <class REG> int MAX4147X<REG>::set_lo_ctr_freq_upper(uint8_t lo_ctr_freq_upper) { SET_BIT_FIELD(LO_CTR_FREQ3_ADDR, this->reg_map->reg_lo_ctr_freq3, this->reg_map->reg_lo_ctr_freq3.bits.lo_ctr_freq_23_to_16, lo_ctr_freq_upper); return 0; } template <class REG> int MAX4147X<REG>::get_lo_ctr_freq_upper(uint8_t* lo_ctr_freq_upper) { int ret; ret = read_register(LO_CTR_FREQ3_ADDR, (uint8_t *) & (this->reg_map->reg_lo_ctr_freq3), 1); if (ret < 0) { return ret; } *lo_ctr_freq_upper = (uint8_t)this->reg_map->reg_lo_ctr_freq3.bits.lo_ctr_freq_23_to_16; return 0; } template <class REG> int MAX4147X<REG>::set_lo_ctr_freq_middle(uint8_t lo_ctr_freq_middle) { SET_BIT_FIELD(LO_CTR_FREQ2_ADDR, this->reg_map->reg_lo_ctr_freq2, this->reg_map->reg_lo_ctr_freq2.bits.lo_ctr_freq_15_to_8, lo_ctr_freq_middle); return 0; } template <class REG> int MAX4147X<REG>::get_lo_ctr_freq_middle(uint8_t* lo_ctr_freq_middle) { int ret; ret = read_register(LO_CTR_FREQ2_ADDR, (uint8_t *) & (this->reg_map->reg_lo_ctr_freq2), 1); if (ret < 0) { return ret; } *lo_ctr_freq_middle = (uint8_t)this->reg_map->reg_lo_ctr_freq2.bits.lo_ctr_freq_15_to_8; return 0; } template <class REG> int MAX4147X<REG>::set_lo_ctr_freq_lower(uint8_t lo_ctr_freq_lower) { SET_BIT_FIELD(LO_CTR_FREQ1_ADDR, this->reg_map->reg_lo_ctr_freq1, this->reg_map->reg_lo_ctr_freq1.bits.lo_ctr_freq_7_to_0, lo_ctr_freq_lower); return 0; } template <class REG> int MAX4147X<REG>::get_lo_ctr_freq_lower(uint8_t* lo_ctr_freq_lower) { int ret; ret = read_register(LO_CTR_FREQ1_ADDR, (uint8_t *) & (this->reg_map->reg_lo_ctr_freq1), 1); if (ret < 0) { return ret; } *lo_ctr_freq_lower = (uint8_t)this->reg_map->reg_lo_ctr_freq1.bits.lo_ctr_freq_7_to_0; return 0; } template <class REG> int MAX4147X<REG>::set_preamb_len(uint8_t preamb_len) { SET_BIT_FIELD(PREAMBLE_CFG1_ADDR, this->reg_map->reg_preamble_cfg1, this->reg_map->reg_preamble_cfg1.bits.preamb_len, preamb_len); return 0; } template <class REG> int MAX4147X<REG>::get_preamb_len(uint8_t* preamb_len) { int ret; ret = read_register(PREAMBLE_CFG1_ADDR, (uint8_t *) & (this->reg_map->reg_preamble_cfg1), 1); if (ret < 0) { return ret; } *preamb_len = (uint8_t)this->reg_map->reg_preamble_cfg1.bits.preamb_len; return 0; } template <class REG> int MAX4147X<REG>::set_preamb_word_lower(uint8_t preamb_word_lower) { SET_BIT_FIELD(PREAMBLE_WORD1_ADDR, this->reg_map->reg_preamble_word1, this->reg_map->reg_preamble_word1.bits.preamb_word_7_to_0, preamb_word_lower); return 0; } template <class REG> int MAX4147X<REG>::get_preamb_word_lower(uint8_t* preamb_word_lower) { int ret; ret = read_register(PREAMBLE_WORD1_ADDR, (uint8_t *) & (this->reg_map->reg_preamble_word1), 1); if (ret < 0) { return ret; } *preamb_word_lower = (uint8_t)this->reg_map->reg_preamble_word1.bits.preamb_word_7_to_0; return 0; } template <class REG> int MAX4147X<REG>::set_preamb_word_upper(uint8_t preamb_word_upper) { SET_BIT_FIELD(PREAMBLE_WORD2_ADDR, this->reg_map->reg_preamble_word2, this->reg_map->reg_preamble_word2.bits.preamb_word_15_to_8, preamb_word_upper); return 0; } template <class REG> int MAX4147X<REG>::get_preamb_word_upper(uint8_t* preamb_word_upper) { int ret; ret = read_register(PREAMBLE_WORD2_ADDR, (uint8_t *) & (this->reg_map->reg_preamble_word2), 1); if (ret < 0) { return ret; } *preamb_word_upper = (uint8_t)this->reg_map->reg_preamble_word2.bits.preamb_word_15_to_8; return 0; } template <class REG> int MAX4147X<REG>::get_rssi(uint8_t* rssi) { int ret; ret = read_register(RSSI_ADDR, (uint8_t *) & (this->reg_map->reg_rssi), 1); if (ret < 0) { return ret; } *rssi = (uint8_t)this->reg_map->reg_rssi.bits.rssi; return 0; } template <class REG> int MAX4147X<REG>::get_fei(uint8_t* fei) { int ret; ret = read_register(FEI_ADDR, (uint8_t *) & (this->reg_map->reg_fei), 1); if (ret < 0) { return ret; } *fei = (uint8_t)this->reg_map->reg_fei.bits.fei; return 0; } template <class REG> int MAX4147X<REG>::get_pdf_out(uint8_t* pdf_out) { int ret; ret = read_register(PDF_OUT_ADDR, (uint8_t *) & (this->reg_map->reg_pdf_out), 1); if (ret < 0) { return ret; } *pdf_out = (uint8_t)this->reg_map->reg_pdf_out.bits.pdf_out; return 0; } template <class REG> int MAX4147X<REG>::get_preamb_det(preamb_det_t *preamb_det) { int ret; ret = read_register(ISR_ADDR, (uint8_t *) & (this->reg_map->reg_isr), 1); if (ret < 0) { return ret; } *preamb_det = (preamb_det_t)this->reg_map->reg_isr.bits.preamb_det; return 0; } template <class REG> int MAX4147X<REG>::set_cdr_mode(cdr_mode_t cdr_mode) { SET_BIT_FIELD(CDR_CFG1_ADDR, this->reg_map->reg_cdr_cfg1, this->reg_map->reg_cdr_cfg1.bits.cdr_mode, cdr_mode); return 0; } template <class REG> int MAX4147X<REG>::get_cdr_mode(cdr_mode_t* cdr_mode) { int ret; ret = read_register(CDR_CFG1_ADDR, (uint8_t *) & (this->reg_map->reg_cdr_cfg1), 1); if (ret < 0) { return ret; } *cdr_mode = (cdr_mode_t)this->reg_map->reg_cdr_cfg1.bits.cdr_mode; return 0; } template <class REG> int MAX4147X<REG>::set_en_xo(en_xo_t en_xo) { SET_BIT_FIELD(STATE_CTRL1_ADDR, this->reg_map->reg_state_ctrl1, this->reg_map->reg_state_ctrl1.bits.en_xo, en_xo); return 0; } template <class REG> int MAX4147X<REG>::get_en_xo(en_xo_t* en_xo) { int ret; ret = read_register(STATE_CTRL1_ADDR, (uint8_t *) & (this->reg_map->reg_state_ctrl1), 1); if (ret < 0) { return ret; } *en_xo = (en_xo_t)this->reg_map->reg_state_ctrl1.bits.en_xo; return 0; } template <class REG> int MAX4147X<REG>::set_wut_en(wut_en_t wut_en) { SET_BIT_FIELD(STATE_CTRL1_ADDR, this->reg_map->reg_state_ctrl1, this->reg_map->reg_state_ctrl1.bits.wut_en, wut_en); return 0; } template <class REG> int MAX4147X<REG>::get_wut_en(wut_en_t* wut_en) { int ret; ret = read_register(STATE_CTRL1_ADDR, (uint8_t *) & (this->reg_map->reg_state_ctrl1), 1); if (ret < 0) { return ret; } *wut_en = (wut_en_t)this->reg_map->reg_state_ctrl1.bits.wut_en; return 0; } template <class REG> int MAX4147X<REG>::set_slave_rx_en(slave_rx_en_t slave_rx_en) { SET_BIT_FIELD(STATE_CTRL1_ADDR, this->reg_map->reg_state_ctrl1, this->reg_map->reg_state_ctrl1.bits.slave_rx_en, slave_rx_en); return 0; } template <class REG> int MAX4147X<REG>::get_slave_rx_en(slave_rx_en_t* slave_rx_en) { int ret; ret = read_register(STATE_CTRL1_ADDR, (uint8_t *) & (this->reg_map->reg_state_ctrl1), 1); if (ret < 0) { return ret; } *slave_rx_en = (slave_rx_en_t)this->reg_map->reg_state_ctrl1.bits.slave_rx_en; return 0; } template <class REG> int MAX4147X<REG>::get_rx_state(rx_state_t* rx_state) { int ret; ret = read_register(STATE_CTRL2_ADDR, (uint8_t *) & (this->reg_map->reg_state_ctrl2), 1); if (ret < 0) { return ret; } *rx_state = (rx_state_t)this->reg_map->reg_state_ctrl2.bits.rx_state; return 0; } template <class REG> int MAX4147X<REG>::set_rx_reset_time(rx_reset_time_t rx_reset_time) { SET_BIT_FIELD(STATE_CTRL3_ADDR, this->reg_map->reg_state_ctrl3, this->reg_map->reg_state_ctrl3.bits.rx_reset_time, rx_reset_time); return 0; } template <class REG> int MAX4147X<REG>::get_rx_reset_time(rx_reset_time_t* rx_reset_time) { int ret; ret = read_register(STATE_CTRL3_ADDR, (uint8_t *) & (this->reg_map->reg_state_ctrl3), 1); if (ret < 0) { return ret; } *rx_reset_time = (rx_reset_time_t)this->reg_map->reg_state_ctrl3.bits.rx_reset_time; return 0; } template <class REG> int MAX4147X<REG>::set_tdet(uint8_t tdet) { SET_BIT_FIELD(WUT1_ADDR, this->reg_map->reg_wut1, this->reg_map->reg_wut1.bits.tdet, tdet); return 0; } template <class REG> int MAX4147X<REG>::get_tdet(uint8_t* tdet) { int ret; ret = read_register(WUT1_ADDR, (uint8_t *) & (this->reg_map->reg_wut1), 1); if (ret < 0) { return ret; } *tdet = (uint8_t)this->reg_map->reg_wut1.bits.tdet; return 0; } template <class REG> int MAX4147X<REG>::set_tsby_tdet_ratio(uint8_t tsby_tdet_ratio) { SET_BIT_FIELD(WUT2_ADDR, this->reg_map->reg_wut2, this->reg_map->reg_wut2.bits.tsby_tdet_ratio, tsby_tdet_ratio); return 0; } template <class REG> int MAX4147X<REG>::get_tsby_tdet_ratio(uint8_t* tsby_tdet_ratio) { int ret; ret = read_register(WUT2_ADDR, (uint8_t *) & (this->reg_map->reg_wut2), 1); if (ret < 0) { return ret; } *tsby_tdet_ratio = (uint8_t)this->reg_map->reg_wut2.bits.tsby_tdet_ratio; return 0; } template <class REG> int MAX4147X<REG>::set_xoclkdelay(xoclkdelay_t xoclkdelay) { SET_BIT_FIELD(AFE_CTL1_ADDR, this->reg_map->reg_afe_ctl1, this->reg_map->reg_afe_ctl1.bits.xoclkdelay, xoclkdelay); return 0; } template <class REG> int MAX4147X<REG>::get_xoclkdelay(xoclkdelay_t* xoclkdelay) { int ret; ret = read_register(AFE_CTL1_ADDR, (uint8_t *) & (this->reg_map->reg_afe_ctl1), 1); if (ret < 0) { return ret; } *xoclkdelay = (xoclkdelay_t)this->reg_map->reg_afe_ctl1.bits.xoclkdelay; return 0; } template <class REG> int MAX4147X<REG>::set_xoclkdiv(xoclkdiv_t xoclkdiv) { SET_BIT_FIELD(AFE_CTL1_ADDR, this->reg_map->reg_afe_ctl1, this->reg_map->reg_afe_ctl1.bits.xoclkdiv, xoclkdiv); return 0; } template <class REG> int MAX4147X<REG>::get_xoclkdiv(xoclkdiv_t* xoclkdiv) { int ret; ret = read_register(AFE_CTL1_ADDR, (uint8_t *) & (this->reg_map->reg_afe_ctl1), 1); if (ret < 0) { return ret; } *xoclkdiv = (xoclkdiv_t)this->reg_map->reg_afe_ctl1.bits.xoclkdiv; return 0; } template <class REG> int MAX4147X<REG>::set_mix_hs_lsbar(mix_hs_lsbar_t mix_hs_lsbar) { SET_BIT_FIELD(AFE_CTL1_ADDR, this->reg_map->reg_afe_ctl1, this->reg_map->reg_afe_ctl1.bits.mix_hs_lsbar, mix_hs_lsbar); return 0; } template <class REG> int MAX4147X<REG>::get_mix_hs_lsbar(mix_hs_lsbar_t* mix_hs_lsbar) { int ret; ret = read_register(AFE_CTL1_ADDR, (uint8_t *) & (this->reg_map->reg_afe_ctl1), 1); if (ret < 0) { return ret; } *mix_hs_lsbar = (mix_hs_lsbar_t)this->reg_map->reg_afe_ctl1.bits.mix_hs_lsbar; return 0; } template <class REG> int MAX4147X<REG>::set_lodiv(lodiv_t lodiv) { SET_BIT_FIELD(AFE_CTL1_ADDR, this->reg_map->reg_afe_ctl1, this->reg_map->reg_afe_ctl1.bits.lodiv, lodiv); return 0; } template <class REG> int MAX4147X<REG>::get_lodiv(lodiv_t* lodiv) { int ret; ret = read_register(AFE_CTL1_ADDR, (uint8_t *) & (this->reg_map->reg_afe_ctl1), 1); if (ret < 0) { return ret; } *lodiv = (lodiv_t)this->reg_map->reg_afe_ctl1.bits.lodiv; return 0; } template <class REG> int MAX4147X<REG>::set_fracmode(fracmode_t fracmode) { SET_BIT_FIELD(AFE_CTL1_ADDR, this->reg_map->reg_afe_ctl1, this->reg_map->reg_afe_ctl1.bits.fracmode, fracmode); return 0; } template <class REG> int MAX4147X<REG>::get_fracmode(fracmode_t* fracmode) { int ret; ret = read_register(AFE_CTL1_ADDR, (uint8_t *) & (this->reg_map->reg_afe_ctl1), 1); if (ret < 0) { return ret; } *fracmode = (fracmode_t)this->reg_map->reg_afe_ctl1.bits.fracmode; return 0; } template <class REG> int MAX4147X<REG>::set_ir_adjust(uint8_t ir_adjust) { SET_BIT_FIELD(IR_ADJUST_ADDR, this->reg_map->reg_ir_adjust, this->reg_map->reg_ir_adjust.bits.ir_adjust, ir_adjust); return 0; } template <class REG> int MAX4147X<REG>::get_ir_adjust(uint8_t* ir_adjust) { int ret; ret = read_register(IR_ADJUST_ADDR, (uint8_t *) & (this->reg_map->reg_ir_adjust), 1); if (ret < 0) { return ret; } *ir_adjust = (uint8_t)this->reg_map->reg_ir_adjust.bits.ir_adjust; return 0; } template <class REG> int MAX4147X<REG>::get_part_num(part_num_t* part_num) { int ret; ret = read_register(PART_NUM_ADDR, (uint8_t *) & (this->reg_map->reg_part_num), 1); if (ret < 0) { return ret; } *part_num = (part_num_t)this->reg_map->reg_part_num.bits.part_num; return 0; } template <class REG> int MAX4147X<REG>::get_rev_num(uint8_t* rev_num) { int ret; ret = read_register(REV_NUM_ADDR, (uint8_t *) & (this->reg_map->reg_rev_num), 1); if (ret < 0) { return ret; } *rev_num = (uint8_t)this->reg_map->reg_rev_num.bits.rev_num; return 0; } template <class REG> int MAX4147X<REG>::get_pll_lock(pll_lock_t* pll_lock) { int ret; ret = read_register(STATUS_ADDR, (uint8_t *) & (this->reg_map->reg_status), 1); if (ret < 0) { return ret; } *pll_lock = (pll_lock_t)this->reg_map->reg_status.bits.pll_lock; return 0; } template <class REG> int MAX4147X<REG>::set_crystal_frequency(float freq) { if( ((int)freq == 12)) this->crystal_frequency = 12.8; else if((int)freq == 16) this->crystal_frequency = 16.0; else if((int)freq == 19) this->crystal_frequency = 19.2; else return -1; if(this->adjust_crystal_divider() < 0) return -2; if(this->set_center_frequency(this->center_frequency) < 0) return -3; return 0; } template <class REG> float MAX4147X<REG>::get_crystal_frequency() { return this->crystal_frequency; } template <class REG> int MAX4147X<REG>::adjust_baud_rate(float baud_rate) { int return_val = 0; uint8_t rate_index, src_lg_conf_idx, src_sm_conf_idx; float nearestValue = 400, minDiff = 400; float bit_rate_min, bit_rate_max, bit_rate, pre_rate, conf_rate, recommended_bit_rate, dif0, dif1; if_sel_t *if_sel = (if_sel_t *)malloc(sizeof(if_sel_t)); if(if_sel == NULL) return -99; chf_sel_t *chf_sel = (chf_sel_t *)malloc(sizeof(chf_sel_t)); if(chf_sel == NULL){ free(if_sel); return -98; } src_lg_t *src_lg = (src_lg_t *)malloc(sizeof(src_lg_t)); if(src_lg == NULL){ free(if_sel); free(chf_sel); return -97; } src_sm_t *src_sm = (src_sm_t *)malloc(sizeof(src_sm_t)); if(src_sm == NULL){ free(if_sel); free(chf_sel); free(src_lg); return -96; } if(encoding == Manchester){ bit_rate = baud_rate * 2; recommended_bit_rate = this->baud_rate * 2; }else{ bit_rate = baud_rate; recommended_bit_rate = this->baud_rate; } if (bit_rate > 200.0 || bit_rate < 0){ return_val = -1; goto free_and_return; } if(this->get_if_sel(if_sel) < 0){ return_val = -2; goto free_and_return; } if(this->get_chf_sel(chf_sel) < 0){ return_val = -3; goto free_and_return; } if(this->get_src_lg(src_lg) < 0){ return_val = -4; goto free_and_return; } if(this->get_src_sm(src_sm) < 0){ return_val = -5; goto free_and_return; } rate_index = (*if_sel) * 5 + (*chf_sel); bit_rate_min = bit_rate_min_max[rate_index][0]; bit_rate_max = bit_rate_min_max[rate_index][1]; if(bit_rate < bit_rate_min || bit_rate > bit_rate_max){ return_val = -6; goto free_and_return; } pre_rate = 1600.0 / (pow(2, (*if_sel + *chf_sel))); for (src_sm_conf_idx = 0; src_sm_conf_idx < 8; src_sm_conf_idx++) { for (src_lg_conf_idx = 0; src_lg_conf_idx < 8; src_lg_conf_idx++) { conf_rate = (pre_rate / ((8 + src_sm_conf_idx) * pow(2, src_lg_conf_idx))); dif0 = fabs(bit_rate - conf_rate); dif1 = fabs(bit_rate - floor(conf_rate)); if (dif1 <= nearestValue && dif0 < minDiff && (0.6 * conf_rate) < bit_rate && bit_rate < (1.03 * conf_rate)) { nearestValue = dif1; minDiff = dif0; *src_sm = (src_sm_t)src_sm_conf_idx; *src_lg = (src_lg_t)src_lg_conf_idx; this->baud_rate_ratio = bit_rate / conf_rate; recommended_bit_rate = conf_rate; } } } this->set_src_lg(*src_lg); this->set_src_sm(*src_sm); if(encoding == Manchester) this->baud_rate = recommended_bit_rate/2; else this->baud_rate = recommended_bit_rate; if(this->update_ath_tc() < 0){ return_val = -7; goto free_and_return; } if(this->update_ath_dt() < 0){ return_val = -8; goto free_and_return; } if(this->update_ath_bw() < 0){ return_val = -9; goto free_and_return; } if(this->update_agc_threl() < 0){ return_val = -10; goto free_and_return; } if(this->update_demod_tctrl() < 0){ return_val = -11; goto free_and_return; } if(this->update_ath_lb() < 0){ return_val = -12; goto free_and_return; } free_and_return: free(if_sel); free(chf_sel); free(src_lg); free(src_sm); return return_val; } template <class REG> float MAX4147X<REG>::get_baud_rate() { return this->baud_rate; } template <class REG> int MAX4147X<REG>::set_center_frequency(float freq) { int return_val = 0, lo_ctr_freq_reg_val; float f_if, crystal_frequency; mix_hs_lsbar_t *mix_hs_lsbar = (mix_hs_lsbar_t *)malloc(sizeof(mix_hs_lsbar_t)); if(mix_hs_lsbar == NULL) return -99; if_sel_t *if_sel = (if_sel_t *)malloc(sizeof(if_sel_t)); if(if_sel == NULL){ free(mix_hs_lsbar); return -98; } if(freq < 290 || freq > 960){ return_val = -1; goto free_and_return; } if(freq >= 286.0 && freq<= 320.0) this->set_lodiv(LODIV_286MHZ_TO_320MHZ); else if(freq >= 425.0 && freq<= 480.0) this->set_lodiv(LODIV_425MHZ_TO_480MHZ); else if(freq >= 860.0 && freq<= 960.0) this->set_lodiv(LODIV_860MHZ_TO_960MHZ); else{ return_val = -2; goto free_and_return; } if(this->get_mix_hs_lsbar(mix_hs_lsbar) < 0){ return_val = -3; goto free_and_return; } if(this->get_if_sel(if_sel) < 0){ return_val = -4; goto free_and_return; } crystal_frequency = this->get_crystal_frequency(); if(*if_sel == (IF_SEL_400_KHZ)) f_if = 0.4; //400kHz else f_if = 0.2; //200kHz if(*mix_hs_lsbar == (MIX_HS_LSBAR_TARGET_HT_LO_FREQ)) lo_ctr_freq_reg_val = uint32_t( (65536*(freq - f_if)) / crystal_frequency); else lo_ctr_freq_reg_val = uint32_t( (65536*(freq + f_if)) / crystal_frequency); this->set_lo_ctr_freq_upper(uint8_t(lo_ctr_freq_reg_val>>16)); this->set_lo_ctr_freq_middle(uint8_t(lo_ctr_freq_reg_val>>8)); this->set_lo_ctr_freq_lower(uint8_t(lo_ctr_freq_reg_val)); this->center_frequency = freq; free_and_return: free(mix_hs_lsbar); free(if_sel); return return_val; } template <class REG> float MAX4147X<REG>::get_center_frequency() { return this->center_frequency; } template <class REG> int MAX4147X<REG>::set_power_on_off(uint8_t power) { if (power > 0) { // Shut down the device *this->power_pin = power; } else { // Turn on the device *this->power_pin = 0; wait_us(1500); *this->power_pin = 1; wait_us(1500); *this->power_pin = 0; } return 0; } template <class REG> int MAX4147X<REG>::initial_programming(void) { uint8_t address; this->set_power_on_off(0); this->set_en_xo(EN_XO_EN_XO); wait_us(500); if(this->write_register(0, default_register_value_0, (Q_CONF_LEN-1)) < 0) return -1; if(this->write_register(0x19, &default_register_value_0[Q_CONF_LEN-1], 1) <0 ) return -2; wait_us(500); address = 0x05; if(this->write_register(0x14, &address, 1) < 0) //This will turn on the receiver and place the device into the SlaveRX state. return -3; return 0; } template <class REG> int MAX4147X<REG>::adjust_crystal_divider(void) { if( (int)this->crystal_frequency == 12) return set_xoclkdiv(XOCLKDIV_DIVIDE_BY_4); else if((int)this->crystal_frequency == 16) return set_xoclkdiv(XOCLKDIV_DIVIDE_BY_5); else if((int)this->crystal_frequency == 19) return set_xoclkdiv(XOCLKDIV_DIVIDE_BY_6); else return -1; } template <> int MAX4147X<max41470_reg_map_t>::read_data(uint8_t *data, uint32_t length) { preamb_det_t *preamb_det = (preamb_det_t *)malloc(sizeof(preamb_det_t)); if(preamb_det == NULL){ return -99; } if (this->preset_mode == 0) { if(this->get_preamb_det(preamb_det) < 0){ //ISR Register is Read. PREAMB_DET bit and WUT_EN bit automatically cleared. MAX41470 placed into the Standby State. free(preamb_det); return -1; } if(*preamb_det != PREAMB_DET_PREAMB_DETECTED){ //Interrupt Status Register is not Set! free(preamb_det); return -2; } this->set_slave_rx_en(SLAVE_RX_EN_EN_RECEIVER); //MAX41470 moved from Standby to the SlaveRX state. DATA pin will be stream } free(preamb_det); return this->io_read(data, length); } template <class REG> int MAX4147X<REG>::read_data(uint8_t *data, uint32_t length) { if (this->preset_mode == 0) { if (length > 32767) { return -100; } } else { this->io_read(data, length); } return 0; } template <class REG> int MAX4147X<REG>::io_read(uint8_t *data, uint32_t length) { uint32_t byte_idx, bit_idx, bit_val, bit_cnt = 0; uint32_t signal_period_us, read_period_us, time; float baud_rate; Timer *t = NULL; t = new Timer(); t->start(); baud_rate = this->get_baud_rate(); signal_period_us = 1000000 / baud_rate; read_period_us = signal_period_us/2; core_util_critical_section_enter(); t->reset(); for(byte_idx=0; byte_idx<length; byte_idx++) { data[byte_idx] = 0; for(bit_idx=0; bit_idx<8; bit_idx++) { while(1) { time = t->read_us(); if(byte_idx == 0 && bit_idx == 0) { if(time >= read_period_us/2) { bit_val = uint8_t(data_read->read()); data[byte_idx] |= bit_val<<bit_idx; bit_cnt++; t->reset(); break; } continue; } if(time >= (read_period_us * bit_cnt)) { bit_val = uint8_t(data_read->read()); data[byte_idx] |= bit_val<<bit_idx; bit_cnt++; break; } } } } core_util_critical_section_exit(); t->~Timer(); delete t; return 0; } template <class REG> int MAX4147X<REG>::adjust_encoding_type(encoding_t encoding_type) { int return_val = 0; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ return -99; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } encoding = encoding_type; if(this->update_ath_type() < 0){ return_val = -3; goto free_and_return; } if(this->update_ath_bw() < 0){ return_val = -4; goto free_and_return; } if(this->update_ath_dt() < 0){ return_val = -5; goto free_and_return; } if(this->update_ath_lb() < 0){ return_val = -6; goto free_and_return; } free_and_return: free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::get_encoding_type() { return int(encoding); } template <class REG> int MAX4147X<REG>::adjust_demodulation(ask_fsk_sel_t demodulation_type) { int return_val = 0; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ return -99; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } this->set_ask_fsk_sel(demodulation_type); if(this->update_demod_tctrl() < 0){ return_val = -3; goto free_and_return; } if(this->update_afc_lg() < 0){ return_val = -4; goto free_and_return; } if(this->update_agc_threl() < 0){ return_val = -5; goto free_and_return; } /*Update ASK Bit Fields*/ if(this->update_ath_lb() < 0){ return_val = -6; goto free_and_return; } if(this->update_afc_mo() < 0){ return_val = -7; goto free_and_return; } if(this->update_ath_gc() < 0){ return_val = -8; goto free_and_return; } if(this->update_ath_dt() < 0){ return_val = -9; goto free_and_return; } if(this->update_ath_bw() < 0){ return_val = -10; goto free_and_return; } if(this->update_ath_type() < 0){ return_val = -11; goto free_and_return; } /*End of Update ASK Bit Fields*/ free_and_return: free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_ath_lb(void) { int return_val = 0; float src_ratio = 0; uint8_t src_r0 = 0, src_r1= 0, foo = 0; uint32_t mu_1= 0, mu_2 = 0; char data = 0; chf_sel_t *chf_sel = (chf_sel_t *)malloc(sizeof(chf_sel_t)); if(chf_sel == NULL) return -99; if_sel_t *if_sel = (if_sel_t *)malloc(sizeof(if_sel_t)); if(if_sel == NULL){ free(chf_sel); return -98; } src_lg_t *src_lg = (src_lg_t *)malloc(sizeof(src_lg_t)); if(src_lg == NULL){ free(chf_sel); free(if_sel); return -97; } src_sm_t *src_sm = (src_sm_t *)malloc(sizeof(src_sm_t)); if(src_sm == NULL){ free(chf_sel); free(if_sel); free(src_lg); return -96; } ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL){ free(chf_sel); free(if_sel); free(src_lg); free(src_sm); return -95; } rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(chf_sel); free(if_sel); free(src_lg); free(src_sm); free(ask_fsk_sel); return -94; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto free_and_return; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->set_ath_lb(0) < 0) return_val = -4; goto free_and_return; } if(this->get_if_sel(if_sel) < 0){ return_val = -5; goto free_and_return; } if(this->get_chf_sel(chf_sel) < 0){ return_val = -6; goto free_and_return; } if(this->get_src_sm(src_sm) < 0){ return_val = -7; goto free_and_return; } if(this->get_src_lg(src_lg) < 0){ return_val = -8; goto free_and_return; } src_ratio = *src_lg + log2(*src_sm + 8) - 3; if(src_ratio < 1.0){ src_r0 = 29; src_r1 = 21; } else if (src_ratio < 2){ src_r0 = 21; src_r1 = 15; } else if (src_ratio < 3){ src_r0 = 15; src_r1 = 11; } else if (src_ratio < 4){ src_r0 = 11; src_r1 = 8; } else if (src_ratio < 5){ src_r0 = 8; src_r1 = 6; } else if (src_ratio < 6){ src_r0 = 6; src_r1 = 4; } else if (src_ratio < 7){ src_r0 = 4; src_r1 = 3; } else if (src_ratio < 8){ src_r0 = 3; src_r1 = 2; } else { src_r0 = 2; src_r1 = 2; } mu_1 = mu1_conf[(*if_sel) * 5 + *chf_sel]; mu_2 = (int)round(src_r0 - ((src_r0 - src_r1) * (src_ratio - floor(src_ratio)))); data = (char)(mu_1 + mu_2 - 6); foo = (uint8_t)(data + 256); if(this->set_ath_lb(foo) < 0) return_val = -9; free_and_return: free(chf_sel); free(if_sel); free(src_lg); free(src_sm); free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_ath_type(void) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto free_and_return; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->set_ath_type(ATH_TYPE_PRELPF_MANCHESTER) < 0){ return_val = -4; goto free_and_return; } } else{ if(encoding == Manchester){ if(this->set_ath_type(ATH_TYPE_PRELPF_MANCHESTER) < 0){ return_val = -5; goto free_and_return; } }else{ if(this->set_ath_type(ATH_TYPE_APD_NRZ) < 0){ return_val = -6; goto free_and_return; } } } if(this->update_demod_tctrl() < 0) return_val = -7; free_and_return: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_ath_bw(void) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto free_and_return; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->set_ath_bw(ATH_BW_DEFAULT) < 0) return_val = -4; goto free_and_return; } if(encoding == Manchester){ if(baud_rate_ratio < 0.6){ if(this->set_ath_bw(ATH_BW_DEFAULT_X2) < 0) return_val = -5; }else{ if(this->set_ath_bw(ATH_BW_DEFAULT) < 0) return_val = -6; } }else{ if(this->set_ath_bw(ATH_BW_DEFAULT) < 0) return_val = -7; } free_and_return: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_ath_dt(void) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto free_and_return; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->set_ath_dt(ATH_DT_DEFAULT_DISCHARGE_TIME) < 0) return_val = -4; goto free_and_return; } if(encoding == Manchester){ if(baud_rate_ratio < 0.6){ if(this->set_ath_dt(ATH_DT_DISCHARGE_TIME_X2) < 0) return_val = -5; }else{ if(this->set_ath_dt(ATH_DT_DEFAULT_DISCHARGE_TIME) < 0) return_val = -6; } }else{ if(this->set_ath_dt(ATH_DT_DISCHARGE_TIME_X8) < 0) return_val = -7; } free_and_return: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_ath_tc(void) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; src_lg_t *src_lg = (src_lg_t *)malloc(sizeof(src_lg_t)); if(src_lg == NULL){ free(ask_fsk_sel); return -98; } rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); free(src_lg); return -97; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto free_and_return; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->set_ath_tc(0) < 0) return_val = -4; goto free_and_return; } if(this->get_src_lg(src_lg) < 0){ return_val = -5; goto free_and_return; } if(*src_lg > 7){ return_val = -6; goto free_and_return; } if(this->set_ath_tc(ath_tc_conf[*src_lg]) < 0){ return_val = -7; goto free_and_return; } free_and_return: free(ask_fsk_sel); free(src_lg); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_ath_gc(void) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; chf_sel_t *chf_sel = (chf_sel_t *)malloc(sizeof(chf_sel_t)); if(chf_sel == NULL){ free(ask_fsk_sel); return -98; } if_sel_t *if_sel = (if_sel_t *)malloc(sizeof(if_sel_t)); if(if_sel == NULL){ free(ask_fsk_sel); free(chf_sel); return -97; } rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); free(chf_sel); free(if_sel); return -96; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto free_and_return; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto free_and_return; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto free_and_return; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->set_ath_gc(0) < 0) return_val = -4; goto free_and_return; } if(this->get_if_sel(if_sel) < 0){ return_val = -5; goto free_and_return; } if(this->get_chf_sel(chf_sel) < 0){ return_val = -6; goto free_and_return; } if(this->set_ath_gc(ath_gc_conf[(*if_sel) * 5 + *chf_sel]) < 0){ return_val = -7; goto free_and_return; } free_and_return: free(ask_fsk_sel); free(chf_sel); free(if_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_afc_mo(void) { rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ return -99; } if(this->get_rx_state(rx_state) < 0){ free(rx_state); return -1; } if(*rx_state != RX_STATE_STANDBY){ free(rx_state); return -2; } free(rx_state); return (this->set_afc_mo(AFC_MO_CONF_7) < 0) ? -3 : 0; } template <class REG> int MAX4147X<REG>::update_afc_lg(void) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(this->get_ask_fsk_sel(ask_fsk_sel)){ return_val = -3; goto error; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->set_afc_lg(AFC_LG_CONF_DEFAULT) < 0){ return_val = -4; goto error; } }else{ if(this->set_afc_lg(AFC_LG_CONF_DEFAULT_X2) < 0){ return_val = -5; goto error; } } error: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_agc_threl(void) { int return_val = 0; float bit_rate; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(encoding == Manchester) bit_rate = this->baud_rate * 2; else bit_rate = this->baud_rate; if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto error; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(bit_rate > 51.5){ if(this->set_agc_threl(0x0F) < 0){ return_val = -4; goto error; } }else{ if(this->set_agc_threl(0x09) < 0){ return_val = -5; goto error; } } } else{ if(bit_rate > 26){ if(this->set_agc_threl(0x0F) < 0){ return_val = -6; goto error; } }else{ if(this->set_agc_threl(0x09) < 0){ return_val = -7; goto error; } } } error: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::update_demod_tctrl(void) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; src_lg_t *src_lg = (src_lg_t *)malloc(sizeof(src_lg_t)); if(src_lg == NULL){ free(ask_fsk_sel); return -98; } chf_sel_t *chf_sel = (chf_sel_t *)malloc(sizeof(chf_sel_t)); if(chf_sel == NULL){ free(ask_fsk_sel); free(src_lg); return -97; } ath_type_t *ath_type = (ath_type_t *)malloc(sizeof(ath_type_t)); if(ath_type == NULL){ free(ask_fsk_sel); free(src_lg); free(chf_sel); return -96; } rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); free(src_lg); free(chf_sel); free(ath_type); return -95; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto error; } if(*ask_fsk_sel == ASK_FSK_SEL_FSK){ if(this->get_chf_sel(chf_sel) < 0){ return_val = -4; goto error; } set_demod_tctrl(demod_tctrl_t(4 - *chf_sel)); } else{ if(this->get_ath_type(ath_type) < 0){ return_val = -5; goto error; } if(this->get_src_lg(src_lg) < 0){ return_val = -6; goto error; } if(*ath_type == ATH_TYPE_PRELPF_MANCHESTER){ if(2 + *src_lg < 7) set_demod_tctrl(demod_tctrl_t(2 + *src_lg)); else set_demod_tctrl(demod_tctrl_t(7)); } else{ if(3 + *src_lg < 7) set_demod_tctrl(demod_tctrl_t(3 + *src_lg)); else set_demod_tctrl(demod_tctrl_t(7)); } } error: free(ask_fsk_sel); free(src_lg); free(chf_sel); free(ath_type); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::adjust_receiver_bandwidth(int receiver_bw) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto error; } if(*ask_fsk_sel != ASK_FSK_SEL_ASK){ return_val = -4; goto error; } if(receiver_bw == 340 || receiver_bw == 170) set_chf_sel(CHF_SEL_RXBW_340_170_KHZ); else if(receiver_bw == 120 || receiver_bw == 60) set_chf_sel(CHF_SEL_RXBW_120_60_KHZ); else if(receiver_bw == 52 || receiver_bw == 26) set_chf_sel(CHF_SEL_RXBW_52_26_KHZ); else if(receiver_bw == 24 || receiver_bw == 12) set_chf_sel(CHF_SEL_RXBW_24_12_KHZ); else if(receiver_bw == 12 || receiver_bw == 6) set_chf_sel(CHF_SEL_RXBW_12_6_KHZ); else{ return_val = -5; goto error; } if(this->adjust_baud_rate(this->baud_rate) < 0){ return_val = -6; goto error; } if(this->update_ath_gc() < 0){ return_val = -7; goto error; } if(this->update_ath_lb() < 0){ return_val = -8; goto error; } if(this->update_demod_tctrl() < 0){ return_val = -9; goto error; } error: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::adjust_receiver_bandwidth(int receiver_bw, float deviation) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto error; } if(*ask_fsk_sel != ASK_FSK_SEL_FSK){ return_val = -4; goto error; } if(receiver_bw == 340 || receiver_bw == 170) set_chf_sel(CHF_SEL_RXBW_340_170_KHZ); else if(receiver_bw == 120 || receiver_bw == 60) set_chf_sel(CHF_SEL_RXBW_120_60_KHZ); else if(receiver_bw == 52 || receiver_bw == 26) set_chf_sel(CHF_SEL_RXBW_52_26_KHZ); else if(receiver_bw == 24 || receiver_bw == 12) set_chf_sel(CHF_SEL_RXBW_24_12_KHZ); else if(receiver_bw == 12 || receiver_bw == 6) set_chf_sel(CHF_SEL_RXBW_12_6_KHZ); else{ return_val = -5; goto error; } if(this->adjust_baud_rate(this->baud_rate) < 0){ return_val = -6; goto error; } if(this->update_ath_gc() < 0){ return_val = -7; goto error; } if(this->update_ath_lb() < 0){ return_val = -8; goto error; } if(this->update_demod_tctrl() < 0){ return_val = -9; goto error; } if(this->adjust_fsk_deviation(deviation) < 0){ return_val = -10; goto error; } error: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::adjust_if_sel(if_sel_t if_sel) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto error; } if(*ask_fsk_sel != ASK_FSK_SEL_ASK){ return_val = -4; goto error; } this->set_if_sel(if_sel); if(this->adjust_baud_rate(this->baud_rate) < 0){ return_val = -5; goto error; } if(this->update_ath_gc() < 0){ return_val = -6; goto error; } if(this->update_demod_tctrl() < 0){ return_val = -7; goto error; } if(this->update_ath_lb() < 0){ return_val = -8; goto error; } if(this->set_center_frequency(this->center_frequency) < 0){ return_val = -9; goto error; } error: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::adjust_if_sel(if_sel_t if_sel, float deviation) { int return_val = 0; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); return -98; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto error; } if(*ask_fsk_sel != ASK_FSK_SEL_FSK){ return_val = -4; goto error; } this->set_if_sel(if_sel); if(this->adjust_baud_rate(this->baud_rate) < 0){ return_val = -5; goto error; } if(this->update_ath_gc() < 0){ return_val = -6; goto error; } if(this->update_demod_tctrl() < 0){ return_val = -7; goto error; } if(this->update_ath_lb() < 0){ return_val = -8; goto error; } if(this->set_center_frequency(this->center_frequency) < 0){ return_val = -9; goto error; } if(this->adjust_fsk_deviation(deviation) < 0){ return_val = -10; goto error; } error: free(ask_fsk_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::adjust_fsk_deviation(float deviation) { int return_val = 0; uint8_t fsk_dev_conf_idx, conf_chf_sel, conf_demod_fsk; float conf_nominal_fsk_df; ask_fsk_sel_t *ask_fsk_sel = (ask_fsk_sel_t *)malloc(sizeof(ask_fsk_sel_t)); if(ask_fsk_sel == NULL) return -99; chf_sel_t *chf_sel = (chf_sel_t *)malloc(sizeof(chf_sel_t)); if(chf_sel == NULL){ free(ask_fsk_sel); return -98; } if_sel_t *if_sel = (if_sel_t *)malloc(sizeof(if_sel_t)); if(if_sel == NULL){ free(ask_fsk_sel); free(chf_sel); return -97; } rx_state_t *rx_state = (rx_state_t *)malloc(sizeof(rx_state_t)); if(rx_state == NULL){ free(ask_fsk_sel); free(chf_sel); free(if_sel); return -96; } if(this->get_rx_state(rx_state) < 0){ return_val = -1; goto error; } if(*rx_state != RX_STATE_STANDBY){ return_val = -2; goto error; } if(this->get_ask_fsk_sel(ask_fsk_sel) < 0){ return_val = -3; goto error; } if(*ask_fsk_sel != ASK_FSK_SEL_FSK){ return_val = -4; goto error; } if (this->get_if_sel(if_sel) < 0){ return_val = -5; goto error; } if(this->get_chf_sel(chf_sel) < 0){ return_val = -6; goto error; } for(fsk_dev_conf_idx = 0; fsk_dev_conf_idx < 14; fsk_dev_conf_idx++) { conf_nominal_fsk_df = nominal_fsk_conf[fsk_dev_conf_idx]; conf_nominal_fsk_df = (conf_nominal_fsk_df*10)/(*if_sel + 1); if(int(conf_nominal_fsk_df) == int(deviation*10)) { conf_chf_sel = chf_sel_demod_fsk_conf[fsk_dev_conf_idx][0]; conf_demod_fsk = chf_sel_demod_fsk_conf[fsk_dev_conf_idx][1]; if(conf_chf_sel == *chf_sel) { set_demod_fsk(demod_fsk_t(conf_demod_fsk)); free(ask_fsk_sel); free(chf_sel); free(if_sel); free(rx_state); return conf_demod_fsk; } } } error: free(ask_fsk_sel); free(chf_sel); free(if_sel); free(rx_state); return return_val; } template <class REG> int MAX4147X<REG>::adjust_preamble(int preamble, uint8_t preamb_len) { uint8_t preamb_w1, preamb_w2; if(preamble < 0 || preamble > 65535) return -1; if(preamb_len < 1 || preamb_len > 16) return -2; if(this->set_preamb_len(preamb_len-1) < 0) return -3; preamb_w1 = (preamble & 0xFF); preamb_w2 = ((preamble >> 8) & 0xFF); if(this->set_preamb_word_lower(preamb_w1) < 0) return -4; if(this->set_preamb_word_upper(preamb_w2) < 0) return -5; return 0; } template class MAX4147X<max41470_reg_map_t>; template class MAX4147X<max41473_4_reg_map_t>;