User Tools

Site Tools


tamiwiki:users:6r1d:diymall_esp32_s3_fixture

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tamiwiki:users:6r1d:diymall_esp32_s3_fixture [2025/10/20 05:25] – [ESP-IDF (+ history and PWM debug)] 6r1dtamiwiki:users:6r1d:diymall_esp32_s3_fixture [2025/10/20 05:43] (current) – [ESP-IDF (+ history and PWM debug)] 6r1d
Line 108: Line 108:
 </code> </code>
  
-CMake config (code):+For your convenience, I have shared the whole [[https://git.telavivmakers.space/6r1d/esp32_s3_pin_tracer_espidf|repository]] at TAMI Gitea.
  
-<code> +Clone it like that: 
-idf_component_register(SRCS "main.c" + 
-                      INCLUDE_DIRS ".")+<code bash
 +git clone https://git.telavivmakers.space/6r1d/esp32_s3_pin_tracer_espidf.git esp32_s3_pin_tracer
 </code> </code>
  
-CMake config (project):+Also, you can use Minicom to interact with the tracing code if you'd like. It's just one of the default baudrates, 115200.
  
-<code> +<code bash
-# The following five lines of boilerplate have to be in your project'+minicom -D /dev/ttyUSB0 -b 115200 -o
-# CMakeLists in this exact order for cmake to work correctly +
-cmake_minimum_required(VERSION 3.16) +
- +
-include($ENV{IDF_PATH}/tools/cmake/project.cmake) +
-project(.)+
 </code> </code>
- 
-<file cpp esp32_s3_pin_tracer.c> 
-#include <stdio.h> 
-#include <string.h> 
-#include <ctype.h> 
-#include <inttypes.h> 
-#include <stdbool.h> 
- 
-#include "freertos/FreeRTOS.h" 
-#include "freertos/task.h" 
- 
-#include "driver/gpio.h" 
-#include "driver/uart.h" 
-#include "driver/uart_vfs.h" 
-#include "esp_err.h" 
-#include "esp_vfs_dev.h" 
-#include "esp_system.h" 
-#include "driver/ledc.h" 
- 
-/*======== CONFIG ========*/ 
-// Blink defaults 
-static uint32_t g_blink_delay_ms = 100; 
- 
-// Console config 
-#define CLI_LINE_MAX 128 
-#define HIST_MAX     10 
- 
-// PWM configuration (safe defaults) 
-#define LEDC_TIMER              LEDC_TIMER_0 
-#define LEDC_MODE               LEDC_LOW_SPEED_MODE 
-#define LEDC_CHANNEL            LEDC_CHANNEL_0 
-#define LEDC_DUTY_RES           LEDC_TIMER_8_BIT   // 0..(2^RES-1) 
-#define LEDC_FREQUENCY_DEFAULT  5000               // 5 kHz 
- 
-/*======== SAFE GPIO CANDIDATES ========*/ 
-static const gpio_num_t TEST_SAFE_GPIO[] = { 
-    1,  2, 
-    4,  5,  6,  7, 
-    8,  9,  10, 11, 12, 13, 14, 
-    15, 16, 17, 18, 
-    /* 19,20 excluded (USB D-/D+) */ 
-    21, 
-    /* 22..34 not bonded on typical modules */ 
-    /* 35,36,37 excluded (PSRAM on some variants) */ 
-    38, 39, 40, 41, 42,          /* JTAG-capable if configured */ 
-    /* 43,44 excluded (UART0 console) */ 
-    47, 48                       /* may be 1.8 V on R16V */ 
-}; 
-static const size_t TEST_SAFE_GPIO_COUNT = sizeof(TEST_SAFE_GPIO)/sizeof(TEST_SAFE_GPIO[0]); 
- 
-/*======== CONSTANTS & HELPERS ========*/ 
- 
-/* Sentinels */ 
-#define HIST_NONE        (-1) 
-#define INVALID_GPIO     ((gpio_num_t)-1) 
- 
-/* Bounds */ 
-#define BLINK_DELAY_MIN_MS  10u 
-#define BLINK_DELAY_MAX_MS  60000u 
- 
-#define BRIGHT_MIN          0 
-#define BRIGHT_MAX          99 
- 
-#define FREQ_MIN_HZ         100u 
-#define FREQ_MAX_HZ         50000u  /* conservative for 8-bit @ low-speed */ 
- 
-/* Task sizes & priorities */ 
-#define BLINK_STACK         2048 
-#define CONSOLE_STACK       4096 
-#define BLINK_TASK_PRIO     (tskIDLE_PRIORITY + 1) 
-#define CONSOLE_TASK_PRIO   (tskIDLE_PRIORITY + 2) 
- 
-/* UART driver buffer */ 
-#define UART_RX_BUF         512 
- 
-/* Generic clamps */ 
-static inline uint32_t clamp_u32(uint32_t v, uint32_t lo, uint32_t hi) { 
-    return (v < lo) ? lo : (v > hi) ? hi : v; 
-} 
-static inline int clamp_int(int v, int lo, int hi) { 
-    return (v < lo) ? lo : (v > hi) ? hi : v; 
-} 
- 
-/* LEDC helpers */ 
-static inline uint32_t ledc_max_duty(void) { 
-    // LEDC_DUTY_RES is enum like LEDC_TIMER_8_BIT → 8 
-    return (1u << LEDC_DUTY_RES) - 1u; 
-} 
-static inline uint32_t brightness_to_duty(uint8_t level) { 
-    // Map BRIGHT_MIN..BRIGHT_MAX → 0..max_duty; guard divide 
-    const uint32_t maxd = ledc_max_duty(); 
-    const uint32_t denom = (BRIGHT_MAX > 0) ? (uint32_t)BRIGHT_MAX : 1u; 
-    return (uint32_t)level * maxd / denom; 
-} 
- 
-/* Tiny predicates */ 
-static inline bool is_valid_gpio(gpio_num_t pin) { return pin != INVALID_GPIO; } 
- 
-/*======== RUNTIME ========*/ 
-static gpio_num_t   g_current_pin      = INVALID_GPIO; 
-static bool         g_blinking         = false; 
-static bool         g_pwm_mode         = false; 
-static uint8_t      g_pwm_brightness   = 50;                 // BRIGHT_MIN..BRIGHT_MAX 
-static uint32_t     g_pwm_frequency    = LEDC_FREQUENCY_DEFAULT; 
-static TaskHandle_t g_blink_task       = NULL; 
- 
-/*======== CLI ========*/ 
-typedef struct { 
-    uart_port_t uart; 
-    char  *line; 
-    size_t *pos; 
-    size_t *cursor; 
-    char  (*hist)[CLI_LINE_MAX]; 
-    int   *hist_count, *hist_head, *hist_view; 
-} cli_ctx_t; 
- 
-/*---- CLI helpers ----*/ 
-static inline void cli_write(cli_ctx_t *c, const char *s) { 
-    uart_write_bytes(c->uart, s, strlen(s)); 
-} 
- 
-static void cli_prompt(cli_ctx_t *c) { 
-    cli_write(c, "\r\n> "); 
-    fflush(stdout); 
-} 
- 
-static void cli_redraw(cli_ctx_t *c) { 
-    // Clear line, print prompt + buffer, then move cursor left if needed 
-    cli_write(c, "\r\x1b[2K> "); 
-    if (*c->pos) uart_write_bytes(c->uart, c->line, *c->pos); 
-    if (*c->pos > *c->cursor) { 
-        char seq[16]; 
-        int n = snprintf(seq, sizeof(seq), "\x1b[%zuD", (size_t)(*c->pos - *c->cursor)); 
-        uart_write_bytes(c->uart, seq, n); 
-    } 
-} 
- 
-static void cli_push_hist(cli_ctx_t *c, const char *cmd) { 
-    if (!cmd[0]) return; 
-    int last = (*c->hist_head - 1 + HIST_MAX) % HIST_MAX; 
-    if (*c->hist_count > 0 && strncmp(c->hist[last], cmd, CLI_LINE_MAX) == 0) return; 
-    strncpy(c->hist[*c->hist_head], cmd, CLI_LINE_MAX - 1); 
-    c->hist[*c->hist_head][CLI_LINE_MAX - 1] = 0; 
-    *c->hist_head = (*c->hist_head + 1) % HIST_MAX; 
-    if (*c->hist_count < HIST_MAX) (*c->hist_count)++; 
-} 
- 
-static void cli_load_hist(cli_ctx_t *c, int idx) { 
-    strncpy(c->line, c->hist[idx], CLI_LINE_MAX - 1); 
-    c->line[CLI_LINE_MAX - 1] = 0; 
-    *c->pos = *c->cursor = strlen(c->line); 
-    cli_redraw(c); 
-} 
- 
-static inline bool cli_in_hist(cli_ctx_t *c) { return *c->hist_view != HIST_NONE; } 
- 
-/*======== HELPERS ========*/ 
-static bool is_test_safe(gpio_num_t gpio) { 
-    for (size_t i = 0; i < TEST_SAFE_GPIO_COUNT; ++i) { 
-        if (TEST_SAFE_GPIO[i] == gpio) return true; 
-    } 
-    return false; 
-} 
- 
-static void print_test_safe_pins(void) { 
-    printf("\nTest-safe GPIOs (ESP32-S3):\n  "); 
-    for (size_t i = 0; i < TEST_SAFE_GPIO_COUNT; ++i) { 
-        printf("%s%d", (i ? ", " : ""), TEST_SAFE_GPIO[i]); 
-    } 
-    printf("\nExcluded (reason): 0,3,45,46 (boot/strap/JTAG) | 19,20 (USB D-/D+) | 35-37 (PSRAM on some) | 43,44 (UART0 console)\n"); 
-    printf("Note: On some R16V modules, GPIO47/48 are 1.8 V only.\n"); 
-} 
- 
-static void release_pin(gpio_num_t pin) { 
-    if (is_valid_gpio(pin)) { 
-        gpio_set_level(pin, 0); 
-        gpio_reset_pin(pin); // back to default (input/hi-z) 
-    } 
-} 
- 
-static void stop_pwm(void) { 
-    if (g_pwm_mode) { 
-        ledc_stop(LEDC_MODE, LEDC_CHANNEL, 0); 
-        g_pwm_mode = false; 
-    } 
-} 
- 
-static void stop_blink(void) { 
-    if (g_blink_task) { 
-        TaskHandle_t t = g_blink_task; 
-        g_blink_task = NULL; // signal task to exit 
-        for (int i = 0; i < 20 && eTaskGetState(t) != eDeleted; ++i) { 
-            vTaskDelay(pdMS_TO_TICKS(5)); 
-        } 
-    } 
-    g_blinking = false; 
-} 
- 
-static void stop_all(void) { 
-    stop_blink(); 
-    stop_pwm(); 
-    release_pin(g_current_pin); 
-    g_current_pin = INVALID_GPIO; 
-    printf("Stopped. Pin released to INPUT.\n"); 
-} 
- 
-/*======== BLINK TASK ========*/ 
-static void blink_task(void *arg) { 
-    gpio_num_t pin = (gpio_num_t)(intptr_t)arg; 
-    gpio_config_t io = { 
-        .pin_bit_mask = 1ULL << pin, 
-        .mode = GPIO_MODE_OUTPUT, 
-        .pull_up_en = GPIO_PULLUP_DISABLE, 
-        .pull_down_en = GPIO_PULLDOWN_DISABLE, 
-        .intr_type = GPIO_INTR_DISABLE 
-    }; 
-    gpio_config(&io); 
-    gpio_set_level(pin, 0); 
-    while (g_blink_task == xTaskGetCurrentTaskHandle()) { 
-        gpio_set_level(pin, 1); 
-        vTaskDelay(pdMS_TO_TICKS(g_blink_delay_ms)); 
-        gpio_set_level(pin, 0); 
-        vTaskDelay(pdMS_TO_TICKS(g_blink_delay_ms)); 
-    } 
-    release_pin(pin); 
-    vTaskDelete(NULL); 
-} 
- 
-/*======== PWM ========*/ 
-static bool setup_pwm(gpio_num_t gpio) { 
-    if (g_pwm_mode) ledc_stop(LEDC_MODE, LEDC_CHANNEL, 0); 
-    // Configure LEDC timer 
-    ledc_timer_config_t ledc_timer = { 
-        .speed_mode      = LEDC_MODE, 
-        .timer_num       = LEDC_TIMER, 
-        .duty_resolution = LEDC_DUTY_RES, 
-        .freq_hz         = g_pwm_frequency, 
-        .clk_cfg         = LEDC_AUTO_CLK 
-    }; 
-    esp_err_t ret = ledc_timer_config(&ledc_timer); 
-    if (ret != ESP_OK) { 
-        printf("PWM timer config failed: %s (try lower freq or lower duty resolution)\n", esp_err_to_name(ret)); 
-        return false; 
-    } 
-    // Configure LEDC channel 
-    ledc_channel_config_t ledc_channel = { 
-        .speed_mode = LEDC_MODE, 
-        .channel    = LEDC_CHANNEL, 
-        .timer_sel  = LEDC_TIMER, 
-        .intr_type  = LEDC_INTR_DISABLE, 
-        .gpio_num   = gpio, 
-        .duty       = 0, 
-        .hpoint     = 0 
-    }; 
-    ret = ledc_channel_config(&ledc_channel); 
-    if (ret != ESP_OK) { 
-        printf("PWM channel config failed: %s\n", esp_err_to_name(ret)); 
-        return false; 
-    } 
-    return true; 
-} 
- 
-static void set_pwm_brightness(uint8_t level) { 
-    level = (uint8_t)clamp_int(level, BRIGHT_MIN, BRIGHT_MAX); 
-    g_pwm_brightness = level; 
-    const uint32_t duty = brightness_to_duty(level); 
-    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, duty); 
-    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL); 
-    printf("PWM brightness set to %u%% (duty: %" PRIu32 "/%" PRIu32 ")\n", 
-           (unsigned)level, duty, ledc_max_duty()); 
-} 
- 
-static void set_pwm_frequency(uint32_t freq) { 
-    g_pwm_frequency = clamp_u32(freq, FREQ_MIN_HZ, FREQ_MAX_HZ); 
-    if (g_pwm_mode) { 
-        ledc_timer_config_t ledc_timer = { 
-            .speed_mode      = LEDC_MODE, 
-            .timer_num       = LEDC_TIMER, 
-            .duty_resolution = LEDC_DUTY_RES, 
-            .freq_hz         = g_pwm_frequency, 
-            .clk_cfg         = LEDC_AUTO_CLK 
-        }; 
-        esp_err_t ret = ledc_timer_config(&ledc_timer); 
-        if (ret == ESP_OK) { 
-            printf("PWM frequency set to %" PRIu32 " Hz\n", g_pwm_frequency); 
-            set_pwm_brightness(g_pwm_brightness); // restore duty for new timer base 
-        } else { 
-            printf("Failed to set PWM frequency: %s\n", esp_err_to_name(ret)); 
-        } 
-    } else { 
-        printf("PWM frequency set to %" PRIu32 " Hz (applies when PWM starts)\n", g_pwm_frequency); 
-    } 
-} 
- 
-/*======== MODE START ========*/ 
-static void start_blink(gpio_num_t gpio) { 
-    if (!is_test_safe(gpio)) { 
-        printf("Restricted: GPIO %d is not in the test-safe set.\n", gpio); 
-        return; 
-    } 
-    stop_all(); 
-    g_current_pin = gpio; 
-    g_blinking = true; 
-    if (xTaskCreatePinnedToCore(blink_task, "blink_task", BLINK_STACK, (void*)(intptr_t)gpio, 
-                                BLINK_TASK_PRIO, &g_blink_task, tskNO_AFFINITY) != pdPASS) { 
-        printf("Error: Failed to create blink task\n"); 
-        g_blinking = false; 
-        g_current_pin = INVALID_GPIO; 
-        return; 
-    } 
-    printf("Blinking GPIO %d at %" PRIu32 " ms.\n", g_current_pin, g_blink_delay_ms); 
-} 
- 
-static void start_pwm(gpio_num_t gpio, uint8_t brightness) { 
-    if (!is_test_safe(gpio)) { 
-        printf("Restricted: GPIO %d is not in the test-safe set.\n", gpio); 
-        return; 
-    } 
-    stop_all(); 
-    if (!setup_pwm(gpio)) { 
-        printf("Failed to setup PWM on GPIO %d\n", gpio); 
-        return; 
-    } 
-    g_current_pin = gpio; 
-    g_pwm_mode = true; 
-    set_pwm_brightness(brightness); 
-    printf("PWM started on GPIO %d at %" PRIu32 " Hz\n", gpio, g_pwm_frequency); 
-} 
- 
-/*======== COMMAND PARSER ========*/ 
-static void trim(char *s) { 
-    size_t len = strlen(s); 
-    while (len && (s[len-1] == '\r' || s[len-1] == '\n' || isspace((unsigned char)s[len-1]))) s[--len] = 0; 
-    size_t i = 0; 
-    while (s[i] && isspace((unsigned char)s[i])) i++; 
-    if (i) memmove(s, s+i, strlen(s+i)+1); 
-} 
- 
-static bool all_digits(const char *s) { 
-    if (!*s) return false; 
-    for (const char *p = s; *p; ++p) if (!isdigit((unsigned char)*p)) return false; 
-    return true; 
-} 
- 
-static void handle_command(char *line) { 
-    trim(line); 
-    if (!*line) return; 
- 
-    char cmd[64]; 
-    strncpy(cmd, line, sizeof(cmd)-1); 
-    cmd[sizeof(cmd)-1] = 0; 
-    for (char *p = cmd; *p; ++p) *p = (char)tolower((unsigned char)*p); 
- 
-    if (strcmp(cmd, "list") == 0) { 
-        print_test_safe_pins(); 
-        return; 
-    } 
-    if (strcmp(cmd, "status") == 0) { 
-        printf("Pin: %d, mode: %s, ", 
-               (int)g_current_pin, g_blinking ? "blink" : (g_pwm_mode ? "pwm" : "idle")); 
-        if (g_blinking) { 
-            printf("delay: %" PRIu32 " ms\n", g_blink_delay_ms); 
-        } else if (g_pwm_mode) { 
-            printf("brightness: %u%%, frequency: %" PRIu32 " Hz\n", 
-                   (unsigned)g_pwm_brightness, g_pwm_frequency); 
-        } else { 
-            printf("no active output\n"); 
-        } 
-        return; 
-    } 
-    if (strcmp(cmd, "stop") == 0 || strcmp(cmd, "pwm off") == 0 || strcmp(cmd, "mode off") == 0) { 
-        stop_all(); 
-        return; 
-    } 
-    if (strncmp(cmd, "pin ", 4) == 0) { 
-        int gpio = atoi(line + 4); 
-        start_blink((gpio_num_t)gpio); 
-        return; 
-    } 
-    if (strncmp(cmd, "delay ", 6) == 0) { 
-        int v = atoi(line + 6); 
-        g_blink_delay_ms = clamp_u32((uint32_t)v, BLINK_DELAY_MIN_MS, BLINK_DELAY_MAX_MS); 
-        printf("Set blink delay to %" PRIu32 " ms.\n", g_blink_delay_ms); 
-        return; 
-    } 
-    if (strncmp(cmd, "pwm ", 4) == 0) { 
-        // "pwm <pin> [brightness]" 
-        char *args = line + 4; trim(args); 
-        int gpio = -1, brightness = g_pwm_brightness; 
-        if (sscanf(args, "%d %d", &gpio, &brightness) >= 1) { 
-            brightness = clamp_int(brightness, BRIGHT_MIN, BRIGHT_MAX); 
-            start_pwm((gpio_num_t)gpio, (uint8_t)brightness); 
-        } else { 
-            printf("Usage: pwm <pin> [brightness %d-%d]\nCurrent brightness: %u%%\n", 
-                   BRIGHT_MIN, BRIGHT_MAX, (unsigned)g_pwm_brightness); 
-        } 
-        return; 
-    } 
-    if (strncmp(cmd, "brightness ", 11) == 0 || strncmp(cmd, "bright ", 7) == 0) { 
-        const char *arg = (strncmp(cmd, "bright ", 7) == 0) ? (line + 7) : (line + 11); 
-        int brightness = atoi(arg); 
-        brightness = clamp_int(brightness, BRIGHT_MIN, BRIGHT_MAX); 
-        if (g_pwm_mode) { 
-            set_pwm_brightness((uint8_t)brightness); 
-        } else { 
-            printf("Error: PWM mode not active. Use 'pwm <pin> [brightness]' first.\n"); 
-        } 
-        return; 
-    } 
-    if (strncmp(cmd, "freq ", 5) == 0 || strncmp(cmd, "frequency ", 10) == 0) { 
-        char *arg = (cmd[4] == ' ') ? (line + 5) : (line + 10); 
-        int freq = atoi(arg); 
-        if (freq > 0) set_pwm_frequency((uint32_t)freq); 
-        else printf("Frequency must be positive\n"); 
-        return; 
-    } 
-    if (strcmp(cmd, "help") == 0) { 
-        printf("Commands:\n" 
-               "  list                          -> show test-safe GPIOs\n" 
-               "  status                        -> show current pin/mode\n" 
-               "  pin <gpio>                    -> start blinking GPIO\n" 
-               "  <gpio>                        -> same as 'pin <gpio>'\n" 
-               "  delay <ms>                    -> set blink delay (%u..%u)\n" 
-               "  pwm <pin> [brightness]        -> start PWM (%d..%d, current: %u%%)\n" 
-               "  brightness <level>            -> set PWM brightness (%d..%d)\n" 
-               "  freq <frequency>              -> set PWM frequency (Hz, %u..%u)\n" 
-               "  pwm off | mode off | stop     -> stop output and release pin\n", 
-               BLINK_DELAY_MIN_MS, BLINK_DELAY_MAX_MS, 
-               BRIGHT_MIN, BRIGHT_MAX, (unsigned)g_pwm_brightness, 
-               BRIGHT_MIN, BRIGHT_MAX, 
-               FREQ_MIN_HZ, FREQ_MAX_HZ); 
-        return; 
-    } 
-    if (all_digits(line)) { // bare number = pin 
-        start_blink((gpio_num_t)atoi(line)); 
-        return; 
-    } 
-    printf("Unknown. Type 'help' for commands.\n"); 
-} 
- 
-/*======== CONSOLE TASK ========*/ 
-static void console_task(void *arg) { 
-    const uart_port_t uart_num = UART_NUM_0; 
-    char   line[CLI_LINE_MAX] = {0}; 
-    size_t pos = 0;              // length used 
-    size_t cursor = 0;           // caret position 
-    char hist[HIST_MAX][CLI_LINE_MAX] = {{0}}; 
-    int  hist_count = 0; 
-    int  hist_head  = 0; 
-    int  hist_view  = HIST_NONE; 
-    cli_ctx_t C = { 
-        .uart       = uart_num, 
-        .line       = line, 
-        .pos        = &pos, 
-        .cursor     = &cursor, 
-        .hist       = hist, 
-        .hist_count = &hist_count, 
-        .hist_head  = &hist_head, 
-        .hist_view  = &hist_view 
-    }; 
-    cli_prompt(&C); 
-    enum { ESC_IDLE, ESC_ESC, ESC_CSI } esc = ESC_IDLE; 
-    char csi_param_buf[4] = {0}; 
-    int  csi_param_len = 0; 
-    while (1) { 
-        uint8_t ch; 
-        int got = uart_read_bytes(uart_num, &ch, 1, pdMS_TO_TICKS(30)); 
-        if (got != 1) continue; 
-        // Escape handling (arrows/Home/End/Del and Alt-B/F) 
-        if (esc == ESC_ESC) { 
-            if (ch == '[') { esc = ESC_CSI; csi_param_len = 0; continue; } 
-            // Alt-b / Alt-f 
-            if (ch == 'b' || ch == 'B') { 
-                if (cursor > 0) { 
-                    while (cursor > 0 && isspace((unsigned char)line[cursor-1])) cursor--; 
-                    while (cursor > 0 && !isspace((unsigned char)line[cursor-1])) cursor--; 
-                    cli_redraw(&C); 
-                } 
-                esc = ESC_IDLE; continue; 
-            } 
-            if (ch == 'f' || ch == 'F') { 
-                if (cursor < pos) { 
-                    while (cursor < pos && !isspace((unsigned char)line[cursor])) cursor++; 
-                    while (cursor < pos &&  isspace((unsigned char)line[cursor])) cursor++; 
-                    cli_redraw(&C); 
-                } 
-                esc = ESC_IDLE; continue; 
-            } 
-            esc = ESC_IDLE; // unknown ESC seq 
-            continue; 
-        } else if (esc == ESC_CSI) { 
-            if (ch >= '0' && ch <= '9') { 
-                if (csi_param_len < (int)sizeof(csi_param_buf)-1) csi_param_buf[csi_param_len++] = (char)ch; 
-                continue; 
-            } 
-            if (ch == '~') { 
-                // [3~ delete, [1~ home, [4~ end 
-                int p = atoi(csi_param_buf); 
-                if (p == 3) { // Delete forward 
-                    if (cursor < pos) { 
-                        memmove(&line[cursor], &line[cursor+1], pos - cursor - 1); 
-                        pos--; line[pos] = 0; 
-                        cli_redraw(&C); 
-                    } 
-                } else if (p == 1) { 
-                    cursor = 0; cli_redraw(&C); 
-                } else if (p == 4) { 
-                    cursor = pos; cli_redraw(&C); 
-                } 
-                esc = ESC_IDLE; continue; 
-            } 
-            // Final byte for standard arrows/home/end 
-            if (ch == 'A') { // Up 
-                if (hist_count) { 
-                    if (!cli_in_hist(&C)) hist_view = (hist_head - 1 + HIST_MAX) % HIST_MAX; 
-                    else { 
-                        int oldest = (hist_head - hist_count + HIST_MAX) % HIST_MAX; 
-                        if (hist_view != oldest) hist_view = (hist_view - 1 + HIST_MAX) % HIST_MAX; 
-                    } 
-                    cli_load_hist(&C, hist_view); 
-                } 
-            } else if (ch == 'B') { // Down 
-                if (cli_in_hist(&C)) { 
-                    int newest = (hist_head - 1 + HIST_MAX) % HIST_MAX; 
-                    if (hist_view != newest) { hist_view = (hist_view + 1) % HIST_MAX; cli_load_hist(&C, hist_view); } 
-                    else { hist_view = HIST_NONE; pos = cursor = 0; line[0] = 0; cli_redraw(&C); } 
-                } 
-            } else if (ch == 'C') { // Right 
-                if (cursor < pos) { cursor++; cli_redraw(&C); } 
-            } else if (ch == 'D') { // Left 
-                if (cursor > 0) { cursor--; cli_redraw(&C); } 
-            } else if (ch == 'H') { // Home 
-                cursor = 0; cli_redraw(&C); 
-            } else if (ch == 'F') { // End 
-                cursor = pos; cli_redraw(&C); 
-            } 
-            esc = ESC_IDLE; 
-            continue; 
-        } 
-        if (ch == 0x1B) { esc = ESC_ESC; continue; } // start ESC 
-        // CR / LF -> execute 
-        if (ch == '\r' || ch == '\n') { 
-            cli_write(&C, "\r\n"); 
-            line[pos] = 0; 
-            if (pos) { cli_push_hist(&C, line); hist_view = HIST_NONE; } 
-            handle_command(line); 
-            pos = cursor = 0; line[0] = 0; 
-            cli_prompt(&C); 
-            continue; 
-        } 
-        // Ctrl-A / Ctrl-E 
-        if (ch == 0x01) { cursor = 0; cli_redraw(&C); continue; } 
-        if (ch == 0x05) { cursor = pos; cli_redraw(&C); continue; } 
-        // Backspace 
-        if (ch == 0x08 || ch == 0x7F) { 
-            if (cursor > 0) { 
-                memmove(&line[cursor - 1], &line[cursor], pos - cursor); 
-                cursor--; pos--; 
-                line[pos] = 0; 
-                cli_redraw(&C); 
-            } 
-            continue; 
-        } 
-        // Ctrl-U: clear line 
-        if (ch == 0x15) { pos = cursor = 0; line[0] = 0; cli_redraw(&C); continue; } 
-        // Ctrl-L: redraw 
-        if (ch == 0x0C) { cli_redraw(&C); continue; } 
-        // Ctrl-W: delete previous word 
-        if (ch == 0x17) { 
-            size_t start = cursor; 
-            while (start > 0 && isspace((unsigned char)line[start-1])) start--; 
-            while (start > 0 && !isspace((unsigned char)line[start-1])) start--; 
-            if (start < cursor) { 
-                memmove(&line[start], &line[cursor], pos - cursor); 
-                pos -= (cursor - start); 
-                cursor = start; 
-                line[pos] = 0; 
-                cli_redraw(&C); 
-            } 
-            continue; 
-        } 
-        // Printable ASCII: insert at cursor 
-        if (isprint(ch)) { 
-            if (pos + 1 < CLI_LINE_MAX) { 
-                if (cli_in_hist(&C)) { hist_view = HIST_NONE; /* keep recalled text */ } 
-                memmove(&line[cursor + 1], &line[cursor], pos - cursor); 
-                line[cursor++] = (char)ch; 
-                pos++; 
-                line[pos] = 0; 
-                cli_redraw(&C); 
-            } 
-            continue; 
-        } 
-        // ignore other control bytes 
-    } 
-} 
- 
-/*======== APP ========*/ 
-void app_main(void) { 
-    const int baud = 115200; 
-    const uart_port_t uart_num = UART_NUM_0; 
-    uart_config_t cfg = { 
-        .baud_rate  = baud, 
-        .data_bits  = UART_DATA_8_BITS, 
-        .parity     = UART_PARITY_DISABLE, 
-        .stop_bits  = UART_STOP_BITS_1, 
-        .flow_ctrl  = UART_HW_FLOWCTRL_DISABLE, 
-        .source_clk = UART_SCLK_DEFAULT, 
-    }; 
-    ESP_ERROR_CHECK(uart_driver_install(uart_num, UART_RX_BUF, 0, 0, NULL, 0)); 
-    ESP_ERROR_CHECK(uart_param_config(uart_num, &cfg)); 
-    uart_vfs_dev_use_driver(uart_num); 
-    uart_vfs_dev_port_set_rx_line_endings(uart_num, ESP_LINE_ENDINGS_CRLF); 
-    uart_vfs_dev_port_set_tx_line_endings(uart_num, ESP_LINE_ENDINGS_CRLF); 
-    vTaskDelay(pdMS_TO_TICKS(200)); 
-    uart_flush_input(uart_num); 
-    printf("\nESP32-S3 GPIO Tester with PWM (ESP-IDF)\n"); 
-    printf("Type 'help' for commands. Cursor keys, history, word jumps supported.\n"); 
-    print_test_safe_pins(); 
-    xTaskCreatePinnedToCore(console_task, "console", CONSOLE_STACK, NULL, 
-                            CONSOLE_TASK_PRIO, NULL, tskNO_AFFINITY); 
-    // Don't return; keep prompt active 
-    vTaskDelete(NULL); 
-} 
-</file> 
- 
- 
 ===== Arduino (basic version) ===== ===== Arduino (basic version) =====
  
tamiwiki/users/6r1d/diymall_esp32_s3_fixture.1760937940.txt.gz · Last modified: by 6r1d