/*
*********************************************************************************************************
*                                       IAR Development Kits
*                                              on the
*
*                                    Nano100
*
* Filename      : uart_BDModule.h
* Version       : V1.00
* Programmer(s) : Qian Xianghong
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                             INCLUDE FILES
*********************************************************************************************************
*/
#include "includes.h"

const uint8_t BD_APP = RF_APP_AJH;
const uint8_t BD_PROTOCOL_VER = RF_PROTOCOL_VER_2;	

#define RF_SelfPSN (dcBuff.configBottle.PSN)

uint8_t BD_RF_MAC_FN = 0;
uint8_t BD_RF_APP_PN = 0;
uint8_t BD_RF_APP_IDX = 0;

// 发送、接收帧
bd_frame_t BD_Send_Frame, BD_RecvFrame;

// 接收自检信息和反馈信息
volatile uint8_t BD_semZjxx = 0, BD_semFkxx = 0;
bd_zjxx_t BD_Zjxx;
bd_fkxx_t BD_Fkxx;

// 北斗初始化状态
uint8_t BD_initStatus = 0;

volatile uint8_t BD_hasPowered = 0;

// 计算校验和（异或）
uint8_t bd_cs_nor(uint8_t *message, int16_t len)
{
    int16_t i;
    uint8_t cs = 0;

    for(i = 0; i < len; i++)
        cs ^= message[i];

    return cs;
}

// 初始化帧
void bd_initial_frame(bd_frame_t *frame, char *cmd)
{
	memset((uint8_t *) frame, 0, sizeof(bd_frame_t));
	frame->sof = BD_FRAME_SOF;
	memmove(frame->cmd, cmd, 4);
	frame->len = BD_MIN_FRAME_LEN; // 小端模式，发送时再转换成大端模式
}

// 追加负载数据
uint8_t bd_append_payload(bd_frame_t *frame, uint8_t payload_len, uint8_t *payload)
{
	if(frame->len < BD_MIN_FRAME_LEN || frame->len + payload_len > BD_MAX_FRAME_LEN)
		return 0;
	
	if(payload_len > 0)
		memmove(frame->bd_payload + (frame->len - BD_MIN_FRAME_LEN), payload, payload_len);
	frame->len += payload_len;
	return 1;
}

void bd_prepare_send(bd_frame_t *frame)
{
	uint8_t *buf = (uint8_t *) frame;
	uint16_t len = frame->len;
	
	frame->len = htons(len);				// 转换成大端模式
	buf[len - 1] = bd_cs_nor(buf, len - 1);	// 填写校验码
}

// 北斗物理层校验
uint8_t bd_phy_valid(bd_frame_t *frame)
{
	// 通信信息帧
	if(strncmp(frame->cmd, BD_TXXX, 4) == 0)
	{
		// 通信01、代码1、不回执0、通信0、无密钥0、保留00
		if(frame->txxx.xxlb != 0x60 || ntohs(frame->txxx.bitLen) > 624) 
			return 0;
	}
	
	// 北斗帧校验成功
	return 1;
}

// 物理层校验
uint8_t bd_rf_phy_valid(bd_rf_frame_t *frame)
{
	if(frame->sof != RF_FRAME_SOF || frame->len < BD_RF_MIN_FRAME_LEN || frame->len > BD_RF_MAX_FRAME_LEN)
		return 0;
	if(frame->vendor_id != RF_MARK_LS ||  frame->app_id != BD_APP || frame->protocol_ver != BD_PROTOCOL_VER)
		return 0;
	if(rf_crc_16((uint8_t *) frame, frame->len) != 0)
		return 0;
	
	// 物理层校验成功
	return 1;
}

// mac层校验
uint8_t bd_rf_mac_valid(bd_rf_frame_t *frame, uint8_t dir)
{
	if(frame->dir != dir)
		return 0;

	// mac层校验成功
	return 1;
}

