// #include "uart_handler.h"
// #include "pca9685.h"
// #include "driver/uart.h"
// #include "esp_log.h"
// #include "freertos/FreeRTOS.h"
// #include "freertos/task.h"
// #include "freertos/queue.h"
// #include <string.h>
// #include <math.h>

// #define UART_BUF_SIZE 1024
// #define TAG "UART_HANDLER"
// #define MAX_SERVOS 32
// #define MAX_DEVICES 2

// // 设备配置 (在main.c中初始化)
// extern PCA9685_Device devices[MAX_DEVICES];
// // 当前角度状态
// static ServoAngle current_angles[MAX_SERVOS];
// static int angle_count = 0;
// // 舵机控制队列
// static QueueHandle_t servo_queue = NULL;

// // 获取当前角度
// static float get_angle(uint8_t addr, uint8_t channel) {
//     for(int i = 0; i < angle_count; i++) {
//         if(current_angles[i].addr == addr && 
//            current_angles[i].channel == channel) {
//             return current_angles[i].angle;
//         }
//     }
//     // 不存在则添加默认值
//     if(angle_count < MAX_SERVOS) {
//         current_angles[angle_count] = (ServoAngle){addr, channel, 90.0f};
//         return current_angles[angle_count++].angle;
//     }
//     return 90.0f; // 安全默认值
// }

// // 更新角度
// static void update_angle(uint8_t addr, uint8_t channel, float angle) {
//     for(int i = 0; i < angle_count; i++) {
//         if(current_angles[i].addr == addr && 
//            current_angles[i].channel == channel) {
//             current_angles[i].angle = angle;
//             return;
//         }
//     }
//     // 不存在则添加
//     if(angle_count < MAX_SERVOS) {
//         current_angles[angle_count++] = (ServoAngle){addr, channel, angle};
//     }
// }

// // 线性缓动执行
// static void move_servo_linear(uint8_t addr, uint8_t channel, float from, float to, uint16_t duration_ms) {
//     int steps = duration_ms / 20;
//     steps = steps < 1 ? 1 : steps;
    
//     for (int i = 0; i <= steps; ++i) {
//         float t = (float)i / steps;
//         float angle = from + (to - from) * t;
        
//         // 查找设备
//         for (int d = 0; d < MAX_DEVICES; d++) {
//             if (devices[d].addr == addr) {
//                 pca9685_set_angle(devices[d].port, addr, channel, angle);
//                 break;
//             }
//         }
//         vTaskDelay(20 / portTICK_PERIOD_MS);
//     }
//     update_angle(addr, channel, to);
// }

// // 舵机控制任务
// static void servo_control_task(void *param) {
//     ServoCommand cmd;
    
//     while (1) {
//         if (xQueueReceive(servo_queue, &cmd, portMAX_DELAY) == pdTRUE) {
//             float current = get_angle(cmd.addr, cmd.channel);
            
//             if (cmd.duration <= 1) {
//                 // 立即设置
//                 for (int d = 0; d < MAX_DEVICES; d++) {
//                     if (devices[d].addr == cmd.addr) {
//                         pca9685_set_angle(devices[d].port, cmd.addr, cmd.channel, cmd.angle);
//                         break;
//                     }
//                 }
//                 update_angle(cmd.addr, cmd.channel, cmd.angle);
//             } else {
//                 // 缓动控制
//                 move_servo_linear(cmd.addr, cmd.channel, current, cmd.angle, cmd.duration);
//             }
//         }
//     }
// }

// void uart_handler_init(uart_port_t uart_num) {
    
//     uart_config_t config = {
//         .baud_rate = 115200,
//         .data_bits = UART_DATA_8_BITS,
//         .parity    = UART_PARITY_DISABLE,
//         .stop_bits = UART_STOP_BITS_1,
//         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
//     };
//     uart_param_config(uart_num, &config);
//     esp_err_t ret = uart_driver_install(uart_num, UART_BUF_SIZE * 4, 0, 0, NULL, 0);
//     if (ret != ESP_OK) {
//         ESP_LOGE(TAG, "UART driver install failed: 0x%X", ret);
//     } else {
//         ESP_LOGI(TAG, "UART%d driver installed", uart_num);
//     }
    
//     // 创建舵机控制队列
//     servo_queue = xQueueCreate(20, sizeof(ServoCommand));
//     if (servo_queue == NULL) {
//         ESP_LOGE(TAG, "Failed to create servo queue");
//     } else {
//         ESP_LOGI(TAG, "Servo queue created");
//     }
    
//     // 创建舵机控制任务
//     BaseType_t task_ret = xTaskCreate(servo_control_task, "servo_ctrl", 4096, (void*)UART_NUM_0, 5, NULL);
//     if (task_ret != pdPASS) {
//         ESP_LOGE(TAG, "Failed to create servo_control_task");
//     } else {
//         ESP_LOGI(TAG, "servo_control_task created");
//     }
// }

