/*
 * Functions for using SX127x in FSK mode (mainly receive)
 * Copyright (C) 2019 Hansi Reiser, dl9rdz
 *
 * Partially based on the SX1278 libraray for managing Semtech modules
 *  Copyright (C) 2015 Wireless Open Source
 *  http://wirelessopensource.com
 *
 *  SPDX-License-Identifier:    LGPL-2.1+
 */

#include "SX1278FSK.h"
#include "SPI.h"
#include <Sonde.h>
#include <Display.h>

SX1278FSK::SX1278FSK()
{
	// Initialize class variables
};


static SPISettings spiset = SPISettings(40000000L, MSBFIRST, SPI_MODE0);

/*
Function: Turns the module ON.
Returns: 0 on success, 1 otherwise
*/
uint8_t SX1278FSK::ON()
{
	uint8_t state = 2;
#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'ON'"));
#endif

	// Powering the module
	pinMode(SX1278_SS, OUTPUT);
	digitalWrite(SX1278_SS, HIGH);

	//Configure the MISO, MOSI, CS, SPCR.
	SPI.begin();
	//Set most significant bit first
	SPI.setBitOrder(MSBFIRST);
	//Divide the clock frequency
	SPI.setClockDivider(SPI_CLOCK_DIV2);
	//Set data mode
	SPI.setDataMode(SPI_MODE0);

	// Set Maximum Over Current Protection
	state = setMaxCurrent(0x1B);
	if( state == 0 )
	{
#if (SX1278FSK_debug_mode > 1)
		Serial.println(F("## Setting ON with maximum current supply ##"));
		Serial.println();
#endif
	}
	else
	{
		return 1;
	}

	// set FSK mode
	state = setFSK();
	return state;
}

/*
Function: Turn the module OFF.
Returns: Nothing
*/
void SX1278FSK::OFF()
{
#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'OFF'"));
#endif

	SPI.end();
	// Powering the module
	pinMode(SX1278_SS,OUTPUT);
	digitalWrite(SX1278_SS,LOW);

#if (SX1278FSK_debug_mode > 1)
	Serial.println(F("## Setting OFF ##"));
	Serial.println();
#endif
}

/*
Function: Reads the indicated register.
Returns: The content of the register
Parameters:
	address: address register to read from
*/
byte SX1278FSK::readRegister(byte address)
{
	byte value = 0x00;

	SPI.beginTransaction(spiset);
	digitalWrite(SX1278_SS,LOW);

	//delay(1);
	bitClear(address, 7);		// Bit 7 cleared to write in registers
	SPI.transfer(address);
	value = SPI.transfer(0x00);
	digitalWrite(SX1278_SS,HIGH);
	SPI.endTransaction();

#if (SX1278FSK_debug_mode > 1)
	if(address!=0x3F) {
		Serial.print(F("## Reading:  ##\t"));
		Serial.print(F("Register "));
		Serial.print(address, HEX);
		Serial.print(F(":  "));
		Serial.print(value, HEX);
		Serial.println();
	}
#endif

	return value;
}

/*
Function: Writes on the indicated register.
Returns: Nothing
Parameters:
	address: address register to write in
	data: value to write in the register
*/
void SX1278FSK::writeRegister(byte address, byte data)
{
	SPI.beginTransaction(spiset);
	digitalWrite(SX1278_SS,LOW);

	//delay(1);
	bitSet(address, 7);			// Bit 7 set to read from registers
	SPI.transfer(address);
	SPI.transfer(data);
	digitalWrite(SX1278_SS,HIGH);
	SPI.endTransaction();

#if (SX1278FSK_debug_mode > 1)
	Serial.print(F("## Writing:  ##\t"));
	Serial.print(F("Register "));
	bitClear(address, 7);
	Serial.print(address, HEX);
	Serial.print(F(":  "));
	Serial.print(data, HEX);
	Serial.println();
#endif

}

/*
 * Function: Clears the IRQ flags
 * 
 * Configuration registers are accessed through the SPI interface. 
 * Registers are readable in all device mode including Sleep. However, they 
 * should be written only in Sleep and Stand-by modes.
 * 
 * Returns: Nothing
 */
