#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "esp_log.h"

#include "uart0_modbus_slave.h"
#include "ModbusS.h"
#include "led.h"

static const char *TAG = "UART0";

uint8_t txbuf[BUF_SIZE];
uint8_t rxbuf[BUF_SIZE];
extern uint16_t gWordVar[];

void uart0_init(void)
{
    const int uart_num = UART_PORT_NUM;
    uart_config_t uart_config = {
        .baud_rate = BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .rx_flow_ctrl_thresh = 122,
        .source_clk = UART_SCLK_APB,
    };
    // Set UART log level
    // esp_log_level_set(TAG, ESP_LOG_NONE);

    ESP_LOGI(TAG, "Start RS485 application test and configure UART.");

    // Install UART driver (we don't need an event queue here)
    // In this example we don't even use a buffer for sending data.
    ESP_ERROR_CHECK(uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE, 0, NULL, 0));

    // Configure UART parameters
    ESP_ERROR_CHECK(uart_param_config(uart_num, &uart_config));
    ESP_LOGI(TAG, "UART set pins, mode and install driver.");
    // Set UART pins as per KConfig settings
    //ESP_ERROR_CHECK(uart_set_pin(uart_num, UART_TXD_PIN, UART_RXD_PIN, UART_RTS_PIN, UART_CTS_PIN));之前没解开注释
    //ESP_ERROR_CHECK(uart_set_pin(uart_num, 11, 13, 12, -1));
    // Set RS485 half duplex mode
    ESP_ERROR_CHECK(uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX));
    // Set read timeout of UART TOUT feature
    ESP_ERROR_CHECK(uart_set_rx_timeout(uart_num, UART_READ_TOUT));
}

void uart0_modbus_slave_task(void *arg)
{
    ESP_LOGI(TAG, "uart0_modbus_slave_task");

    while (1)
    {
        int txlen = 0;
        int len = uart_read_bytes(UART_PORT_NUM, rxbuf, BUF_SIZE, UART_READ_TOUT);
        // xTaskGetTickCount();
        // ESP_LOGI("modbus_slave","-----------------------------rxlen:%d", len);
        // for (int i = 0; i < len; i++)
        //     ESP_LOGI("modbus_slave","uart0 get: 0x%x", rxbuf[i]);

        if (len > 0)
        {
            txlen = ModbusSlaveProcess(txbuf, rxbuf, len, 1);
            // if (txlen > 0)
            // {
            //     LED_Toggle(LED1_GPIO_PIN);
            //     int uart_write_length = uart_write_bytes(UART_PORT_NUM, txbuf, txlen);
            //     ESP_LOGI("modbus_slave","-----------------------------txlen:%d   uart_write_length:%d", txlen, uart_write_length);
            //     for (int i = 0; i < uart_write_length; i++)
            //         ESP_LOGI("modbus_slave","uart0 return: 0x%x", txbuf[i]);
            // }
        }
    }
}

void uart0_modbus_slave_init(void)
{
    uart0_init();
    xTaskCreate(uart0_modbus_slave_task, "uart0_modbus_slave_task", 4096, NULL, 10, NULL);
}