/***********************************************************************
 * Copyright (c)  2017 - 2022, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : app.c
 * Description : app source file
 * Author(s)   : Mason
 * version     : V1.0
 * Modify date : 2022-08-04
 ***********************************************************************/
#include  "app.h"
#include  "config.h"
#include  "common.h"
#include  "uart0.h"
#include  "uart1.h"
#include  "uart2.h"
#include  "can.h"
#include  "can_protocol.h"

uint32_t g_data_buf[512];

volatile uint8_t rx_flag = 0;
volatile uint8_t can_irq_flag = 0;

extern S_Can_Filter_Msg can_filter_msg;
extern S_Can_Rx_Msg can_rx_msg;
static uint32_t can_filter_reg_value;

#define CAN_RX_BUFF 		(0x20003000 + CAN_RX_ADDR)  //注意：如果用到CAN，SRAM 最后64 bytes不要被其他变量或堆栈占用
#define can_rx_data_buff    ((uint32_t *)CAN_RX_BUFF)   //can_rx_data_buff[16]  (64 bytes)

static uint32_t can_rx_data[4];

static uint8_t test_data[8] = {0,1,2,3,4,5,6,7};        //用于测试接收的数据是否正确；接收和发送的数据保持一致；


#ifdef UART0_COMM
uint8_t uart0_rx_flag = 0;
uint8_t uart0_rx_buf[64];
uint8_t uart0_rx_count = 0;
#endif

#ifdef UART1_COMM
uint8_t uart1_rx_flag = 0;
uint8_t uart1_rx_buf[64];
uint8_t uart1_rx_count = 0;
#endif

#ifdef UART2_COMM
uint8_t uart2_rx_flag = 0;
uint8_t uart2_rx_buf[64];
uint8_t uart2_rx_count = 0;
#endif

#ifdef UART0_COMM
/************************************************************************
 * Function     : uart0_rec_pro
 * Description  : uart0 rec pro 串口接收处理回调函数
 * Input        : none
 * Return       : none
 ************************************************************************/
void uart0_rec_pro(void)
{
	uart0_rx_buf[uart0_rx_count] = uart0_recv_byte();
	uart0_rx_count++;
	uart0_rx_flag = 1;	
}
#endif

#ifdef UART1_COMM
/************************************************************************
 * Function     : uart1_rec_pro
 * Description  : uart1 rec pro 串口接收处理回调函数
 * Input        : none
 * Return       : none
 ************************************************************************/
void uart1_rec_pro(void)
{
	uart1_rx_buf[uart1_rx_count] = uart1_recv_byte();
	uart1_rx_count++;
	uart1_rx_flag = 1;	
}
#endif

#ifdef UART2_COMM
/************************************************************************
 * Function     : uart2_rec_pro
 * Description  : uart2 rec pro 串口接收处理回调函数
 * Input        : none
 * Return       : none
 ************************************************************************/
void uart2_rec_pro(void)
{
	uart2_rx_buf[uart2_rx_count] = uart2_recv_byte();
	uart2_rx_count++;
	uart2_rx_flag = 1;	
}
#endif

/************************************************************************
 * Function     : uart_init
 * Description  : uart_init 串口初始化
 * Input        : none
 * Return       : none
 ************************************************************************/
void uart_init(void)
{
#ifdef  UART0_COMM     
	uart0_rx_flag = 0;
	uart0_init(PCLK, UART0_BAUD_RATE);
	uart0_irq_init(UART0_IRQ_ENABLE, uart0_rec_pro);
#endif

#ifdef  UART1_COMM	
	uart1_rx_flag = 0;	
	uart1_init(PCLK, UART1_BAUD_RATE);
	uart1_irq_init(UART1_IRQ_ENABLE, uart1_rec_pro);
#endif

#ifdef  UART2_COMM    
    uart2_rx_flag = 0;	
	uart2_init(PCLK, UART2_BAUD_RATE);
	uart2_irq_init(UART2_IRQ_ENABLE, uart2_rec_pro);
#endif
}

/************************************************************************
 * Function     : can_irq_pro
 * Description  : can interrupt callback function
 * Input        : none
 * Return       : none
 ************************************************************************/
void can_irq_pro(void)
{
	can_irq_flag = 1;
}

/************************************************************************
 * Function     : compare_data
 * Description  : compare data
 * Input        : uint8_t *p, uint8_t *q, uint32_t len
 * Return       : 1:相等；0：不相等
 ************************************************************************/