void SX1278FSK::clearIRQFlags()
{
	byte st0;

	// Save the previous status
	st0 = readRegister(REG_OP_MODE);		
	// Stdby mode to write in registers
	writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);	
	// FSK mode flags1 register
	writeRegister(REG_IRQ_FLAGS1, 0xFF);
	// FSK mode flags2 register 
	writeRegister(REG_IRQ_FLAGS2, 0xFF);
	// Getting back to previous status
	if(st0 != FSK_STANDBY_MODE)  {
		writeRegister(REG_OP_MODE, st0);
	}
#if (SX1278FSK_debug_mode > 1)
	Serial.println(F("## FSK flags cleared ##"));
#endif
}

/*
Function: Sets the module in FSK mode.
Returns:   Integer that determines if there has been any error
	state = 2  --> The command has not been executed
	state = 1  --> There has been an error while executing the command
	state = 0  --> The command has been executed with no errors
*/
uint8_t SX1278FSK::setFSK()
{
	uint8_t state = 2;
	byte st0;
	//byte config1;

#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'setFSK'"));
#endif

	writeRegister(REG_OP_MODE, FSK_SLEEP_MODE);	// Sleep mode (mandatory to change mode)
	// If we are in LORA mode, above line activate Sleep mode, but does not change mode to FSK
	// as mode change is only allowed in sleep mode. Next line changes to FSK
	writeRegister(REG_OP_MODE, FSK_SLEEP_MODE);

	writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);	// FSK standby mode

	//writeRegister(REG_FIFO_THRESH, 0x80);	// condition to start packet tx
	//config1 = readRegister(REG_SYNC_CONFIG);
	//config1 = config1 & B00111111;
	//writeRegister(REG_SYNC_CONFIG,config1);

	delay(100);

	st0 = readRegister(REG_OP_MODE);	// Reading config mode
	if( st0 == FSK_STANDBY_MODE )
	{ // FSK mode
		state = 0;
#if (SX1278FSK_debug_mode > 1)
		Serial.println(F("## FSK set with success ##"));
		Serial.println();
#endif
	} else { // LoRa mode
		state = 1;
		Serial.println( st0 );
#if (SX1278FSK_debug_mode > 1)
		Serial.println(F("** There has been an error while setting FSK **"));
		Serial.println();
#endif
	}
	return state;
}


/* Function: Sets FSK bitrate
 * Returns: 0 for success, >0 in case of error
 * Parameters: bps: requested bitrate
 * (raw data rate, for Mancester encoding, the effective bitrate is bps/2)
*/

uint8_t SX1278FSK::setBitrate(float bps)
{
	// TODO: Check if FSK mode is active

	// check if bitrate is allowed allowed bitrate
	if((bps < 1200) || (bps > 300000)) {
	  return 1;
	}

	// set mode to FSK STANDBY
	writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); 

	// set bit rate
	uint16_t bitRate = (SX127X_CRYSTAL_FREQ * 1.0) / bps;
	writeRegister(REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8);
	writeRegister(REG_BITRATE_LSB, (bitRate & 0x00FF));

	// also set fractional part
	uint16_t fracRate = (SX127X_CRYSTAL_FREQ * 16.0) / bps - bitRate * 16 + 0.5;
	writeRegister(REG_BIT_RATE_FRAC, fracRate&0x0F);
	return 0;
}
/* Function: Gets configured bitrate 
 * Returns bitrate in bit/second
 */
float SX1278FSK::getBitrate()
{
	uint8_t fmsb = readRegister(REG_BITRATE_MSB);
	uint8_t flsb = readRegister(REG_BITRATE_LSB);
	uint8_t ffrac = readRegister(REG_BIT_RATE_FRAC) & 0x0F;
	return SX127X_CRYSTAL_FREQ / ( (fmsb<<8) + flsb + ffrac / 16.0 );
}

//typedef struct rxbwset { float bw; uint8_t mant; uint8_t rxp; } st_rxbwsettings;

uint8_t SX1278FSK::setRxBandwidth(float bw)
{
	// TODO: Check if in FSK mode
	//
	if(bw<2600 || bw>250000) { return 1; /* invalid */ }

	uint8_t rxbwexp = 1;
	bw = SX127X_CRYSTAL_FREQ / bw / 8;
	while(bw>31) { rxbwexp++; bw/=2.0; }
	uint8_t rxbwmant = bw<17?0 : bw<21? 1:2;

	// set mode to FSK STANDBY
	writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); 

	writeRegister(REG_RX_BW, rxbwexp | (rxbwmant<<3));
	return 0;
}

