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 = ® 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 = ® 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 *)®_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; }