// 重新寻找SOF
void BD_SearchSOF(uint8_t *buf, uint16_t fromPos, uint16_t *len)
{
	uint16_t i;
	
	for(i = fromPos; i < *len && buf[i] != BD_FRAME_SOF; i++)
	{
	}
	
	*len -= i;
	memmove(buf, buf + i, *len);
}

// 分析串口数据，组帧
void BD_ParseFrame(uint8_t c)
{
	static uint16_t RdIdx = 0;
	uint8_t *BD_ModuleData = (uint8_t *) &BD_RecvFrame;
	uint8_t frameOk, frameErr;
	uint16_t len;

	if(RdIdx == 0 && c != BD_FRAME_SOF)
		return;
	
	BD_ModuleData[RdIdx++] = c;

	do
	{
		if(RdIdx < 7)
			break;
		len = (BD_ModuleData[5] << 8) | BD_ModuleData[6];
		
		frameErr = (len < BD_MIN_FRAME_LEN || len > BD_MAX_FRAME_LEN);
		if(frameErr)
		{
			// 从1开始寻找SOF
			BD_SearchSOF(BD_ModuleData, 1, &RdIdx);

			if(RdIdx < 7)
				break;
			len = (BD_ModuleData[5] << 8) | BD_ModuleData[6];
		}

		frameOk = (len >= BD_MIN_FRAME_LEN && len <= BD_MAX_FRAME_LEN && RdIdx >= len);
		if(frameOk)
		{
			if(bd_cs_nor(BD_ModuleData, len) == 0)
			{
				if(bd_phy_valid(&BD_RecvFrame))
				{
					if(strncmp(BD_RecvFrame.cmd, BD_TXXX, 4) == 0)
					{
					}
					else if(strncmp(BD_RecvFrame.cmd, BD_ZJXX, 4) == 0)
					{
						dcBuff.powerInfo.bdNumber = (BD_RecvFrame.selfAddr[0] << 16) | (BD_RecvFrame.selfAddr[1] << 8) | BD_RecvFrame.selfAddr[2];
						BD_Zjxx = BD_RecvFrame.zjxx;
						BD_semZjxx = 1;
					}
					else if(strncmp(BD_RecvFrame.cmd, BD_FKXX, 4) == 0)
					{
						BD_Fkxx = BD_RecvFrame.fkxx;
						BD_semFkxx = 1;
					}
				}
				
				// 继续寻找下一帧
				RdIdx -= len;
				memmove(BD_ModuleData, BD_ModuleData + len, RdIdx);
				// 从0开始寻找SOF
				BD_SearchSOF(BD_ModuleData, 0, &RdIdx);
			}
			else
			{
				// 从1开始寻找SOF
				BD_SearchSOF(BD_ModuleData, 1, &RdIdx);
			}
		}
	} while(frameOk || frameErr);
}

// 自检
uint8_t BD_Xtzj()
{
	uint8_t try_cnt;
	uint32_t stop_seconds;
	
	bd_initial_frame(&BD_Send_Frame, BD_XTZJ);
	bd_append_payload(&BD_Send_Frame, sizeof(bd_xtzj_t), BD_Send_Frame.bd_payload);
	bd_prepare_send(&BD_Send_Frame);
	for(try_cnt = 0; try_cnt < 1; try_cnt++)
	{
		// 清除返回标志
		BD_semZjxx = 0;
		// 发送命令
		UART_Transmit(&huart3, (uint8_t *) &BD_Send_Frame, ntohs(BD_Send_Frame.len));

		// 等待返回数据
		stop_seconds = rf_get_seconds() + 2;
		while(rf_get_seconds() < stop_seconds)
		{
			if(BD_semZjxx)
			{
				printf("\nBD Module self check returned.\n");
				if(BD_Zjxx.antennaErr)
					printf("\nThe antenna has error!\n");
				if(BD_Zjxx.boardErr)
					printf("\nThe board has error!\n");
				if(BD_Zjxx.cardErr)
					printf("\nThe card has error!\n");
				if(BD_Zjxx.channelErr)
					printf("\nThe channel has error!\n");
				if(BD_Zjxx.snErr)
					printf("\nThe serial no has error!\n");
				if(BD_Zjxx.dataErr)
					printf("\nThe data has error!\n");
				if(BD_Zjxx.chkErr)
					printf("\nThe check has error!\n");
				if(BD_Zjxx.idErr)
					printf("\nThe id has error!\n");
				if(BD_Zjxx.phyErr)
					printf("\nThe physical has error!\n");
				
				if(!BD_Zjxx.antennaErr && !BD_Zjxx.boardErr && !BD_Zjxx.cardErr && !BD_Zjxx.channelErr
					&& !BD_Zjxx.snErr && !BD_Zjxx.dataErr && !BD_Zjxx.chkErr && !BD_Zjxx.idErr && !BD_Zjxx.phyErr)
				{
					return 1;
				}
				break;
			}
			delay_ms(200);
		}
		delay_ms(500);
	}
	return 0;
}

