#include "app_protocol.h"
#include "hc32_ll_mcan.h"
#include "hal_uart.h"
#include "hal_flash.h"
#include "hal_spi.h"
#include "hal_can.h"

#include "project_config.h"




static uint16_t g_dnpcrc_table[256] = 
{
		0x0000, 0x365E, 0x6CBC, 0x5AE2, 0xD978, 0xEF26, 0xB5C4, 0x839A,
		0xFF89, 0xC9D7, 0x9335, 0xA56B, 0x26F1, 0x10AF, 0x4A4D, 0x7C13,
		0xB26B, 0x8435, 0xDED7, 0xE889, 0x6B13, 0x5D4D, 0x07AF, 0x31F1,
		0x4DE2, 0x7BBC, 0x215E, 0x1700, 0x949A, 0xA2C4, 0xF826, 0xCE78,
		0x29AF, 0x1FF1, 0x4513, 0x734D, 0xF0D7, 0xC689, 0x9C6B, 0xAA35,
		0xD626, 0xE078, 0xBA9A, 0x8CC4, 0x0F5E, 0x3900, 0x63E2, 0x55BC,
		0x9BC4, 0xAD9A, 0xF778, 0xC126, 0x42BC, 0x74E2, 0x2E00, 0x185E,
		0x644D, 0x5213, 0x08F1, 0x3EAF, 0xBD35, 0x8B6B, 0xD189, 0xE7D7,
		0x535E, 0x6500, 0x3FE2, 0x09BC, 0x8A26, 0xBC78, 0xE69A, 0xD0C4,
		0xACD7, 0x9A89, 0xC06B, 0xF635, 0x75AF, 0x43F1, 0x1913, 0x2F4D,
		0xE135, 0xD76B, 0x8D89, 0xBBD7, 0x384D, 0x0E13, 0x54F1, 0x62AF,
		0x1EBC, 0x28E2, 0x7200, 0x445E, 0xC7C4, 0xF19A, 0xAB78, 0x9D26,
		0x7AF1, 0x4CAF, 0x164D, 0x2013, 0xA389, 0x95D7, 0xCF35, 0xF96B,
		0x8578, 0xB326, 0xE9C4, 0xDF9A, 0x5C00, 0x6A5E, 0x30BC, 0x06E2,
		0xC89A, 0xFEC4, 0xA426, 0x9278, 0x11E2, 0x27BC, 0x7D5E, 0x4B00,
		0x3713, 0x014D, 0x5BAF, 0x6DF1, 0xEE6B, 0xD835, 0x82D7, 0xB489,
		0xA6BC, 0x90E2, 0xCA00, 0xFC5E, 0x7FC4, 0x499A, 0x1378, 0x2526,
		0x5935, 0x6F6B, 0x3589, 0x03D7, 0x804D, 0xB613, 0xECF1, 0xDAAF,
		0x14D7, 0x2289, 0x786B, 0x4E35, 0xCDAF, 0xFBF1, 0xA113, 0x974D,
		0xEB5E, 0xDD00, 0x87E2, 0xB1BC, 0x3226, 0x0478, 0x5E9A, 0x68C4,
		0x8F13, 0xB94D, 0xE3AF, 0xD5F1, 0x566B, 0x6035, 0x3AD7, 0x0C89,
		0x709A, 0x46C4, 0x1C26, 0x2A78, 0xA9E2, 0x9FBC, 0xC55E, 0xF300,
		0x3D78, 0x0B26, 0x51C4, 0x679A, 0xE400, 0xD25E, 0x88BC, 0xBEE2,
		0xC2F1, 0xF4AF, 0xAE4D, 0x9813, 0x1B89, 0x2DD7, 0x7735, 0x416B,
		0xF5E2, 0xC3BC, 0x995E, 0xAF00, 0x2C9A, 0x1AC4, 0x4026, 0x7678,
		0x0A6B, 0x3C35, 0x66D7, 0x5089, 0xD313, 0xE54D, 0xBFAF, 0x89F1,
		0x4789, 0x71D7, 0x2B35, 0x1D6B, 0x9EF1, 0xA8AF, 0xF24D, 0xC413,
		0xB800, 0x8E5E, 0xD4BC, 0xE2E2, 0x6178, 0x5726, 0x0DC4, 0x3B9A,
		0xDC4D, 0xEA13, 0xB0F1, 0x86AF, 0x0535, 0x336B, 0x6989, 0x5FD7,
		0x23C4, 0x159A, 0x4F78, 0x7926, 0xFABC, 0xCCE2, 0x9600, 0xA05E,
		0x6E26, 0x5878, 0x029A, 0x34C4, 0xB75E, 0x8100, 0xDBE2, 0xEDBC,
		0x91AF, 0xA7F1, 0xFD13, 0xCB4D, 0x48D7, 0x7E89, 0x246B, 0x1235,
};

