////////// Created by lijie on 2025/2/6.

#include "mymain.h"

#define USART2_RX_BUFFER_SIZE 516

#define USART_REC_LEN   200
#define USART_EN_RX     1
#define RXBUFFERSIZE    1
uint16_t g_usart_rx_sta = 0;
uint8_t g_usart_rx_buf[USART_REC_LEN];
uint8_t g_rx_buffer[RXBUFFERSIZE];
//平均次数
uint8_t Target_Average_Times = 1;


uint16_t Receive_Data_Buffer[USART2_RX_BUFFER_SIZE - 1];
uint16_t USART2_RX_Buffer[USART2_RX_BUFFER_SIZE];
uint16_t Average_Buffer[USART2_RX_BUFFER_SIZE - 1];
uint16_t Moving_Buffer[10][USART2_RX_BUFFER_SIZE - 1];
uint16_t Moving_Average_Buffer[USART2_RX_BUFFER_SIZE - 1];
uint32_t Receive_Data_Count = 0;
uint32_t Last_Receive_Data_Count = 0;

uint32_t shutter_time = 20;
uint32_t mode = 1;
float Temperature = 0;
/*  Send_Data_Type
 *  0                   发送原始数据
 *  1                   发送多次平均数据
 *  2                   发送sgi数据
 *  3                   发送多次均数据
 *  4                   发送滑动平均数据
 */
uint8_t Send_Data_Type = 0;
uint32_t sn = 1699;

void Communication_Init() {
    __HAL_UART_DISABLE(&huart2);
    HAL_UART_Receive_DMA(&huart2, (uint8_t *)USART2_RX_Buffer, USART2_RX_BUFFER_SIZE*2);
    USART2->CR3 |= USART_CR3_DMAT;  // 启用DMA传输
}

void Send_Data(uint8_t command,uint8_t *pData, uint16_t Size) {
    if (__HAL_DMA_GET_FLAG(&g_dma_handle, DMA_FLAG_TCIF3_7))
    {
        __HAL_DMA_CLEAR_FLAG(&g_dma_handle, DMA_FLAG_TCIF3_7);
        HAL_UART_DMAStop(&huart1);
    }
    uint8_t send_buff[1024*2];
    uint32_t send_lenth;

    send_lenth = IRIS_Protocol_Pack(command,Size,pData,send_buff);
    // printf("Send_Data: %s\n", send_buff);
    HAL_UART_Transmit_DMA(&huart1,(uint8_t *)send_buff,send_lenth);
}

void mymain()
{
    // HAL_Delay(5000);
    HAL_NVIC_SetPriorityGrouping(2);

    HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
    setvbuf(stdout, NULL, _IONBF, 0);
    dma_init(DMA2_Stream7, DMA_REQUEST_USART1_TX);
    /////

    // uint8_t p[4] = {0x00,0x01,0x5f,0x90};
    // HAL_UART_Transmit(&huart2,p,4,100);

    DS18B20_Init();



    // led_init();

    Communication_Init();
    // __HAL_UART_DISABLE(&huart2);
    // HAL_UART_Receive_DMA(&huart2, (uint8_t *)USART2_RX_Buffer, USART2_RX_BUFFER_SIZE*2);
    // USART2->CR3 |= USART_CR3_DMAT;  // 启用DMA传输
    Send_Shutter_Time(15);

    // LED_OFF;
    // // HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);
    // LED_ON;
    uint32_t Average_Times = 0;
    uint32_t Moving_Average_Times = 0;
    uint32_t a=0;
    while (1) {
        while (mode == 0) {
            commander_run();
            if (Receive_Data_Count != Last_Receive_Data_Count) {

                uint32_t a = Opt_Snenser(90, Receive_Data_Buffer ,USART2_RX_BUFFER_SIZE,shutter_time );
                if (a !=0) shutter_time = a;
                else mode = 1;

                memset(g_usart_rx_buf,0,200);
                g_usart_rx_sta=0;
            }
        }

        while(mode == 1) {
            //处理指令
            commander_run();
            //处理数据
            if (Receive_Data_Count != Last_Receive_Data_Count)
            {
                // Send_Data((uint8_t *)Receive_Data_Buffer,USART2_RX_BUFFER_SIZE*2);
                //2多次平均
                Average_Times ++;
                if(Average_Times <= Target_Average_Times ) {
                    for (uint32_t i = 0; i < USART2_RX_BUFFER_SIZE; i++) {
                        Average_Buffer[i] = (Average_Buffer[i] * (Average_Times-1) + Receive_Data_Buffer[i]) / Average_Times;
                    }
                }else {
                    Average_Times = 0;
                }

                //滑动平均
                memcpy(&Moving_Average_Buffer[Moving_Average_Times % 10], Receive_Data_Buffer, USART2_RX_BUFFER_SIZE*2);
                Moving_Average_Times ++;
                for (uint32_t i = 0; i < USART2_RX_BUFFER_SIZE; i++) {
                    for (uint32_t j = 0; j < 10; j++) {
                        Moving_Average_Buffer[i] += Moving_Buffer[j][i] / 10;
                    }
                }
            }
            //按命令发送数据
            if((Send_Data_Type & 0x80) !=0)
            {
                Send_Data_Type = Send_Data_Type & 0x7F;
                uint16_t sgi_result[USART2_RX_BUFFER_SIZE];
                // printf("AAA");
                switch (Send_Data_Type)
                {
                    case 0:
                        Send_Data(0x61,(uint8_t *)Receive_Data_Buffer,515*2);
                        break;
                    case 1:
                        Send_Data(0x61,(uint8_t *)Average_Buffer,515*2);
                        break;
                    case 2:
                        sgi(Receive_Data_Buffer,sgi_result);
                        Send_Data(0x61,(uint8_t *)sgi_result,515*2);
                        break;
                    case 3:
                        sgi(Average_Buffer,sgi_result);
                        Send_Data(0x61,(uint8_t *)sgi_result,515*2);
                        break;
                    case 4:
                        Send_Data(0x61,(uint8_t *)Moving_Average_Buffer,515*2);
                        break;
                }
                Send_Data_Type = Send_Data_Type & 0x7F;
            }
            // if ( a == 1300 * 15) {
            //     Temperature = DS18B20_GetTemperature();
            //     printf("Temperatureqqq: %f\n", Temperature);
            //     a = 0;
            // }
            a++;
        }
    }
 }


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
 {
     // 当DMA接收完成时，这个回调函数会被触发
     if (huart->Instance == USART2)
     {
         __HAL_UART_DISABLE(&huart2);

         memcpy(Receive_Data_Buffer, USART2_RX_Buffer+2, USART2_RX_BUFFER_SIZE*2);
         Receive_Data_Count ++;

         HAL_UART_Receive_DMA(&huart2, (uint8_t *)USART2_RX_Buffer, USART2_RX_BUFFER_SIZE*2);
     }

     if(huart->Instance == USART1)
     {
         g_usart_rx_buf[g_usart_rx_sta] = g_rx_buffer[0];
         g_usart_rx_sta++;
         HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
     }
 }


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
 {
     if (GPIO_Pin == GPIO_PIN_0)
     {
         __HAL_UART_ENABLE(&huart2);
     }
 }