void BD_IRQHandler(USART_Handle *huart)
{
	uint8_t c = (uint8_t) huart->Instance->RDR;
	
//	printf("%02X ", c);
	// 直接处理，分析并组帧
	BD_ParseFrame(c);
}

// 初始化
void BD_Init()
{
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
	/**USART3 GPIO Configuration  
	PB10   ------> USART3_TX
	PB11   ------> USART3_RX 
	*/
	GPIO_InitStruct.Pin = LL_GPIO_PIN_10|LL_GPIO_PIN_11;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
	GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
	GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
	GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
	LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void BD_Open()
{
	LL_USART_InitTypeDef USART_InitStruct = {0};

	// 用PSN的CRC校验值作为伪随机数的种子
	srand(rf_crc_16(dcBuff.configBottle.PSN, 6));

	BD_RF_MAC_FN = rand() % 256;
	BD_RF_APP_PN = rand() % 256;

	huart3.RxISR = BD_IRQHandler;

	/* Peripheral clock enable */
	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);

	/* USART3 interrupt Init */
	NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
	NVIC_EnableIRQ(USART3_IRQn);

	USART_InitStruct.BaudRate = 115200;
	USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
	USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
	USART_InitStruct.Parity = LL_USART_PARITY_NONE;
	USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
	USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
	USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
	LL_USART_Init(USART3, &USART_InitStruct);
	LL_USART_ConfigAsyncMode(USART3);

	SET_BIT(USART3->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
	LL_USART_Enable(USART3);
}

// 初始化帧
void bd_rf_initial_frame(bd_rf_frame_t *frame)
{
	memset((uint8_t *) frame, 0, sizeof(bd_rf_frame_t));
	frame->len = BD_RF_MIN_FRAME_LEN;
}

// 追加负载数据
uint8_t bd_rf_append_payload(bd_rf_frame_t *frame, uint8_t payload_len, uint8_t *payload)
{
	if(frame->len < BD_RF_MIN_FRAME_LEN || frame->len + payload_len > BD_RF_MAX_FRAME_LEN)
		return 0;
	
	if(payload_len > 0)
		memmove(frame->app_payload + (frame->len - BD_RF_MIN_FRAME_LEN), payload, payload_len);
	frame->len += payload_len;
	return 1;
}

// 模块上电，设置硬件参数
void BD_PowerOn()
{
	uint8_t i, count = 0;
	static uint8_t first = 1;
	
	if(BD_hasPowered)
		return;
	
	printf("\nBD power on ...\n");

	VCC_BD_ON();
	delay_ms(2700);

	if(BD_Xtzj())
	{
//		for(i = 0; i < 6; i++)
//		{
//			if(BD_Zjxx.power[i] >= 2)
//				count++;
//		}
//		if(count >= 2)
		{
			// 设置状态：以第一次检测的结果为准
			if(first)
				BD_initStatus = 1;
		}
	}

	first = 0;
	
	BD_hasPowered = 1;
}

void BD_PowerOff()
{
	if(!BD_hasPowered)
		return;
	
	BD_hasPowered = 0;

	printf("\nBD power off ...\n");
	VCC_BD_OFF();
	delay_ms(200);
}

// 应用层发送：数据
uint8_t bd_rf_app_send_data(uint8_t payload_len, uint8_t *payload)
{
//	uint16_t i;
	
	uint8_t try_cnt;
	uint32_t stop_seconds;
	uint16_t crc;
	bd_rf_frame_t *rf = (bd_rf_frame_t *) BD_Send_Frame.txsq.bytes;
	S_RTC_TIME_DATA_T sRTC;
	
	// 初始化BD帧
	bd_initial_frame(&BD_Send_Frame, BD_TXSQ);
	// 初始化RF帧
	bd_rf_initial_frame(rf);

	// 应用层
	bd_rf_append_payload(rf, payload_len, payload);
	rf->app_pn = BD_RF_APP_PN;
	rf->app_idx = 0;	// 暂不实现分包组包
	rf->app_tbc = 0;

	// net层
	rf->net_type = RF_NET_TYPE_DATA;
	
	// mac层
	rf->dir = RF_DIR_UP;
	rf->mac_type = RF_MAC_TYPE_DATA;
	rf->mac_ack_req = 0;
	rf->mac_fn = BD_RF_MAC_FN;
	
	// 物理层
	rf->sof = RF_FRAME_SOF;
	rf->vendor_id = RF_MARK_LS;
	rf->app_id = BD_APP;
	rf->protocol_ver = BD_PROTOCOL_VER;
	memmove(rf->srcPSN, RF_SelfPSN, 6);
	crc = rf_crc_16((uint8_t *) rf, rf->len - 2);
	((uint8_t *) rf)[rf->len - 2] = crc >> 8;
	((uint8_t *) rf)[rf->len - 1] = crc & 0xFF;
		
	// 通讯申请
	BD_Send_Frame.txsq.xxlb = 0x46; 		// 普通报文代码
	BD_Send_Frame.txsq.dstAddr[0] = (dcBuff.configDisplay.bdCommander >> 16) & 0xFF; // 指挥机卡号
	BD_Send_Frame.txsq.dstAddr[1] = (dcBuff.configDisplay.bdCommander >> 8) & 0xFF;
	BD_Send_Frame.txsq.dstAddr[2] = (dcBuff.configDisplay.bdCommander & 0xFF);
	BD_Send_Frame.txsq.bitLen = htons(rf->len * 8);	
	// 追加通讯申请内容
	bd_append_payload(&BD_Send_Frame, 
		sizeof(BD_Send_Frame.txsq) - sizeof(BD_Send_Frame.txsq.bytes) + payload_len + BD_RF_MIN_FRAME_LEN,
		(uint8_t *) &BD_Send_Frame.txsq); 
	// 修改数据格式，计算cs
	bd_prepare_send(&BD_Send_Frame);
		
	for(try_cnt = 0; try_cnt < 3; try_cnt++)
	{
		// 清除返回标志
		BD_semFkxx = 0;
		// 发送命令
		UART_Transmit(&huart3, (uint8_t *) &BD_Send_Frame, ntohs(BD_Send_Frame.len));

//		for(i = 0; i < ntohs(BD_Send_Frame.len); i++)
//			printf("%02X ", ((uint8_t *) &BD_Send_Frame)[i]);
//		printf("\n");
		
		// 等待返回数据s
		stop_seconds = rf_get_seconds() + 2;
		while(rf_get_seconds() < stop_seconds)
		{
			if(BD_semFkxx)
			{
				printf("\nBD Module feedback returned.\n");
				if(BD_Fkxx.fkbz == 0 && strncmp(BD_Fkxx.fjxx, BD_TXSQ, 4) == 0)
				{
					printf("\nThe message has send.\n");
					BD_RF_MAC_FN++;
					BD_RF_APP_PN++;
					// 记录发送成功的时间
					RTC_GetDateAndTime(&sRTC);
					DTU_succTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day,
							sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second);
					return 1;
				}
				printf("\nThe message has not send.\n");
				break;
			}
			delay_ms(200);
		}
		delay_ms(500);
	}		
	
	return 0;
}