float SX1278FSK::getRxBandwidth()
{
	uint8_t rxbw = readRegister(REG_RX_BW);
	uint8_t rxbwexp = rxbw&0x07;
	uint8_t rxbwmant = (rxbw>>3)&0x03;
	rxbwmant = 16 + 4*rxbwmant;
	return SX127X_CRYSTAL_FREQ / ( rxbwmant << (rxbwexp+2));
}

uint8_t SX1278FSK::setAFCBandwidth(float bw)
{
	// TODO: Check if in FSK mode
	//
	if(bw<2600 || bw>250000) { return 1; /* invalid */ }

	uint8_t rxbwexp = 1;
	bw = SX127X_CRYSTAL_FREQ / bw / 8;
	while(bw>31) { rxbwexp++; bw/=2.0; }
	uint8_t rxbwmant = bw<17?0 : bw<21? 1:2;

	// set mode to FSK STANDBY
	writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); 

	writeRegister(REG_AFC_BW, rxbwexp | (rxbwmant<<3));
	return 0;
}

float SX1278FSK::getAFCBandwidth()
{
	uint8_t rxbw = readRegister(REG_AFC_BW);
	uint8_t rxbwexp = rxbw&0x07;
	uint8_t rxbwmant = (rxbw>>3)&0x03;
	rxbwmant = 16 + 4*rxbwmant;
	return SX127X_CRYSTAL_FREQ / ( rxbwmant << (rxbwexp+2));
}


uint8_t SX1278FSK::setFrequency(float freq) {

	// set mode to FSK STANDBY 
	writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);
	freq += sonde.config.freqofs;  // manual frequency correction

	uint32_t frf = freq * 1.0 * (1<<19) / SX127X_CRYSTAL_FREQ;
	writeRegister(REG_FRF_MSB, (frf&0xff0000)>>16);
	writeRegister(REG_FRF_MID, (frf&0x00ff00)>>8);
	writeRegister(REG_FRF_LSB, (frf&0x0000ff));
	return 0;
}

float SX1278FSK::getFrequency() {
	uint8_t fmsb = readRegister(REG_FRF_MSB);
	uint8_t fmid = readRegister(REG_FRF_MID);
	uint8_t flsb = readRegister(REG_FRF_LSB);
	return ((fmsb<<16)|(fmid<<8)|flsb) * 1.0 / (1<<19) * SX127X_CRYSTAL_FREQ;
}


static int gaintab[]={-999,0,-6,-12,-24,-36,-48,-999};
int SX1278FSK::getLNAGain() {
	int gain = (readRegister(REG_LNA)>>5)&0x07;
	return gaintab[gain];
}
uint8_t SX1278FSK::setLNAGain(int gain) {
	uint8_t g=1;
	while(gain<gaintab[g] && g<6) {g++; }
	writeRegister(REG_LNA, g<<5);
	return 0;
}

uint8_t SX1278FSK::getRxConf() {
	return readRegister(REG_RX_CONFIG);
}
uint8_t SX1278FSK::setRxConf(uint8_t conf) {
	writeRegister(REG_RX_CONFIG, conf);
	return 0;
}

uint8_t SX1278FSK::setSyncConf(uint8_t conf, int len, const uint8_t *syncpattern) {
	int res=0;
	writeRegister(REG_SYNC_CONFIG, conf);
	if(len>8) return 1;
	for(int i=0; i<len; i++) {
		writeRegister(REG_SYNC_VALUE1+i, syncpattern[i]);
	}
	return res;
}

uint8_t SX1278FSK::getSyncConf() {
	return sx1278.readRegister(REG_SYNC_CONFIG);
}

uint8_t SX1278FSK::setPreambleDetect(uint8_t conf) {
	sx1278.writeRegister(REG_PREAMBLE_DETECT, conf);
	return 0;
}

uint8_t SX1278FSK::getPreambleDetect() {
	return sx1278.readRegister(REG_PREAMBLE_DETECT);
}

uint8_t SX1278FSK::setPacketConfig(uint8_t conf1, uint8_t conf2)
{
	uint8_t ret=0;
	sx1278.writeRegister(REG_PACKET_CONFIG1, conf1);
	sx1278.writeRegister(REG_PACKET_CONFIG2, conf2);
	return ret;
};
uint16_t SX1278FSK::getPacketConfig() {
	uint8_t c1 = sx1278.readRegister(REG_PACKET_CONFIG1);
	uint8_t c2 = sx1278.readRegister(REG_PACKET_CONFIG2);
	return (c2<<8)|c1;
}