void commander_run(void)
 {
     if(g_usart_rx_sta > 7)
     {
         uint16_t data_length = g_usart_rx_sta & 0x3fff;
         uint8_t data_type = 0;
         uint8_t command_data[USART_REC_LEN] = {0};
         // data_length = IRIS_Cut_Befor_Header(g_usart_rx_buf,data_length);
         int ret = IRIS_STM32_Protocol_Unpack(g_usart_rx_buf,data_length,&data_type,command_data);

        if (ret > 0) {
            switch(data_type)
            {
                // 获取设备信息
                case 0x50: {
                    // printf("hello \n");
                    uint8_t str[8];
                    str[0] = 'I';
                    str[1] = 'S';
                    str[2] = '3';
                    str[3] = '-';
                    str[4] = '0'+ sn/1000%10;
                    str[5] = '0'+ sn/100%10;
                    str[6] = '0'+ sn/10%10;
                    str[7] = '0'+ sn%10;

                    // printf("shutter_time %d\n",shutter_time);
                    Send_Data(0x50,str,8);

                    break;
                }
                //设置曝光时间
                case  0x51: {
                    shutter_time = command_data[0]<<24 | command_data[1]<<16 | command_data[2]<<8 | command_data[3];
                    Send_Shutter_Time(shutter_time);
                    // memset()
                    Send_Data(0x51,command_data,4);
                    break;
                }
                //自动曝光
                case 0x52:{
                    mode = 0;

                    Send_Data(0x52,command_data,1);
                    break;
                }
                //获取曝光时间
                case 0x53:{
                    uint8_t st[4];
                    // memcpy(st,&shutter_time,4);
                    st[3] = shutter_time & 0xff;
                    st[2] = (shutter_time >> 8) & 0xff;
                    st[1] = (shutter_time >> 16) & 0xff;
                    st[0] = (shutter_time >> 24) & 0xff;


                    // printf("shutter_time %d\n",shutter_time);
                    Send_Data(0x53,st,4);
                    break;
                }
                //获取温度
                case 0x54: {
                    // 将Temperature的值转换为uint8_t数组，并将其作为参数传递给Send_Data函数。
                    uint8_t temp[4];
                    Temperature = DS18B20_GetTemperature();
                    memcpy(&temp[0],(uint8_t *)&Temperature + 3,1);
                    memcpy(&temp[1],(uint8_t *)&Temperature + 2,1);
                    memcpy(&temp[2],(uint8_t *)&Temperature + 1,1);
                    memcpy(&temp[3],(uint8_t *)&Temperature + 0,1);

                    Send_Data(0x54,temp,4);
                    break;
                }
                //开启快门
                case 0x55: {
                    Shutter_Open(command_data[0]);
                    Send_Data(0x55,command_data,1);
                    break;
                }
                //关闭快门
                case 0x56: {
                    Shutter_Close(command_data[0]);
                    Send_Data(0x56,command_data,1);
                    break;
                }

                //设置数据处理方式
                case 0x60: {
                    Send_Data_Type = command_data[0];
                    Target_Average_Times = command_data[1]<<24 | command_data[2]<<16 | command_data[3]<<8 | command_data[4];
                    Send_Data(0x60,command_data,5);
                    break;
                }
                //获取数据
                case 0x61: {
                    Send_Data_Type = Send_Data_Type | 0x80;
                    break;
                }
                case 0x62: {
                    uint8_t d = Send_Data_Type & 0x7F;
                    Send_Data(0x62,&d,1);
                    break;
                }

            }
        }
         memset(g_usart_rx_buf,0,200);
         g_usart_rx_sta=0;
     }
 }