MBED driver for Max1471.

Revision:
0:99e9397112f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX1471.cpp	Fri Oct 04 15:15:06 2019 +0300
@@ -0,0 +1,715 @@
+/*
+ * MAX1471.cpp
+ *
+ *  Created on: Dec 17, 2018
+ */
+
+#include <limits.h>
+#include "spim.h"
+#include "max32630fthr.h"
+#include "MAX1471.h"
+#include "tmr.h"
+#include "gpio.h"
+
+
+#define GPIO_P3_IN          (uint32_t)0x4000A18C
+
+using namespace std;
+
+#define BITBAND(reg, bit)               ((0xf0000000 & (uint32_t)(reg)) + 0x2000000 + \
+                                            (((uint32_t)(reg) & 0x0fffffff) << 5) + ((bit) << 2))
+
+#define MXC_CLRBIT(reg, bit)            (*(volatile uint32_t *)BITBAND(reg, bit) = 0)
+#define MXC_SETBIT(reg, bit)            (*(volatile uint32_t *)BITBAND(reg, bit) = 1)
+#define MXC_GETBIT(reg, bit)            (*(volatile uint32_t *)BITBAND(reg, bit))
+
+#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;                                                             \
+                }}
+
+//Constructors
+
+int MAX1471::ASKPeakDetectorEnable(bool enable)
+{
+	SET_BIT_FIELD( PWR_CFG_ADDR, this -> reg->reg_pwr_cfg, this -> reg->reg_pwr_cfg.bits.askpd_en, enable );
+
+	return 0;
+}
+
+int MAX1471::FSKPeakDetectorEnable(bool enable)
+{
+	SET_BIT_FIELD( PWR_CFG_ADDR, this -> reg->reg_pwr_cfg, this -> reg->reg_pwr_cfg.bits.fskpd_en, enable );
+
+	return 0;
+}
+
+int MAX1471::ASKBaseBandReceiverEnable(bool enable)
+{
+	SET_BIT_FIELD( PWR_CFG_ADDR, this -> reg->reg_pwr_cfg, this -> reg->reg_pwr_cfg.bits.askbb_en, enable );
+
+	return 0;
+}
+
+int MAX1471::FSKBaseBandReceiverEnable(bool enable)
+{
+	SET_BIT_FIELD( PWR_CFG_ADDR, this -> reg->reg_pwr_cfg, this -> reg->reg_pwr_cfg.bits.fskbb_en, enable );
+
+	return 0;
+}
+
+int MAX1471::RFMixerEnable(bool enable)
+{
+	SET_BIT_FIELD( PWR_CFG_ADDR, this -> reg->reg_pwr_cfg, this -> reg->reg_pwr_cfg.bits.mixer_en, enable );
+
+	return 0;
+}
+
+int MAX1471::AGCEnable(bool enable)
+{
+	SET_BIT_FIELD( PWR_CFG_ADDR, this -> reg->reg_pwr_cfg, this -> reg->reg_pwr_cfg.bits.agc_en, enable );
+
+	return 0;
+}
+
+int MAX1471::LNAEnable(bool enable)
+{
+	SET_BIT_FIELD( PWR_CFG_ADDR, this -> reg->reg_pwr_cfg, this -> reg->reg_pwr_cfg.bits.lna_en, enable );
+
+	return 0;
+}
+
+int MAX1471::DRXEnable(bool enable)
+{
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this -> reg->reg_cfg.bits.drx_mode, enable );
+
+	return 0;
+}
+
+
+int MAX1471::SetFDATAasDOUTPin(bool enable)
+{
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this->reg->reg_cfg.bits.dout_fsk, enable );
+
+	return 0;
+}
+
+int MAX1471::SetADATAasDOUTPin(bool enable)
+{
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this->reg->reg_cfg.bits.dout_ask, enable );
+
+	return 0;
+}
+
+int MAX1471::LongerFSKCalibrationEnable(bool enable)
+{
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this->reg->reg_cfg.bits.fskcallsb, enable );
+
+	return 0;
+}
+
+int MAX1471::LNAGainState(bool isHighGain)
+{
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this->reg->reg_cfg.bits.gainset, isHighGain );
+
+	return 0;
+}
+
+int MAX1471::FSKCalibrationDone(bool enable)
+{
+	SET_BIT_FIELD( CTRL_ADDR, this -> reg->reg_ctrl, this->reg->reg_ctrl.bits.fsk_cal_en, enable );
+
+	return 0;
+}
+
+int MAX1471::PollTimerCalibrationEnable(bool enable)
+{
+	SET_BIT_FIELD( CTRL_ADDR, this -> reg->reg_ctrl, this->reg->reg_ctrl.bits.pol_cal_en, enable );
+
+	return 0;
+}
+
+int MAX1471::ASKPeakDetectorTrackEnable(bool enable)
+{
+	SET_BIT_FIELD( CTRL_ADDR, this -> reg->reg_ctrl, this->reg->reg_ctrl.bits.asktrk_en, enable );
+
+	return 0;
+}
+
+int MAX1471::FSKPeakDetectorTrackEnable(bool enable)
+{
+	SET_BIT_FIELD( CTRL_ADDR, this -> reg->reg_ctrl, this->reg->reg_ctrl.bits.fsktrk_en, enable );
+
+	return 0;
+}
+
+int MAX1471::LockAGCCurrentState()
+{
+	SET_BIT_FIELD( CTRL_ADDR, this -> reg->reg_ctrl, this->reg->reg_ctrl.bits.agclock, 1 );
+
+	return 0;
+}
+
+int MAX1471::GetPollTimerCalibrationDoneStatus( unsigned char *valuePtr )
+{
+	read_register( STAT_ADDR, &this -> reg->reg_stat.raw, 1 );
+
+	*valuePtr = this -> reg->reg_stat.bits.pol_cal_done;
+
+	return 0;
+}
+
+int MAX1471::GetFSKCalibrationDoneStatus( unsigned char *valuePtr )
+{
+	read_register( STAT_ADDR, &this -> reg->reg_stat.raw, 1 );
+
+	*valuePtr = this -> reg->reg_stat.bits.fsk_cal_done;
+
+	return 0;
+}
+
+int MAX1471::GetClockAliveStatus( unsigned char *valuePtr )
+{
+	read_register( STAT_ADDR, &this -> reg->reg_stat.raw, 1 );
+
+	*valuePtr = this -> reg->reg_stat.bits.clkalive;
+
+	return 0;
+}
+
+int MAX1471::GetAGCStatus( unsigned char *valuePtr )
+{
+	read_register( STAT_ADDR, &this -> reg->reg_stat.raw, 1 );
+
+	*valuePtr = this -> reg->reg_stat.bits.agcst;
+
+	return 0;
+}
+
+int MAX1471::GetPLLLockStatus( unsigned char *valuePtr )
+{
+	read_register( STAT_ADDR, &this -> reg->reg_stat.raw, 1 );
+
+	*valuePtr = this -> reg->reg_stat.bits.lockdet;
+
+	return 0;
+}
+
+int MAX1471::GetOffTimerPrescale( unsigned char *valuePtr )
+{
+	read_register( CFG_ADDR, &this -> reg->reg_cfg.raw, 1 );
+
+	*valuePtr =  this->reg->reg_cfg.bits.toff_ps1;
+	*valuePtr =  ( *valuePtr << 1 ) | this->reg->reg_cfg.bits.toff_ps0;
+
+	return 0;
+}
+
+int MAX1471::SetOffTimerPrescale( unsigned char value )
+{
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this->reg->reg_cfg.bits.toff_ps0, value & 0x01 );
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this->reg->reg_cfg.bits.toff_ps1, !!( value & 0x02 ) );
+
+	return 0;
+}
+
+int MAX1471::GetAGCDwellTimer( unsigned char *valuePtr )
+{
+	return read_register( AGC_DWL_TMR_ADDR, valuePtr, 1 );
+}
+
+int MAX1471::SetAGCDwellTimer( unsigned char value )
+{
+	return write_register( AGC_DWL_TMR_ADDR, value & 0x1F, 1);
+}
+
+int MAX1471::SetRFSettleTimer( unsigned short int value )
+{
+	write_register( RF_ST_UP_ADDR, ( value >> 8 ), 1 );
+	write_register( RF_ST_DWN_ADDR, ( value & 0x00FF ), 1 );
+
+	return 0;
+}
+
+int MAX1471::GetRFSettleTimer( unsigned short int *valuePtr )
+{
+	unsigned char *valueUint8Ptr;
+
+
+	valueUint8Ptr = ( unsigned char * )valuePtr;
+
+	read_register( RF_ST_UP_ADDR, &valueUint8Ptr[1], 1 );
+	read_register( RF_ST_DWN_ADDR, &valueUint8Ptr[0], 1 );
+
+	return 0;
+}
+
+int MAX1471::SetOFFTimer( unsigned short int value )
+{
+	write_register( OFF_TMR_UP_ADDR, ( value >> 8 ), 1 );
+
+	return write_register( OFF_TMR_DWN_ADDR, ( value & 0x00FF ), 1 );;
+}
+
+int MAX1471::GetOFFTimer( unsigned short int *valuePtr )
+{
+	unsigned char *valueUint8Ptr;
+
+
+	valueUint8Ptr = ( unsigned char * )valuePtr;
+
+	read_register( OFF_TMR_UP_ADDR, &valueUint8Ptr[1], 1 );
+
+	return read_register( OFF_TMR_DWN_ADDR, &valueUint8Ptr[0], 1 );;
+}
+
+int MAX1471::SetCPURecoveryTimer( unsigned char value )
+{
+	return write_register( CPU_REC_ADDR, value, 1 );;
+}
+
+int MAX1471::GetCPURecoveryTimer( unsigned char *valuePtr )
+{
+	return read_register( CPU_REC_ADDR, valuePtr, 1 );
+}
+
+int MAX1471::SetRFOscillatorFreq( float frequency )
+{
+	if( frequency >= 9.0406 && frequency <= 13.7281 )
+	{
+		unsigned char regValue = ( unsigned char )( ( frequency * 10 ) + 0.5 );
+		oscFrequency = frequency;
+		return write_register( OSC_FREQ_ADDR, regValue, 1 );
+	}
+
+	return -1;
+}
+
+int MAX1471::GetRFOscillatorFreq( float *freqPtr )
+{
+	*freqPtr = oscFrequency;
+	return 0;
+}
+
+MAX1471::MAX1471(DigitalOut *cs)
+{
+	modulation = ASK; /*!< Current modulation mode */
+	oscFrequency = 0; /*!< Extern oscillator frequency */
+#if defined(TARGET_MAX32630FTHR)
+	this->spi_handler =  new SPI(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
+#endif
+
+#if defined(TARGET_MAX32625PICO)
+	this->spi_handler =  new SPI(P0_5, P0_6, P0_4); /* mosi, miso, sclk */
+#endif
+
+	this->spi_handler->format(8,0);
+	this->spi_handler->frequency(100000);
+
+	this->ssel = cs;
+	*(this->ssel) = 1;
+
+	this->spi_mode = 0;
+
+	this->reg = new max1471_reg_map_t();
+
+	this->set_spi_type(0);
+}
+
+int MAX1471::read_register(uint8_t reg, uint8_t *value, uint8_t len)
+{
+	int rtn_val = -1;
+
+    if (value == NULL) {
+        return -1;
+    }
+
+    if (this->reg == NULL) {
+        return -1;
+    }
+
+#if defined(TARGET_MAX32630FTHR)
+	SPI *spi = new SPI(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
+	mxc_spim_regs_t *MAX1471_SPI = MXC_SPIM2;
+#endif
+
+#if defined(TARGET_MAX32625PICO)
+	SPI *spi =  new SPI(P0_5, P0_6, P0_4); /* mosi, miso, sclk */
+	mxc_spim_regs_t *MAX1471_SPI = MXC_SPIM0;
+#endif
+
+	spi->format(8,0);
+	spi->frequency(400000);
+
+    if (ssel != NULL) {
+        *ssel = 0;
+    }
+
+    spi->write((uint8_t)0x20 | reg);
+    spi->write(0x00);     // dummy write command for waiting data read
+
+    if (ssel != NULL) {
+        *ssel = 1;
+    }
+
+    wait_us(1);
+
+    if (ssel != NULL) {
+        *ssel = 0;
+    }
+
+	if (this->spi_mode == 0) {
+
+		MAX1471_SPI->mstr_cfg |= MXC_F_SPIM_MSTR_CFG_THREE_WIRE_MODE;
+
+		// Disable SPI for General Control Configuration
+		MAX1471_SPI->gen_ctrl = 0;
+		MAX1471_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
+
+		MAX1471_SPI->simple_headers &= 0x0000FFFF;
+		MAX1471_SPI->simple_headers |= 0x2016<<16;
+		MAX1471_SPI->gen_ctrl |=MXC_F_SPIM_GEN_CTRL_START_RX_ONLY;
+
+		// Enable the SPI
+		MAX1471_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(MAX1471_SPI));
+
+		int avail = ((MAX1471_SPI->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) >> MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED_POS);
+
+		Timer t;
+
+		t.start();
+
+		while (avail < 1) {
+			if (t.read_ms() > 1000) {
+				break;
+			} else {
+				avail = ((MAX1471_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];
+		}
+
+		while (MAX1471_SPI->fifo_ctrl & MXC_F_SPIM_FIFO_CTRL_RX_FIFO_USED) {
+			fifo->rslts_8[0];
+		}
+
+		MAX1471_SPI->gen_ctrl = 0;
+		MAX1471_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
+
+		MAX1471_SPI->gen_ctrl |= MXC_F_SPIM_GEN_CTRL_SPI_MSTR_EN;
+
+	} else {
+		MAX1471_SPI->mstr_cfg &= ~MXC_F_SPIM_MSTR_CFG_THREE_WIRE_MODE;
+
+		for (uint8_t i = 0; i < len; i++) {
+        *(value++) = spi->write(0x00);     // read back  data bytes
+		}
+	}
+
+    if (ssel != NULL) {
+        *ssel = 1;
+    }
+
+	delete spi;
+
+    return 0;
+}
+
+int MAX1471::write_register(uint8_t reg, const uint8_t *value, uint8_t len)
+{
+    int rtn_val = -1;
+
+    if (value == NULL) {
+        return -1;
+    }
+
+#if defined(TARGET_MAX32630FTHR)
+	SPI *spi = new SPI(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
+#endif
+
+#if defined(TARGET_MAX32625PICO)
+	SPI *spi =  new SPI(P0_5, P0_6, P0_4); /* mosi, miso, sclk */
+#endif
+
+	spi->format(8,0);
+	spi->frequency(100000);
+
+    if (ssel != NULL) {
+        *ssel = 0;
+    }
+
+    rtn_val = spi->write(0x10 | reg); // write mode and adress send
+
+    rtn_val = spi->write((int)*value); // write adress
+
+
+    if (ssel != NULL) {
+        *ssel = 1;
+    }
+
+    delete spi;
+
+    if (rtn_val != 0) {
+        return rtn_val;
+    }
+
+    return 0;
+}
+
+int MAX1471::write_register(uint8_t reg, const uint8_t value, uint8_t len)
+{
+    int rtn_val = -1;
+
+
+#if defined(TARGET_MAX32630FTHR)
+	SPI *spi = new SPI(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
+#endif
+
+#if defined(TARGET_MAX32625PICO)
+	SPI *spi =  new SPI(P0_5, P0_6, P0_4); /* mosi, miso, sclk */
+#endif
+
+	spi->format(8,0);
+	spi->frequency(100000);
+
+    if (ssel != NULL) {
+        *ssel = 0;
+    }
+
+    rtn_val = spi->write(0x10 | reg); // write mode and adress send
+
+    rtn_val = spi->write((int)value); // write adress
+
+
+    if (ssel != NULL) {
+        *ssel = 1;
+    }
+
+    delete spi;
+
+    if (rtn_val != 0) {
+        return rtn_val;
+    }
+
+    return 0;
+}
+
+int MAX1471::set_spi_type(uint8_t type)
+{
+	/*
+	 *  0 -> 3-Wire Default
+	 *  1 -> 4-Wire (DOUT_FSK) enabled
+	 *  2 -> 4-Wire (DOUT_ASK) enabled
+	 */
+
+	switch (type)
+	{
+		case 0:
+			this->reg->reg_cfg.bits.dout_ask = 0;
+			this->reg->reg_cfg.bits.dout_fsk = 0;
+			break;
+		case 1:
+			this->reg->reg_cfg.bits.dout_ask = 0;
+			this->reg->reg_cfg.bits.dout_fsk = 1;
+			break;
+		case 2:
+			this->reg->reg_cfg.bits.dout_ask = 1;
+			this->reg->reg_cfg.bits.dout_fsk = 0;
+			break;
+		default:
+			break;
+	}
+
+	if (this->write_register(CFG_ADDR, (uint8_t *)&this->reg->reg_cfg.raw, 1) == 0) {
+		spi_mode = type;
+	}
+
+	return 0;
+}
+
+int MAX1471::reset()
+{
+#if defined(TARGET_MAX32630FTHR)
+	SPI *spi = new SPI(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
+#endif
+
+#if defined(TARGET_MAX32625PICO)
+	SPI *spi =  new SPI(P0_5, P0_6, P0_4); /* mosi, miso, sclk */
+#endif
+
+	spi->format(8,0);
+	spi->frequency(100000);
+
+    if (ssel != NULL) {
+        *ssel = 0;
+    }
+
+	int rtrn = spi->write(0x30); // write mode and adress send
+
+    if (ssel != NULL) {
+        *ssel = 1;
+    }
+
+    delete spi;
+
+    return rtrn;
+
+}
+
+int MAX1471::nop()
+{
+#if defined(TARGET_MAX32630FTHR)
+	SPI *spi = new SPI(P5_1, P5_2, P5_0); /* mosi, miso, sclk */
+#endif
+
+#if defined(TARGET_MAX32625PICO)
+	SPI *spi =  new SPI(P0_5, P0_6, P0_4); /* mosi, miso, sclk */
+#endif
+
+	spi->format(8,0);
+	spi->frequency(100000);
+
+    if (ssel != NULL) {
+        *ssel = 0;
+    }
+
+	int rtrn = spi->write(0x00); // write mode and adress send
+
+    if (ssel != NULL) {
+        *ssel = 1;
+    }
+
+    delete spi;
+
+    return rtrn;
+
+}
+
+int MAX1471::InitMAX1471()
+{
+	// Write 0x3000 to reset the part
+	this->reset();
+	// wait for 100ms
+	Thread::wait(100);
+	// Write 0x10FE to enable all RF and baseband sections.
+	uint8_t value = 0xF4;
+	this->write_register(PWR_CFG_ADDR, &value, 1);
+
+	// Write 0x135F to set the oscillator frequency register to work with a 315MHz crystal.
+	// Write 0x1384 to set the oscillator frequency register to work with a 433.92MHz crystal.
+	value = 0x84;
+	this->write_register(OSC_FREQ_ADDR, &value, 1);
+
+	return 0;
+}
+
+
+int MAX1471::PrepMAX1471RX( modulation_type_t modType ) {
+	uint8_t value = 0x20;
+	uint8_t *readValue = &value;
+
+
+	if( modType == ASK ){
+		this->ASKBaseBandReceiverEnable(true);
+		this->ASKPeakDetectorEnable(true);
+		this->RFMixerEnable(true);
+
+		this->LNAEnable(true);
+
+		this->AGCEnable(true);
+		this->LNAGainState(true);
+		this->AGCEnable(false);
+	}
+	else if( modType == FSK ){
+		this->FSKBaseBandReceiverEnable(true);
+		this->FSKPeakDetectorEnable(true);
+
+		this->RFMixerEnable(true);
+
+		this->LNAEnable(true);
+
+		this->LongerFSKCalibrationEnable(true);
+
+		this->AGCEnable(true);
+		this->LNAGainState(true);
+		this->AGCEnable(false);
+
+		this->FSKCalibrationDone(true);
+
+		uint8_t *readValue = &value;
+
+		*readValue = 0;
+
+		while (*readValue == 0) {
+			this->GetFSKCalibrationDoneStatus( readValue );
+		}
+	}
+	else{
+		this->PrepMAX1471RX();
+	}
+
+	return 0;
+
+}
+
+int MAX1471::PrepMAX1471RX() {
+	uint8_t value;
+
+	this->ASKBaseBandReceiverEnable(true);
+	this->ASKPeakDetectorEnable(true);
+
+	this->FSKBaseBandReceiverEnable(true);
+	this->FSKPeakDetectorEnable(true);
+
+	this->RFMixerEnable(true);
+
+	this->LNAEnable(true);
+
+	this->LongerFSKCalibrationEnable(true);
+
+	this->AGCEnable(true);
+	this->LNAGainState(true);
+	this->AGCEnable(false);
+
+	this->FSKCalibrationDone(true);
+
+	uint8_t *readValue = &value;
+
+	*readValue = 0;
+
+	while (*readValue == 0) {
+		this->GetFSKCalibrationDoneStatus( readValue );
+	}
+
+  return 0;
+}
+
+int MAX1471::PrepMAX1471Sleep(bool enable) {
+	/* This routine is used to prepare the MAX7032 for sleep mode */
+
+	SET_BIT_FIELD( CFG_ADDR, this -> reg->reg_cfg, this->reg->reg_cfg.bits.toff_ps0, enable );
+
+	return 0;
+}
+
+
+
+
+
+
+