compiles on targets esp32, esp32-s3, and esp32-c5
This commit is contained in:
parent
7924da11c7
commit
0e2cea8da7
|
|
@ -11,15 +11,15 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
// --- SAFE WIRING FOR ESP32-C5 ---
|
static const char *TAG = "GPS_SYNC";
|
||||||
#define GPS_UART_NUM UART_NUM_1
|
|
||||||
#define GPS_RX_PIN GPIO_NUM_23
|
// --- INTERNAL MACROS ---
|
||||||
#define GPS_TX_PIN GPIO_NUM_24
|
|
||||||
#define PPS_GPIO GPIO_NUM_25
|
|
||||||
#define GPS_BAUD_RATE 9600
|
#define GPS_BAUD_RATE 9600
|
||||||
#define UART_BUF_SIZE 1024
|
#define UART_BUF_SIZE 1024
|
||||||
|
|
||||||
static const char *TAG = "GPS_SYNC";
|
// --- GLOBAL STATE ---
|
||||||
|
// MUST be defined before gps_task uses it
|
||||||
|
static uart_port_t gps_uart_num = UART_NUM_1;
|
||||||
|
|
||||||
// GPS sync state
|
// GPS sync state
|
||||||
static int64_t monotonic_offset_us = 0;
|
static int64_t monotonic_offset_us = 0;
|
||||||
|
|
@ -28,8 +28,6 @@ static volatile time_t next_pps_gps_second = 0;
|
||||||
static bool gps_has_fix = false;
|
static bool gps_has_fix = false;
|
||||||
static bool use_gps_for_logs = false;
|
static bool use_gps_for_logs = false;
|
||||||
static SemaphoreHandle_t sync_mutex;
|
static SemaphoreHandle_t sync_mutex;
|
||||||
|
|
||||||
// Force update flag (defaults to true so boot-up snaps immediately)
|
|
||||||
static volatile bool force_sync_update = true;
|
static volatile bool force_sync_update = true;
|
||||||
|
|
||||||
// PPS interrupt - captures exact monotonic time at second boundary
|
// PPS interrupt - captures exact monotonic time at second boundary
|
||||||
|
|
@ -98,77 +96,87 @@ void gps_force_next_update(void) {
|
||||||
|
|
||||||
// GPS processing task
|
// GPS processing task
|
||||||
static void gps_task(void* arg) {
|
static void gps_task(void* arg) {
|
||||||
|
// Buffer for UART reads (more efficient than reading 1 byte at a time)
|
||||||
|
uint8_t d_buf[64];
|
||||||
char line[128];
|
char line[128];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
static int log_counter = 0; // NEW: Counter to throttle logs
|
static int log_counter = 0; // Counter to throttle logs
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
uint8_t data;
|
// Read up to 64 bytes with a 100ms timeout
|
||||||
int len = uart_read_bytes(GPS_UART_NUM, &data, 1, 100 / portTICK_PERIOD_MS);
|
int len = uart_read_bytes(gps_uart_num, d_buf, sizeof(d_buf), pdMS_TO_TICKS(100));
|
||||||
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (data == '\n') {
|
// Process all bytes received in this batch
|
||||||
line[pos] = '\0';
|
for (int i = 0; i < len; i++) {
|
||||||
|
uint8_t data = d_buf[i];
|
||||||
|
|
||||||
struct tm gps_tm;
|
if (data == '\n') {
|
||||||
bool valid;
|
line[pos] = '\0';
|
||||||
if (parse_gprmc(line, &gps_tm, &valid)) {
|
|
||||||
if (valid) {
|
|
||||||
time_t gps_time = mktime(&gps_tm);
|
|
||||||
|
|
||||||
xSemaphoreTake(sync_mutex, portMAX_DELAY);
|
struct tm gps_tm;
|
||||||
next_pps_gps_second = gps_time + 1;
|
bool valid;
|
||||||
xSemaphoreGive(sync_mutex);
|
if (parse_gprmc(line, &gps_tm, &valid)) {
|
||||||
|
if (valid) {
|
||||||
|
time_t gps_time = mktime(&gps_tm);
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(300));
|
xSemaphoreTake(sync_mutex, portMAX_DELAY);
|
||||||
|
next_pps_gps_second = gps_time + 1;
|
||||||
|
xSemaphoreGive(sync_mutex);
|
||||||
|
|
||||||
xSemaphoreTake(sync_mutex, portMAX_DELAY);
|
// Wait a bit to ensure PPS has likely fired if it was going to
|
||||||
if (last_pps_monotonic > 0) {
|
vTaskDelay(pdMS_TO_TICKS(300));
|
||||||
int64_t gps_us = (int64_t)next_pps_gps_second * 1000000LL;
|
|
||||||
int64_t new_offset = gps_us - last_pps_monotonic;
|
|
||||||
|
|
||||||
if (monotonic_offset_us == 0 || force_sync_update) {
|
xSemaphoreTake(sync_mutex, portMAX_DELAY);
|
||||||
monotonic_offset_us = new_offset;
|
if (last_pps_monotonic > 0) {
|
||||||
|
int64_t gps_us = (int64_t)next_pps_gps_second * 1000000LL;
|
||||||
|
int64_t new_offset = gps_us - last_pps_monotonic;
|
||||||
|
|
||||||
if (force_sync_update) {
|
if (monotonic_offset_us == 0 || force_sync_update) {
|
||||||
ESP_LOGW(TAG, "GPS sync SNAP: Offset forced to %lld us", monotonic_offset_us);
|
monotonic_offset_us = new_offset;
|
||||||
force_sync_update = false;
|
|
||||||
log_counter = 0; // Ensure we see the log immediately after a snap
|
if (force_sync_update) {
|
||||||
|
ESP_LOGW(TAG, "GPS sync SNAP: Offset forced to %lld us", monotonic_offset_us);
|
||||||
|
force_sync_update = false;
|
||||||
|
log_counter = 0; // Ensure we see the log immediately after a snap
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Low-pass filter: 90% old + 10% new
|
||||||
|
monotonic_offset_us = (monotonic_offset_us * 9 + new_offset) / 10;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Low-pass filter: 90% old + 10% new
|
|
||||||
monotonic_offset_us = (monotonic_offset_us * 9 + new_offset) / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
gps_has_fix = true;
|
gps_has_fix = true;
|
||||||
|
|
||||||
// LOGGING THROTTLE: Only print every 60th update (approx 60 seconds)
|
// LOGGING THROTTLE: Only print every 60th update (approx 60 seconds)
|
||||||
if (log_counter == 0) {
|
if (log_counter == 0) {
|
||||||
ESP_LOGI(TAG, "GPS sync: %04d-%02d-%02d %02d:%02d:%02d, offset=%lld us",
|
ESP_LOGI(TAG, "GPS sync: %04d-%02d-%02d %02d:%02d:%02d, offset=%lld us",
|
||||||
gps_tm.tm_year + 1900, gps_tm.tm_mon + 1, gps_tm.tm_mday,
|
gps_tm.tm_year + 1900, gps_tm.tm_mon + 1, gps_tm.tm_mday,
|
||||||
gps_tm.tm_hour, gps_tm.tm_min, gps_tm.tm_sec,
|
gps_tm.tm_hour, gps_tm.tm_min, gps_tm.tm_sec,
|
||||||
monotonic_offset_us);
|
monotonic_offset_us);
|
||||||
log_counter = 60;
|
log_counter = 60;
|
||||||
|
}
|
||||||
|
log_counter--;
|
||||||
}
|
}
|
||||||
log_counter--;
|
xSemaphoreGive(sync_mutex);
|
||||||
|
} else {
|
||||||
|
gps_has_fix = false;
|
||||||
}
|
}
|
||||||
xSemaphoreGive(sync_mutex);
|
|
||||||
} else {
|
|
||||||
gps_has_fix = false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
} else if (pos < sizeof(line) - 1) {
|
} else if (pos < sizeof(line) - 1) {
|
||||||
line[pos++] = data;
|
line[pos++] = data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gps_sync_init(bool use_gps_log_timestamps) {
|
void gps_sync_init(const gps_sync_config_t *config, bool use_gps_log_timestamps) {
|
||||||
ESP_LOGI(TAG, "Initializing GPS sync");
|
ESP_LOGI(TAG, "Initializing GPS sync");
|
||||||
|
|
||||||
|
// 1. Store the UART port for the task to use
|
||||||
|
gps_uart_num = config->uart_port;
|
||||||
use_gps_for_logs = use_gps_log_timestamps;
|
use_gps_for_logs = use_gps_log_timestamps;
|
||||||
|
|
||||||
// Ensure we start with a forced update
|
// Ensure we start with a forced update
|
||||||
|
|
@ -176,12 +184,12 @@ void gps_sync_init(bool use_gps_log_timestamps) {
|
||||||
|
|
||||||
if (use_gps_log_timestamps) {
|
if (use_gps_log_timestamps) {
|
||||||
ESP_LOGI(TAG, "ESP_LOG timestamps: GPS time in seconds.milliseconds format");
|
ESP_LOGI(TAG, "ESP_LOG timestamps: GPS time in seconds.milliseconds format");
|
||||||
// Override vprintf to add decimal point to timestamps
|
|
||||||
esp_log_set_vprintf(gps_log_vprintf);
|
esp_log_set_vprintf(gps_log_vprintf);
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_mutex = xSemaphoreCreateMutex();
|
sync_mutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
|
// 2. Configure UART
|
||||||
uart_config_t uart_config = {
|
uart_config_t uart_config = {
|
||||||
.baud_rate = GPS_BAUD_RATE,
|
.baud_rate = GPS_BAUD_RATE,
|
||||||
.data_bits = UART_DATA_8_BITS,
|
.data_bits = UART_DATA_8_BITS,
|
||||||
|
|
@ -191,26 +199,34 @@ void gps_sync_init(bool use_gps_log_timestamps) {
|
||||||
.source_clk = UART_SCLK_DEFAULT,
|
.source_clk = UART_SCLK_DEFAULT,
|
||||||
};
|
};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(uart_driver_install(GPS_UART_NUM, UART_BUF_SIZE, 0, 0, NULL, 0));
|
ESP_ERROR_CHECK(uart_driver_install(config->uart_port, UART_BUF_SIZE, 0, 0, NULL, 0));
|
||||||
ESP_ERROR_CHECK(uart_param_config(GPS_UART_NUM, &uart_config));
|
ESP_ERROR_CHECK(uart_param_config(config->uart_port, &uart_config));
|
||||||
ESP_ERROR_CHECK(uart_set_pin(GPS_UART_NUM, GPS_TX_PIN, GPS_RX_PIN,
|
|
||||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
|
||||||
|
|
||||||
|
// 3. Set Pins (Dynamic Configuration)
|
||||||
|
ESP_ERROR_CHECK(uart_set_pin(config->uart_port,
|
||||||
|
config->tx_pin,
|
||||||
|
config->rx_pin,
|
||||||
|
UART_PIN_NO_CHANGE,
|
||||||
|
UART_PIN_NO_CHANGE));
|
||||||
|
|
||||||
|
// 4. Configure PPS GPIO
|
||||||
gpio_config_t io_conf = {
|
gpio_config_t io_conf = {
|
||||||
.intr_type = GPIO_INTR_POSEDGE,
|
.intr_type = GPIO_INTR_POSEDGE,
|
||||||
.mode = GPIO_MODE_INPUT,
|
.mode = GPIO_MODE_INPUT,
|
||||||
.pin_bit_mask = (1ULL << PPS_GPIO),
|
.pin_bit_mask = (1ULL << config->pps_pin),
|
||||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||||
|
|
||||||
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
// 5. Install ISR
|
||||||
ESP_ERROR_CHECK(gpio_isr_handler_add(PPS_GPIO, pps_isr_handler, NULL));
|
gpio_install_isr_service(0);
|
||||||
|
ESP_ERROR_CHECK(gpio_isr_handler_add(config->pps_pin, pps_isr_handler, NULL));
|
||||||
|
|
||||||
xTaskCreate(gps_task, "gps_task", 4096, NULL, 5, NULL);
|
xTaskCreate(gps_task, "gps_task", 4096, NULL, 5, NULL);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "GPS sync initialized (RX=GPIO%d, PPS=GPIO%d)", GPS_RX_PIN, PPS_GPIO);
|
ESP_LOGI(TAG, "GPS sync initialized (UART=%d, RX=%d, TX=%d, PPS=%d)",
|
||||||
|
config->uart_port, config->rx_pin, config->tx_pin, config->pps_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
gps_timestamp_t gps_get_timestamp(void) {
|
gps_timestamp_t gps_get_timestamp(void) {
|
||||||
|
|
@ -250,24 +266,16 @@ bool gps_is_synced(void) {
|
||||||
|
|
||||||
// ---------------- LOGGING SYSTEM INTERCEPTION ----------------
|
// ---------------- LOGGING SYSTEM INTERCEPTION ----------------
|
||||||
|
|
||||||
// We now only return standard system time (ms) to ESP-IDF.
|
|
||||||
// We do NOT return GPS time here because it overflows 32 bits.
|
|
||||||
uint32_t gps_log_timestamp(void) {
|
uint32_t gps_log_timestamp(void) {
|
||||||
return (uint32_t)(esp_timer_get_time() / 1000ULL);
|
return (uint32_t)(esp_timer_get_time() / 1000ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intercepts the log line string before it is printed.
|
|
||||||
// It detects the timestamp `(1234)` which is monotonic ms,
|
|
||||||
// and mathematically converts it to `(+17544234.123)` GPS sec.ms
|
|
||||||
int gps_log_vprintf(const char *fmt, va_list args) {
|
int gps_log_vprintf(const char *fmt, va_list args) {
|
||||||
static char buffer[512];
|
static char buffer[512];
|
||||||
|
|
||||||
// Format the message into our buffer
|
|
||||||
int ret = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
int ret = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
assert(ret >= 0);
|
assert(ret >= 0);
|
||||||
|
|
||||||
if (use_gps_for_logs) {
|
if (use_gps_for_logs) {
|
||||||
// Look for timestamp pattern: "I (", "W (", etc.
|
|
||||||
char *timestamp_start = NULL;
|
char *timestamp_start = NULL;
|
||||||
for (int i = 0; buffer[i] != '\0' && i < sizeof(buffer) - 20; i++) {
|
for (int i = 0; buffer[i] != '\0' && i < sizeof(buffer) - 20; i++) {
|
||||||
if ((buffer[i] == 'I' || buffer[i] == 'W' || buffer[i] == 'E' ||
|
if ((buffer[i] == 'I' || buffer[i] == 'W' || buffer[i] == 'E' ||
|
||||||
|
|
@ -281,44 +289,33 @@ int gps_log_vprintf(const char *fmt, va_list args) {
|
||||||
if (timestamp_start) {
|
if (timestamp_start) {
|
||||||
char *timestamp_end = strchr(timestamp_start, ')');
|
char *timestamp_end = strchr(timestamp_start, ')');
|
||||||
if (timestamp_end) {
|
if (timestamp_end) {
|
||||||
// Parse the MONOTONIC ms that ESP-IDF put there
|
|
||||||
uint32_t monotonic_log_ms = 0;
|
uint32_t monotonic_log_ms = 0;
|
||||||
if (sscanf(timestamp_start, "%lu", &monotonic_log_ms) == 1) {
|
if (sscanf(timestamp_start, "%lu", &monotonic_log_ms) == 1) {
|
||||||
|
|
||||||
char reformatted[512];
|
char reformatted[512];
|
||||||
size_t prefix_len = timestamp_start - buffer;
|
size_t prefix_len = timestamp_start - buffer;
|
||||||
memcpy(reformatted, buffer, prefix_len);
|
memcpy(reformatted, buffer, prefix_len);
|
||||||
int decimal_len = 0;
|
int decimal_len = 0;
|
||||||
|
|
||||||
if (gps_has_fix) {
|
if (gps_has_fix) {
|
||||||
// MATH: Calculate GPS time based on the log's monotonic time
|
|
||||||
int64_t log_mono_us = (int64_t)monotonic_log_ms * 1000;
|
int64_t log_mono_us = (int64_t)monotonic_log_ms * 1000;
|
||||||
int64_t log_gps_us = log_mono_us + monotonic_offset_us;
|
int64_t log_gps_us = log_mono_us + monotonic_offset_us;
|
||||||
|
|
||||||
// Split into Seconds and Milliseconds
|
|
||||||
uint64_t gps_sec = log_gps_us / 1000000;
|
uint64_t gps_sec = log_gps_us / 1000000;
|
||||||
uint32_t gps_ms = (log_gps_us % 1000000) / 1000;
|
uint32_t gps_ms = (log_gps_us % 1000000) / 1000;
|
||||||
|
|
||||||
decimal_len = snprintf(reformatted + prefix_len,
|
decimal_len = snprintf(reformatted + prefix_len,
|
||||||
sizeof(reformatted) - prefix_len,
|
sizeof(reformatted) - prefix_len,
|
||||||
"+%" PRIu64 ".%03lu", gps_sec, gps_ms);
|
"+%" PRIu64 ".%03lu", gps_sec, gps_ms);
|
||||||
} else {
|
} else {
|
||||||
// No fix: just show monotonic nicely
|
|
||||||
uint32_t sec = monotonic_log_ms / 1000;
|
uint32_t sec = monotonic_log_ms / 1000;
|
||||||
uint32_t ms = monotonic_log_ms % 1000;
|
uint32_t ms = monotonic_log_ms % 1000;
|
||||||
decimal_len = snprintf(reformatted + prefix_len,
|
decimal_len = snprintf(reformatted + prefix_len,
|
||||||
sizeof(reformatted) - prefix_len,
|
sizeof(reformatted) - prefix_len,
|
||||||
"*%lu.%03lu", sec, ms);
|
"*%lu.%03lu", sec, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the rest of the message (from the closing parenthesis onwards)
|
|
||||||
strcpy(reformatted + prefix_len + decimal_len, timestamp_end);
|
strcpy(reformatted + prefix_len + decimal_len, timestamp_end);
|
||||||
|
|
||||||
return printf("%s", reformatted);
|
return printf("%s", reformatted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return printf("%s", buffer);
|
return printf("%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,36 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/uart.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uart_port_t uart_port;
|
||||||
|
gpio_num_t tx_pin;
|
||||||
|
gpio_num_t rx_pin;
|
||||||
|
gpio_num_t pps_pin;
|
||||||
|
} gps_sync_config_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t monotonic_us; // Microseconds - never jumps backward
|
int64_t monotonic_us; // Microseconds - never jumps backward
|
||||||
int64_t monotonic_ms; // Milliseconds - for easier logging
|
int64_t monotonic_ms; // Milliseconds - for easier logging
|
||||||
int64_t gps_us; // GPS UTC time in microseconds
|
int64_t gps_us; // GPS UTC time in microseconds
|
||||||
int64_t gps_ms; // GPS UTC time in milliseconds
|
int64_t gps_ms; // GPS UTC time in milliseconds
|
||||||
struct timespec mono_ts; // POSIX timespec (for clock_gettime)
|
struct timespec mono_ts; // POSIX timespec
|
||||||
bool synced; // true if GPS has valid fix
|
bool synced; // true if GPS has valid fix
|
||||||
} gps_timestamp_t;
|
} gps_timestamp_t;
|
||||||
|
|
||||||
// Initialize GPS sync system
|
void gps_sync_init(const gps_sync_config_t *config, bool use_gps_log_timestamps);
|
||||||
// If use_gps_log_timestamps is true, ESP_LOGI/ESP_LOGW/etc will use GPS time
|
|
||||||
// with visual indicators:
|
|
||||||
// I (+1733424645.234) TAG: message <-- + indicates GPS synced
|
|
||||||
// I (*1.234) TAG: message <-- * indicates not synced (monotonic)
|
|
||||||
void gps_sync_init(bool use_gps_log_timestamps);
|
|
||||||
|
|
||||||
// FORCE UPDATE: Ignore the low-pass filter for the next valid GPS fix.
|
|
||||||
// This snaps the time offset immediately to the new value.
|
|
||||||
// Useful on boot or if you detect a massive time discrepancy.
|
|
||||||
void gps_force_next_update(void);
|
void gps_force_next_update(void);
|
||||||
|
|
||||||
// Get current timestamp (with both us and ms)
|
|
||||||
gps_timestamp_t gps_get_timestamp(void);
|
gps_timestamp_t gps_get_timestamp(void);
|
||||||
|
|
||||||
// Get millisecond timestamp using clock_gettime
|
|
||||||
int64_t gps_get_monotonic_ms(void);
|
int64_t gps_get_monotonic_ms(void);
|
||||||
|
|
||||||
// Check if GPS is synced
|
|
||||||
bool gps_is_synced(void);
|
bool gps_is_synced(void);
|
||||||
|
|
||||||
// Internal functions (called automatically by ESP-IDF - don't call directly)
|
// Internal logging hooks
|
||||||
uint32_t gps_log_timestamp(void);
|
uint32_t gps_log_timestamp(void);
|
||||||
int gps_log_vprintf(const char *fmt, va_list args);
|
int gps_log_vprintf(const char *fmt, va_list args);
|
||||||
|
|
|
||||||
76
main/main.c
76
main/main.c
|
|
@ -26,14 +26,40 @@
|
||||||
#include "wifi_monitor.h"
|
#include "wifi_monitor.h"
|
||||||
#include "gps_sync.h"
|
#include "gps_sync.h"
|
||||||
|
|
||||||
|
// --- BOARD CONFIGURATION ---
|
||||||
|
// --- Hardware Configuration ---
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
|
// ESP32-S3 Specific Wiring
|
||||||
|
#define RGB_LED_GPIO 48 // Standard S3 DevKit RGB pin
|
||||||
|
#define GPS_TX_PIN GPIO_NUM_5
|
||||||
|
#define GPS_RX_PIN GPIO_NUM_4
|
||||||
|
#define GPS_PPS_PIN GPIO_NUM_6
|
||||||
|
|
||||||
|
#elif defined(CONFIG_IDF_TARGET_ESP32C5)
|
||||||
|
// ESP32-C5 Specific Wiring
|
||||||
|
#define RGB_LED_GPIO 27
|
||||||
|
#define GPS_TX_PIN GPIO_NUM_24
|
||||||
|
#define GPS_RX_PIN GPIO_NUM_23
|
||||||
|
#define GPS_PPS_PIN GPIO_NUM_25
|
||||||
|
|
||||||
|
#elif defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
// ESP32 (Original) Specific Wiring
|
||||||
|
// Note: ESP32 has no GPIO 24. GPIO 8 causes flash crash.
|
||||||
|
#define RGB_LED_GPIO 2 // Often onboard Blue LED (valid GPIO)
|
||||||
|
#define GPS_TX_PIN GPIO_NUM_17 // Standard UART2 TX
|
||||||
|
#define GPS_RX_PIN GPIO_NUM_16 // Standard UART2 RX
|
||||||
|
#define GPS_PPS_PIN GPIO_NUM_4
|
||||||
|
|
||||||
|
#else
|
||||||
|
// Fallback / Other Chips (C6, etc.)
|
||||||
|
#define RGB_LED_GPIO 8
|
||||||
|
#define GPS_TX_PIN GPIO_NUM_24
|
||||||
|
#define GPS_RX_PIN GPIO_NUM_23
|
||||||
|
#define GPS_PPS_PIN GPIO_NUM_25
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *TAG = "MAIN";
|
static const char *TAG = "MAIN";
|
||||||
|
|
||||||
// --- Hardware Configuration ---
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32C5
|
|
||||||
#define RGB_LED_GPIO 27
|
|
||||||
#else
|
|
||||||
#define RGB_LED_GPIO 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// --- WiFi Operation Mode ---
|
// --- WiFi Operation Mode ---
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -146,24 +172,38 @@ static void csi_cb(void *ctx, wifi_csi_info_t *info) {
|
||||||
ESP_LOGI("CSI", "Captured %lu CSI packets", (unsigned long)s_csi_packet_count);
|
ESP_LOGI("CSI", "Captured %lu CSI packets", (unsigned long)s_csi_packet_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wifi_enable_csi_once(void) {
|
static void wifi_enable_csi_once(void) {
|
||||||
if (s_csi_enabled) return;
|
if (s_csi_enabled) return;
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||||
wifi_csi_config_t csi_cfg;
|
|
||||||
memset(&csi_cfg, 0, sizeof(csi_cfg));
|
// Initialize with defaults (safe for all chips)
|
||||||
csi_cfg.enable = true;
|
wifi_csi_config_t csi_cfg = { 0 };
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
|
// These fields ONLY exist on Xtensa-based chips (S3, S2, Original)
|
||||||
|
// The ESP32-C5/C6 (RISC-V) hardware handles this automatically/internally.
|
||||||
|
csi_cfg.lltf_en = true;
|
||||||
|
csi_cfg.htltf_en = true;
|
||||||
|
csi_cfg.stbc_htltf2_en = true;
|
||||||
|
csi_cfg.ltf_merge_en = true;
|
||||||
|
csi_cfg.channel_filter_en = true;
|
||||||
|
csi_cfg.manu_scale = false;
|
||||||
|
csi_cfg.shift = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
ESP_LOGI("CSI", "Configuring CSI...");
|
ESP_LOGI("CSI", "Configuring CSI...");
|
||||||
if (esp_wifi_set_csi_config(&csi_cfg) != ESP_OK) {
|
if (esp_wifi_set_csi_config(&csi_cfg) != ESP_OK) {
|
||||||
ESP_LOGE("CSI", "Failed to set CSI config");
|
ESP_LOGE("CSI", "Failed to set CSI config");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_wifi_set_csi_rx_cb(csi_cb, NULL) != ESP_OK) {
|
if (esp_wifi_set_csi_rx_cb(csi_cb, NULL) != ESP_OK) {
|
||||||
ESP_LOGE("CSI", "Failed to set CSI callback");
|
ESP_LOGE("CSI", "Failed to set CSI callback");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Explicit enable call
|
||||||
if (esp_wifi_set_csi(true) != ESP_OK) {
|
if (esp_wifi_set_csi(true) != ESP_OK) {
|
||||||
ESP_LOGE("CSI", "Failed to enable CSI");
|
ESP_LOGE("CSI", "Failed to enable CSI");
|
||||||
return;
|
return;
|
||||||
|
|
@ -755,8 +795,20 @@ void app_main(void) {
|
||||||
// 4. Initialize GPS (Enable GPS-timestamped logs)
|
// 4. Initialize GPS (Enable GPS-timestamped logs)
|
||||||
ESP_LOGI(TAG, "========================================");
|
ESP_LOGI(TAG, "========================================");
|
||||||
ESP_LOGI(TAG, "Initializing GPS sync...");
|
ESP_LOGI(TAG, "Initializing GPS sync...");
|
||||||
gps_sync_init(true); // true = GPS timestamps for ESP_LOG
|
|
||||||
ESP_LOGI(TAG, "GPS initialized");
|
// CONFIGURATION STRUCT: Maps the correct pins based on the chip type
|
||||||
|
const gps_sync_config_t gps_cfg = {
|
||||||
|
.uart_port = UART_NUM_1,
|
||||||
|
.tx_pin = GPS_TX_PIN,
|
||||||
|
.rx_pin = GPS_RX_PIN,
|
||||||
|
.pps_pin = GPS_PPS_PIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pass the config and enable GPS timestamps in logs
|
||||||
|
gps_sync_init(&gps_cfg, true);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "GPS initialized on UART1 (TX:%d, RX:%d, PPS:%d)",
|
||||||
|
GPS_TX_PIN, GPS_RX_PIN, GPS_PPS_PIN);
|
||||||
ESP_LOGI(TAG, " - Waiting for GPS lock...");
|
ESP_LOGI(TAG, " - Waiting for GPS lock...");
|
||||||
ESP_LOGI(TAG, " - Timestamps: (*) = not synced, (+) = GPS synced");
|
ESP_LOGI(TAG, " - Timestamps: (*) = not synced, (+) = GPS synced");
|
||||||
ESP_LOGI(TAG, "========================================");
|
ESP_LOGI(TAG, "========================================");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue