#include <stdio.h>
#include <string.h>
#include "sx1276_api.h"
#include "sx1276-LoRa.h"


#include "sys_tick.h"
#include "sx1276-Hal.h"
#include "radio.h"
#include "sx1276.h"
#include "queue.h"

#include "led.h"
#include "sx1276-LoRaMisc.h"

/************************************************
函数名称 ： 应用层函数，SX1276_Send_Data
功    能 ： Lora发送   阻塞函数,自动计算发送超时时间
参    数 ： buffer  发送缓存区，
						bufferLen 发送数据长度，最长不能超过128个字节
返 回 值 ： 返回1发送成功，其他值发送失败
作    者 ： sun
*************************************************/
uint8_t SX1276_Send_Data(uint8_t * buffer,uint16_t bufferLen)
{
	uint32_t result = 0;
	uint32_t Timeout = 0;

	Timeout = SX1276GetLoraTimeOnAir(bufferLen);
	Timeout = 2*Timeout;
	SX1276LoRaSetTxPacketTimeout( Timeout );
	if(bufferLen > 255)
	{
	//SX1276LoRaSetPayloadLength(128);
	//SX1276SetTxPacket( buffer, 128 );		//开始发送
		return 0;
	}
	else
	{
	//start_led(1,bufferLen,99,30*10);//(led,delay*0.1ms,duty,period*0.1ms)
	//LED1=!LED1;
		SX1276LoRaSetPayloadLength(bufferLen);
		SX1276SetTxPacket( buffer, bufferLen );		//开始发送


	}
	while( 1 )
	{
	//start_led(1,3*10,90,100*10);//(led,delay*0.1ms,duty,period*0.1ms)
	//LED3=!LED3;
		result = SX1276Process( );


		if( result == RF_TX_DONE || result == RF_TX_TIMEOUT )
		{
			break;
		}
	}

	//start_led(1,0,90,100*10);//(led,delay*0.1ms,duty,period*0.1ms)
	if( result == RF_TX_DONE )
	{
		return 1;
	}
	return 0;
}

 /************************************************
函数名称 ： SX1276_Read_Data  LoRa单次接函数
功    能 ： 单信道接收,阻塞函数,接收指定敷在长度的数据,用于发送完成后开启短暂接收窗
参    数 ：	Buffer 接收到的数据
					  timeout  接收超时时间
						snr   	 信噪比   输出接收当前包的信噪比
						rssi     信号强度 输出接收当前包的信噪比
返 回 值 ： 接收到数据返回数据长度  失败返回-1
作    者 ： sun
*************************************************/
int16_t SX1276_Read_Data( void *Buffer ,uint32_t Timeout, int8_t *snr,double *rssi )
{
	uint32_t result;
	uint16_t bufferLen = 0;
	SX1276LoRaSetRxSingleOn( 1 );
	SX1276LoRaSetRxPacketTimeout( Timeout );
	SX1276StartRx( );
	while( 1 )
	{
		result = SX1276Process( );
		if( result == RF_RX_DONE || result == RF_RX_TIMEOUT )
		break;
	}
	if( result == RF_RX_DONE )
	{
		SX1276GetRxPacket( Buffer, ( uint16_t* )&bufferLen );
		*snr = SX1276LoRaGetPacketSnr( );
		//*rssi = ( int16_t )( SX1276LoRaGetPacketRssi( ) + 0.5 );
		//*rssi = SX1276LoRaReadRssi();
		*rssi = SX1276LoRaGetPacketRssi();
		return bufferLen;
	}
	
	return -1;
}

/************************************************
函数名称 ： 应用层函数，SX1276_Send_Data_Listen_Ch
功    能 ： Lora发送   阻塞函数,自动计算发送超时时间,并且在发送时进行CAD监听。
参    数 ： buffer  发送缓存区，
						bufferLen 发送数据长度
						ldelay_ms,两次发送等待时间 单位ms
						
返 回 值 ： 返回1发送成功，其他值发送失败
作    者 ： sun
*************************************************/
uint8_t SX1276_Send_Data_Listen_Ch(uint8_t * buffer,uint16_t bufferLen,uint32_t ldelay_ms,uint8_t num)
{
	uint32_t result = RF_IDLE;
	uint8_t send_r = 0;
	uint8_t temp = num ;

	while(temp--)
	{
		//SX1276_API_DEBUG_F("temp=%d\r\n",temp);
		Delay_Ms(10);
		SX1276StartCad( );
		while( 1 )
		{
			result = SX1276Process( );
			Delay_Ms(10);
			//SX1276_API_DEBUG_F("result=%d\r\n",result);
			if( result == RF_CHANNEL_ACTIVITY_DETECTED) {
				printf("RF_CHANNEL_ACTIVITY_DETECTED,temp=%d\r\n",temp);
				Delay_Ms(ldelay_ms);
				//delay_ms(10);
				//延时
				//goto cad_start;
				break;
			} else if( result == RF_CHANNEL_EMPTY) {
				//goto send_start; //信道时空的开始发送
				//SX1276_API_DEBUG_F("SX1276_Send_Data\r\n");
				send_r = SX1276_Send_Data(buffer,bufferLen);
				//SX1276_API_DEBUG_F("SX1276_Send_Data completed\r\n");
				if(send_r > 0)
				{
					return 1;
				}
				else
				{
					return 0;
				}
 			} else {
				if(temp == 0)
				{
					return 0;  //信道一直忙,发送失败
				}
			}
			temp--;
			if(temp>100)
				temp=0;
			Delay_Ms(50);
		}

		if(temp == 0)
		{
			return 0;  //信道一直忙,发送失败
		}
	}
	return 0; 
}


