#include "bsp_Uart.h"
/* UART Echo Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "bsp_Gpio.h"
#include "string.h"
#include "Protocol_User.h"
#include "Protocol_Lib.h"
#include "bsp_Uart.h"
/**
 * This is an example which echos any data it receives on configured UART back to the sender,
 * with hardware flow control turned off. It does not use UART driver event queue.
 *
 * - Port: configured UART
 * - Receive (Rx) buffer: on
 * - Transmit (Tx) buffer: off
 * - Flow control: off
 * - Event queue: off
 * - Pin assignment: see defines below (See Kconfig)
 */

#define UART_TXD (18ULL)
#define UART_RXD (38ULL)
#define UART_RTS (UART_PIN_NO_CHANGE)
#define UART_CTS (UART_PIN_NO_CHANGE)

#define ECHO_UART_BAUD_RATE (115200)
#define ECHO_TASK_STACK_SIZE (4096)

#define RXbufSize 255

typedef struct
{
    uint16_t Rxlen;
    uint8_t Rxbuff[RXbufSize];
} _G031_UART_Ctrl;

_G031_UART_Ctrl G031_UART;

static const char *TAG = "UART TEST";

#define BUF_SIZE (1024)
#define EX_UART_NUM (ECHO_UART_PORT_NUM)
static QueueHandle_t uart0_queue;

uint8_t UARTTEST[] = {'T', 'Y', 'W'};
void uart_event_task(void *pvParameters)
{

    printf("bsp_Uart_Init \n");
    bsp_Uart_Init();
    uart_event_t event;
    size_t buffered_size;
    uint8_t *dtmp = (uint8_t *)malloc(BUF_SIZE);
    for (;;)
    {
        // uint8_t syncField = 0x55;

        // uint8_t test = 0X88;
        // uart_write_bytes(ECHO_UART_PORT_NUM, (const char *) &test, 1);
        if (xQueueReceive(uart0_queue, (void *)&event, (TickType_t)portMAX_DELAY))
        {

            bzero(dtmp, BUF_SIZE);
            // ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
            switch (event.type)
            {
            // Event of UART receving data
            /*We'd better handler data event fast, there would be much more data events than
            other types of events. If we take too much time on data event, the queue might
            be full.*/
            case UART_DATA:
                bzero(dtmp, BUF_SIZE);
                int len = uart_read_bytes(ECHO_UART_PORT_NUM, dtmp, event.size, portMAX_DELAY);

                if (len < RXbufSize)
                {
                    G031_UART.Rxlen = event.size;

                    esp_log_buffer_hex("UART ", dtmp, G031_UART.Rxlen);
                    memcpy(G031_UART.Rxbuff, dtmp, event.size);
                    for (uint16_t i = 0; i < G031_UART.Rxlen; i++)
                    {
                        // printf("G031_UART.Rxbuff = %d\r\n",G031_UART.Rxbuff[i]);

                        UART_Put(G031_UART.Rxbuff[i]);
                    }
                }
                // printf("len %d\r\n",len);

                // int len = uart_read_bytes(ECHO_UART_PORT_NUM, dtmp, event.size, portMAX_DELAY);
                // ESP_LOGI(TAG, "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
                // dtmp[0], dtmp[1], dtmp[2], dtmp[3], dtmp[4], dtmp[5], dtmp[6], dtmp[7], dtmp[8], dtmp[9], dtmp[10], dtmp[11], dtmp[12], dtmp[13], dtmp[14], dtmp[15], dtmp[16], dtmp[17] );

                // ESP_LOGI(TAG, "event.size is %d", event.size);
                break;
            // Event of HW FIFO overflow detected
            case UART_FIFO_OVF:
                // If fifo overflow happened, you should consider adding flow control for your application.
                // The ISR has already reset the rx FIFO,
                // As an example, we directly flush the rx buffer here in order to read more data.
                uart_flush_input(EX_UART_NUM);
                xQueueReset(uart0_queue);
                break;
            // Event of UART ring buffer full
            case UART_BUFFER_FULL:
                // If buffer full happened, you should consider encreasing your buffer size
                // As an example, we directly flush the rx buffer here in order to read more data.
                uart_flush_input(EX_UART_NUM);
                xQueueReset(uart0_queue);
                break;
            // Event of UART RX break detected
            case UART_BREAK:
                // if (LinRadar.RxStep == 0)
                //{
                //     LinRadar.RxStep = 1;
                // }
                //  ESP_LOGI(TAG, "uart rx break");
                break;
            // Event of UART parity check error
            case UART_PARITY_ERR:
                break;
            // Event of UART frame error
            case UART_FRAME_ERR:
                break;
            // UART_PATTERN_DET
            case UART_PATTERN_DET:
                break;
            // Others
            default:
                ESP_LOGI(TAG, "uart event type: %d", event.type);
                break;
            }
        }
    }
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
}

void bsp_Uart_Init(void)
{
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = ECHO_UART_BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    int intr_alloc_flags = 0;

#if CONFIG_UART_ISR_IN_IRAM
    intr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif

    uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, intr_alloc_flags);
    uart_param_config(EX_UART_NUM, &uart_config);
    uart_set_pin(EX_UART_NUM, UART_TXD, UART_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

    // Create a task to handler UART event from ISR
}

void MCU_UART_TEST(void)
{

    int test = 0;
}
