|
libjoybus
Joybus implementation for 32-bit MCUs
|
Interfaces for implementing Joybus targets and N64 accessories. More...
Topics | |
| GameCube Controller Target | |
| Joybus target implementation for standard GameCube controllers and WaveBird receivers. | |
| N64 Controller Target | |
| Joybus target implementation for standard N64 controllers. | |
| PixelFX Game ID Target | |
| Joybus target which listens for the PixelFX game ID command. | |
Data Structures | |
| struct | joybus_target_api |
| API for implementing a Joybus target. More... | |
| struct | joybus_target |
| Interface for a Joybus target, a device on the Joybus which responds to commands from a host. More... | |
Macros | |
| #define | JOYBUS_TARGET(target) |
| Macro to cast a concrete Joybus target instance to a generic Joybus target instance. | |
Typedefs | |
| typedef void(* | joybus_target_response_cb) (const uint8_t *response, uint8_t len, void *user_data) |
| Callback type for sending responses from target command handlers. | |
Functions | |
| static int | joybus_target_byte_received (struct joybus_target *target, const uint8_t *command, uint8_t byte_idx, joybus_target_response_cb send_response, void *user_data) |
| Handle a received command byte for a single Joybus target. | |
| static bool | joybus_target_is_attached (struct joybus_target *target) |
| Check if a target is currently attached to a bus. | |
Interfaces for implementing Joybus targets and N64 accessories.
A Joybus target is a device on the bus that responds to commands from a host (the console), such as an N64 or GameCube controller.
Commands arrive one byte at a time. As each byte is received, libjoybus calls the joybus_target_api::byte_received handler with the bytes accumulated so far. The handler inspects them to decide how many more bytes the command needs, returning the count of bytes still expected.
To send a response, the handler must call the "response ready" callback with a pointer to the (long-lived) response data and its length.
Handlers should call the response callback as soon as the response is ready, even if they are still expecting more command bytes. For many commands, the response data is fully determined by the first few bytes of the command. This allows the backend to start transmitting the response immediately after the last byte is received.
Handlers run in interrupt context, on the response critical path. Mark them with JOYBUS_RAM_FUNC so a flash fetch cannot delay the reply.
To create your own target, define a struct whose first member is a joybus_target (so it can be cast through JOYBUS_TARGET), point its api at a joybus_target_api table, and attach it to a bus with joybus_attach_target().
A bus accepts more than one target. Each command is offered to the attached targets in attachment order, and the first one that accepts it handles that command to the end. This places the following contract on a target:
| #define JOYBUS_TARGET | ( | target | ) |
Macro to cast a concrete Joybus target instance to a generic Joybus target instance.
| typedef void(* joybus_target_response_cb) (const uint8_t *response, uint8_t len, void *user_data) |
Callback type for sending responses from target command handlers.
| response | the response data to send |
| len | the length of the response data |
| user_data | user data passed to the command handler |
|
inlinestatic |
Handle a received command byte for a single Joybus target.
Backends do not call this directly. They call joybus_byte_received(), which offers the command to each target attached to the bus.
| target | the target to handle the command |
| command | the command buffer |
| byte_idx | the index of the byte that was just received |
| send_response | a callback function to send the response |
| user_data | user data to pass to the response callback |
|
inlinestatic |
Check if a target is currently attached to a bus.
| target | the target to check |