Phase 1: ESP-IDF v5 project scaffold, custom partitions, managed deps, AGENTS.md hardware context
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
build/
|
||||||
|
managed_components/
|
||||||
|
sdkconfig.old
|
||||||
|
sdkconfig.defaults.bak
|
||||||
|
dependencies.lock
|
||||||
131
AGENTS.md
Normal file
131
AGENTS.md
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# AGENTS.md — MTG RFID Companion (ESP-IDF)
|
||||||
|
|
||||||
|
> **Context for AI Agents & Assistant Tools:**
|
||||||
|
> This file outlines the architecture, coding guidelines, dependencies, hardware constraints, and build procedures for the **MTG RFID Companion** project. Read this completely before generating code, refactoring, or suggesting dependencies.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Project Overview
|
||||||
|
|
||||||
|
The **MTG RFID Companion** is a hand-held hardware utility for Magic: The Gathering players. It uses an **ESP32** microcontroller running **ESP-IDF v5.x (FreeRTOS)** to scan RFID/NFC tags embedded in card sleeves, query card data locally or via Scryfall's API, render data to a 2.0" ST7789 TFT LCD (240x320), and host a local registration web server.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Target Hardware & Specifications
|
||||||
|
|
||||||
|
* **MCU:** ESP32-WROOM-32 (Dual-Core Xtensa LX6, 240MHz, 520KB SRAM, 4MB Flash). *No external PSRAM.*
|
||||||
|
* **Display:** 2.0" ST7789 SPI TFT LCD (240x320 resolution, RGB565 format). Full-screen JPEG wallpapers supported via tjpgd decoder.
|
||||||
|
* **RFID Reader:** MFRC522 (13.56 MHz, SPI Interface, ISO/IEC 14443A).
|
||||||
|
* **Target Tags:** NTAG213 / NTAG215 micro FPC stickers or standard MIFARE ISO cards (7-byte or 4-byte UIDs).
|
||||||
|
* **User Input:** EC11 Rotary Encoder with integrated push button.
|
||||||
|
* **Storage:** On-chip SPI Flash partitioned with **LittleFS** (mounted at `/spiffs`, size ~1.5 MB).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Peripheral Wiring & GPIO Pinout
|
||||||
|
|
||||||
|
> **CRITICAL:** Do NOT modify GPIO pin assignments in code generation unless explicitly instructed. SPI bus is shared between ST7789 and MFRC522.
|
||||||
|
|
||||||
|
| Peripheral | Functional Pin | ESP32 GPIO Pin | Shared Bus / Notes |
|
||||||
|
| :--- | :--- | :--- | :--- |
|
||||||
|
| **Shared SPI** | SCK / MOSI / MISO | GPIO 18 / 23 / 19 | Shared SPI2_HOST (VSPI) |
|
||||||
|
| **MFRC522 RFID**| CS (SDA) / RST | GPIO 5 / GPIO 22 | Dedicated CS & Reset |
|
||||||
|
| **ST7789 Display**| CS / DC / RST | GPIO 15 / GPIO 2 / GPIO 4 | Dedicated CS, Data/Cmd & Reset |
|
||||||
|
| **Rotary Encoder**| CLK / DT / SW | GPIO 32 / GPIO 33 / GPIO 25 | Active low / Interrupt driven |
|
||||||
|
| **Indicators** | Neopixel (WS2812B) | GPIO 27 | RMT driver |
|
||||||
|
| **Audio** | Piezo Buzzer | GPIO 14 | LEDC PWM channel |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Software Architecture & FreeRTOS Task Allocation
|
||||||
|
|
||||||
|
The project strictly follows a **multithreaded, event-driven model** using FreeRTOS tasks and the ESP Event Loop.
|
||||||
|
|
||||||
|
### Core Core Split
|
||||||
|
* **Core 0 (System, I/O & Network):**
|
||||||
|
* `rc522_task`: Continuously polls RFID reader, emits events upon card detection.
|
||||||
|
* `net_task`: Manages Wi-Fi reconnects, Scryfall HTTPS fetches (`esp_http_client`), and `esp_http_server`.
|
||||||
|
* `storage_task`: Reads/writes JSON files to `/spiffs` via VFS.
|
||||||
|
* **Core 1 (User Interface & Rendering):**
|
||||||
|
* `ui_task`: Handles ST7789 display drawing using `esp_lcd` and rotary encoder inputs. Maintains UI frame rates without blocking Core 0 I/O.
|
||||||
|
|
||||||
|
### System State Machine
|
||||||
|
State transitions must be managed cleanly using FreeRTOS Event Groups or Queue messaging:
|
||||||
|
1. `STATE_BOOT`: Hardware setup, LittleFS mount, Wi-Fi auto-connect.
|
||||||
|
2. `STATE_SCANNER`: Waiting for RFID tag read.
|
||||||
|
3. `STATE_CARD_VIEW`: Displaying fetched/cached card attributes (P/T, Mana, Oracle text).
|
||||||
|
4. `STATE_LIFE_COUNTER`: Interactive 20/40 life counter utilizing rotary encoder.
|
||||||
|
5. `STATE_REGISTRATION`: Local SoftAP mode (`192.168.4.1`) active to pair unknown UIDs with card names via web browser.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Storage Structure (LittleFS `/spiffs`)
|
||||||
|
|
||||||
|
Do NOT assume an SD card is attached. All local database operations use standard C file I/O (`fopen`, `fread`, `fwrite`) over LittleFS.
|
||||||
|
|
||||||
|
* `/spiffs/mappings.json` — Maps scanned UIDs to Card Names:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"04A2B3C4": "Sol Ring",
|
||||||
|
"04E1F2A3": "Atraxa, Praetors' Voice"
|
||||||
|
}
|
||||||
|
|
||||||
|
/spiffs/cards/[UID].json — Cached Scryfall card attribute details:
|
||||||
|
JSON
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Sol Ring",
|
||||||
|
"mana_cost": "{1}",
|
||||||
|
"type": "Artifact",
|
||||||
|
"oracle": "Tap: Add CC.",
|
||||||
|
"price_usd": "1.25"
|
||||||
|
}
|
||||||
|
|
||||||
|
6. Coding Standards & Conventions
|
||||||
|
|
||||||
|
When generating or editing code for this repository:
|
||||||
|
|
||||||
|
Framework: Pure ESP-IDF v5.x (C99/C11 standard). Do NOT use Arduino.h headers, functions, or Arduino libraries (Serial.print, delay(), Wire, etc.).
|
||||||
|
|
||||||
|
Error Handling: Always wrap ESP-IDF API functions in ESP_ERROR_CHECK() or handle errors gracefully using esp_err_t ret. Log errors via ESP_LOGE().
|
||||||
|
|
||||||
|
Memory Management: SRAM is tight (~520KB total, no PSRAM).
|
||||||
|
|
||||||
|
Do NOT allocate huge static buffers on the FreeRTOS task stack.
|
||||||
|
|
||||||
|
Allocate HTTP response buffers and cJSON trees dynamically on the heap (heap_caps_malloc(..., MALLOC_CAP_8BIT)), and always free them immediately after use.
|
||||||
|
|
||||||
|
JSON Parsing: Use native cJSON. Check every pointer return for NULL before accessing object fields.
|
||||||
|
|
||||||
|
Logging Tag: Define a static tag per source file:
|
||||||
|
C
|
||||||
|
|
||||||
|
static const char *TAG = "MODULE_NAME";
|
||||||
|
|
||||||
|
7. Project Dependencies & Configuration
|
||||||
|
|
||||||
|
Managed via idf_component.yml:
|
||||||
|
|
||||||
|
abobija/rc522: SPI RFID reader driver.
|
||||||
|
|
||||||
|
joltwallet/littlefs: LittleFS VFS port for ESP-IDF.
|
||||||
|
|
||||||
|
espressif/esp_lcd: Official display subsystem (ST7789 controller driver).
|
||||||
|
|
||||||
|
Build Commands
|
||||||
|
|
||||||
|
Build Project: idf.py build
|
||||||
|
|
||||||
|
Flash to Device: idf.py -p <PORT> flash
|
||||||
|
|
||||||
|
Monitor Logs: idf.py -p <PORT> monitor
|
||||||
|
|
||||||
|
Partition Table: Uses custom partitions.csv (Flash allocation: 2MB App, 1.5MB LittleFS data).
|
||||||
|
|
||||||
|
8. Guidance for AI Agents Generating Code
|
||||||
|
|
||||||
|
When asked to build features: Write full, compile-ready C files (.c) and header files (.h) targeting ESP-IDF v5.x.
|
||||||
|
|
||||||
|
When modifying hardware code: Cross-check the shared SPI bus configurations to prevent SPI2_HOST bus conflicts between ST7789 and MFRC522.
|
||||||
|
|
||||||
|
When implementing network code: Use non-blocking esp_http_client requests running on a dedicated FreeRTOS task to keep screen rendering smooth.
|
||||||
7
CMakeLists.txt
Normal file
7
CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(mtg-rfid-companion)
|
||||||
|
|
||||||
|
idf_build_set_property(PROJECT_DESCRIPTION "MTG RFID Companion")
|
||||||
|
idf_build_set_property(PROJECT_HOMEPAGE_URL "https://scryfall.com")
|
||||||
4
main/CMakeLists.txt
Normal file
4
main/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS
|
||||||
|
"main.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
)
|
||||||
6
main/idf_component.yml
Normal file
6
main/idf_component.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
## IDF Component Manager dependencies for MTG RFID Companion
|
||||||
|
## NOTE: espressif/esp_lcd is a built-in IDF component - do NOT declare it here.
|
||||||
|
dependencies:
|
||||||
|
idf: ">=5.0"
|
||||||
|
abobija/rc522: "*"
|
||||||
|
joltwallet/littlefs: "*"
|
||||||
20
main/main.c
Normal file
20
main/main.c
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* MTG RFID Companion - Entry point
|
||||||
|
*
|
||||||
|
* Phase 1: Boot scaffold. Subsequent phases attach managers here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
static const char *TAG = "MAIN";
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
ESP_LOGI(TAG, "MTG RFID Companion booting...");
|
||||||
|
while (1) {
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
4
partitions.csv
Normal file
4
partitions.csv
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size
|
||||||
|
# 2MB factory (app) partition + 1.5MB LittleFS data partition on 4MB flash
|
||||||
|
factory, app, factory, 0x10000, 0x200000
|
||||||
|
storage, data, littlefs, 0x210000, 0x1F0000
|
||||||
|
6
sdkconfig.defaults
Normal file
6
sdkconfig.defaults
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# MTG RFID Companion - ESP32 SDK defaults
|
||||||
|
CONFIG_IDF_TARGET="esp32"
|
||||||
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
|
CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
|
||||||
Reference in New Issue
Block a user