Files
pico/projects/tzpuPico/esp32/main/include/ipc_protocol.h
Philip Smart 4196e58420 MZ-1500 persona, expansion boards, Celestite LAN, QDF format, virtual mode
New drivers:
- MZ-1500 persona driver with MZ-700/MZ-1500 mode switch, PCG bank switching,
  PSG stubs, physical I/O forwarding for virtual mode
- MZ-2200 persona driver (based on MZ-2000)
- MZ-1R23/MZ-1R24 Kanji ROM / Dictionary ROM board (B8h/B9h IDM)
- MZ-1R37 640KB EMM (ACh/ADh, no auto-increment, 20-bit addressing)
- PIO-3034 320KB EMM (configurable base, 19-bit, auto-increment)
- Celestite LAN/Memory composite board:
  - W5100 TCP/IP via ESP32 WiFi (connect, send, recv, ping)
  - Integrated MZ-1R12 32/64KB CMOS RAM with SD persistence
  - Integrated MZ-1R37 640KB EMM with SD persistence
  - UFM flash, unlock state machine, interrupt controller

Celestite networking (Phase 2):
- New IPC commands: NET_CFG, NET_SOCK, NET_SEND, NET_RECV, NET_PING
- ESP32 BSD socket handlers with non-blocking connect and recv
- Shared volatile struct for cross-core results (bypasses responseQueue)
- Inline IDM read check for socket status and recv data
- Z80 test programs: celestite_test.asm (17 tests), celestite_stress.asm (loop)

MZ-1500 virtual mode fixes:
- I/O writes forwarded to physical hardware (PSG, bank switching, PCG)
- E000-E7FF always stays physical during bank switching
- PCG bank (F000-FFFF) properly remapped to PHYSICAL when open

QDF format support:
- Japanese standard QD format auto-detected on load (81936 bytes)
- Hunt pattern changed to 00+16 (mark+sync) for inter-block gap handling
- Sync stripping handles long preambles (9+ bytes)
- MZQDTool updated with -j flag and format conversion

Other:
- Debug shell load command: len parameter now optional
- FSPI filename field: memcpy instead of strncpy for binary data
- Interface availability expanded across MZ-700/1500/80A/2000/2200
- Web GUI: param hints for Celestite, updated driver interface lists

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-17 11:34:55 +01:00

110 lines
6.5 KiB
C
Vendored