/*
Function: Gets the preamble length from the module.
Returns: preamble length
*/
uint16_t SX1278FSK::getPreambleLength()
{
	uint16_t p_length;

#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'getPreambleLength'"));
#endif

	p_length = readRegister(REG_PREAMBLE_MSB_FSK);
	p_length = (p_length<<8) | readRegister(REG_PREAMBLE_LSB_FSK);
#if (SX1278FSK_debug_mode > 1)
		Serial.print(F("## Preamble length configured is "));
		Serial.print(p_length, HEX);
		Serial.print(F(" ##"));
		Serial.println();
#endif
	return p_length;
}

/*
Function: Sets the preamble length in the module
Returns: Integer that determines if there has been any error
state = 2  --> The command has not been executed
state = 1  --> There has been an error while executing the command
state = 0  --> The command has been executed with no errors
Parameters:
l: length value to set as preamble length.
*/
uint8_t SX1278FSK::setPreambleLength(uint16_t l)
{
	byte st0;
	int8_t state = 2;

#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'setPreambleLength'"));
#endif

	st0 = readRegister(REG_OP_MODE);	// Save the previous status

	writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);    // Set Standby mode to write in registers
	// Storing MSB preamble length in FSK mode
	writeRegister(REG_PREAMBLE_MSB_FSK, l>>8);
	writeRegister(REG_PREAMBLE_LSB_FSK, l&0xFF);

	state = 0;
#if (SX1278FSK_debug_mode > 1)
	Serial.print(F("## Preamble length "));
	Serial.print(l, HEX);
	Serial.println(F(" has been successfully set ##"));
	Serial.println();
#endif

	if(st0 != FSK_STANDBY_MODE) {
		writeRegister(REG_OP_MODE, st0);	// Getting back to previous status
	}
	return state;
}

/*
Function: Gets the payload length from the module.
Returns: configured length; -1 on error
*/
int SX1278FSK::getPayloadLength()
{	
	int length;
#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'getPayloadLength'"));
#endif
	length = readRegister(REG_PAYLOAD_LENGTH_FSK);

#if (SX1278FSK_debug_mode > 1)
	Serial.print(F("## Payload length configured is "));
	Serial.print(length);
	Serial.println(F(" ##"));
#endif
	return length;
}

/*
Function: Sets the payload length from the module.
Returns: 0 for ok, otherwise error
// TODO: Larger than 255 bytes?
*/
uint8_t SX1278FSK::setPayloadLength(int len)
{	
#if (SX1278FSK_debug_mode > 1)
	Serial.print(F("Starting 'setPayloadLength'"));
	Serial.println(len);
#endif
	uint8_t conf2 = readRegister(REG_PACKET_CONFIG2);
	conf2 = (conf2 & 0xF8) | ( (len>>8)&0x7 );
	writeRegister(REG_PACKET_CONFIG2, conf2);
	writeRegister(REG_PAYLOAD_LENGTH_FSK, len&0xFF);
	return 0;
}

/*
Function: Gets the current value of RSSI.
Returns: RSSI value
*/
int16_t SX1278FSK::getRSSI()
{
	int16_t RSSI;
	//int rssi_mean = 0;
	int total = 1;

	/// FSK mode
	// get mean value of RSSI
	for(int i = 0; i < total; i++)
	{
		RSSI = readRegister(REG_RSSI_VALUE_FSK);
		//rssi_mean += _RSSI;
	}
	//rssi_mean = rssi_mean / total;	
	//RSSI = rssi_mean;

#if (SX1278FSK_debug_mode > 0)
	Serial.print(F("## RSSI value is "));
	Serial.print(RSSI);
	Serial.println(F(" ##"));
#endif
	return RSSI;
}

/*
Function: Gets the current value of FEI (frequency error indication)
Returns: FEI value in Hz
*/
int32_t SX1278FSK::getFEI()
{
	int32_t FEI;
	int16_t regval = (readRegister(REG_FEI_MSB)<<8) | readRegister(REG_FEI_LSB);
	//Serial.printf("feireg: %04x\n", regval);
	FEI = (int32_t)(regval * SX127X_FSTEP);
	return FEI;
}
/*
Function: Gets the current value of AFC (automated frequency correction)
Returns: AFC value in Hz
*/
int32_t SX1278FSK::getAFC()
{
	int32_t AFC;
	int16_t regval = (readRegister(REG_AFC_MSB)<<8) | readRegister(REG_AFC_LSB);
	//Serial.printf("afcreg: %04x\n", regval);
	AFC = (int32_t)(regval * SX127X_FSTEP);
	return AFC;
}