// void uart_handler_task(void *param) {
//     uart_port_t uart_num = (uart_port_t)param;
//     uint8_t buf[UART_BUF_SIZE];

//     while (1) {
//         ESP_LOGI(TAG, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
//         int len = uart_read_bytes(uart_num, buf, UART_BUF_SIZE, 0 / portTICK_PERIOD_MS);
//         if (len <= 0) continue;
//         ESP_LOGI("UART", "收到 %d 字节数据", len);
//         ESP_LOG_BUFFER_HEXDUMP("UART DATA", buf, len, ESP_LOG_INFO);

//         ESP_LOGI(TAG, "Received %d bytes", len);
//         esp_log_buffer_hex(TAG, buf, len);

//         // 寻找帧头 0xAA
//         int i = 0;
//         while (i < len && buf[i] != 0xAA) ++i;
//         if (i >= len - 1) continue;
        
//         int remaining = len - i;
//         uint8_t count = buf[i + 1];
//         if (remaining < 2 + count * 5) {
//             ESP_LOGW(TAG, "Incomplete frame, need %d bytes, have %d", 2+count*5, remaining);
//             continue;
//         }

//         // 计算校验和
//         uint8_t calc_checksum = 0;
//         for (int j = 0; j < 2 + count * 5; j++) {
//             calc_checksum ^= buf[i + j];
//         }
//         uint8_t packet_checksum = buf[i + 2 + count * 5]; // 最后一个字节

//         if (calc_checksum != packet_checksum) {
//             ESP_LOGE(TAG, "Checksum error: calc=0x%02X, packet=0x%02X", 
//                     calc_checksum, packet_checksum);
//             continue;
//         }
//         // 解析指令
//         for (int j = 0; j < count; ++j) {
//             int idx = i + 2 + j * 5;
//             ServoCommand cmd = {
//                 .addr     = buf[idx],
//                 .channel  = buf[idx + 1],
//                 .angle    = (float)buf[idx + 2],
//                 .duration = (uint16_t)(buf[idx + 3] | (buf[idx + 4] << 8))
//             };
            
//             // 发送到舵机控制队列
//             if (xQueueSend(servo_queue, &cmd, 10 / portTICK_PERIOD_MS) != pdTRUE) {
//                 ESP_LOGE(TAG, "Failed to send command to queue");
//             }
//         }
//     }
// }



// #include "uart_handler.h"
// #include "pca9685.h"
// #include "driver/uart.h"
// #include "esp_log.h"
// #include "freertos/FreeRTOS.h"
// #include "freertos/task.h"
// #include "freertos/queue.h"
// #include <string.h>
// #include <math.h>

// #define UART_BUF_SIZE 1024
// #define TAG "UART_HANDLER"
// #define MAX_SERVOS 32
// #define MAX_DEVICES 2

// extern PCA9685_Device devices[MAX_DEVICES];
// static ServoAngle current_angles[MAX_SERVOS];
// static int angle_count = 0;
// static QueueHandle_t servo_queue = NULL;

// static float get_angle(uint8_t addr, uint8_t channel) {
//     for(int i = 0; i < angle_count; i++) {
//         if(current_angles[i].addr == addr && current_angles[i].channel == channel) {
//             return current_angles[i].angle;
//         }
//     }
//     if(angle_count < MAX_SERVOS) {
//         current_angles[angle_count] = (ServoAngle){addr, channel, 90.0f};
//         return current_angles[angle_count++].angle;
//     }
//     return 90.0f;
// }

// static void update_angle(uint8_t addr, uint8_t channel, float angle) {
//     for(int i = 0; i < angle_count; i++) {
//         if(current_angles[i].addr == addr && current_angles[i].channel == channel) {
//             current_angles[i].angle = angle;
//             return;
//         }
//     }
//     if(angle_count < MAX_SERVOS) {
//         current_angles[angle_count++] = (ServoAngle){addr, channel, angle};
//     }
// }

// static void move_servo_linear(uint8_t addr, uint8_t channel, float from, float to, uint16_t duration_ms) {
//     int steps = duration_ms / 20;
//     steps = steps < 1 ? 1 : steps;
    
//     for (int i = 0; i <= steps; ++i) {
//         float t = (float)i / steps;
//         float angle = from + (to - from) * t;
        
//         for (int d = 0; d < MAX_DEVICES; d++) {
//             if (devices[d].addr == addr) {
//                 pca9685_set_angle(devices[d].port, addr, channel, angle);
//                 break;
//             }
//         }
//         vTaskDelay(20 / portTICK_PERIOD_MS);
//     }
//     update_angle(addr, channel, to);
// }

