SummerCart64/docs/03_usb_interface.md
Mateusz Faderewski 421d0438f3
[SC64][FW][SW] Controller rewrite to remove task subsystem + minor bug fixes (#64)
This PR completely removes `task.c / task.h` from `sw/controller` STM32
code.
Additionally, these changes were implemented:
- Updated IPL3
- Added new diagnostic data (voltage and temperature) readout commands
for USB and N64
- Fixed some issues with FlashRAM save type
- Joybus timings were relaxed to accommodate communication with
unsynchronized master controller (like _Datel Game Killer_, thanks
@RWeick)
- N64 embedded test program now waits for release of button press to
proceed
- Fixed issue where, in rare circumstances, I2C peripheral in STM32
would get locked-up on power-up
- LED blinking behavior on SD card access was changed
- LED blink duration on save writeback has been extended
- Minor fixes through the entire of hardware abstraction layer for STM32
code
- Primer now correctly detects issues with I2C bus during first time
programming
- `primer.py` script gives more meaningful error messages
- Fixed bug where RTC time was always written on N64FlashcartMenu boot
- sc64deployer now displays "Diagnostic data" instead of "MCU stack
usage"
2024-01-29 14:23:18 +01:00

25 KiB


Protocol

SC64 exposes itself in the system as a simple serial device. This allows it to work without manually installed drivers. Serial communication is also well supported in almost all programming languages making it easy to work with. USB protocol use simple packet based communication. Every packet starts with 3 byte identifier and 1 byte data ID. Every argument/data is sent as big-endian value.

Resetting communication

Due to serial communication nature, data transfer between PC and flashcart might get out of sync (for example when long data transfer is aborted before sending/receiving all bytes). Communication reset is done via emulated DTR/DSR pins. Start reset procedure by setting DTR pin value to high (1). Next, observe DSR pin until its state is set to high (1). At this point communication has been reset and USB interface is disabled. Now it is a good moment to clear/purge any buffers. Finish reset procedure by setting DTR pin value to low (0) and observe DSR pin until its state is set to low (0). Flashcart should be ready to accept new commands.

PC -> SC64 packets

identifier description
CMD Send command to the SC64

SC64 understands only one packet identifier - CMD. Fourth byte denotes command ID listed in supported commands section.

CMD packet

General structure of packet:

offset type description
0 char[3] CMD identifier
3 char[1] Command ID
4 uint32_t First argument (arg0)
8 uint32_t Second argument (arg1)
12 uint8_t[data_length] Command data (if required)

CMD packet always require arguments to be sent even if command does not require them. Packet data length is derived from the argument if specific command supports it.

SC64 -> PC packets

identifier description
RSP Success response to the received command
ERR Error response to the received command
PKT Asynchronous data packet

SC64 sends response packet RSP/ERR to almost every command received from the PC. Fourth byte is the same as in the command that triggered the response. If command execution was not successful, then RSP identifier is replaced by the ERR identifier.

SC64 can also send PKT packet at any time as a response to action triggered by the N64 or the flashcart itself. Fourth byte denotes packet ID listed in the asynchronous packets section.

RSP/ERR packets

General structure of packet:

offset type description
0 char[3] RSP/ERR identifier
3 char[1] Command ID
4 uint32_t Response data length
8 uint8_t[data_length] Response data (if any)

RSP/ERR packet is sent as a response to the command sent by the PC. ERR response might contain no (or undefined) data in the arbitrary data field compared to regular RSP packet.

PKT packet

General structure of packet:

offset type description
0 char[3] PKT identifier
3 char[1] Packet ID
4 uint32_t Packet data length
8 uint8_t[data_length] Packet data (if any)

Available packet IDs are listed in the asynchronous packets section.


Supported commands

id name arg0 arg1 data response description
v IDENTIFIER_GET --- --- --- identifier Get flashcart identifier SCv2
V VERSION_GET --- --- --- version Get flashcart firmware version
R STATE_RESET --- --- --- --- Reset flashcart state (CIC params and config options)
B CIC_PARAMS_SET cic_params_0 cic_params_1 --- --- Set CIC emulation parameters (disable/seed/checksum)
c CONFIG_GET config_id --- --- config_value Get config option
C CONFIG_SET config_id config_value --- --- Set config option
a SETTING_GET setting_id --- --- setting_value Get persistent setting option
A SETTING_SET setting_id setting_value --- --- Set persistent setting option
t TIME_GET --- --- --- time Get current RTC value
T TIME_SET time_0 time_1 --- --- Set new RTC value
m MEMORY_READ address length --- data Read data from specified memory address
M MEMORY_WRITE address length data --- Write data to specified memory address
U USB_WRITE type length data N/A Send data to be received by app running on N64 (no response!)
D DD_SET_BLOCK_READY error --- --- --- Notify flashcart about 64DD block readiness
W WRITEBACK_ENABLE --- --- --- --- Enable save writeback through USB packet
p FLASH_WAIT_BUSY wait --- --- erase_block_size Wait until flash ready / Get flash block erase size
P FLASH_ERASE_BLOCK address --- --- --- Start flash block erase
f FIRMWARE_BACKUP address --- --- status/length Backup firmware to specified memory address
F FIRMWARE_UPDATE address length --- status Update firmware from specified memory address
? DEBUG_GET --- --- --- debug_data Get internal FPGA debug info
% DIAGNOSTIC_GET --- --- --- diagnostic_data Get diagnostic data

v: IDENTIFIER_GET

Get flashcart identifier SCv2

This command does not require arguments or data.

response (identifier)

offset type description
0 char[4] Identifier

Identifier is always SCv2 represented in ASCII code.


V: VERSION_GET

Get flashcart firmware version

This command does not require arguments or data.

response (version)

offset type description
0 uint16_t Major version
2 uint16_t Minor version
4 uint32_t Revision

Increment in major version represents breaking API changes.

Increment in minor version represents non breaking API changes.

Increment in revision field represents no API changes, usually it's denoting bugfixes.


R: STATE_RESET

Reset flashcart state (CIC params and config options)

This command does not require arguments or data.

This command does not send response data.

This command is used to reset most of the config options to default state (same as on power-up). Additionally, CIC emulation is enabled and 6102/7101 seed/checksum values are set.


B: CIC_PARAMS_SET

Set CIC emulation parameters (disable/seed/checksum)

arg0 (cic_params_0)

bits description
[32:25] Unused
[24] Disable CIC
[23:16] CIC seed (IPL2 and IPL3 stages)
[15:0] Checksum (upper 16 bits)

arg1 (cic_params_1)

bits description
[31:0] Checksum (lower 32 bits)

This command does not send response data.

Use this command to set custom seed/checksum CIC values. Very useful for testing custom IPL3 replacements.


c: CONFIG_GET

Get config option

arg0 (config_id)

bits description
[31:0] Config ID

response (config_value)

offset type description
0 uint32_t Config value

Use this command to get value of config option. Available config options are listed here.


C: CONFIG_SET

Set config option

arg0 (config_id)

bits description
[31:0] Config ID

arg1 (config_value)

bits description
[31:0] Config value

This command does not send response data.

Use this command to set value of config option. Available config options are listed here.


a: SETTING_GET

Get persistent setting option

arg0 (setting_id)

bits description
[31:0] Setting ID

response (setting_value)

offset type description
0 uint32_t Setting value

Use this command to get value of persistent setting option. Available persistent setting options are listed here.


A: SETTING_SET

Set persistent setting option

arg0 (setting_id)

bits description
[31:0] Setting ID

arg1 (setting_value)

bits description
[31:0] Setting value

This command does not send response data.

Use this command to set value of persistent setting option. Available persistent setting options are listed here.


t: TIME_GET

Get current RTC value

This command does not require arguments or data.

response (time)

offset type description
0 uint8_t Weekday (1 - 7), 1 represents Monday
1 uint8_t Hours (0 - 23)
2 uint8_t Minutes (0 - 59)
3 uint8_t Seconds (0 - 59)
4 uint8_t Unused (returns zero)
5 uint8_t Year (0 - 99)
6 uint8_t Month (1 - 12)
7 uint8_t Day (1 - 31)

Date/time values use the BCD format.


T: TIME_SET

Set new RTC value

arg0 (time_0)

bits description
[31:24] Weekday (1 - 7), 1 represents Monday
[23:16] Hours (0 - 23)
[15:8] Minutes (0 - 59)
[7:0] Seconds (0 - 59)

arg1 (time_1)

bits description
[31:24] Unused
[23:16] Year (0 - 99)
[15:8] Month (1 - 12)
[7:0] Day (1 - 31)

This command does not send response data.

Date/time values use the BCD format.


m: MEMORY_READ

Read data from specified memory address

arg0 (address)

bits description
[31:0] Starting memory address

arg1 (length)

bits description
[31:0] Number of bytes to read from the memory

response (data)

offset type description
0 uint8_t[length] Memory contents

Reads bytes from the specified memory address. Please refer to the internal memory map for available memory ranges.


M: MEMORY_WRITE

Write data to specified memory address

arg0 (address)

bits description
[31:0] Starting memory address

arg1 (length)

bits description
[31:0] Number of bytes to write to the memory

data (data)

offset type description
0 uint8_t[length] Data to write to the memory

This command does not send response data.

Writes bytes to the specified memory address. Please refer to the internal memory map for available memory ranges.


U: USB_WRITE

Send data to be received by app running on N64 (no response!)

arg0 (type)

bits description
[31:8] Unused
[7:0] Datatype

arg1 (length)

bits description
[31:0] Data length

data (data)

offset type description
0 uint8_t[length] Arbitrary data

This command does not send response data.

This command does not send RSP/ERR packet response!

This command notifies N64 that data is waiting to be acknowledged. If N64 side doesn't acknowledge data via m USB_READ N64 command within 1 second then data is flushed and G DATA_FLUSHED asynchronous packet is sent to the PC. If N64 acknowledge the request, then data is written to the flashcart memory to address specified in m USB_READ N64 command.


D: DD_SET_BLOCK_READY

Notify flashcart about 64DD block readiness

arg0 (error)

bits description
[31:1] Unused
[0] 0 - Success, 1 - Error

This command does not send response data.

This command informs SC64 that 64DD disk block data was successfully (or not) read to the requested buffer or written to the 64DD disk file. This command must be sent for each incoming DISK_REQUEST asynchronous packet.


W: WRITEBACK_ENABLE

Enable save writeback through USB packet

This command does not require arguments or data.

This command does not send response data.

This command is used to enable save writeback module and set its mode to send data to the USB interface instead of writing to the SD card. To disable save writeback change save type via SAVE_TYPE config option (setting the same save type as currently enabled will also disable writeback module). Save data is sent via SAVE_WRITEBACK asynchronous packet.


Asynchronous packets

id name data description
B BUTTON --- Button on the back of the SC64 was pressed
U DATA data Data sent from the N64
G DATA_FLUSHED --- Data from U USB_WRITE USB command was discarded
D DISK_REQUEST disk_info/block_data 64DD disk block R/W request
I IS_VIEWER_64 text IS-Viewer 64 printf text
S SAVE_WRITEBACK save_contents Flushed save data
F UPDATE_STATUS progress Firmware update progress

B: BUTTON

Button on the back of the SC64 was pressed

This packet is sent only when BUTTON_MODE config option is set to value "2 - Button press sends USB packet".

This packet does not send additional data.


U: DATA

Data sent from the N64

This packet is sent when N64 command USB_WRITE is executed.

data (data)

offset type description
0 uint8_t Datatype
1 uint24_t Data length
4 uint8_t[data_length] Packet data

G: DATA_FLUSHED

Data from U USB_WRITE USB command was discarded

This packet is sent only when data sent with USB command U USB_WRITE was not acknowledged by the N64 side with m USB_READ within 1 second time limit.

This packet does not send additional data.


D: DISK_REQUEST

64DD disk block R/W request

This packet is sent when 64DD mode is set to pass R/W requests to the USB interface with DD_SD_ENABLE config option. Every disk request packet must be acknowledged by the PC side with D DD_SET_BLOCK_READY USB command.

data (disk_info/block_data)

offset type description
0 uint32_t Disk command
4 uint32_t Memory address
8 uint32_t Disk track/head/block
12 uint8_t[packet_length - 12] Data to be written to the 64DD disk block (optional)

Fields details

Disk command:

value description
1 Read data from 64DD disk block
2 Write data to 64DD disk block

Memory address:

Internal SC64 address where data is expected to be written for read command

Disk track/head/block:

bits description
[31:13] Unused
[12:2] Track
[1] Head
[0] Block

I: IS_VIEWER_64

IS-Viewer 64 printf text

This packet is sent when IS-Viewer 64 module is enabled in the SC64 with ISV_ADDRESS config option, and data is written to the IS-Viewer 64 buffer.

data (text)

offset type description
0 uint8_t[packet_length] Text

S: SAVE_WRITEBACK

Flushed save data

This packet is sent when save writeback module is enabled and set to send data to the USB interface with W WRITEBACK_ENABLE USB command. Save data is flushed after 1 second delay from the last write to the save region by the app/game running on the N64.

data (save_contents)

offset type description
0 uint32_t Save type (same as in SAVE_TYPE config option)
4 uint8_t[packet_length - 4] Save data

F: UPDATE_STATUS

Firmware update progress

This packet is sent during firmware update process to indicate progress and errors.

data (progress)

offset type description
0 uint32_t Progress

Fields details

Progress:

value description
1 Update process has started flashing MCU software
2 Update process has started flashing FPGA firmware
3 Update process has started flashing bootloader software
0x80 Firmware update process was successful
0xFF Error encountered during firmware update process