
/*Includes**********************************************************************/
#include "usart.h"

struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  /* 初始化配置参数 */
/* 用于接收消息的信号量 */
static struct rt_semaphore rx_sem;
static rt_device_t serial;
uint16_t USART3_REC_STA=0;//串口3接收标志
uint8_t USART3_REC_BUF[11]={0};//串口3接收BUF
float Roll_X,Pitch_Y,Yaw_Z;
uint8_t print_str[100];               //存放LCD字符串
//串口接收回调函数
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    rt_sem_release(&rx_sem);
    return RT_EOK;
}

//串口1数据读取线程入口
static void serial_thread_entry(void *parameter)
{
    uint8_t Res_U3;
    uint8_t Sum_U3=0,i_U3;
    while (1)
    {
        /* 从串口读取一个字节的数据，没有读取到则等待接收信号量 */
        while (rt_device_read(serial, -1, &Res_U3, 1) != 1)
        {
            /* 阻塞等待接收信号量，等到信号量后再次读取数据 */
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        }
        /* 读取到的数据输出 */
        //rt_kprintf("%c",Res_U3);


        if((USART3_REC_STA&0x8000)==0)//接收未完成
        {
            if((USART3_REC_STA&0x00FF)>11)//数据长度出错
            {
                USART3_REC_STA=0;////接收错误，重新接收
                //rt_kprintf("->1\n");
            }
            else
            {
                if((USART3_REC_STA&0x4000)==0)//未接收到帧头
                {
                    if(Res_U3==0x55) //本字节为帧头
                    {
                        USART3_REC_STA |= 0x4000;
                        USART3_REC_BUF[USART3_REC_STA&0x00FF]=Res_U3;
                        USART3_REC_STA++;
                        //rt_kprintf("->2\n");
                    }
                    else {
                        //rt_kprintf("->3\n");
                    }
                }
                else//已接收到帧头
                {
                    if((USART3_REC_STA&0x2000)==0)//未接收到标识字节
                    {
                        if((Res_U3==0x53)||(0))//本字节为标识字节  (Res_U3==0x54)
                        {
                            USART3_REC_STA |= 0x2000;
                            USART3_REC_BUF[USART3_REC_STA&0x00FF]=Res_U3;
                            USART3_REC_STA++;
                            //rt_kprintf("->4\n");
                        }
                        else
                        {
                            USART3_REC_STA=0;//接收错误，重新接收
                            //rt_kprintf("->5  Res_U3=%X\n",Res_U3);
                        }
                    }
                    else//已接收到标识字节
                    {
                        if((USART3_REC_STA&0x00FF)<11)//
                        {
                            USART3_REC_BUF[USART3_REC_STA&0x00FF]=Res_U3;
                            USART3_REC_STA++;
                            //rt_kprintf("->6\n");
                            if((USART3_REC_STA&0x00FF)==11)
                            {
                                //求和
                                Sum_U3=0;//清零
                                for(i_U3=0;i_U3<10;i_U3++)
                                {
                                    Sum_U3=(uint8_t)(Sum_U3+USART3_REC_BUF[i_U3]);
                                }
                                //校验和
                                if(Sum_U3==USART3_REC_BUF[10])
                                {
                                    USART3_REC_STA |= 0x8000;//校验和成功，接收完成
                                    //rt_kprintf("rec success!\n");

                                }
                                else
                                {
                                    USART3_REC_STA=0;//校验和失败，重新接收
                                    //rt_kprintf("->7\n");
                                }
                            }
                        }
                        else {
                            //rt_kprintf("->8\n");
                        }
                    }
                }
            }

        }
    }
}


//数据分析函数
void Data_analysis(uint8_t fun_byte)
{
    uint8_t DataH,DataL;
    if((USART3_REC_STA&0x8000)==0) return;
    switch(fun_byte)
    {
    case 0x53:
    {
        Roll_X= ((short)((USART3_REC_BUF[3]<<8)|USART3_REC_BUF[2]))/32768.0*180;
        Pitch_Y=((short)((USART3_REC_BUF[5]<<8)|USART3_REC_BUF[4]))/32768.0*180;
        Yaw_Z=  ((short)((USART3_REC_BUF[7]<<8)|USART3_REC_BUF[6]))/32768.0*180;
    }break;
    default :USART3_REC_STA=0;break;
    }

}


static void thread_usart1_recsho(void *parameter)
{

    while(1)
    {
        if(USART3_REC_STA&0x8000)
        {
            Data_analysis(USART3_REC_BUF[1]);
            sprintf((char*)print_str,"%3.1f",Roll_X);
            ssd1306_SetCursor(66,8);
            ssd1306_WriteString(print_str,Font_11x18,White);
            sprintf((char*)print_str,"%3.1f",Pitch_Y);
            ssd1306_SetCursor(66,8+18);
            ssd1306_WriteString(print_str,Font_11x18,White);
            sprintf((char*)print_str,"%3.1f",Yaw_Z);
            ssd1306_SetCursor(66,8+18+18);
            ssd1306_WriteString(print_str,Font_11x18,White);
            ssd1306_UpdateScreen();
            /*
            sprintf((char*)print_str,"Roll_X:%3.1f\n",Roll_X);
            rt_kprintf("%s",print_str);
            sprintf((char*)print_str,"Pitch_Y:%3.1f\n",Pitch_Y);
            rt_kprintf("%s",print_str);
            sprintf((char*)print_str,"Yaw_Z:%3.1f\n",Yaw_Z);
            rt_kprintf("%s",print_str);*/
            USART3_REC_STA=0;
        }
        rt_thread_mdelay(10);
    }
}

int rtt_show(void)
{
    //ssd1306_Init();//初始化OLED显示屏

    rt_err_t ret = RT_EOK;
    rt_thread_t thread = rt_thread_create("show",thread_usart1_recsho,RT_NULL,4096,30,20);
    if(thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else {
        ret = RT_ERROR;
    }
    return ret;
}

//串口初始化函数
int rtt_serinit(void)
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    char str[] = "hello RT-Thread!\r\n";

    rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);

    /* 查找系统中的串口设备 */
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", uart_name);
        return RT_ERROR;
    }
    /* 修改串口配置参数 */
    config.baud_rate = BAUD_RATE_115200;        //修改波特率为 9600
    config.data_bits = DATA_BITS_8;           //数据位 8
    config.stop_bits = STOP_BITS_1;           //停止位 1
    config.bufsz     = 128;                   //修改缓冲区 buff size 为 128
    config.parity    = PARITY_NONE;           //无奇偶校验位

    /* 控制串口设备。通过控制接口传入命令控制字，与控制参数 */
    rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);

    /* 初始化信号量 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial, uart_input);
    /* 发送字符串 */
    rt_device_write(serial, 0, str, (sizeof(str) - 1));

    rt_thread_t thread = rt_thread_create("rec",serial_thread_entry,RT_NULL,1024,20,20);
    if(thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else {
        ret = RT_ERROR;
    }
    return ret;

}



/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(rtt_serinit, uart rec);
MSH_CMD_EXPORT(rtt_show, uart show);
