Skip to content

Commit 5e0f2ed

Browse files
authored
Merge pull request #18 from loopj/libsi-command-refactor
Refactor SI command handling to reduce memory usage, make command logic platform independent
2 parents aa63707 + ef40fff commit 5e0f2ed

File tree

11 files changed

+259
-274
lines changed

11 files changed

+259
-274
lines changed

firmware/libsi/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cmake_minimum_required(VERSION "3.21")
55
project(si LANGUAGES C)
66

77
# Define the library
8-
add_library(si STATIC "src/crc8.c" "src/commands.c" "src/device/gc_controller.c")
8+
add_library(si STATIC "src/crc8.c" "src/device/commands.c" "src/device/gc_controller.c")
99

1010
# Configure SI peripheral selection
1111
if(DEFINED SI_RX_TIMER_IDX)

firmware/libsi/include/si/commands.h renamed to firmware/libsi/include/si/device/commands.h

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <stdbool.h>
44
#include <stdint.h>
55

6-
#include "si.h"
6+
#include "si/si.h"
77

88
/**
99
* Function type for command handlers.
@@ -14,42 +14,45 @@
1414
*
1515
* @return 0 on success, negative error code on failure
1616
*/
17-
typedef int (*si_command_handler_fn)(const uint8_t *command, si_callback_fn callback, void *context);
17+
typedef int (*si_command_handler_fn)(const uint8_t *command, si_complete_cb_t callback, void *context);
18+
19+
/**
20+
* Command structure representing a registered command.
21+
*/
22+
struct si_command {
23+
uint8_t command;
24+
uint8_t length;
25+
si_command_handler_fn handler;
26+
void *user_data;
27+
};
1828

1929
/**
2030
* Register a command handler for commands from an SI host.
2131
*
2232
* @param command the command to handle
23-
* @param command_length the length of the command
33+
* @param command_length the length of the command in bytes
2434
* @param handler the command handler function
2535
*
2636
*/
2737
void si_command_register(uint8_t command, uint8_t length, si_command_handler_fn handler, void *context);
2838

2939
/**
30-
* Get the expected length of an SI command.
31-
*
32-
* @param command the command to check
33-
*
34-
* @return the expected length of the command, in bytes, or 0 if the command is unknown
35-
*/
36-
uint8_t si_command_get_length(uint8_t command);
37-
38-
/**
39-
* Get the command handler for an SI command.
40+
* Look up a command structure by command ID.
4041
*
41-
* @param command the command to check
42+
* @param command the command ID to look up
4243
*
43-
* @return the command handler function, or NULL if the command is unknown
44+
* @return pointer to the command structure, or NULL if not found
4445
*/
45-
si_command_handler_fn si_command_get_handler(uint8_t command);
46+
struct si_command *si_command_find_by_id(uint8_t command);
4647

4748
/**
48-
* Process an SI command.
49+
* Process a single SI command on the bus.
4950
*
51+
* This will read a command from the SI bus and call the registered handler.
5052
*
53+
* @param await_bus_idle if true, will wait for the SI bus to be idle before reading commands
5154
*/
52-
void si_command_process();
55+
void si_command_process(bool await_bus_idle);
5356

