initial commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
.cache/
|
||||||
Vendored
+8
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"cmake.generator": "Ninja",
|
||||||
|
"cmake.buildDirectory": "${workspaceFolder}/build",
|
||||||
|
"cmake.configureOnOpen": true,
|
||||||
|
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
|
||||||
|
|
||||||
|
"cmake.cmakePath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Common7\\IDE\\CommonExtensions\\Microsoft\\CMake\\CMake\\bin\\cmake.exe"
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
# Nova64 Cartridge Pinout Overview
|
||||||
|
|
||||||
|
This document provides a compact, high-level technical view of the Nova64 cartridge connector from the cartridge developer perspective.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
A concise 32-pin cartridge interface for expansion modules, storage, I/O, and optional power delivery.
|
||||||
|
|
||||||
|
## Connector Goals
|
||||||
|
|
||||||
|
- single edge connector for compact form factor
|
||||||
|
- separate power, data, and control signals
|
||||||
|
- support for smart cartridges and passive media
|
||||||
|
- keep SDMMC always available for cartridge-level storage access
|
||||||
|
- leave space for future expansion without extra pins
|
||||||
|
- describe pin numbering and signal roles from the cartridge edge view
|
||||||
|
|
||||||
|
## 32-Pin Layout
|
||||||
|
|
||||||
|
| Pin | Signal | Role | Default idle state |
|
||||||
|
| --: | ------------- | --------------------------------------- | ------------------ |
|
||||||
|
| 1 | GND | ground | grounded |
|
||||||
|
| 2 | VCC_3V3 | supply | N/A |
|
||||||
|
| 3 | CARTRIDGE_DET | cartridge presence detect | pull-up |
|
||||||
|
| 4 | POWER_CTRL | power direction control | pull-down |
|
||||||
|
| 5 | USB_FLAG | USB-capable flag | pull-up |
|
||||||
|
| 6 | USB_DP | USB D+ | pull-down |
|
||||||
|
| 7 | USB_DM | USB D- | pull-down |
|
||||||
|
| 8 | USB_ID | USB host/device mode | pull-up |
|
||||||
|
| 9 | USB_VBUS | VBUS sense / optional power | pull-down |
|
||||||
|
| 10 | SD_CMD | SDMMC command / host->cartridge control | pull-up |
|
||||||
|
| 11 | SD_CLK | SDMMC clock / host->cartridge | pull-down |
|
||||||
|
| 12 | SD_D0 | SDMMC data0 (bi-directional) | pull-up |
|
||||||
|
| 13 | SD_D1 | SDMMC data1 (bi-directional) | pull-up |
|
||||||
|
| 14 | SD_D2 | SDMMC data2 (bi-directional) | pull-up |
|
||||||
|
| 15 | SD_D3 | SDMMC data3 (bi-directional) | pull-up |
|
||||||
|
| 16 | I2C_SCL | I2C clock | pull-up |
|
||||||
|
| 17 | I2C_SDA | I2C data | pull-up |
|
||||||
|
| 18 | I2S_SCLK | I2S bit clock | pull-down |
|
||||||
|
| 19 | I2S_WS | I2S word select / frame clock | pull-down |
|
||||||
|
| 20 | I2S_SDOUT | I2S data out (cartridge->host) | pull-down |
|
||||||
|
| 21 | I2S_SDIN | I2S data in (host->cartridge) | pull-down |
|
||||||
|
| 22 | I2S_MCLK | I2S master clock | pull-down |
|
||||||
|
| 23 | SPI_MOSI | SPI MOSI (host->cartridge) | pull-down |
|
||||||
|
| 24 | SPI_MISO | SPI MISO (cartridge->host) | pull-down |
|
||||||
|
| 25 | SPI_SCLK | SPI clock (host->cartridge) | pull-down |
|
||||||
|
| 26 | SPI_CS0 | SPI chip select (host->cartridge) | pull-down |
|
||||||
|
| 27 | CAN_H | CAN high | recessive bias |
|
||||||
|
| 28 | CAN_L | CAN low | recessive bias |
|
||||||
|
| 29 | UART_RX | UART RX (host->cartridge) | pull-up |
|
||||||
|
| 30 | UART_TX | UART TX (cartridge->host) | pull-up |
|
||||||
|
| 31 | VCC_5V | supply | N/A |
|
||||||
|
| 32 | GND | ground | grounded |
|
||||||
|
|
||||||
|
## Signal Groups
|
||||||
|
|
||||||
|
- Ground: pins 1, 32
|
||||||
|
- 3.3V supply: pin 2
|
||||||
|
- Cartridge detection: pin 3
|
||||||
|
- Power direction: pin 4
|
||||||
|
- USB flag: pin 5
|
||||||
|
- USB: pins 6-9
|
||||||
|
- SDMMC: pins 10-15
|
||||||
|
- I2C: pins 16-17
|
||||||
|
- I2S audio: pins 18-22
|
||||||
|
- SPI: pins 23-26
|
||||||
|
- CAN: pins 27-28
|
||||||
|
- UART: pins 29-30
|
||||||
|
- 5V supply: pin 31
|
||||||
|
|
||||||
|
## Design Rationale
|
||||||
|
|
||||||
|
- Keep storage and interface signals separate from power.
|
||||||
|
- Reserve the SDMMC channel so cartridges can provide their own software/data layer.
|
||||||
|
- Include USB and serial buses for smart module support.
|
||||||
|
- Use a dedicated ID input for simple cartridge recognition.
|
||||||
|
- Provide optional audio and GPIO for versatile cartridge types.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- This is a high-level connector map, not a full electrical specification.
|
||||||
|
- Exact pin assignments may be refined later during hardware design.
|
||||||
|
- Preferred placement for pull-ups / pull-downs is the main device, with cartridge-side resistors only used for optional or cartridge-specific functions.
|
||||||
|
- Cartridge presence should be detected via a dedicated `CARTRIDGE_DET` pin, not by ORing multiple ID signals.
|
||||||
|
- Cartridge features such as SD/storage, I2C, SPI, CAN, UART and audio should be discovered dynamically at runtime after insertion.
|
||||||
|
- For bidirectional power delivery, the system should use a dedicated power-path controller and a clear source priority scheme.
|
||||||
|
- Monitor main device and cartridge voltage presence before enabling any power path.
|
||||||
|
- Use POWER_CTRL as a control input for a power-path switch or enable pin, not as a current-carrying line.
|
||||||
|
- If the main device is powered and the cartridge is not actively supplying power, keep cartridge supply disabled.
|
||||||
|
- If the main device is unpowered and a powered cartridge is inserted, allow the cartridge to supply the system after voltage stability is confirmed.
|
||||||
|
- Prevent backfeed by using ideal diodes or bidirectional power-path ICs that only conduct from the active source.
|
||||||
|
|
||||||
|
Suggested cartridge categories:
|
||||||
|
|
||||||
|
| Category | Meaning |
|
||||||
|
| ----------------: | ------------------------------------------------------------- |
|
||||||
|
| software only | cartridge provides software/application data only |
|
||||||
|
| special hardware | cartridge includes additional hardware functions |
|
||||||
|
| dynamic detection | actual capabilities are determined at runtime after insertion |
|
||||||
|
|
||||||
|
USB_FLAG = 1 indicates the cartridge can present USB functionality in addition to its category.
|
||||||
|
|
||||||
|
POWER_CTRL = 1 indicates the cartridge provides power to the main device
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
A short technical reference for the Nova64 cartridge connector, intended for initial design discussion.
|
||||||
+105
@@ -0,0 +1,105 @@
|
|||||||
|
file(GLOB_RECURSE CORE_SOURCES CONFIGURE_DEPENDS "src/*.c")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(ESP_PLATFORM)
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# 1. ESP-IDF BUILD MODE (Target: ESP32-P4)
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
message(STATUS "[Nova64] Building as ESP-IDF Component for ESP32...")
|
||||||
|
|
||||||
|
idf_component_register(
|
||||||
|
SRCS
|
||||||
|
${CORE_SOURCES}
|
||||||
|
INCLUDE_DIRS
|
||||||
|
"include"
|
||||||
|
REQUIRES
|
||||||
|
freertos
|
||||||
|
wamr
|
||||||
|
)
|
||||||
|
|
||||||
|
else()
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# 2. DESKTOP BUILD MODE (Target: Windows .dll / Linux .so / macOS .dylib)
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(nova64_core VERSION 1.0.0 LANGUAGES C)
|
||||||
|
|
||||||
|
message(STATUS "[Nova64] Building Desktop Shared Library...")
|
||||||
|
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# FreeRTOS Configuration
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
add_library(freertos_config INTERFACE)
|
||||||
|
|
||||||
|
target_include_directories(freertos_config SYSTEM
|
||||||
|
INTERFACE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(freertos_config
|
||||||
|
INTERFACE
|
||||||
|
projCOVERAGE_TEST=0
|
||||||
|
)
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# FreeRTOS Kernel via FetchContent
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
# Download FreeRTOS-Kernel Repository
|
||||||
|
FetchContent_Declare(
|
||||||
|
FreeRTOS_Kernel
|
||||||
|
GIT_REPOSITORY https://github.com/FreeRTOS/FreeRTOS-Kernel.git
|
||||||
|
GIT_TAG V11.3.0
|
||||||
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(FREERTOS_PORT "MSVC_MINGW" CACHE STRING "")
|
||||||
|
else()
|
||||||
|
set(FREERTOS_PORT "GCC/POSIX" CACHE STRING "")
|
||||||
|
endif()
|
||||||
|
# Select FreeRTOS heap implementation (provides pvPortMalloc/vPortFree)
|
||||||
|
set(FREERTOS_HEAP 4 CACHE STRING "FreeRTOS Heap Implementation")
|
||||||
|
# Disable FreeRTOS Demos/Tests
|
||||||
|
set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
# define Target 'freertos_kernel'
|
||||||
|
FetchContent_MakeAvailable(FreeRTOS_Kernel)
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Nova64 Core Target
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Shared Library (.dll / .so / .dylib)
|
||||||
|
add_library(nova64_core SHARED ${CORE_SOURCES})
|
||||||
|
|
||||||
|
target_include_directories(nova64_core PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
|
)
|
||||||
|
|
||||||
|
# Link FreeRTOS Kernel to the nova64_core library
|
||||||
|
target_link_libraries(nova64_core PRIVATE freertos_kernel freertos_config)
|
||||||
|
|
||||||
|
target_compile_definitions(nova64_core PRIVATE NOVA64_EXPORTS)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set_target_properties(nova64_core PROPERTIES
|
||||||
|
C_VISIBILITY_PRESET hidden
|
||||||
|
VISIBILITY_INLINES_HIDDEN YES
|
||||||
|
PREFIX ""
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set_target_properties(nova64_core PROPERTIES
|
||||||
|
C_VISIBILITY_PRESET hidden
|
||||||
|
VISIBILITY_INLINES_HIDDEN YES
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
endif()
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# Nova64 Cyberdeck Platform - High-Level System Specification
|
||||||
|
|
||||||
|
## 1. System Overview & Core Concept
|
||||||
|
* **Project Name:** Nova64
|
||||||
|
* **Architecture Model:** Dual-target modular system featuring a native execution core (`nova64_core`) running on top of **FreeRTOS**.
|
||||||
|
* **Target Microcontroller:** **ESP32-P4** (RISC-V architecture) driving local display output, audio generation, custom expansion bus, and network interfaces.
|
||||||
|
* **Desktop Simulator / Tooling:** Native C core compiled as a shared library (`.dll` / `.so`) and driven by a **C# Host Application** via P/Invoke. Hardware dependencies are injected at runtime via function pointer callbacks (Dependency Injection pattern).
|
||||||
|
* **Central Unit Input Constraint:** The base display unit **contains no (or only limited) built-in physical input controls** (no onboard buttons or D-pad). Control inputs are provided externally via connected cartridges, expansion modules, network interfaces, or desktop simulator inputs.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Physical Cartridge & Expansion Slot Architecture
|
||||||
|
* **Mechanical Interface:** Uses a 32-pin edge-connector format (Game Boy style form factor, required PCB thickness: 1.2 mm).
|
||||||
|
* **Poka-Yoke Protection:** Custom mechanical keying (notches/grooves) to physically prevent legacy/original Game Boy cartridges from being inserted and damaging the 3.3V logic lines.
|
||||||
|
* **Bus Protocols & Interfaces:**
|
||||||
|
* **SD Card Interface (SDMMC):** Dedicated high-speed lines. *Rule: SD pins must remain allocated and accessible across all slot modes. This allows loading custom cartridge software for specialized cartridges.*
|
||||||
|
* **USB:** Native USB Host / Device capability for smart cartridges or peripherals.
|
||||||
|
* **I2C, SPI & CAN-Bus:** Serial buses for sensors, co-processors, and expanders.
|
||||||
|
* **Cartridge pinout reference:** Detailed connector numbering, signal roles, and idle states are defined in [CARTRIDGE_PINOUT.md](./CARTRIDGE_PINOUT.md) to keep this document as the single high-level system spec.
|
||||||
|
* **Power Bus:** Supports dual-directional power delivery (supplying power to cartridges or receiving alternative system power/charging from external battery cartridges).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Networking Interface (10BASE-T1L)
|
||||||
|
* **Protocol:** **10BASE-T1L** (Single-Pair Ethernet) for long-distance, industrial-grade point-to-point and networked communication between decks/modules.
|
||||||
|
* **Physical Cabling:** routed through **audio-style connectors/cables** (e.g., 3.5mm/6.3mm jacks) to fit the cyberpunk aesthetic while maintaining robust single-pair data transmission.
|
||||||
|
* **Audio Use:** the same 10BASE-T1L connector is also intended to carry analog audio signals in some modes, requiring dedicated isolation and protection circuitry to separate audio from data and to protect the network interface.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. WASM Application Runtime (WAMR)
|
||||||
|
* **Runtime Engine:** **WAMR (WebAssembly Micro Runtime)** embedded directly into `nova64_core`.
|
||||||
|
* **Execution Model:** Sandboxed application layer for dynamic software, games, and cartridge binaries.
|
||||||
|
* **Cross-Platform Parity:** Uncompiled WASM bytecode runs identically on both the physical ESP32-P4 hardware and the C# Desktop Simulator.
|
||||||
|
* **Host Bindings:** WAMR exports host functions bound to the internal `nova64_core` APIs, allowing sandboxed WASM applications to draw to the framebuffer, play audio, and read cartridge storage safely.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Software HAL & FreeRTOS Architecture
|
||||||
|
* **Hardware Abstraction (I/O Callbacks):**
|
||||||
|
* Core engine defines function pointer contracts: `display_flush`, `audio_output`, `sd_read_sector`, and `cartridge_status` (with `slot_idx` support for multi-slot setups).
|
||||||
|
* System initialized via `nova64_init_io()`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Display, Framebuffer & Core Allocation Strategy
|
||||||
|
* **Dual-Core Processor Allocation (ESP32-P4):**
|
||||||
|
* **Core 0 (System & I/O Core):** Handles background FreeRTOS tasks, hardware drivers, 10BASE-T1L networking stack, audio generation, and system status bar overlays.
|
||||||
|
* **Core 1 (Execution Core):** Exclusively dedicated to running the WAMR WebAssembly engine and application code, guaranteeing deterministic performance and preventing OS tasks from causing frame drops.
|
||||||
|
* **Framebuffer Architecture:**
|
||||||
|
* Uses double-buffering (RGB565 format) to prevent screen tearing during active rendering.
|
||||||
|
* Framebuffers are explicitly allocated in **External PSRAM via the AXI bus**, enabling direct DMA (Direct Memory Access) streaming to the MIPI-DSI controller without CPU overhead.
|
||||||
|
* Application output and system UI are composited into the target buffer before triggering the host-injected `display_flush` callback (or VSYNC pointer swap).
|
||||||
|
* **Persistent System Status Bar:**
|
||||||
|
* A reserved hardware/system UI region at the top of the display rendered independently by Core 0.
|
||||||
|
* Displays active cartridge ID, 10BASE-T1L link status, battery levels, and system health metrics without interfering with running WASM applications.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/* Desktop Simulator Settings */
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configUSE_IDLE_HOOK 1
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||||
|
#define configMAX_PRIORITIES ( 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 64 * 1024 ) )
|
||||||
|
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||||
|
#define configUSE_TRACE_FACILITY 0
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
|
||||||
|
/* Synchronisation Objects */
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configUSE_QUEUE_SETS 1
|
||||||
|
|
||||||
|
/* Memory Management */
|
||||||
|
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||||
|
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||||
|
|
||||||
|
/* Disable API Functions */
|
||||||
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
|
#define INCLUDE_vTaskDelete 1
|
||||||
|
#define INCLUDE_vTaskCleanUpResources 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
|
||||||
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
#ifndef NOVA64_CORE_H
|
||||||
|
#define NOVA64_CORE_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Cross-platform DLL export/import visibility macros
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
#ifdef NOVA64_EXPORTS
|
||||||
|
#define NOVA64_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define NOVA64_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __GNUC__ >= 4
|
||||||
|
#define NOVA64_API __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define NOVA64_API
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* I/O Callback Typedefs */
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback to flush a frame buffer to the display.
|
||||||
|
* @param buffer Pointer to raw pixel data (e.g., RGB565 / RGBA8888).
|
||||||
|
* @param width Frame width in pixels.
|
||||||
|
* @param height Frame height in pixels.
|
||||||
|
*/
|
||||||
|
typedef void (*nova64_display_flush_cb_t)(const uint16_t *buffer,
|
||||||
|
uint16_t width, uint16_t height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback to output audio samples.
|
||||||
|
* @param samples Pointer to PCM audio sample buffer.
|
||||||
|
* @param count Number of samples in the buffer.
|
||||||
|
*/
|
||||||
|
typedef void (*nova64_audio_output_cb_t)(const int16_t *samples,
|
||||||
|
uint32_t count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback to read sectors from the SD card.
|
||||||
|
* @param sector_idx The zero-based sector index to read.
|
||||||
|
* @param destination_buffer Pointer to memory where sector data should be
|
||||||
|
* copied.
|
||||||
|
* @param sector_count Number of 512-byte sectors to read.
|
||||||
|
* @return True on success, false on read error.
|
||||||
|
*/
|
||||||
|
typedef bool (*nova64_sd_read_sector_cb_t)(uint32_t sector_idx,
|
||||||
|
uint8_t *destination_buffer,
|
||||||
|
uint32_t sector_count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback triggered when a cartridge state change occurs (e.g.
|
||||||
|
* inserted/removed).
|
||||||
|
* @param slot_idx Zero-based cartridge slot index.
|
||||||
|
* @param is_inserted True if a cartridge is detected, false if ejected.
|
||||||
|
*/
|
||||||
|
typedef void (*nova64_cartridge_status_cb_t)(uint32_t slot_idx,
|
||||||
|
bool is_inserted);
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* I/O Interface Configuration Struct */
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Struct containing all I/O hardware abstraction callbacks.
|
||||||
|
* Pass NULL for any unneeded callback.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
nova64_display_flush_cb_t display_flush;
|
||||||
|
nova64_audio_output_cb_t audio_output;
|
||||||
|
nova64_sd_read_sector_cb_t sd_read_sector;
|
||||||
|
nova64_cartridge_status_cb_t cartridge_status;
|
||||||
|
} nova64_io_interface_t;
|
||||||
|
|
||||||
|
/* ========================================================================== */
|
||||||
|
/* Engine Core API */
|
||||||
|
/* ========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the core engine and registers host I/O interface
|
||||||
|
* callbacks.
|
||||||
|
* @param io_interface Pointer to filled struct containing I/O function
|
||||||
|
* pointers.
|
||||||
|
* @return True if initialized successfully, false if already initialized or
|
||||||
|
* invalid.
|
||||||
|
*/
|
||||||
|
NOVA64_API bool nova64_init_io(const nova64_io_interface_t *io_interface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Executes one engine processing tick.
|
||||||
|
* @param delta_ms Elapsed time in milliseconds since the last tick.
|
||||||
|
* @return 0 on success, negative error code on failure.
|
||||||
|
*/
|
||||||
|
NOVA64_API int32_t nova64_process_tick(uint32_t delta_ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves the engine version integer.
|
||||||
|
* @return 24-bit packed version number (0xMMmmPP -> Major, Minor, Patch).
|
||||||
|
*/
|
||||||
|
NOVA64_API uint32_t nova64_get_version(void);
|
||||||
|
|
||||||
|
#endif // NOVA64_CORE_H
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#include "nova64_core.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined(ESP_PLATFORM)
|
||||||
|
/* ESP32-spezifische Header für Low-Power & Watchdog */
|
||||||
|
#include "esp_pm.h"
|
||||||
|
#include "esp_rom_sys.h"
|
||||||
|
#include "esp_task_wdt.h"
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
/* Windows API für Schlafen im Desktop-Thread */
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
/* POSIX / Linux / macOS Sleep */
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool is_initialized = false;
|
||||||
|
static QueueHandle_t event_queue = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
NOVA64_API bool nova64_init_io(const nova64_io_interface_t *io_interface) {
|
||||||
|
printf("[Nova64 Core] System Initializing...\n");
|
||||||
|
|
||||||
|
event_queue = xQueueCreate(10, sizeof(uint32_t));
|
||||||
|
|
||||||
|
is_initialized = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NOVA64_API int32_t nova64_process_tick(uint32_t delta_ms) {
|
||||||
|
if (!is_initialized)
|
||||||
|
return -1;
|
||||||
|
// Core Game-Logic & State Machine Ticks
|
||||||
|
return 0; // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
NOVA64_API uint32_t nova64_get_version(void) {
|
||||||
|
return 0x010000; // v1.0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FreeRTOS hook: called by the kernel when the idle task runs.
|
||||||
|
* Required because configUSE_IDLE_HOOK is enabled in FreeRTOSConfig.h
|
||||||
|
*/
|
||||||
|
void vApplicationIdleHook(void) {
|
||||||
|
#if defined(ESP_PLATFORM)
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// ESP32-specific idle hook code
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
#if CONFIG_ESP_TASK_WDT
|
||||||
|
// Feed the watchdog to prevent reset
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
#endif
|
||||||
|
asm volatile("wfi"); // Wait for interrupt to save power
|
||||||
|
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Windows-specific idle hook code
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
Sleep(1); // Sleep for 1 millisecond to yield CPU
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// POSIX-specific idle hook code
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
struct timespec ts = {0, 1000000}; // 1 millisecond
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user