#include "e32_demo.h"
#include "main.h"
#include "application.h"
#include <string.h>

/** 
 * 模组数据操作缓存
 */
static e32_opt_buffer_t e32_buffer;
	
/** 
 * 模组参数读取指令
 */	
static const uint8_t request_config[3]={0xC1,0xC1,0xC1};

/** 
 * AT指令 读取设备名
 */
static const char request_name[]="AT+DEVTYPE=?";

/** 
 * AT指令 读取固件版本
 */
static const char request_version[]="AT+FWCODE=?";

/** 
 * E32-900T22S 默认配置参数
 */
static const e32_register_t register_default = 
{
	.register_1 = {
		.address_h = 0x00,
	},
	.register_2 = {
		.address_l = 0x00,
	},
	.register_3.field = {
		.radio_rate      = RADIO_RATE_2400,
		.uart_baud_rate  = UART_RATE_9600,
		.uart_parity     = UART_8N1,
	},
	.register_4 = {
		.channel = 0x06,
	},  
	.register_5.field = {
		.tx_power                  = TX_POWER_DBM_20,
		.packet_fec                = ON,
		.wake_on_radio_period      = WOR_PERIOD_250MS,
		.reserve                   = OFF,
		.specify_target            = OFF,
	}, 
};

/**
 * @brief  向模组写入配置参数指令
 *
 * @param  config 配置信息
 */
static void e32_send_config_command( const e32_register_t *config )
{
	/* 第1字节：控制指令 
	   C0代表写入参数并保存 */
	e32_buffer.hex_cmd.command = 0xC0;
	
	/* 第2~6字节开始就是用户配置参数了 */
	memcpy( e32_buffer.hex_cmd.config , (uint8_t*)config , sizeof(e32_register_t));
	
	/* 串口写入 */
	e32_hal_uart_tx( (uint8_t*)&e32_buffer, sizeof(e32_register_t) + 1);
}

/**
 * @brief  向模组写入查询指令
 *
 * @param  cmd 查询类型
 */
static void e32_send_request_command( request_cmd_t cmd )
{
	switch( cmd )
	{
		/* 读取配置参数 */
		case REQUEST_CMD_CONFIG:
			e32_hal_uart_tx( (uint8_t*)request_config, sizeof(request_config));		
			break;
		
		/* 读取设备名称 */
		case REQUEST_CMD_NAME:
			e32_hal_uart_tx( (uint8_t*)request_name, strlen(request_name));	
			break;

		/* 读取固件版本 */
		case REQUEST_CMD_VERSION:
			e32_hal_uart_tx( (uint8_t*)request_version, strlen(request_version));	
			break;		
	}
}

/**
 * @brief  (查询指令的)模组应答数据检查
 *
 * @param   cmd 查询类型
 * @param   buffer 指向应答数据缓存
 * @param   length 应答数据长度
 * @return  bool 正确返回true; 否则返回false。
 */
static bool e32_response_command_check( request_cmd_t cmd , uint8_t *buffer , uint8_t length )
{
	bool ret = false;
	
	switch( cmd )
	{
		/* 读取配置参数 */	
		case REQUEST_CMD_CONFIG:
			
		  /* 长度检查 必须等于6字节*/
			if( length == 6 )
			{
				/* 内容检查 帧头必须为0xC1 */
				if( buffer[0] == 0xC1)			
				{
						ret = true;
				}
			}
			break;
		
		/* 读取设备名称 */	
		case REQUEST_CMD_NAME:
			/* 内容检查 */
			if( strncmp( "DEVTYPE=", (char*)buffer, 8) == 0 )
			{
					ret = true;
			}	
			break;
		
		/* 读取固件版本 */
		case REQUEST_CMD_VERSION:
			/* 内容检查 */
			if( strncmp( "FWCODE=", (char*)buffer, 7) == 0 )
			{
					ret = true;
			}	
			break;				
	}
	
	return ret;
}

/**
 * @brief  向模组串口写入数据
 *
 * @note 请注意模组工作模式
 * @param buffer 指向数据缓存
 * @param length 写入长度
 */
void e32_demo_transmit( uint8_t *buffer , uint16_t length )
{
	/* 串口写入 */
	e32_hal_uart_tx( buffer, length);	
	
}

