sd card sdio 변경
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
#include <SPI.h>
|
||||
#include <mcp2515.h>
|
||||
#include <SoftWire.h>
|
||||
#include <SD.h>
|
||||
#include <SD_MMC.h> // ⭐ SDIO 4-bit
|
||||
#include <WiFi.h>
|
||||
#include <esp_wifi.h>
|
||||
#include <esp_task_wdt.h>
|
||||
@@ -55,11 +55,14 @@
|
||||
#define HSPI_SCLK 12
|
||||
#define HSPI_CS 10
|
||||
|
||||
// VSPI 핀 (SD Card)
|
||||
#define VSPI_MISO 41
|
||||
#define VSPI_MOSI 40
|
||||
#define VSPI_SCLK 39
|
||||
#define VSPI_CS 42
|
||||
// ⭐⭐⭐ SDIO 4-bit Pins (ESP32-S3)
|
||||
// CLK: GPIO39, CMD: GPIO38, D0-D3: GPIO40,41,42,21
|
||||
#define SDIO_CLK 39
|
||||
#define SDIO_CMD 38
|
||||
#define SDIO_D0 40
|
||||
#define SDIO_D1 41
|
||||
#define SDIO_D2 42
|
||||
#define SDIO_D3 21 // ⭐ OPI PSRAM 호환
|
||||
|
||||
// I2C2 핀 (RTC DS3231)
|
||||
#define RTC_SDA 8
|
||||
@@ -216,7 +219,7 @@ SerialSettings serial2Settings = {115200, 8, 0, 1}; // ⭐ Serial2 추가
|
||||
|
||||
// 전역 객체 (내부 SRAM)
|
||||
SPIClass hspi(HSPI);
|
||||
SPIClass vspi(FSPI);
|
||||
// SPIClass vspi(FSPI); // ⭐ SDIO 사용으로 제거
|
||||
MCP2515 mcp2515(HSPI_CS, 20000000, &hspi);
|
||||
HardwareSerial SerialComm(1); // UART1
|
||||
HardwareSerial Serial2Comm(2); // ⭐ UART2 추가
|
||||
@@ -1007,7 +1010,7 @@ void sdWriteTask(void *parameter) {
|
||||
// ⭐⭐⭐ 500개마다 파일 재오픈 (핵심!)
|
||||
if (++csvReopenCounter >= 500) {
|
||||
logFile.close();
|
||||
logFile = SD.open(currentFilename, FILE_APPEND);
|
||||
logFile = SD_MMC.open(currentFilename, FILE_APPEND);
|
||||
if (logFile) {
|
||||
Serial.printf("✓ CSV 파일 재오픈: %s (%lu bytes)\n", currentFilename, currentFileSize);
|
||||
} else {
|
||||
@@ -1061,7 +1064,7 @@ void sdWriteTask(void *parameter) {
|
||||
|
||||
// 파일 닫고 다시 열기
|
||||
logFile.close();
|
||||
logFile = SD.open(currentFilename, FILE_APPEND);
|
||||
logFile = SD_MMC.open(currentFilename, FILE_APPEND);
|
||||
if (logFile) {
|
||||
Serial.printf("✓ BIN 파일 재오픈: %s (%lu bytes)\n", currentFilename, currentFileSize);
|
||||
} else {
|
||||
@@ -1123,7 +1126,7 @@ void sdMonitorTask(void *parameter) {
|
||||
void saveFileComments() {
|
||||
if (!sdCardReady) return;
|
||||
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
File commentFile = SD.open("/comments.dat", FILE_WRITE);
|
||||
File commentFile = SD_MMC.open("/comments.dat", FILE_WRITE);
|
||||
if (commentFile) {
|
||||
commentFile.write((uint8_t*)&commentCount, sizeof(commentCount));
|
||||
commentFile.write((uint8_t*)fileComments, sizeof(FileComment) * commentCount);
|
||||
@@ -1136,8 +1139,8 @@ void saveFileComments() {
|
||||
void loadFileComments() {
|
||||
if (!sdCardReady) return;
|
||||
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
if (SD.exists("/comments.dat")) {
|
||||
File commentFile = SD.open("/comments.dat", FILE_READ);
|
||||
if (SD_MMC.exists("/comments.dat")) {
|
||||
File commentFile = SD_MMC.open("/comments.dat", FILE_READ);
|
||||
if (commentFile) {
|
||||
commentFile.read((uint8_t*)&commentCount, sizeof(commentCount));
|
||||
if (commentCount > MAX_FILE_COMMENTS) commentCount = MAX_FILE_COMMENTS;
|
||||
@@ -1184,7 +1187,7 @@ void addFileComment(const char* filename, const char* comment) {
|
||||
void saveSequences() {
|
||||
if (!sdCardReady) return;
|
||||
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
File seqFile = SD.open("/sequences.dat", FILE_WRITE);
|
||||
File seqFile = SD_MMC.open("/sequences.dat", FILE_WRITE);
|
||||
if (seqFile) {
|
||||
seqFile.write((uint8_t*)&sequenceCount, sizeof(sequenceCount));
|
||||
seqFile.write((uint8_t*)sequences, sizeof(CANSequence) * sequenceCount);
|
||||
@@ -1197,8 +1200,8 @@ void saveSequences() {
|
||||
void loadSequences() {
|
||||
if (!sdCardReady) return;
|
||||
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
if (SD.exists("/sequences.dat")) {
|
||||
File seqFile = SD.open("/sequences.dat", FILE_READ);
|
||||
if (SD_MMC.exists("/sequences.dat")) {
|
||||
File seqFile = SD_MMC.open("/sequences.dat", FILE_READ);
|
||||
if (seqFile) {
|
||||
seqFile.read((uint8_t*)&sequenceCount, sizeof(sequenceCount));
|
||||
if (sequenceCount > MAX_SEQUENCES) sequenceCount = MAX_SEQUENCES;
|
||||
@@ -1406,7 +1409,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, ext);
|
||||
|
||||
// ⭐⭐⭐ 파일 생성 (헤더 쓰기)
|
||||
logFile = SD.open(currentFilename, FILE_WRITE);
|
||||
logFile = SD_MMC.open(currentFilename, FILE_WRITE);
|
||||
|
||||
if (logFile) {
|
||||
if (canLogFormatCSV) {
|
||||
@@ -1416,7 +1419,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
logFile.close(); // ⭐ 헤더 쓰고 닫기
|
||||
|
||||
// ⭐⭐⭐ APPEND 모드로 다시 열기
|
||||
logFile = SD.open(currentFilename, FILE_APPEND);
|
||||
logFile = SD_MMC.open(currentFilename, FILE_APPEND);
|
||||
|
||||
if (logFile) {
|
||||
loggingEnabled = true;
|
||||
@@ -1498,7 +1501,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
|
||||
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, ext);
|
||||
|
||||
serialLogFile = SD.open(currentSerialFilename, FILE_WRITE);
|
||||
serialLogFile = SD_MMC.open(currentSerialFilename, FILE_WRITE);
|
||||
|
||||
if (serialLogFile) {
|
||||
if (serialLogFormatCSV) {
|
||||
@@ -1623,7 +1626,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
|
||||
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, ext);
|
||||
|
||||
serial2LogFile = SD.open(currentSerial2Filename, FILE_WRITE);
|
||||
serial2LogFile = SD_MMC.open(currentSerial2Filename, FILE_WRITE);
|
||||
|
||||
if (serial2LogFile) {
|
||||
if (serial2LogFormatCSV) {
|
||||
@@ -1765,7 +1768,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
response["type"] = "files";
|
||||
JsonArray files = response.createNestedArray("files");
|
||||
|
||||
File root = SD.open("/");
|
||||
File root = SD_MMC.open("/");
|
||||
if (root) {
|
||||
File file = root.openNextFile();
|
||||
int fileCount = 0;
|
||||
@@ -1844,8 +1847,8 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
bool success = false;
|
||||
|
||||
if (SD.exists(fullPath)) {
|
||||
if (SD.remove(fullPath)) {
|
||||
if (SD_MMC.exists(fullPath)) {
|
||||
if (SD_MMC.remove(fullPath)) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
@@ -1959,7 +1962,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
|
||||
// SD 카드에 저장
|
||||
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
File seqFile = SD.open("/sequences.dat", FILE_WRITE);
|
||||
File seqFile = SD_MMC.open("/sequences.dat", FILE_WRITE);
|
||||
if (seqFile) {
|
||||
seqFile.write((uint8_t*)&sequenceCount, sizeof(sequenceCount));
|
||||
seqFile.write((uint8_t*)sequences, sizeof(CANSequence) * sequenceCount);
|
||||
@@ -2061,7 +2064,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length)
|
||||
|
||||
// SD 카드에 저장
|
||||
if (xSemaphoreTake(sdMutex, pdMS_TO_TICKS(1000)) == pdTRUE) {
|
||||
File seqFile = SD.open("/sequences.dat", FILE_WRITE);
|
||||
File seqFile = SD_MMC.open("/sequences.dat", FILE_WRITE);
|
||||
if (seqFile) {
|
||||
seqFile.write((uint8_t*)&sequenceCount, sizeof(sequenceCount));
|
||||
seqFile.write((uint8_t*)sequences, sizeof(CANSequence) * sequenceCount);
|
||||
@@ -2406,13 +2409,8 @@ void setup() {
|
||||
hspi.begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_CS);
|
||||
hspi.beginTransaction(SPISettings(40000000, MSBFIRST, SPI_MODE0));
|
||||
hspi.endTransaction();
|
||||
pinMode(VSPI_CS, OUTPUT);
|
||||
digitalWrite(VSPI_CS, HIGH);
|
||||
delay(100);
|
||||
|
||||
vspi.begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_CS);
|
||||
vspi.setFrequency(40000000);
|
||||
Serial.println("✓ SPI 초기화 완료");
|
||||
// ⭐ VSPI 제거: SDIO는 별도 SPI 초기화 불필요
|
||||
Serial.println("✓ SPI 초기화 완료 (HSPI only)");
|
||||
|
||||
// Watchdog 비활성화
|
||||
esp_task_wdt_deinit();
|
||||
@@ -2469,14 +2467,29 @@ void setup() {
|
||||
// RTC 초기화
|
||||
initRTC();
|
||||
|
||||
// SD 카드 초기화
|
||||
if (SD.begin(VSPI_CS, vspi)) {
|
||||
// ⭐⭐⭐ SD 카드 초기화 (SDIO 4-bit Mode)
|
||||
Serial.println("SD 카드 초기화 (SDIO 4-bit)...");
|
||||
|
||||
// setPins() 호출: clk, cmd, d0, d1, d2, d3
|
||||
if (!SD_MMC.setPins(SDIO_CLK, SDIO_CMD, SDIO_D0, SDIO_D1, SDIO_D2, SDIO_D3)) {
|
||||
Serial.println("✗ SD_MMC.setPins() 실패!");
|
||||
sdCardReady = false;
|
||||
} else if (SD_MMC.begin("/sdcard", false)) { // false = 4-bit mode
|
||||
sdCardReady = true;
|
||||
Serial.println("✓ SD 카드 초기화 완료");
|
||||
Serial.println("✓ SD 카드 초기화 완료 (SDIO 4-bit)");
|
||||
Serial.printf(" 카드 크기: %llu MB\n", SD_MMC.cardSize() / (1024 * 1024));
|
||||
Serial.printf(" 핀: CLK=%d, CMD=%d, D0=%d, D1=%d, D2=%d, D3=%d\n",
|
||||
SDIO_CLK, SDIO_CMD, SDIO_D0, SDIO_D1, SDIO_D2, SDIO_D3);
|
||||
loadFileComments();
|
||||
loadSequences();
|
||||
} else {
|
||||
sdCardReady = false;
|
||||
Serial.println("✗ SD 카드 초기화 실패");
|
||||
Serial.println(" 확인 사항:");
|
||||
Serial.println(" - 배선: CLK=39, CMD=38, D0=40, D1=41, D2=42, D3=21");
|
||||
Serial.println(" - 10kΩ 풀업 저항 확인 (CMD, D0-D3)");
|
||||
Serial.println(" - SD 카드 포맷 (FAT32)");
|
||||
Serial.println(" - SDIO 지원 SD 카드 모듈 사용");
|
||||
}
|
||||
|
||||
// WiFi 설정
|
||||
@@ -2550,8 +2563,8 @@ void setup() {
|
||||
if (server.hasArg("file")) {
|
||||
String filename = "/" + server.arg("file");
|
||||
|
||||
if (SD.exists(filename)) {
|
||||
File file = SD.open(filename, FILE_READ);
|
||||
if (SD_MMC.exists(filename)) {
|
||||
File file = SD_MMC.open(filename, FILE_READ);
|
||||
if (file) {
|
||||
String displayName = server.arg("file");
|
||||
server.sendHeader("Content-Disposition",
|
||||
|
||||
Reference in New Issue
Block a user