SDSPI fix for ESP32-C5: correct API v5.5, CMake dependencies, pin mapping

This commit is contained in:
Clawdia
2026-05-09 17:59:43 +02:00
parent 240a374148
commit 913b33d839
1519 changed files with 210337 additions and 610 deletions
+101 -50
View File
@@ -1,11 +1,11 @@
/**
* V2X-SD Driver - SD-Karte via SDMMC (ESP32-C5 native) + CSV-Ausgabe
* V2X-SD Driver - SD-Karte via SDSPI (ESP32-C5 kompatibel) + CSV-Ausgabe
*
* T-Dongle-C5 SD-Karte:
* SD_CMD = GPIO 2
* SD_CLK = GPIO 6
* SD_D0 = GPIO 7
* SD_CS = GPIO 23
* T-Dongle-C5 SD-Karte ber SPI (SDSPI):
* SD_CLK = GPIO 4
* SD_MOSI = GPIO 5
* SD_MISO = GPIO 0
* SD_CS = GPIO 1
*
* Format v2x_frames.csv:
* timestamp_us,msg_type,channel,frequency_mhz,rssi_dbm,noise_dbm,rate_index,frame_len,mac_addr,bssid,raw_hex
@@ -17,14 +17,18 @@
*/
#include "esp_log.h"
#include "v2x_db.h"
#include "esp_timer.h"
#include <time.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "driver/spi_master.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <inttypes.h>
#include "v2x_display.h" /* Typ-Definitonen: v2x_frame_t, v2x_stats_t, v2x_msg_type_t, Konstanten */
static const char *TAG = "v2x-sd";
@@ -32,57 +36,78 @@ static const char *TAG = "v2x-sd";
static v2x_stats_t s_stats;
static FILE *s_log_fp = NULL;
static bool s_initialized = false;
static sdmmc_card_t *s_sd_card = NULL;
/* ====== SD-Karte initialisieren (ESP-IDF v5.x SDMMC, 1-Bit) ====== */
/* ====== SD-Karte initialisieren (SDSPI-Modus fr ESP32-C5) ====== */
esp_err_t v2x_sd_init(void)
{
esp_err_t ret;
sdmmc_card_t *card = NULL;
FILE *fp;
ESP_LOGI(TAG, "Initialisiere SD-Karte via SDMMC (1-Bit)...");
ESP_LOGI(TAG, "Initialisiere SD-Karte ber SDSPI (ESP32-C5)...");
/* SDMMC Host */
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
host.flags = SDMMC_HOST_FLAG_1BIT;
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
/* Slot konfigurieren (ESP32-C5 native SDMMC) */
sdmmc_slot_config_t slot = SDMMC_SLOT_DEFAULT_CONFIG();
slot.width = 1;
slot.clk = GPIO_NUM_6;
slot.cmd = GPIO_NUM_2;
slot.d0 = GPIO_NUM_7;
slot.cd = -1; /* Card detect nicht verwendet */
slot.wr = -1; /* Write protect nicht verwendet */
/* FATFS mounten */
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 4,
.allocation_unit_size = 16 * 1024, /* 16 KB Blöcke */
/* SPI-Bus konfigurieren */
spi_bus_config_t bus_cfg = {
.mosi_io_num = 5, // SD_MOSI
.miso_io_num = 0, // SD_MISO
.sclk_io_num = 4, // SD_CLK
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
ret = esp_vfs_fat_sdmmc_mount(SD_CARD_MOUNT_POINT, &host, &slot, &mount_config, &card);
ret = spi_bus_initialize(SPI2_HOST, &bus_cfg, SPI_DMA_CH_AUTO);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "SD mount fehlgeschlagen: %s", esp_err_to_name(ret));
ESP_LOGE(TAG, "SPI-Bus initialisieren fehlgeschlagen: %s", esp_err_to_name(ret));
return ret;
}
ESP_LOGI(TAG, "SD-Karte erkannt: %lu MB (%s)",
(unsigned long)(card->card_size / (1024 * 1024)),
card->type == SDMMC_TYPE_SDHC ? "SDHC" : "SD");
/* SDSPI-Gert konfigurieren */
sdspi_device_config_t device_cfg = {
.host_id = SPI2_HOST,
.gpio_cs = GPIO_NUM_1, // SD_CS
.gpio_cd = GPIO_NUM_NC, // SD Card Detect
.gpio_wp = GPIO_NUM_NC, // SD Write Protect
.gpio_int = GPIO_NUM_NC,
.gpio_wp_polarity = false,
.duty_cycle_pos = 0,
};
/* SDSPI-Host konfigurieren */
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
host.slot = SPI2_HOST;
host.max_freq_khz = SDMMC_FREQ_HIGHSPEED;
/* FATFS-Mount-Konfiguration (korrekter Typ: esp_vfs_fat_mount_config_t) */
esp_vfs_fat_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 4,
.allocation_unit_size = 16 * 1024,
};
/* FATFS mounten (SDSPI-Variante) */
ret = esp_vfs_fat_sdspi_mount("/sdcard", &host, &device_cfg, &mount_config, &card);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "SD-FATFS mount fehlgeschlagen: %s", esp_err_to_name(ret));
return ret;
}
s_sd_card = card;
/* SD-Karten-Info ausgeben */
ESP_LOGI(TAG, "SD-Karte erkannt: %lu MB",
(unsigned long)(card->csd.capacity * card->csd.sector_size / (1024 * 1024)));
/* Schreibtest */
fp = fopen(SD_CARD_MOUNT_POINT "/test.txt", "w");
FILE *fp = fopen("/sdcard/test.txt", "w");
if (fp) {
fprintf(fp, "OK\n");
fclose(fp);
remove(SD_CARD_MOUNT_POINT "/test.txt");
ESP_LOGI(TAG, "SD Schreibtest OK");
remove("/sdcard/test.txt");
ESP_LOGI(TAG, "SD-Schreibtest OK");
} else {
ESP_LOGW(TAG, "SD Schreibtest fehlgeschlagen");
ESP_LOGW(TAG, "SD-Schreibtest fehlgeschlagen");
}
/* Log-Datei erstellen */
@@ -95,7 +120,7 @@ esp_err_t v2x_sd_init(void)
fprintf(s_log_fp, "= V2X-Sniffer Log =\n");
fprintf(s_log_fp, "Start: %s\n", tbuf);
fprintf(s_log_fp, "SD-Karte: %lu MB\n", (unsigned long)(card->card_size / (1024 * 1024)));
fprintf(s_log_fp, "SD-Karte: SDSPI-Modus (/sdcard)\n");
fprintf(s_log_fp, "CSV: %s\n", SD_CSV_FILE);
fprintf(s_log_fp, "==============\n\n");
fflush(s_log_fp);
@@ -104,10 +129,35 @@ esp_err_t v2x_sd_init(void)
s_initialized = true;
s_stats.start_timestamp_us = esp_timer_get_time();
ESP_LOGI(TAG, "SD-Karte eingebunden: %s", SD_CARD_MOUNT_POINT);
ESP_LOGI(TAG, "SD-Karte eingebunden: /sdcard");
return ESP_OK;
}
/* ====== SD-Karte aushngen ====== */
void v2x_sd_deinit(void)
{
if (!s_initialized) return;
ESP_LOGI(TAG, "SD-Karte aushngen...");
if (s_log_fp) {
fprintf(s_log_fp, "\n===== Shutdown =====\n");
fflush(s_log_fp);
fclose(s_log_fp);
s_log_fp = NULL;
}
/* SD-Karte unmounten */
if (s_sd_card) {
esp_vfs_fat_sdcard_unmount("/sdcard", s_sd_card);
s_sd_card = NULL;
}
s_initialized = false;
ESP_LOGI(TAG, "SD-Karte entfernt");
}
/* ====== MAC-Adresse als Hex-String ====== */
static void mac_to_str(const uint8_t *mac, char *out)
@@ -175,11 +225,11 @@ esp_err_t v2x_sd_write_frame(const v2x_frame_t *frame)
char line[RAW_HEX_BUF + 128];
frame_to_csv_line(frame, line, sizeof(line));
/* An CSV anhängen */
FILE *fp = fopen(SD_CSV_FILE, "a+");
/* An CSV anhngen */
FILE *fp = fopen("/sdcard/v2x_frames.csv", "a+");
if (!fp) {
s_stats.sd_write_errors++;
ESP_LOGE(TAG, "CSV-Datei kann nicht geöffnet werden");
ESP_LOGE(TAG, "CSV-Datei kann nicht geffnet werden");
return ESP_FAIL;
}
@@ -208,10 +258,11 @@ esp_err_t v2x_sd_log_write(const char *fmt, ...)
const v2x_stats_t* v2x_sd_get_stats(void) { return &s_stats; }
void v2x_sd_reset_stats(void)
esp_err_t v2x_sd_reset_stats(void)
{
memset(&s_stats, 0, sizeof(s_stats));
s_stats.start_timestamp_us = esp_timer_get_time();
return ESP_OK;
}
esp_err_t v2x_sd_dump_stats(void)
@@ -237,7 +288,7 @@ esp_err_t v2x_sd_dump_stats(void)
(unsigned long)stats->unknown_count);
v2x_sd_log_write("SD-Fehler: %lu", (unsigned long)stats->sd_write_errors);
FILE *f = fopen(SD_CSV_FILE, "r");
FILE *f = fopen("/sdcard/v2x_frames.csv", "r");
if (f) {
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
@@ -249,15 +300,15 @@ esp_err_t v2x_sd_dump_stats(void)
char rotated[128];
strftime(tbuf, sizeof(tbuf), "%Y%m%d_%H%M%S", tm_info);
snprintf(rotated, sizeof(rotated), "/sdcard/v2x_frames_%s.csv", tbuf);
ESP_LOGW(TAG, "CSV rotieren: %s -> %s", SD_CSV_FILE, rotated);
rename(SD_CSV_FILE, rotated);
ESP_LOGW(TAG, "CSV rotieren: v2x_frames.csv -> %s", rotated);
rename("/sdcard/v2x_frames.csv", rotated);
f = fopen(SD_CSV_FILE, "w");
f = fopen("/sdcard/v2x_frames.csv", "w");
if (f) {
fprintf(f, "%s\n", CSV_HEADER);
fprintf(f, "timestamp_us,msg_type,channel,frequency_mhz,rssi_dbm,noise_dbm,rate_index,frame_len,mac_addr,bssid,raw_hex\n");
fclose(f);
}
v2x_sd_log_write("Neue CSV: %s", SD_CSV_FILE);
v2x_sd_log_write("Neue CSV: /sdcard/v2x_frames.csv");
}
}