/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "queue.h"

/* Standard demo includes. */
#include "TimerDemo.h"
#include "QueueOverwrite.h"
#include "EventGroupsDemo.h"
#include "IntSemTest.h"
#include "TaskNotify.h"

#include "main.hpp"
#include "lwipopts.h"
#include "common.hpp"
#include "ds18b20.hpp"
#include "ZC13.hpp"
#include "MHZ14B.hpp"

#ifndef PICO_DEFAULT_LED_PIN
#warning pio/hello_pio example requires a board with a regular LED
#define PICO_DEFAULT_LED_PIN 25
#endif

void Led_Blinky(void *pvParameters)
{
    (void)pvParameters;

    const uint LED_PIN = PICO_DEFAULT_LED_PIN;
    gpio_init(LED_PIN);
    gpio_set_dir(LED_PIN, GPIO_OUT);

    _printTaskStackHighWaterMark("Led_Blinky");

    float TEMPERATURE;

    while (1) {
        vTaskDelay(pdMS_TO_TICKS(500));
        gpio_put(LED_PIN, 1);

        vTaskDelay(pdMS_TO_TICKS(500));
        gpio_put(LED_PIN, 0);

        // 从队列接收数据
        if (xQueueReceive(xQueue, &TEMPERATURE, portMAX_DELAY) == pdPASS) {
            // 处理接收到的数据
            printf("%f\n", TEMPERATURE);
        }
        //_printTaskStackHighWaterMark("Led_Blinky");

    }
}

void Read_Onboard_Temperature(void *pvParameters)
{
    (void)pvParameters;

    adc_init();
    adc_set_temp_sensor_enabled(true);
    adc_select_input(4);        // Input 4 is the onboard temperature sensor.

    //_printTaskStackHighWaterMark("Read_Onboard_Temperature");

    while (1) {
        const float conversionFactor = 3.3f / (1 << 12);

        float adc = (float)adc_read() * conversionFactor;
        float tempC = 27.0f - (adc - 0.706f) / 0.001721f;

        printf("Onboard temperature %.02f°C %.02f°F\n", tempC, (tempC * 9 / 5 + 32));

        //_printTaskStackHighWaterMark("Read_Onboard_Temperature");

        vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
    }
}

int main(void)
{
    stdio_init_all();
    sleep_ms(3000);
    //set_sys_clock_khz(250000, true);

    // 创建队列
    xQueue = xQueueCreate(10, sizeof(long));

    // 创建任务
    BaseType_t xReturned;
    TaskHandle_t Led_Blinky_xHandle = NULL;
    TaskHandle_t DS18B20_xHandle = NULL;
    TaskHandle_t CH4_xHandle = NULL;
    TaskHandle_t CO2_xHandle = NULL;

    // 板载LED闪烁
    xReturned = xTaskCreate(Led_Blinky, "Blinky task", 512, NULL, tskIDLE_PRIORITY, &Led_Blinky_xHandle);
    if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) {
        printf("Blinky Task Error!");
    }
    // DS18B20
    xReturned = xTaskCreate(DS18B20, "DS18B20 task", 1024, NULL, tskIDLE_PRIORITY, &DS18B20_xHandle);
    if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) {
        printf("DS18B20() Task Error!");
    }
    // CH4
    xReturned = xTaskCreate(CH4, "CH4 task", 1024, NULL, tskIDLE_PRIORITY, &CH4_xHandle);
    if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) {
        printf("CH4() Task Error!");
    }
    // CO2
    xReturned = xTaskCreate(CO2, "CO2 task", 1024, NULL, tskIDLE_PRIORITY, &CO2_xHandle);
    if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) {
        printf("CO2() Task Error!");
    }

    vTaskStartScheduler();

    return 0;
}
