/*定周期タイマーによりダミーのタッチイベントをエンキューしている。 * * * */ #include #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "semphr.h" #include "pico/stdlib.h" #include "LCD_driver.h" #include "gpio_lcd.h" // IPCとリソース管理 QueueHandle_t xTouchQueue = NULL; SemaphoreHandle_t xDisplaySemaphore = NULL; volatile int g_total_count = 0; // --------------------------------------------------------- // Task 1: [P1] タイマー生成プロセス (1秒周期で自動エンキュー) // --------------------------------------------------------- void vScanTask(void *pvParameters) { vTaskDelay(pdMS_TO_TICKS(2000)); printf("[T1] P1: 1s Timer Generator Online\n"); int event_signal = 1; while (true) { // 1秒待機 vTaskDelay(pdMS_TO_TICKS(1000)); g_total_count++; // 描画パラメータ(色相)を更新 if (xDisplaySemaphore != NULL && xSemaphoreTake(xDisplaySemaphore, portMAX_DELAY) == pdTRUE) { update_hue_on_tap(); // 内部で色相を36度進める xSemaphoreGive(xDisplaySemaphore); } // 各表示タスクへ通知(2回送信) xQueueSend(xTouchQueue, &event_signal, 0); xQueueSend(xTouchQueue, &event_signal, 0); printf("[T1] Tick! Count: %d\n", g_total_count); } } // --------------------------------------------------------- // Task 2: [P4] TFT描画プロセス (0ms地点で実行) // --------------------------------------------------------- void vTftTask(void *pvParameters) { LCD_Driver tft; printf("[T2] TFT Task Starting...\n"); if (xDisplaySemaphore != NULL && xSemaphoreTake(xDisplaySemaphore, portMAX_DELAY) == pdTRUE) { tft.init(); tft.drawHSBBackground(); // 初期描画 xSemaphoreGive(xDisplaySemaphore); } int sig; while (true) { // タイマーイベントを待機 if (xQueueReceive(xTouchQueue, &sig, portMAX_DELAY) == pdPASS) { if (xDisplaySemaphore != NULL && xSemaphoreTake(xDisplaySemaphore, portMAX_DELAY) == pdTRUE) { // 仕様:横軸色相/縦軸明度の描画 tft.drawHSBBackground(); xSemaphoreGive(xDisplaySemaphore); printf("[P4] TFT Updated: %d\n", g_total_count); } } } } // --------------------------------------------------------- // Task 3: [P3] LCD1602表示プロセス (500msオフセットで実行) // --------------------------------------------------------- void vLcdTask(void *pvParameters) { Gpio_LCD lcd1602(6, 7, 2, 3, 4, 5); printf("[T3] LCD Task Starting...\n"); if (xDisplaySemaphore != NULL && xSemaphoreTake(xDisplaySemaphore, portMAX_DELAY) == pdTRUE) { lcd1602.init(); lcd1602.clear(); xSemaphoreGive(xDisplaySemaphore); } int sig; while (true) { // タイマーイベントを受信 if (xQueueReceive(xTouchQueue, &sig, portMAX_DELAY) == pdPASS) { vTaskDelay(pdMS_TO_TICKS(500)); if (xDisplaySemaphore != NULL && xSemaphoreTake(xDisplaySemaphore, portMAX_DELAY) == pdTRUE) { char buf[17]; snprintf(buf, sizeof(buf), "Hello Pico!:%d", g_total_count); lcd1602.clear(); lcd1602.setCursor(0, 0); lcd1602.print(buf); xSemaphoreGive(xDisplaySemaphore); printf("[P3] LCD1602 Updated: %s\n", buf); } } } } // --------------------------------------------------------- // Main // --------------------------------------------------------- int main() { stdio_init_all(); sleep_ms(2000); printf("\n====================================\n"); printf(" sample06: Timer-Driven Success \n"); printf("====================================\n"); xTouchQueue = xQueueCreate(20, sizeof(int)); xDisplaySemaphore = xSemaphoreCreateBinary(); if (xDisplaySemaphore != NULL) { xSemaphoreGive(xDisplaySemaphore); } if (xTouchQueue != NULL && xDisplaySemaphore != NULL) { // 全タスク生成 xTaskCreate(vTftTask, "TFT", 4096, NULL, 1, NULL); xTaskCreate(vLcdTask, "LCD", 2048, NULL, 1, NULL); xTaskCreate(vScanTask, "Gen", 1024, NULL, 2, NULL); vTaskStartScheduler(); } while(1); }