/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Name: ipc_protocol.h
// Created: Mar 2025
// Author(s): Philip Smart
// Description: Binary IPC frame protocol shared between RP2350 and ESP32.
// Commands and data are sent over SPI as packed binary frames.
// UART is retained only for firmware update paths and OOB commands.
// Copyright: (c) 2019-2026 Philip Smart <philip.smart@net2net.org>
//
// History: Mar 2025 v1.0 - Initial write.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef IPC_PROTOCOL_H_
#define IPC_PROTOCOL_H_
#include <stdint.h>
// ---------------------------------------------------------------------------
// Frame type field (t_IpcFrameHdr::frameType)
// ---------------------------------------------------------------------------
#define IPCF_TYPE_NOP 0x00 // No-operation / dummy TX during full-duplex read
#define IPCF_TYPE_COMMAND 0x01 // Command frame from RP2350 → ESP32
#define IPCF_TYPE_RESPONSE 0x02 // Response frame from ESP32 → RP2350
// ---------------------------------------------------------------------------
// Command opcodes (t_IpcFrameHdr::command)
// ---------------------------------------------------------------------------
#define IPCF_CMD_NOP 0x00 // No-operation
#define IPCF_CMD_RDS 0x01 // Read single 512-byte sector
#define IPCF_CMD_WRS 0x02 // Write single 512-byte sector
#define IPCF_CMD_RBURST 0x03 // Read burst: 1-16 sectors in one SPI transaction
#define IPCF_CMD_WBURST 0x04 // Write burst: 1-16 sectors in one SPI transaction
#define IPCF_CMD_RFILE 0x05 // Read whole file (chunked if > max payload)
#define IPCF_CMD_WFILE 0x06 // Write whole file
#define IPCF_CMD_INF 0x07 // Transfer RP2350 version/partition info to ESP32
#define IPCF_CMD_RFD 0x08 // Read floppy disk image file
#define IPCF_CMD_RQD 0x09 // Read quick-disk image file
#define IPCF_CMD_RRF 0x0A // Read RAM-file backup image
#define IPCF_CMD_DIR 0x0B // Read directory listing (returns text in payload)
// Network commands (Celestite W5100 emulation)
#define IPCF_CMD_NET_CFG 0x10 // Get ESP32 network config (IP, gateway, subnet, MAC)
#define IPCF_CMD_NET_SOCK 0x11 // Socket operation (open/connect/listen/close/discon)
#define IPCF_CMD_NET_SEND 0x12 // Send data to socket (payload = data to send)
#define IPCF_CMD_NET_RECV 0x13 // Receive data from socket (response payload = data)
#define IPCF_CMD_NET_PING 0x14 // ICMP echo request (ping)
// ---------------------------------------------------------------------------
// Status codes (t_IpcFrameHdr::status — response frames only)
// ---------------------------------------------------------------------------
#define IPCF_STATUS_OK 0x00 // Success
#define IPCF_STATUS_ERR 0x01 // Generic error
#define IPCF_STATUS_BUSY 0x02 // Resource busy
#define IPCF_STATUS_CRCFAIL 0x03 // CRC32 mismatch detected by receiver
#define IPCF_STATUS_NOTFOUND 0x04 // File or sector not found
#define IPCF_STATUS_PARTIAL 0x05 // Partial data — more chunks follow (file streaming)
// ---------------------------------------------------------------------------
// Flags field (t_IpcFrameHdr::flags)
// ---------------------------------------------------------------------------
#define IPCF_FLAG_LAST_CHUNK 0x01 // This is the last chunk of a multi-chunk file transfer
#define IPCF_FLAG_MORE_DATA 0x02 // More data chunks follow
// ---------------------------------------------------------------------------
// Frame sizing constants
// ---------------------------------------------------------------------------
#define IPCF_HEADER_SIZE 64 // Fixed header size — must stay 64 bytes
#define IPCF_MAX_SECTORS 16 // Maximum sectors per burst command
#define IPCF_SECTOR_SIZE 512 // Bytes per sector
#define IPCF_CRC_SIZE 4 // CRC32 trailer (bytes)
#define IPCF_FILENAME_LEN 48 // Max filename length including path + null
#define IPCF_MAX_PAYLOAD (IPCF_MAX_SECTORS * IPCF_SECTOR_SIZE) // 8192 bytes
#define IPCF_MAX_FRAME_SIZE (IPCF_HEADER_SIZE + IPCF_MAX_PAYLOAD + IPCF_CRC_SIZE) // 8260 bytes
// ---------------------------------------------------------------------------
// IPC frame header — 64 bytes packed, shared by command and response frames.
// Byte offsets must stay stable; add fields only in the reserved area.
// Both RP2350 (arm-none-eabi-gcc) and ESP32 (xtensa-esp32-elf-gcc) support
// __attribute__((packed)).
// ---------------------------------------------------------------------------
typedef struct __attribute__((packed))
{
uint8_t frameType; // 0: IPCF_TYPE_*
uint8_t command; // 1: IPCF_CMD_*
uint8_t status; // 2: IPCF_STATUS_* (response) / 0 (command)
uint8_t seqNum; // 3: Sequence number — used for retry detection
uint16_t payloadLen; // 4: Bytes of payload that follow the header (LE)
uint16_t sectorCount; // 6: Sectors in burst (command) or returned (response)
uint32_t fileOffset; // 8: Byte offset in file (sector-read / write position)
uint8_t diskNo; // 12: Drive number for floppy / QD commands
uint8_t flags; // 13: IPCF_FLAG_*
uint16_t reserved; // 14: Reserved — keep zero
char filename[IPCF_FILENAME_LEN]; // 16: Null-terminated path/filename
// Total: 16 + 48 = 64 bytes exactly
} t_IpcFrameHdr;
#endif // IPC_PROTOCOL_H_