/************************************************
函数名称 ： 应用层函数，SX1276IsLoraChannelFree
功    能 ： 判断环境RSSI，可用于检测信道是否忙，请自行测试界限值，一般无线都用此方法判断。
参    数 ： int16_t rssiThresh 信道忙与不忙的界线值
返 回 值 ： 返回1信道忙，信道不忙，
作    者 ： sun
*************************************************/
bool SX1276IsLoraChannelFree( int16_t rssiThresh )
{
	return rssiThresh > SX1276LoRaReadRssi() ? 0:1;

}

/************************************************
函数名称 ： 应用层函数，SX1276_Sleep
功    能 ： LoRa休眠函数 LoRa休眠后功耗 < 1uA,可直接调用收发函数唤醒
参    数 ： 
返 回 值 ： 
作    者 ： sun
*************************************************/
void SX1276_Sleep(void)
{
	SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
}

/************************************************
函数名称 ： 应用层函数，SX1276_Cad_Listen
功    能 ： CAD模式
参    数 ： 
返 回 值 ： 1，监测到有效前导码，0无检测
作    者 ： sun
*************************************************/
uint8_t SX1276_Cad_Listen(void)
{ 
	uint32_t result =0 ;
	SX1276StartCad( );
	while( 1 )
	{
		result = SX1276Process( );
		if( result == RF_CHANNEL_ACTIVITY_DETECTED || result == RF_CHANNEL_EMPTY )
			break;
	}
	if( result == RF_CHANNEL_ACTIVITY_DETECTED )
	{
		return 1;
	}
	else
	{
		return 0;
	}

}


/************************************************
函数名称 ： 应用层函数，SX1276_CAD_Task
功    能 ： MCU唤醒后执行此代码可CAD检测接收数据
参    数 ： Buffer 数据缓存区，Timeout 超时时间单位ms
返 回 值 ： 没有接受到数据返回0，接收到数据返回数据长度
作    者 ： sun
*************************************************/
uint16_t  SX1276_CAD_Task( void *Buffer ,uint32_t Timeout,int8_t *snr,int16_t *rssi )
{
	uint32_t result = RF_IDLE;
	uint16_t len =0 ;
	SX1276LoRaSetRxPacketTimeout( Timeout );
	SX1276StartCad( );
	while( 1 )
	{
		result = SX1276Process( );
		if( result == RF_CHANNEL_ACTIVITY_DETECTED || result == RF_CHANNEL_EMPTY )
			break;
	}
	if( result == RF_CHANNEL_ACTIVITY_DETECTED )
	{
		while( 1 )
		{
			result = SX1276Process( );
			if( result == RF_RX_DONE || result == RF_RX_TIMEOUT|| result == RF_RX_ID_ERROR )
				break;
		}

		if( result == RF_RX_DONE )
		{
			SX1276GetRxPacket( Buffer, ( uint16_t* )&len );
			*rssi = ( int16_t )( SX1276LoRaGetPacketRssi( ) + 0.5 );
			*snr = SX1276LoRaGetPacketSnr( );
		}
	}
	return len;
}


/************************************************
函数名称 ： 应用层函数，SX1276_Send_Data_Sp
功    能 ： Lora发送   非阻塞函数,自动计算发送超时时间，不判断是否发送成功，请在程序里自行判断。
参    数 ： buffer  发送缓存区，
						bufferLen 发送数据长度
返 回 值 ： 空
作    者 ： sun
*************************************************/
void SX1276_Send_Data_Sp(uint8_t * buffer,uint16_t bufferLen )
{
		uint32_t Timeout = 0;
		Timeout = SX1276GetLoraTimeOnAir(bufferLen);
		Timeout = 2*Timeout;
		SX1276LoRaSetTxPacketTimeout( Timeout );
		if(bufferLen > 128)
		{
			SX1276SetTxPacket( buffer, 128 );		//开始发送
		}
		else
		{
			SX1276LoRaSetPayloadLength(bufferLen);
			SX1276SetTxPacket( buffer, bufferLen );		//开始发送
		}
}

 /************************************************
函数名称 ： SX1276_Read_Data  LoRa单次接函数
功    能 ： 单信道接收,阻塞函数,接收指定敷在长度的数据,用于发送完成后开启短暂接收窗
参    数 ：	Buffer 接收到的数据
					  timeout  接收超时时间
						snr   	 信噪比   输出接收当前包的信噪比
						rssi     信号强度 输出接收当前包的信噪比
返 回 值 ： 接收到数据返回数据长度  失败返回-1
作    者 ： sun
*************************************************/
void SX1276_Read_Data_Sp(uint32_t Timeout)
{
	//SX1276LoRaSetRxSingleOn( 1 );
	SX1276LoRaSetRxPacketTimeout( Timeout );
	SX1276StartRx( );
	
}
 /************************************************
函数名称 ： SX1276_CAD_Start
功    能 ： 启动CAD功能，请在程序中判断CAD结果，防止阻塞
作    者 ： sun
*************************************************/
void SX1276_CAD_Start( void )
{
	 SX1276StartCad( );
}
