Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion firmware/libsi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION "3.21")
project(si LANGUAGES C)

# Define the library
add_library(si STATIC "src/crc8.c" "src/commands.c" "src/device/gc_controller.c")
add_library(si STATIC "src/crc8.c" "src/device/commands.c" "src/device/gc_controller.c")

# Configure SI peripheral selection
if(DEFINED SI_RX_TIMER_IDX)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <stdbool.h>
#include <stdint.h>

#include "si.h"
#include "si/si.h"

/**
* Function type for command handlers.
Expand All @@ -14,42 +14,45 @@
*
* @return 0 on success, negative error code on failure
*/
typedef int (*si_command_handler_fn)(const uint8_t *command, si_callback_fn callback, void *context);
typedef int (*si_command_handler_fn)(const uint8_t *command, si_complete_cb_t callback, void *context);

/**
* Command structure representing a registered command.
*/
struct si_command {
uint8_t command;
uint8_t length;
si_command_handler_fn handler;
void *user_data;
};

/**
* Register a command handler for commands from an SI host.
*
* @param command the command to handle
* @param command_length the length of the command
* @param command_length the length of the command in bytes
* @param handler the command handler function
*
*/
void si_command_register(uint8_t command, uint8_t length, si_command_handler_fn handler, void *context);

/**
* Get the expected length of an SI command.
*
* @param command the command to check
*
* @return the expected length of the command, in bytes, or 0 if the command is unknown
*/
uint8_t si_command_get_length(uint8_t command);

/**
* Get the command handler for an SI command.
* Look up a command structure by command ID.
*
* @param command the command to check
* @param command the command ID to look up
*
* @return the command handler function, or NULL if the command is unknown
* @return pointer to the command structure, or NULL if not found
*/
si_command_handler_fn si_command_get_handler(uint8_t command);
struct si_command *si_command_find_by_id(uint8_t command);

/**
* Process an SI command.
* Process a single SI command on the bus.
*
* This will read a command from the SI bus and call the registered handler.
*
* @param await_bus_idle if true, will wait for the SI bus to be idle before reading commands
*/
void si_command_process();
void si_command_process(bool await_bus_idle);

/**
* Enable automatic command processing.
Expand Down
26 changes: 25 additions & 1 deletion firmware/libsi/include/si/device/gc_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@
#include <stdbool.h>
#include <stdint.h>

// GameCube controller commands
#define SI_CMD_GC_SHORT_POLL 0x40
#define SI_CMD_GC_SHORT_POLL_LEN 3
#define SI_CMD_GC_SHORT_POLL_RESP 8

#define SI_CMD_GC_READ_ORIGIN 0x41
#define SI_CMD_GC_READ_ORIGIN_LEN 1
#define SI_CMD_GC_READ_ORIGIN_RESP 10

#define SI_CMD_GC_CALIBRATE 0x42
#define SI_CMD_GC_CALIBRATE_LEN 3
#define SI_CMD_GC_CALIBRATE_RESP 10

#define SI_CMD_GC_LONG_POLL 0x43
#define SI_CMD_GC_LONG_POLL_LEN 3
#define SI_CMD_GC_LONG_POLL_RESP 10

#define SI_CMD_GC_PROBE_DEVICE 0x4D
#define SI_CMD_GC_PROBE_DEVICE_LEN 3
#define SI_CMD_GC_PROBE_DEVICE_RESP 8

#define SI_CMD_GC_FIX_DEVICE 0x4E
#define SI_CMD_GC_FIX_DEVICE_LEN 3
#define SI_CMD_GC_FIX_DEVICE_RESP 3

/**
* Rumble motor states.
*/
Expand Down Expand Up @@ -88,7 +113,6 @@ struct si_device_gc_controller {
*
* @param device the device to initialize
* @param type the device type flags
* @param input_state pointer to an input state buffer
*/
void si_device_gc_init(struct si_device_gc_controller *device, uint8_t type);

Expand Down
56 changes: 17 additions & 39 deletions firmware/libsi/include/si/si.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

Expand All @@ -56,31 +57,6 @@
#define SI_CMD_INFO_LEN 1
#define SI_CMD_INFO_RESP 3

// GameCube controller commands
#define SI_CMD_GC_SHORT_POLL 0x40
#define SI_CMD_GC_SHORT_POLL_LEN 3
#define SI_CMD_GC_SHORT_POLL_RESP 8

#define SI_CMD_GC_READ_ORIGIN 0x41
#define SI_CMD_GC_READ_ORIGIN_LEN 1
#define SI_CMD_GC_READ_ORIGIN_RESP 10

#define SI_CMD_GC_CALIBRATE 0x42
#define SI_CMD_GC_CALIBRATE_LEN 3
#define SI_CMD_GC_CALIBRATE_RESP 10

#define SI_CMD_GC_LONG_POLL 0x43
#define SI_CMD_GC_LONG_POLL_LEN 3
#define SI_CMD_GC_LONG_POLL_RESP 10

#define SI_CMD_GC_PROBE_DEVICE 0x4D
#define SI_CMD_GC_PROBE_DEVICE_LEN 3
#define SI_CMD_GC_PROBE_DEVICE_RESP 8

#define SI_CMD_GC_FIX_DEVICE 0x4E
#define SI_CMD_GC_FIX_DEVICE_LEN 3
#define SI_CMD_GC_FIX_DEVICE_RESP 3

// SI device info flags
// On wireless controllers 0x00C0FF is reserved for the controller ID

Expand Down Expand Up @@ -118,12 +94,21 @@ enum {
SI_ERR_TRANSFER_TIMEOUT,
};

/**
* Function type for per-byte callbacks during receive operations.
*
* @param byte the received byte
* @param byte_index the zero-based index of the byte (0 for first byte)
* @return true to continue the transfer, false to stop it
*/
typedef bool (*si_byte_cb_t)(uint8_t byte, uint8_t byte_index);

/**
* Function type for transfer completion callbacks.
*
* @param result 0 on success, negative error code on failure
* @param result positive number of bytes read on success, negative error code on failure
*/
typedef void (*si_callback_fn)(int result);
typedef void (*si_complete_cb_t)(int result);

/**
* Initialize the SI bus.
Expand All @@ -143,24 +128,17 @@ void si_init(uint8_t port, uint8_t pin, uint8_t mode, uint32_t rx_freq, uint32_t
* @param length the length of the data
* @param callback function to call when the transfer is complete
*/
void si_write_bytes(const uint8_t *data, uint8_t length, si_callback_fn callback);
void si_write_bytes(const uint8_t *data, uint8_t length, si_complete_cb_t callback);

/**
* Read data from the SI bus.
*
* @param buffer the buffer to read into
* @param length the number of bytes expected
* @param callback function to call when the transfer is complete
*/
void si_read_bytes(uint8_t *buffer, uint8_t length, si_callback_fn callback);

/**
* Read a single command from the SI bus.
*
* @param buffer the buffer to read into
* @param callback function to call when the command has been read
* @param max_length the maximum number of bytes to read (buffer size)
* @param byte_callback optional function to call for each received byte (can be NULL)
* @param complete_callback function to call when the transfer is complete
*/
void si_read_command(uint8_t *buffer, si_callback_fn callback);
void si_read_bytes(uint8_t *buffer, uint8_t max_length, si_byte_cb_t byte_callback, si_complete_cb_t complete_callback);

/**
* Wait for the SI bus to be idle.
Expand Down
136 changes: 0 additions & 136 deletions firmware/libsi/src/commands.c

This file was deleted.

Loading