// static void servo_control_task(void *param) {
//     ServoCommand cmd;
    
//     while (1) {
//         if (xQueueReceive(servo_queue, &cmd, portMAX_DELAY) == pdTRUE) {
//             float current[MAX_SERVOS];
//             int count = 0;

//             for (int i = 0; i < MAX_SERVOS; ++i) {
//                 if (current_angles[i].addr == cmd.addr) {
//                     current[count++] = current_angles[i].angle;
//                 }
//             }

//             if (count > 1) {
//                 pca9685_set_angles(devices[cmd.addr].port, cmd.addr, 0, count, current);
//             } else {
//                 pca9685_set_angle(devices[cmd.addr].port, cmd.addr, cmd.channel, cmd.angle);
//             }

//             update_angle(cmd.addr, cmd.channel, cmd.angle);
//         }
//     }
// }

// void uart_handler_init(uart_port_t uart_num) {
//     uart_config_t config = {
//         .baud_rate = 115200,
//         .data_bits = UART_DATA_8_BITS,
//         .parity    = UART_PARITY_DISABLE,
//         .stop_bits = UART_STOP_BITS_1,
//         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
//     };
//     uart_param_config(uart_num, &config);
//     esp_err_t ret = uart_driver_install(uart_num, UART_BUF_SIZE * 4, 0, 0, NULL, 0);
//     if (ret != ESP_OK) {
//         ESP_LOGE(TAG, "UART driver install failed: 0x%X", ret);
//     } else {
//         ESP_LOGI(TAG, "UART%d driver installed", uart_num);
//     }

//     servo_queue = xQueueCreate(20, sizeof(ServoCommand));
//     if (servo_queue == NULL) {
//         ESP_LOGE(TAG, "Failed to create servo queue");
//     } else {
//         ESP_LOGI(TAG, "Servo queue created");
//     }
    
//     BaseType_t task_ret = xTaskCreate(servo_control_task, "servo_ctrl", 4096, (void*)UART_NUM_0, 5, NULL);
//     if (task_ret != pdPASS) {
//         ESP_LOGE(TAG, "Failed to create servo_control_task");
//     } else {
//         ESP_LOGI(TAG, "servo_control_task created");
//     }
// }

// void uart_handler_task(void *param) {
//     uart_port_t uart_num = (uart_port_t)param;
//     uint8_t buf[UART_BUF_SIZE];

//     while (1) {
//         int len = uart_read_bytes(uart_num, buf, UART_BUF_SIZE, 0 / portTICK_PERIOD_MS);
//         if (len <= 0) continue;

//         int i = 0;
//         while (i < len && buf[i] != 0xAA) ++i;
//         if (i >= len - 1) continue;

//         int remaining = len - i;
//         uint8_t count = buf[i + 1];
//         if (remaining < 2 + count * 5) {
//             ESP_LOGW(TAG, "Incomplete frame, need %d bytes, have %d", 2 + count * 5, remaining);
//             continue;
//         }

//         uint8_t calc_checksum = 0;
//         for (int j = 0; j < 2 + count * 5; j++) {
//             calc_checksum ^= buf[i + j];
//         }
//         uint8_t packet_checksum = buf[i + 2 + count * 5];
//         if (calc_checksum != packet_checksum) {
//             ESP_LOGE(TAG, "Checksum error: calc=0x%02X, packet=0x%02X", 
//                     calc_checksum, packet_checksum);
//             continue;
//         }

//         for (int j = 0; j < count; ++j) {
//             int idx = i + 2 + j * 5;
//             ServoCommand cmd = {
//                 .addr     = buf[idx],
//                 .channel  = buf[idx + 1],
//                 .angle    = (float)buf[idx + 2],
//                 .duration = (uint16_t)(buf[idx + 3] | (buf[idx + 4] << 8))
//             };
            
//             if (xQueueSend(servo_queue, &cmd, 10 / portTICK_PERIOD_MS) != pdTRUE) {
//                 ESP_LOGE(TAG, "Failed to send command to queue");
//             }
//         }
//     }
// }
#include "uart_handler.h"
#include "pca9685.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include <string.h>
#include <math.h>

#define UART_BUF_SIZE 1024
#define TAG "UART_HANDLER"
#define MAX_SERVOS   32
#define MAX_DEVICES  2
#define MAX_CHANNELS 16 // PCA9685 每个设备最多 16 通道

extern PCA9685_Device devices[MAX_DEVICES];
static QueueHandle_t servo_queue = NULL;

// 设备通道角度缓存
static float device_angles[MAX_DEVICES][MAX_CHANNELS];