/*
Function: Gets the current supply limit of the power amplifier, protecting battery chemistries.
Returns: Integer that determines if there has been any error
state = 2  --> The command has not been executed
state = 1  --> There has been an error while executing the command
state = 0  --> The command has been executed with no errors
Parameters:
rate: value to compute the maximum current supply. Maximum current is 45+5*'rate' [mA]
*/
int SX1278FSK::getMaxCurrent()
{
	int value;

#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'getMaxCurrent'"));
#endif

	value = readRegister(REG_OCP);

	// extract only the OcpTrim value from the OCP register
	value &= B00011111;

	if( value <= 15 ) {
		value = (45 + (5 * value));
	} else if( value <= 27 ) {
		value = (-30 + (10 * value));
	} else {
		value = 240;		
	}
#if (SX1278FSK_debug_mode > 1)
	Serial.print(F("## Maximum current supply configured is "));
	Serial.print(value, DEC);
	Serial.println(F(" mA ##"));
	Serial.println();
#endif
	return value;
}

/*
Function: Limits the current supply of the power amplifier, protecting battery chemistries.
Returns: Integer that determines if there has been any error
state = 2  --> The command has not been executed
state = 1  --> There has been an error while executing the command
state = 0  --> The command has been executed with no errors
state = -1 --> Forbidden parameter value for this function
Parameters:
rate: value to compute the maximum current supply. Range: 0x00 to 0x1B. The 
Maximum current is:
Imax = 45+5*OcpTrim [mA] 	if OcpTrim <= 15 (120 mA) /
Imax = -30+10*OcpTrim [mA] 	if 15 < OcpTrim <= 27 (130 to 240 mA)
Imax = 240mA 				for higher settings
*/
int8_t SX1278FSK::setMaxCurrent(uint8_t rate)
{
	int8_t state = 2;
	byte st0;

#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'setMaxCurrent'"));
#endif

	// Maximum rate value = 0x1B, because maximum current supply = 240 mA
	if (rate > 0x1B)
	{
		state = -1;
#if (SX1278FSK_debug_mode > 1)
		Serial.print(F("** Maximum current supply is 240 mA, "));
		Serial.println(F("so maximum parameter value must be 27 (DEC) or 0x1B (HEX) **"));
		Serial.println();
#endif
	}
	else
	{
		// Enable Over Current Protection
		rate |= B00100000;

		state = 1;
		st0 = readRegister(REG_OP_MODE);	// Save the previous status
		writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);	// Set FSK Standby mode to write in registers
		writeRegister(REG_OCP, rate);		// Modifying maximum current supply
		if(st0 != FSK_STANDBY_MODE) {
			writeRegister(REG_OP_MODE, st0);		// Getting back to previous status
		}
		state = 0;
	}
	return state;
}


/*
Function: Configures the module to receive information.
Returns: Integer that determines if there has been any error
state = 2  --> The command has not been executed
state = 1  --> There has been an error while executing the command
state = 0  --> The command has been executed with no errors
*/
uint8_t SX1278FSK::receive()
{
	uint8_t state = 1;
#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'receive'"));
#endif
	// TODO: Is there anything else to be done?
	//
	writeRegister(REG_OP_MODE, FSK_RX_MODE);  
	state = 0;
#if (SX1278FSK_debug_mode > 1)
		Serial.println(F("## Receiving FSK mode activated with success ##"));
#endif
	return state;
}

