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 <inttypes.h>
|
||||
|
||||
// --- SAFE WIRING FOR ESP32-C5 ---
|
||||
#define GPS_UART_NUM UART_NUM_1
|
||||
#define GPS_RX_PIN GPIO_NUM_23
|
||||
#define GPS_TX_PIN GPIO_NUM_24
|
||||
#define PPS_GPIO GPIO_NUM_25
|
||||
static const char *TAG = "GPS_SYNC";
|
||||
|
||||
// --- INTERNAL MACROS ---
|
||||
#define GPS_BAUD_RATE 9600
|
||||
#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
|
||||
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 use_gps_for_logs = false;
|
||||
static SemaphoreHandle_t sync_mutex;
|
||||
|
||||
// Force update flag (defaults to true so boot-up snaps immediately)
|
||||
static volatile bool force_sync_update = true;
|
||||
|
||||
// PPS interrupt - captures exact monotonic time at second boundary
|
||||
|
|
@ -98,15 +96,21 @@ void gps_force_next_update(void) {
|
|||
|
||||
// GPS processing task
|
||||
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];
|
||||
int pos = 0;
|
||||
static int log_counter = 0; // NEW: Counter to throttle logs
|
||||
static int log_counter = 0; // Counter to throttle logs
|
||||
|
||||
while (1) {
|
||||
uint8_t data;
|
||||
int len = uart_read_bytes(GPS_UART_NUM, &data, 1, 100 / portTICK_PERIOD_MS);
|
||||
// Read up to 64 bytes with a 100ms timeout
|
||||
int len = uart_read_bytes(gps_uart_num, d_buf, sizeof(d_buf), pdMS_TO_TICKS(100));
|
||||
|
||||
if (len > 0) {
|
||||
// Process all bytes received in this batch
|
||||
for (int i = 0; i < len; i++) {
|
||||
uint8_t data = d_buf[i];
|
||||
|
||||
if (data == '\n') {
|
||||
line[pos] = '\0';
|
||||
|
||||
|
|
@ -120,6 +124,7 @@ static void gps_task(void* arg) {
|
|||
next_pps_gps_second = gps_time + 1;
|
||||
xSemaphoreGive(sync_mutex);
|
||||
|
||||
// Wait a bit to ensure PPS has likely fired if it was going to
|
||||
vTaskDelay(pdMS_TO_TICKS(300));
|
||||
|
||||
xSemaphoreTake(sync_mutex, portMAX_DELAY);
|
||||
|
|
@ -165,10 +170,13 @@ static void gps_task(void* arg) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
// 1. Store the UART port for the task to use
|
||||
gps_uart_num = config->uart_port;
|
||||
use_gps_for_logs = use_gps_log_timestamps;
|
||||
|
||||
// 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
sync_mutex = xSemaphoreCreateMutex();
|
||||
|
||||
// 2. Configure UART
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = GPS_BAUD_RATE,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
|
|
@ -191,26 +199,34 @@ void gps_sync_init(bool use_gps_log_timestamps) {
|
|||
.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_param_config(GPS_UART_NUM, &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));
|
||||
ESP_ERROR_CHECK(uart_driver_install(config->uart_port, UART_BUF_SIZE, 0, 0, NULL, 0));
|
||||
ESP_ERROR_CHECK(uart_param_config(config->uart_port, &uart_config));
|
||||
|
||||
// 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 = {
|
||||
.intr_type = GPIO_INTR_POSEDGE,
|
||||
.mode = GPIO_MODE_INPUT,
|
||||
.pin_bit_mask = (1ULL << PPS_GPIO),
|
||||
.pin_bit_mask = (1ULL << config->pps_pin),
|
||||
.pull_up_en = GPIO_PULLUP_ENABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
};
|
||||
ESP_ERROR_CHECK(gpio_config(&io_conf));
|
||||
|
||||
ESP_ERROR_CHECK(gpio_install_isr_service(0));
|
||||
ESP_ERROR_CHECK(gpio_isr_handler_add(PPS_GPIO, pps_isr_handler, NULL));
|
||||
// 5. Install ISR
|
||||
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);
|
||||
|
||||
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) {
|
||||
|
|
@ -250,24 +266,16 @@ bool gps_is_synced(void) {
|
|||
|
||||
// ---------------- 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) {
|
||||
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) {
|
||||
static char buffer[512];
|
||||
|
||||
// Format the message into our buffer
|
||||
int ret = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
assert(ret >= 0);
|
||||
|
||||
if (use_gps_for_logs) {
|
||||
// Look for timestamp pattern: "I (", "W (", etc.
|
||||
char *timestamp_start = NULL;
|
||||
for (int i = 0; buffer[i] != '\0' && i < sizeof(buffer) - 20; i++) {
|
||||
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) {
|
||||
char *timestamp_end = strchr(timestamp_start, ')');
|
||||
if (timestamp_end) {
|
||||
// Parse the MONOTONIC ms that ESP-IDF put there
|
||||
uint32_t monotonic_log_ms = 0;
|
||||
if (sscanf(timestamp_start, "%lu", &monotonic_log_ms) == 1) {
|
||||
|
||||
char reformatted[512];
|
||||
size_t prefix_len = timestamp_start - buffer;
|
||||
memcpy(reformatted, buffer, prefix_len);
|
||||
int decimal_len = 0;
|
||||
|
||||
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_gps_us = log_mono_us + monotonic_offset_us;
|
||||
|
||||
// Split into Seconds and Milliseconds
|
||||
uint64_t gps_sec = log_gps_us / 1000000;
|
||||
uint32_t gps_ms = (log_gps_us % 1000000) / 1000;
|
||||
|
||||
decimal_len = snprintf(reformatted + prefix_len,
|
||||
sizeof(reformatted) - prefix_len,
|
||||
"+%" PRIu64 ".%03lu", gps_sec, gps_ms);
|
||||
} else {
|
||||
// No fix: just show monotonic nicely
|
||||
uint32_t sec = monotonic_log_ms / 1000;
|
||||
uint32_t ms = monotonic_log_ms % 1000;
|
||||
decimal_len = snprintf(reformatted + prefix_len,
|
||||
sizeof(reformatted) - prefix_len,
|
||||
"*%lu.%03lu", sec, ms);
|
||||
}
|
||||
|
||||
// Copy the rest of the message (from the closing parenthesis onwards)
|
||||
strcpy(reformatted + prefix_len + decimal_len, timestamp_end);
|
||||
|
||||
return printf("%s", reformatted);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return printf("%s", buffer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,40 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "freertos/FreeRTOS.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 {
|
||||
int64_t monotonic_us; // Microseconds - never jumps backward
|
||||
int64_t monotonic_ms; // Milliseconds - for easier logging
|
||||
int64_t gps_us; // GPS UTC time in microseconds
|
||||
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
|
||||
} gps_timestamp_t;
|
||||
|
||||
// Initialize GPS sync system
|
||||
// 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);
|
||||
void gps_sync_init(const gps_sync_config_t *config, 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);
|
||||
|
||||
// Get current timestamp (with both us and ms)
|
||||
gps_timestamp_t gps_get_timestamp(void);
|
||||
|
||||
// Get millisecond timestamp using clock_gettime
|
||||
int64_t gps_get_monotonic_ms(void);
|
||||
|
||||
// Check if GPS is synced
|
||||
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);
|
||||
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 "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";
|
||||
|
||||
// --- Hardware Configuration ---
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
#define RGB_LED_GPIO 27
|
||||
#else
|
||||
#define RGB_LED_GPIO 8
|
||||
#endif
|
||||
|
||||
// --- WiFi Operation Mode ---
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_enable_csi_once(void) {
|
||||
if (s_csi_enabled) return;
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
wifi_csi_config_t csi_cfg;
|
||||
memset(&csi_cfg, 0, sizeof(csi_cfg));
|
||||
csi_cfg.enable = true;
|
||||
|
||||
// Initialize with defaults (safe for all chips)
|
||||
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...");
|
||||
if (esp_wifi_set_csi_config(&csi_cfg) != ESP_OK) {
|
||||
ESP_LOGE("CSI", "Failed to set CSI config");
|
||||
return;
|
||||
}
|
||||
|
||||
if (esp_wifi_set_csi_rx_cb(csi_cb, NULL) != ESP_OK) {
|
||||
ESP_LOGE("CSI", "Failed to set CSI callback");
|
||||
return;
|
||||
}
|
||||
|
||||
// Explicit enable call
|
||||
if (esp_wifi_set_csi(true) != ESP_OK) {
|
||||
ESP_LOGE("CSI", "Failed to enable CSI");
|
||||
return;
|
||||
|
|
@ -755,8 +795,20 @@ void app_main(void) {
|
|||
// 4. Initialize GPS (Enable GPS-timestamped logs)
|
||||
ESP_LOGI(TAG, "========================================");
|
||||
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, " - Timestamps: (*) = not synced, (+) = GPS synced");
|
||||
ESP_LOGI(TAG, "========================================");
|
||||
|
|
|
|||
Loading…
Reference in New Issue