extern __IO en_flag_status_t spi_rx_complete_flag;
//extern char spi_tx_buf[EXAMPLE_SPI_BUF_LEN];
//extern char spi_rx_buf[EXAMPLE_SPI_BUF_LEN];
extern QueueHandle_t can1_recieve2_data_queue;																				 
extern QueueHandle_t can2_recieve1_data_queue;

static void creat_software_crc16(const uint8_t *pbuf, const uint32_t data_len, uint32_t *cur_crc);
static unsigned short crc16_modbus(unsigned char *pdata, int len);
static int8_t struct_convert_to_buffer(pack_t *pack,uint8_t *data);

uint8_t flash_write_finish = false;
int8_t pack_buffer[DATA_LENTH];

gps_info_t gps_info;
communication_data_t communication_data;
output_control_t output_control;
sleep_control_t sleep_control;
communication_control_t communication_control;
flash_write_t flash_write;
sys_paratemer_info_t sys_paratemer_info;
SemaphoreHandle_t spi_communication_semaphore = NULL;

static unsigned short crc16_modbus(unsigned char *pdata, int len)
{
		int j = 0;
		int i = 0;
		uint16_t reg_crc = 0xffff;
		while (i < len )
		{
				reg_crc ^= pdata[i];
				i++;	 		
				for (j = 0; j < 8; j++)
				{
						if ((reg_crc & 0x01) == 1)
						{
								reg_crc = (uint16_t)((reg_crc >> 1) ^ 0xa001);
						}
						else
						{
								reg_crc = (uint16_t)( reg_crc >> 1);
						}
				}
		}
		
    return reg_crc;
}


 
 

static void creat_software_crc16(const uint8_t *pbuf, const uint32_t data_len, uint32_t *cur_crc)
{
    uint16_t crc = 0u;
    uint32_t index = 0u;
 
    for (index = 0u; index < data_len; index++)
    {
        crc = ( crc >> 8 ) ^ g_dnpcrc_table[( crc ^ pbuf[index]) & 0x00ff] ;
    }

    *cur_crc = (uint32_t)((~crc) & 0xFFFFu);
}




static int8_t struct_convert_to_buffer(pack_t *pack,uint8_t *data)
{
	if(pack!=NULL && data!=NULL && pack->data_lenth<=DATA_LENTH)
	{
		data[0] = pack->frame_head;
		data[1] = pack->source_addr;
		data[2] = pack->destination_addr;
		data[3] = pack->data_head;
		data[4] = pack->cmd;
		data[5] = pack->cmd_type;
		data[6] = pack->data_lenth>>8;
		data[7] = pack->data_lenth&0xff;	
		memcpy(&data[8],pack->data,pack->data_lenth);
		data[pack->data_lenth+8] = pack->crc>>8;
		data[pack->data_lenth+9] = pack->crc&0xff;
		data[pack->data_lenth+10] = pack->frame_tail;
		return 0;
	}
	else
	{
		return -1;
	}
}

uint16_t Full_Frame_Verifi(uint8_t *srcdata, uint16_t srcLen, uint16_t* frame_start)
{
	uint16_t frame_len = 0;	// 获取帧长度
	uint8_t frame_flag = 0;		//找到帧起始位
	
	for(uint32_t i = 0; i < (srcLen - sizeof(frame_pack_t)) && 0 == frame_flag; i++)
	{
		if(0X5A == srcdata[i])
		{
			frame_len = srcdata[i + FRAME_LEN_INDEX] + (srcdata[i + FRAME_LEN_INDEX + 1] << 8);
			if((i + frame_len + 1) < srcLen && 
				(srcdata[i + frame_len - 2] + (srcdata[i + frame_len - 1] << 8) == crc16_modbus(srcdata + i, frame_len -2)))
			{
				frame_flag = 1;
				*frame_start = i;
				break;	
			}
		}
	}
	
	if(1 == frame_flag)
		return 0;
	else
		return frame_len;
}
uint8_t data_decode_mpu(uint8_t *input_data, uint32_t input_data_len, uint8_t* output, uint32_t* output_data_len)
{
	uint16_t frame_start = 0;	// 帧起始位
	uint16_t frame_len = 0;
	
	*output_data_len = 0;
	static frame_pack_t frame_tmp = {0};
	frame_tmp.frame_head = 0X5A;
	frame_tmp.destination_addr = MPU_ADDR;
	frame_tmp.source_addr = MCU_ADDR;
	frame_pack_t* frame_read_tmp;

	frame_len = Full_Frame_Verifi(input_data, input_data_len, &frame_start);
	if(0 != frame_len)
		return 0;
	
	*output_data_len += sizeof(frame_pack_t);
	switch(input_data[frame_start + FRAME_CMD_INDEX])
	{
		case 0X50:
			frame_tmp.cmd = 0X50;
			switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
			{
				case 0X01:
					frame_tmp.cmd_type = 0X01;
					memcpy(output + *output_data_len, &mcu_decie_status, sizeof(cmd_05_01_device_status_t));
					*output_data_len += sizeof(cmd_05_01_device_status_t);
				
					break; 
				case 0X02:
					frame_tmp.cmd_type = 0X02;
					memcpy(output + *output_data_len, gps_05_02_data, gps_data_len);
					*output_data_len += gps_data_len;
					break;
				case 0X03:
					frame_tmp.cmd_type = 0X03;
					memcpy(output + *output_data_len, &com_05_03_data, sizeof(communication_data_t));
					*output_data_len += sizeof(communication_data_t);
					break;
				default:
					*output_data_len = 0;
					return 0;
					break;
			}
			break;
		case 0X60:
			//
			switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
			{
				case 0X01:
					///
					*output_data_len = 0;
					break;
				case 0X02:
					///
				
					break;
				case 0X03:
					//
					break;
				case 0X04:
					//
					break;
				default:
					*output_data_len = 0;
					return 0;
					break;
			}
			*output_data_len = 0;
			return 0;
			break;
		default:
			*output_data_len = 0;
			return 0;
			break;
	}
	frame_tmp.data_lenth = *output_data_len + 2;
	memcpy(output, &frame_tmp, sizeof(frame_pack_t)); //帧固定帧在此复制
	
	uint16_t crc16 = crc16_modbus(output, *output_data_len);
	output[(*output_data_len)++] = crc16 & 0XFF;
	output[(*output_data_len)++] = (crc16 >> 8) & 0XFF;
	
	return frame_len;
}


void mcu_to_mpu_task(void *arg)
{
	can1_recieve2_data_queue = xQueueCreate(5,sizeof(hc32_can_rx_msg_t));//can1存放非升级帧的队列	
	can2_recieve1_data_queue = xQueueCreate(5,sizeof(hc32_can_rx_msg_t));//can2存放非升级帧的队列
	spi_communication_semaphore = xSemaphoreCreateBinary();
	
	while(1)
	{
		if(pdTRUE == xSemaphoreTake(spi_communication_semaphore,1)) 
		{
//			data_process(spi_rx_buf,spi_tx_buf);
//			memset(spi_rx_buf,0,sizeof(spi_rx_buf));
		 
		}
	}
}










 