// 根据 I2C 地址查设备索引
static int find_device_index(uint8_t addr) {
    for (int d = 0; d < MAX_DEVICES; ++d) {
        if (devices[d].addr == addr) return d;
    }
    return -1;
}

// 线性缓动批量更新
static void move_servo_linear(uint8_t addr, uint8_t channel, float from, float to, uint16_t duration_ms) {
    int steps = duration_ms / 20;
    steps = steps < 1 ? 1 : steps;
    int idx = find_device_index(addr);
    if (idx < 0) return;

    for (int i = 0; i <= steps; ++i) {
        float t = (float)i / steps;
        float angle = from + (to - from) * t;
        device_angles[idx][channel] = angle;
        // 一次性批量更新所有通道，保证同步
        pca9685_set_angles(devices[idx].port, addr, 0, MAX_CHANNELS, device_angles[idx]);
        vTaskDelay(20 / portTICK_PERIOD_MS);
    }
}

// 舵机控制任务
static void servo_control_task(void *param) {
    ServoCommand cmd;
    while (1) {
        if (xQueueReceive(servo_queue, &cmd, portMAX_DELAY) == pdTRUE) {
            int idx = find_device_index(cmd.addr);
            if (idx < 0) continue;
            float from = device_angles[idx][cmd.channel];
            float to   = cmd.angle;

            if (cmd.duration <= 1) {
                // 立即批量更新
                device_angles[idx][cmd.channel] = to;
                pca9685_set_angles(devices[idx].port, cmd.addr, 0, MAX_CHANNELS, device_angles[idx]);
            } else {
                // 缓动控制
                move_servo_linear(cmd.addr, cmd.channel, from, to, cmd.duration);
                // 最终角度已在 move_servo_linear 内更新
            }
        }
    }
}

void uart_handler_init(uart_port_t uart_num) {
    uart_config_t config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_param_config(uart_num, &config);
    esp_err_t ret = uart_driver_install(uart_num, UART_BUF_SIZE * 4, 0, 0, NULL, 0);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "UART driver install failed: 0x%X", ret);
    } else {
        ESP_LOGI(TAG, "UART%d driver installed", uart_num);
    }

    // 初始化角度缓存为 90°
    for (int d = 0; d < MAX_DEVICES; ++d) {
        for (int c = 0; c < MAX_CHANNELS; ++c) {
            device_angles[d][c] = 90.0f;
        }
    }

    // 创建舵机控制队列
    servo_queue = xQueueCreate(20, sizeof(ServoCommand));
    if (!servo_queue) {
        ESP_LOGE(TAG, "Failed to create servo queue");
        return;
    }
    ESP_LOGI(TAG, "Servo queue created");

    // 启动舵机控制任务
    BaseType_t task_ret = xTaskCreate(servo_control_task, "servo_ctrl", 4096,
                                      NULL, configMAX_PRIORITIES - 1, NULL);
    if (task_ret != pdPASS) {
        ESP_LOGE(TAG, "Failed to create servo_control_task");
    } else {
        ESP_LOGI(TAG, "servo_control_task created");
    }
}

void uart_handler_task(void *param) {
    uart_port_t uart_num = (uart_port_t)param;
    uint8_t buf[UART_BUF_SIZE];

    while (1) {
        int len = uart_read_bytes(uart_num, buf, UART_BUF_SIZE, 10 / portTICK_PERIOD_MS);
        if (len <= 0) continue;

        // 找到帧头 0xAA
        int i = 0;
        while (i < len && buf[i] != 0xAA) ++i;
        if (i >= len - 1) continue;

        uint8_t count = buf[i + 1];
        int frame_len = 2 + count * 5 + 1;
        if (i + frame_len > len) {
            ESP_LOGW(TAG, "不完整帧，需要 %d 字节，实际 %d", frame_len, len - i);
            continue;
        }

        // 校验
        uint8_t chk = 0;
        for (int j = 0; j < frame_len - 1; ++j) chk ^= buf[i + j];
        if (chk != buf[i + frame_len - 1]) {
            ESP_LOGE(TAG, "校验失败，calc=0x%02X, packet=0x%02X", chk, buf[i + frame_len - 1]);
            continue;
        }

        // 解析并发送命令
        for (int j = 0; j < count; ++j) {
            int idx = i + 2 + j * 5;
            ServoCommand cmd = {
                .addr     = buf[idx],
                .channel  = buf[idx + 1],
                .angle    = (float)buf[idx + 2],
                .duration = (uint16_t)(buf[idx + 3] | (buf[idx + 4] << 8))
            };
            if (xQueueSend(servo_queue, &cmd, 10 / portTICK_PERIOD_MS) != pdTRUE) {
                ESP_LOGE(TAG, "发送命令到队列失败");
            }
        }
    }
}