/*
Function: Configures the module to receive a packet
Returns: Integer that determines if there has been any error
state = 2  --> The command has not been executed
state = 1  --> There has been an error while executing the command
state = 0  --> The command has been executed with no errors
Parameters:
	wait: timeout in ms
	data: memory where to place received data
*/
uint8_t SX1278FSK::receivePacketTimeout(uint32_t wait, byte *data)
{
	int di=0;
	uint8_t state = 2;
	unsigned long previous;
	byte value = 0x00;
#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'receivePacketTimeout'"));
#endif
	// set RX mode
	state = receive();
	if(state != 0) { return state; }

#if (SX1278FSK_debug_mode > 0)
	Serial.println(F("RX mode sucessfully activated"));
#endif
	previous = millis();
	/// FSK mode
	value = readRegister(REG_IRQ_FLAGS2);
	byte ready=0;
	// while not yet done or FIFO not yet empty
	while( (!ready || bitRead(value,6)==0) && (millis() - previous < wait) )
	{
		if( bitRead(value,2)==1 ) ready=1;
		if( bitRead(value, 6) == 0 ) { // FIFO not empty
			data[di++] = readRegister(REG_FIFO);
			// It's a bit of a hack.... get RSSI and AFC (a) at beginning of packet and
			// for RS41 after about 0.5 sec. It might be more logical to put this decoder-specific
			// code into RS41.cpp instead of this file... (maybe TODO?)
			
			if(di==1 || di==290 ) {
				int rssi=getRSSI();
				int afc=getAFC();
#if 0
				Serial.printf("Test(%d): RSSI=%d", rxtask.currentSonde, rssi/2);
				Serial.print("Test: AFC="); Serial.println(afc);
#endif
				sonde.sondeList[rxtask.currentSonde].rssi = rssi;
				sonde.sondeList[rxtask.currentSonde].afc = afc;
				if(rxtask.receiveResult==0xFFFF)
					rxtask.receiveResult = RX_UPDATERSSI;
				//sonde.si()->rssi = rssi;
				//sonde.si()->afc = afc;
			}
			if(di>520) {
				// TODO
				Serial.println("TOO MUCH DATA");
				break;
			}
			previous = millis(); // reset timeout after receiving data
		} else {
			delay(10);
		}
		value = readRegister(REG_IRQ_FLAGS2);
	}
	if( !ready || bitRead(value, 6)==0) {
#if 1&&(SX1278FSK_debug_mode > 0)
		Serial.println(F("** The timeout has expired **"));
		Serial.println();
#endif
		sonde.si()->rssi = getRSSI();
		writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);	// Setting standby FSK mode
		return 1;  // TIMEOUT
	}

#if (SX1278FSK_debug_mode > 0)
	Serial.println(F("## Packet received:"));
	for(unsigned int i = 0; i < di; i++)
	{
		Serial.print(data[i], HEX);		// Printing payload
		Serial.print("|");
	}
	Serial.println(F(" ##"));
#endif
	state = 0;
	// Initializing flags	
	clearIRQFlags();	

	return state;
}


#if 0
/*
Function: It gets the temperature from the measurement block module.
Returns: Integer that determines if there has been any error
state = 2  --> The command has not been executed
state = 1  --> There has been an error while executing the command
state = 0  --> The command has been executed with no errors
*/
uint8_t SX1278FSK::getTemp()
{
	byte st0;
	uint8_t state = 2;

#if (SX1278FSK_debug_mode > 1)
	Serial.println();
	Serial.println(F("Starting 'getTemp'"));
#endif

	st0 = readRegister(REG_OP_MODE);	// Save the previous status

	if( _modem == LORA )
	{ // Allowing access to FSK registers while in LoRa standby mode
		writeRegister(REG_OP_MODE, LORA_STANDBY_FSK_REGS_MODE);
	}

	state = 1;
	// Saving temperature value
	_temp = readRegister(REG_TEMP);
	if( _temp & 0x80 ) // The SNR sign bit is 1
	{
		// Invert and divide by 4
		_temp = ( ( ~_temp + 1 ) & 0xFF );
	}
	else
	{
		// Divide by 4
		_temp = ( _temp & 0xFF );
	}


#if (SX1278FSK_debug_mode > 1)
	Serial.print(F("## Temperature is: "));
	Serial.print(_temp);
	Serial.println(F(" ##"));
	Serial.println();
#endif

	if( _modem == LORA )
	{
		writeRegister(REG_OP_MODE, st0);	// Getting back to previous status
	}

	state = 0;
	return state;
}

/*
Function: It prints the registers related to RX
Returns: Integer that determines if there has been any error
state = 2  --> The command has not been executed
state = 1  --> There has been an error while executing the command
state = 0  --> The command has been executed with no errors
*/
void SX1278FSK::showRxRegisters()
{	
	Serial.println(F("\n--- Show RX register ---"));

	// variable
	byte reg;	

	for(int i = 0x00; i < 0x80; i++)
	{
		reg = readRegister(i);	
		Serial.print(F("Reg 0x"));
		Serial.print(i, HEX);
		Serial.print(F(":"));
		Serial.print(reg, HEX);
		Serial.println();
		delay(100);
	}

	Serial.println(F("------------------------"));

}
#endif

SX1278FSK sx1278 = SX1278FSK();
