#include "ZE07CO.hpp"
#include "HC-12.hpp"
#include "common.hpp"

void ZE07CO_INIT()
{
    // 初始化UART
    uart_init(UART0, BAUD_RATE);
    gpio_set_function(UART0_TX_PIN, GPIO_FUNC_UART);
    gpio_set_function(UART0_RX_PIN, GPIO_FUNC_UART);
    uart_set_hw_flow(UART0, false, false);
    uart_set_format(UART0, DATA_BITS, STOP_BITS, PARITY);
}

// CO
static uint16_t ZE07CO(int ANSWER, int *ZE07_CO_DATA_IS_OK)
{

    if (ANSWER == 1) {
        // 应答模式
        static uint8_t _ANSWER[9] = { 0xFF, 0x01, 0x78, 0x41, 0x00, 0x00, 0x00, 0x00, 0x46 };
        uart_write_blocking(UART0, _ANSWER, 9);
        sleep_ms(100);
        
    }
    
    if (ANSWER == 2) {
        // 主动上传模式
        static uint8_t _ANSWER[9] = { 0xFF, 0x01, 0x78, 0x40, 0x00, 0x00, 0x00, 0x00, 0x47 };
        uart_write_blocking(UART0, _ANSWER, 9);
        sleep_ms(100);
    }
    
    // 读取
    uint8_t CO_DATA[9] = { 0 };
    uart_read_blocking(UART0, CO_DATA, 9);
    sleep_ms(100);
    
    /*
    for(int i=0; i<9; i++) {
        printf("0X%X ", CO_DATA[i]);
    }
    printf("\n");
    */

    // CO 浓度
    uint16_t CO_CONC = (256 * CO_DATA[4]) + CO_DATA[5];

    // 校验
    uint8_t CHECKSUM = (0xFF - (CO_DATA[1] + CO_DATA[2] + CO_DATA[3] + CO_DATA[4] + CO_DATA[5] + CO_DATA[6] + CO_DATA[7])) + 1;

    if (CO_DATA[8] == CHECKSUM && CO_DATA[1] == 0x04) {
        //printf("CHECKSUM: %X = %X\n", CO_DATA[8], CHECKSUM);
        //printf("CO Concentration: %d ppm\n", CO_CONC);
        *ZE07_CO_DATA_IS_OK = 1;
    } else {
        *ZE07_CO_DATA_IS_OK = 0;
    }

    return CO_CONC;
}

void CO(void *pvParameters)
{
    uint16_t CO_DATA = -1;
    int ZE07_CO_DATA_IS_OK = 0;
    _printTaskStackHighWaterMark("CO");
    
    while(1)
    {
        ZE07CO_INIT();
        
        CO_DATA = ZE07CO(2, &ZE07_CO_DATA_IS_OK);
        if (CO_DATA != -1 && ZE07_CO_DATA_IS_OK == 1) {
            printf("CO Concentration: %d ppm\n", CO_DATA);
            
            char CO_DATA_TEMP[BUFER] = { 0 };
            sprintf(CO_DATA_TEMP, "CO Concentration: %d ppm\n", CO_DATA);
            _HC_12(CO_DATA_TEMP);
            
        }
        
        //_printTaskStackHighWaterMark("CO");
        //watchdog_update();                  // 喂狗
        vTaskDelay(pdMS_TO_TICKS(5000)); // 非阻塞延时
    }
    
    return;
}