uint8_t compare_data(uint8_t *p, uint8_t *q, uint32_t len)
{
	for(uint32_t i=0; i<len; i++)
	{
		if(*p == *q)
		{
			p++;
			q++;
		}
		else
		{
			return 0;	                                                //不相等
		}
	}
	return 1;			                                                //相等
}

/************************************************************************
 * Function     : user_app_pro
 * Description  : user app pro , 添加用户代码
 * Input        : none
 * Return       : none
 ************************************************************************/
static void user_app_pro(void)
{
	//以下代码为打印测试，用户可添加应用代码
	if(can_rx_msg.rtr)                                                  //如果是遥控帧
	{
		printfS("received remote frame!! \r\n");
		
		if(can_rx_msg.ide)                                              //扩展帧
		{
			printfS("ext_id = 0x%x\r\n", can_rx_msg.ext_id);
		}
		else                                                            //标准帧
		{
			printfS("std_id = 0x%x\r\n", can_rx_msg.std_id);
		}
		printfS("ide = 0x%x\r\n", can_rx_msg.ide);
		printfS("rtr = 0x%x\r\n", can_rx_msg.rtr);
		
		
	}
	else                                                                //如果是数据帧
	{
		printfS("received data frame!! \r\n");
		
        if(can_rx_msg.ide)                                              //扩展帧
		{
			printfS("ext_id = 0x%x\r\n", can_rx_msg.ext_id);
		}
		else                                                            //标准帧
		{
			printfS("std_id = 0x%x\r\n", can_rx_msg.std_id);
		}
        
		printfS("ide = 0x%x\r\n", can_rx_msg.ide);
		printfS("rtr = 0x%x\r\n", can_rx_msg.rtr);
		printfS("len = 0x%x\r\n", can_rx_msg.len);
		printfS("recv data:\r\n");
		for(uint8_t i=0;i<can_rx_msg.len;i++)
		{
			printfS("%02x   ", can_rx_msg.data[i]);
		}
		printfS("\r\n");
		if(compare_data(&can_rx_msg.data[0], test_data, can_rx_msg.len))
		{
			printfS("test data pass!! \r\n");
		}
		else
		{
			printfS("test data error error!!!!! \r\n");
		}
		printfS("\r\r\n\n");
		
	}
}

/************************************************************************
 * Function     : can_test
 * Description  : can test
 * Input        : none
 * Return       : none
 ************************************************************************/
void can_test(void)
{
	printfS("System run at %dHz\r\n", SystemCoreClock);
	printfS("start test CAN rx function!! \n");
    
	can_filter_msg.std_id1 = 0x592;						                // 过滤器ID1
	can_filter_msg.ext_id1 = 0x11E8E477;				                // 扩展过滤器ID1
	
	can_init(CAN_RATE_125K);
    
    can_filter_value(&can_filter_reg_value, CAN_DOUBLE_FILTER, CAN0_STD_FORMAT);                    //获取过滤器寄存器值
	can_filter_config(can_filter_reg_value, CAN_DOUBLE_FILTER, CAN0_STD_FORMAT, CAN_FILTER_ENABLE); //配置过滤寄存器
	
#ifdef CAN_RX_INT_MODE									                //如果中断使能
	can_irq_init(CAN_IRQ_ENABLE, can_irq_pro);
#else
	can_irq_init(CAN_IRQ_DISABLE, can_irq_pro);
#endif
	
	while(1)
	{
		
#ifdef 	CAN_RX_INT_MODE
        
		if(can_irq_flag)								                //接收完成中断
		{
			can_read_data(can_rx_data, &can_rx_msg.ide, &can_rx_msg.rtr, &can_rx_msg.len); 
			can_read_data_pro(can_rx_data);
			user_app_pro();
			can_irq_flag = 0;
		
		}
#else
		if(can_get_sr_reg()&0x80)                                       //fifo 至少一条消息
		{
			while(can_get_rmc_reg())                                    //处理完fifo中所有帧
			{
				can_read_data(can_rx_data, &can_rx_msg.ide, &can_rx_msg.rtr, &can_rx_msg.len); 
				can_read_data_pro(can_rx_data);
				user_app_pro();
			}
			
		}
#endif	
		
	}
}

/************************************************************************
 * Function     : soc_test
 * Description  : soc test 
 * Input        : none
 * Return       : none
 ************************************************************************/
void soc_test(void)
{
    can_test();
}
