#include "stdio.h"

#include "freerotsTask.h"

#include "uart_dev.h"
#include "FM_GPIO.h"
#include "FM_ADC.h"
#include "queueUart.h"
#include "upUartParse.h"
#include "flash.h"
#include "parameter.h"
#include "busIdleDetection.h"
#include "downUartParse.h"


#define Common_TASK_PRIO     2
#define Common_STK_SIZE      512

#define Transmit_TASK_PRIO     7
#define Transmit_STK_SIZE      256

#define UpReceive_TASK_PRIO     5
#define UpReceive_STK_SIZE      256

#define DownReceive_TASK_PRIO     4
#define DownReceive_STK_SIZE      1024

#define FreeMemory_TASK_PRIO     5
#define FreeMemory_STK_SIZE      256

/* 任务句柄 */
static TaskHandle_t CommonTask_Handler;
static TaskHandle_t TransmitTask_Handler;
static TaskHandle_t UpReceive_Handler;
static TaskHandle_t DownReceive_Handler;
static TaskHandle_t FreeMemory_Handler;


/**
  * @brief  喂狗等任务在其中进行
  * @param
  * @retval
  */
static void common_Task(void *pvParameters)
{
	// writePwrCtrlState(Android_PwrCtrl, PwrCtrlOpen);
	// proportionalInt();
    // while(1) {
    //     // printf("task1 entry\r\n");
	// 	printf_adc_data();
    //     USART_ITConfig(UART5, USART_IT_TXE, ENABLE);
	//     uartInterruptSend(g_Upward_uart5_handle, data, 12);
    //     vTaskDelay(1000);
    // }

    uint16_t HeapSizeNum = 0;

    /* 用于绝对延时 */
    TickType_t xLastWakeTime;
    const TickType_t xFrequency = 100; // 50 个滴答,即200mS
    // 初始化 xLastWakeTime
    xLastWakeTime = xTaskGetTickCount();

    while (1) {
        // uint8_t *Buff = (uint8_t *)pvPortMalloc(200);
        // if (Buff == NULL) {
        //     log_error("Memory allocation failed\n");
        //     return;
        // }

        // queueUartSendInfo *sendBuff = (queueUartSendInfo *)Buff;
        // sendBuff->length = sizeof("hello world\n");
        // sendBuff->data = Buff + sizeof(queueUartSendInfo);
        // strlcpy((char *)sendBuff->data, "hello world\n", sizeof("hello world\n"));

        // xQueueSend(upward_uart_Queue, &Buff, 10);

        

        
        // USARTx_SendStr_Len(USART3, "hello world\n", sizeof("hello world\n"));


        // uint8_t *Buff = (uint8_t *)pvPortMalloc(200);
        // if (Buff == NULL) {
        //     log_error("Memory allocation failed\n");
        //     return;
        // }
        // queueTimeShareSendInfo *sendBuff = (queueTimeShareSendInfo *)Buff;
        // sendBuff->length = sizeof("hello world\n");
        // sendBuff->data = Buff + sizeof(queueTimeShareSendInfo);
        // sendBuff->connectPort = connectJ0;
        // strlcpy((char *)sendBuff->data, "hello world\n", sizeof("hello world\n"));

        // xQueueSend(J5_0_485_Queue, &Buff, 10);

        
        /* 每200ms获取一下数据 */
        setWorkCurrent(getInCurrent());
        setWorkVoltage(getInVoltage());

        /* 当内存碎片过多时,后续可以在其中处理 */
        if (HeapSizeNum == 25) {
            HeapSizeNum = 0;
            log_info("xPortGetFreeHeapSize : %d",xPortGetFreeHeapSize());
        }

        HeapSizeNum++;
        vTaskDelayUntil(&xLastWakeTime, xFrequency);
        // vTaskDelay(200);
    }
}

/**
  * @brief  将数据发送
  * @param
  * @retval
  */
static void transmit_Task(void *pvParameters)
{
    while (1) {
        uartQueueSend();
    }
}

/**
  * @brief  解析su806发送来的数据
  * @param
  * @retval
  */
static void UpReceive_Task(void *pvParameters)
{
    while (1) {
        upwardUartDataAnalysis(g_Upward_uart5_handle);
        vTaskDelay(20);
    }
}

/**
  * @brief  解析传感器发送来的数据
  * @param
  * @retval
  */
static void DownReceive_Task(void *pvParameters)
{
    while (1) {
        J1_SensorDataAnalysis();
        J2_SensorDataAnalysis();
        J3_SensorDataAnalysis();
        J4_SensorDataAnalysis();
        J5_0_SensorDataAnalysis();
        vTaskDelay(5);
    }    
}

/**
  * @brief  通过条件变量通知来释放内存
  * @param
  * @retval
  */
static void FreeMemory_Task(void *pvParameters)
{
    while (1) {
        // vTaskDelay(1000);
        binarySemaphoreFreeMemory();
    }
}

/**
  * @brief  启动
  * @param
  * @retval
  */
void startApp(void)
{    
    // printf("RCC->RSTSCKR = %08x \r\n", RCC->RSTSCKR);
    // RCC->RSTSCKR |= 1<<24;

    /* 初始化flash,读取配置文件 */
    Flash_Init();
    readConfigParameter();

	FM_GPIO_Init();
	FM_ADC_Init();
    proportionalInt();

	Init_Upward_uart(getUpWard_Uart_Baud());
    Init_J1_485(getJ1_485_Baud());
    Init_J2_485(getJ2_485_Baud());
    Init_J3_485(getJ3_485_Baud());
    Init_J4_485(getJ4_485_Baud());
    Init_J5_0_485(getJ5_0_485_Baud());

    uartQueueInit();
    binarySemaphoreInit();
    softwareTimeInit();

    Delay_Ms(1000);
    set_485_Read();


    /* create task */
    xTaskCreate((TaskFunction_t )common_Task,
                    (const char*    )"commonTask",
                    (uint16_t       )Common_STK_SIZE,
                    (void*          )NULL,
                    (UBaseType_t    )Common_TASK_PRIO,
                    (TaskHandle_t*  )&CommonTask_Handler);

    xTaskCreate((TaskFunction_t )transmit_Task,
                    (const char*    )"transmitTask",
                    (uint16_t       )Transmit_STK_SIZE,
                    (void*          )NULL,
                    (UBaseType_t    )Transmit_TASK_PRIO,
                    (TaskHandle_t*  )&TransmitTask_Handler);

    xTaskCreate((TaskFunction_t )UpReceive_Task,
                    (const char*    )"UpReceiveTask",
                    (uint16_t       )UpReceive_STK_SIZE,
                    (void*          )NULL,
                    (UBaseType_t    )UpReceive_TASK_PRIO,
                    (TaskHandle_t*  )&UpReceive_Handler);

    xTaskCreate((TaskFunction_t )DownReceive_Task,
                    (const char*    )"DownReceiveTask",
                    (uint16_t       )DownReceive_STK_SIZE,
                    (void*          )NULL,
                    (UBaseType_t    )DownReceive_TASK_PRIO,
                    (TaskHandle_t*  )&DownReceive_Handler);

    xTaskCreate((TaskFunction_t )FreeMemory_Task,
                    (const char*    )"FreeMemoryTask",
                    (uint16_t       )FreeMemory_STK_SIZE,
                    (void*          )NULL,
                    (UBaseType_t    )FreeMemory_TASK_PRIO,
                    (TaskHandle_t*  )&FreeMemory_Handler);

    vTaskStartScheduler();
}