/**
 * @brief  (可选) 示例如何读取设备名称
 *
 * @note 模组应处于配置模式
 * @param buffer 模组应答内容
 * @param length 模组应答长度
 */
void e32_demo_read_device_name( char *buffer , uint8_t *length  )
{
	uint16_t opt_length;

	/* 配置模式仅支持串口9600波特率 */
	uart1_reconfig(9600);
	
	/* 切换到配置模式 */
	e32_hal_work_mode( WORK_MODE_CONFIG_AND_SLEEP );
	
	/* 发送查询指令 获取设备名 */
	e32_send_request_command( REQUEST_CMD_NAME );	
	
	/* 等待模组应答 */
	uart1_wait_response_blocked( (uint8_t*)buffer , &opt_length );
	
	/* 应答内容检查 */
	if( e32_response_command_check( REQUEST_CMD_NAME, (uint8_t*)buffer , opt_length ) != true )
	{
			/* 应答数据不正确 */
			while(1);	
	}	

	*length = opt_length;
}

/**
 * @brief  (可选) 示例如何读取设备固件版本
 *
 * @note 模组应处于配置模式
 * @param buffer 模组应答内容
 * @param length 模组应答长度
 */
void e32_demo_read_fireware_version( char *buffer , uint8_t *length )
{
	uint16_t opt_length;
	
	/* 配置模式仅支持串口9600波特率 */
	uart1_reconfig(9600);	
	
	/* 切换到配置模式 */
	e32_hal_work_mode( WORK_MODE_CONFIG_AND_SLEEP );	
	
	/* 发送查询指令 获取设备名 */
	e32_send_request_command( REQUEST_CMD_VERSION );	
	
	/* 等待模组应答 */
	uart1_wait_response_blocked( (uint8_t*)buffer , &opt_length );
	
	/* 应答内容检查 */
	if( e32_response_command_check( REQUEST_CMD_VERSION, (uint8_t*)buffer , opt_length ) != true )
	{
			/* 应答数据不正确 */
			while(1);			
	}
			
	*length = opt_length;
}

/**
 * @brief  使用显示菜单用户配置参数重新配置模组
 *
 * @param config 菜单配置参数信息
 */
void e32_demo_menu_config( menu_config_t *config )
{
	uint16_t opt_length;
	e32_register_t register_write;
	transmit_power_t power_select = TX_POWER_DBM_20;
	
	/* 复制默认寄存器配置 */
	memcpy( (uint8_t*)&register_write , (uint8_t*)&register_default ,  sizeof(e32_register_t) );
	/* 功率转换 */	
	switch( config->tx_power )
	{
		case 17: 
			power_select = TX_POWER_DBM_17; 
			break;
		
		case 14:
			power_select = TX_POWER_DBM_14; 
			break;			
		
		case 10:
			power_select = TX_POWER_DBM_10; 
			break;	

		default:
			power_select = TX_POWER_DBM_20; 
			break;
	}
	
	/* 修改用户配置的参数 */
	register_write.register_5.field.tx_power = power_select;        //功率	
	register_write.register_3.field.radio_rate = (radio_rate_t)config->rate_mode; //空速
	register_write.register_4.channel = config->channel;            //信道
	 
	/* 配置模式仅支持串口9600波特率 */
	uart1_reconfig(9600);		
	
	/* 切换到配置模式 */
	e32_hal_work_mode( WORK_MODE_CONFIG_AND_SLEEP );
	
	/* 向模组串口写入配置 */
	e32_send_config_command( &register_write );	
	
	/* 等待模组应答 */
	uart1_wait_response_blocked( e32_buffer.opt_buffer , &opt_length );
	
//	/* 应答数据检查 指令头必为C1 */
//	if( e32_buffer.opt_buffer[0] != 0xC1 )
//	{
//			/* 模组如果回答FF FF FF 表示指令错误 */
//			while(1);
//	}
	
	///@todo 请结合串口波特率配置修改
	/* 切换到用户设置的透传模式串口波特率 */
	uart1_reconfig(9600);			
	
	/* 回到透明传输模式 */
	e32_hal_work_mode( WORK_MODE_TRANSPARENT );	
}