5457
/**
5558
* Enable automatic command processing.

firmware/libsi/include/si/device/gc_controller.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,31 @@
77
#include <stdbool.h>
88
#include <stdint.h>
99

10+
// GameCube controller commands
11+
#define SI_CMD_GC_SHORT_POLL 0x40
12+
#define SI_CMD_GC_SHORT_POLL_LEN 3
13+
#define SI_CMD_GC_SHORT_POLL_RESP 8
14+
15+
#define SI_CMD_GC_READ_ORIGIN 0x41
16+
#define SI_CMD_GC_READ_ORIGIN_LEN 1
17+
#define SI_CMD_GC_READ_ORIGIN_RESP 10
18+
19+
#define SI_CMD_GC_CALIBRATE 0x42
20+
#define SI_CMD_GC_CALIBRATE_LEN 3
21+
#define SI_CMD_GC_CALIBRATE_RESP 10
22+
23+
#define SI_CMD_GC_LONG_POLL 0x43
24+
#define SI_CMD_GC_LONG_POLL_LEN 3
25+
#define SI_CMD_GC_LONG_POLL_RESP 10
26+
27+
#define SI_CMD_GC_PROBE_DEVICE 0x4D
28+
#define SI_CMD_GC_PROBE_DEVICE_LEN 3
29+
#define SI_CMD_GC_PROBE_DEVICE_RESP 8
30+
31+
#define SI_CMD_GC_FIX_DEVICE 0x4E
32+
#define SI_CMD_GC_FIX_DEVICE_LEN 3
33+
#define SI_CMD_GC_FIX_DEVICE_RESP 3
34+
1035
/**
1136
* Rumble motor states.
1237
*/
@@ -88,7 +113,6 @@ struct si_device_gc_controller {
88113
*
89114
* @param device the device to initialize
90115
* @param type the device type flags
91-
* @param input_state pointer to an input state buffer
92116
*/
93117
void si_device_gc_init(struct si_device_gc_controller *device, uint8_t type);
94118

firmware/libsi/include/si/si.h

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#pragma once
4343

44+
#include <stdbool.h>
4445
#include <stddef.h>
4546
#include <stdint.h>
4647

@@ -56,31 +57,6 @@
5657
#define SI_CMD_INFO_LEN 1
5758
#define SI_CMD_INFO_RESP 3
5859

59-
// GameCube controller commands
60-
#define SI_CMD_GC_SHORT_POLL 0x40
61-
#define SI_CMD_GC_SHORT_POLL_LEN 3
62-
#define SI_CMD_GC_SHORT_POLL_RESP 8
63-
64-
#define SI_CMD_GC_READ_ORIGIN 0x41
65-
#define SI_CMD_GC_READ_ORIGIN_LEN 1
66-
#define SI_CMD_GC_READ_ORIGIN_RESP 10
67-
68-
#define SI_CMD_GC_CALIBRATE 0x42
69-
#define SI_CMD_GC_CALIBRATE_LEN 3
70-
#define SI_CMD_GC_CALIBRATE_RESP 10
71-
72-
#define SI_CMD_GC_LONG_POLL 0x43
73-
#define SI_CMD_GC_LONG_POLL_LEN 3
74-
#define SI_CMD_GC_LONG_POLL_RESP 10
75-
76-
#define SI_CMD_GC_PROBE_DEVICE 0x4D
77-
#define SI_CMD_GC_PROBE_DEVICE_LEN 3
78-
#define SI_CMD_GC_PROBE_DEVICE_RESP 8
79-
80-
#define SI_CMD_GC_FIX_DEVICE 0x4E
81-
#define SI_CMD_GC_FIX_DEVICE_LEN 3
82-
#define SI_CMD_GC_FIX_DEVICE_RESP 3
83-
8460
// SI device info flags
8561
// On wireless controllers 0x00C0FF is reserved for the controller ID
8662

@@ -118,12 +94,21 @@ enum {
11894
SI_ERR_TRANSFER_TIMEOUT,
11995
};
12096

97+
/**
98+
* Function type for per-byte callbacks during receive operations.
99+
*
100+
* @param byte the received byte
101+
* @param byte_index the zero-based index of the byte (0 for first byte)
102+
* @return true to continue the transfer, false to stop it
103+
*/
104+
typedef bool (*si_byte_cb_t)(uint8_t byte, uint8_t byte_index);
105+
121106
/**
122107
* Function type for transfer completion callbacks.
123108
*
124-
* @param result 0 on success, negative error code on failure
109+
* @param result positive number of bytes read on success, negative error code on failure
125110
*/
126-
typedef void (*si_callback_fn)(int result);
111+
typedef void (*si_complete_cb_t)(int result);
127112

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

148133
/**
149134
* Read data from the SI bus.
150135
*
151136
* @param buffer the buffer to read into
152-
* @param length the number of bytes expected
153-
* @param callback function to call when the transfer is complete
154-
*/
155-
void si_read_bytes(uint8_t *buffer, uint8_t length, si_callback_fn callback);
156-
157-
/**
158-
* Read a single command from the SI bus.
159-
*
160-
* @param buffer the buffer to read into
161-
* @param callback function to call when the command has been read
137+
* @param max_length the maximum number of bytes to read (buffer size)
138+
* @param byte_callback optional function to call for each received byte (can be NULL)
139+
* @param complete_callback function to call when the transfer is complete
162140
*/
163-
void si_read_command(uint8_t *buffer, si_callback_fn callback);
141+
void si_read_bytes(uint8_t *buffer, uint8_t max_length, si_byte_cb_t byte_callback, si_complete_cb_t complete_callback);
164142

165143
/**
166144
* Wait for the SI bus to be idle.

firmware/libsi/src/commands.c

Lines changed: 0 additions & 136 deletions
This file was deleted.

0 commit comments

Comments
 (0)