libjoybus
Joybus implementation for 32-bit MCUs
Loading...
Searching...
No Matches
bus.h
1
6
7#pragma once
8
9#include <stddef.h>
10#include <stdint.h>
11
12#include <joybus/target.h>
13
14struct joybus;
15
17#define JOYBUS_FREQ_N64_CONSOLE 244141 // PIF-NUS @ 15.625MHz / 64
18
20#define JOYBUS_FREQ_N64_EXTJOY JOYBUS_FREQ_N64_CONSOLE // SECCLK @ 1.953125MHz / 8
21
23#define JOYBUS_FREQ_N64_CONTROLLER 250000 // CNT-NUS @ 2MHz / 8
24
26#define JOYBUS_FREQ_N64_VRU 250000 // VCI-NUS @ 4MHz / 16
27
29#define JOYBUS_FREQ_GCN_CONSOLE 202500 // Flipper @ 162MHz / 800
30
32#define JOYBUS_FREQ_GCN_CONTROLLER 250000 // CNT-DOL @ 4MHz / 16
33
35#define JOYBUS_FREQ_WAVEBIRD_RECEIVER 225000 // WCRX-DOL @ 28.8MHz / 128
36
38#define JOYBUS_FREQ_WII_CONSOLE 202500 // Hollywood @ 243MHz / 1200
39
41#define JOYBUS_FREQ_GCN_GBA_CABLE 262144 // CPU-AGB @ 16.777216MHz / 64
42
44#define JOYBUS_INTER_TRANSFER_DELAY_US 80
45
47#define JOYBUS_REPLY_TIMEOUT_US 100
48
50#define JOYBUS_BUS_IDLE_US 100
51
53#define JOYBUS_BLOCK_SIZE 64
54
56#define JOYBUS_PAK_BLOCK_SIZE 32
57
61#define JOYBUS(bus) ((struct joybus *)(bus))
62
74typedef void (*joybus_transfer_cb)(struct joybus *bus, int status, void *user_data);
75
76// API for a Joybus backend - internal use only
77struct joybus_api {
78 int (*enable)(struct joybus *bus);
79 int (*disable)(struct joybus *bus);
80 int (*transfer)(struct joybus *bus, const uint8_t *write_buf, uint8_t write_len, uint8_t *read_buf, uint8_t read_len,
81 joybus_transfer_cb callback, void *user_data);
82 int (*target_register)(struct joybus *bus, struct joybus_target *target);
83 int (*target_unregister)(struct joybus *bus, struct joybus_target *target);
84};
85
87 joybus_transfer_cb callback;
88 void *user_data;
89 uint8_t *response;
90 uint8_t arg;
91};
92
96struct joybus {
97 const struct joybus_api *api;
98
99 struct joybus_target *target;
100 uint8_t command_buffer[JOYBUS_BLOCK_SIZE];
101 uint8_t response_buffer[JOYBUS_BLOCK_SIZE];
102 struct joybus_host_op host_op;
103};
104
110static inline int joybus_enable(struct joybus *bus)
111{
112 return bus->api->enable(bus);
113}
114
120static inline int joybus_disable(struct joybus *bus)
121{
122 return bus->api->disable(bus);
123}
124
141static inline int joybus_transfer(struct joybus *bus, const uint8_t *write_buf, uint8_t write_len, uint8_t *read_buf,
142 uint8_t read_len, joybus_transfer_cb callback, void *user_data)
143{
144 return bus->api->transfer(bus, write_buf, write_len, read_buf, read_len, callback, user_data);
145}
146
162int joybus_transfer_sync(struct joybus *bus, const uint8_t *write_buf, uint8_t write_len, uint8_t *read_buf,
163 uint8_t read_len);
164
172static inline int joybus_target_register(struct joybus *bus, struct joybus_target *target)
173{
174 // Common setup
175 bus->target = target;
176 target->registered = true;
177
178 // Backend-specific registration
179 return bus->api->target_register(bus, target);
180}
181
189static inline int joybus_target_unregister(struct joybus *bus, struct joybus_target *target)
190{
191 // Backend-specific unregistration
192 int status = bus->api->target_unregister(bus, target);
193
194 // Common teardown
195 bus->target = NULL;
196 target->registered = false;
197
198 return status;
199}
200
201// Context for a blocking Joybus operation
203 volatile bool done;
204 volatile int status;
205};
206
207// Transfer completion callback that records the status into a joybus_sync_ctx.
208void joybus_sync_cb(struct joybus *bus, int status, void *user_data);
209
210// Busy-wait on a joybus_sync_ctx until the operation completes
211int joybus_sync(int start_status, struct joybus_sync_ctx *ctx);
212
static int joybus_enable(struct joybus *bus)
Enable the Joybus instance.
Definition bus.h:110
void(* joybus_transfer_cb)(struct joybus *bus, int status, void *user_data)
Function type for transfer completion callbacks.
Definition bus.h:74
#define JOYBUS_BLOCK_SIZE
Maximum size of a Joybus transfer, in bytes.
Definition bus.h:53
int joybus_transfer_sync(struct joybus *bus, const uint8_t *write_buf, uint8_t write_len, uint8_t *read_buf, uint8_t read_len)
Perform a synchronous "write then read" Joybus transfer.
Definition bus.c:24
static int joybus_target_unregister(struct joybus *bus, struct joybus_target *target)
Unregister a Joybus target.
Definition bus.h:189
static int joybus_transfer(struct joybus *bus, const uint8_t *write_buf, uint8_t write_len, uint8_t *read_buf, uint8_t read_len, joybus_transfer_cb callback, void *user_data)
Perform a Joybus "write then read" transfer.
Definition bus.h:141
static int joybus_disable(struct joybus *bus)
Disable the Joybus instance.
Definition bus.h:120
static int joybus_target_register(struct joybus *bus, struct joybus_target *target)
Enable Joybus "target" mode, and register a target to handle commands.
Definition bus.h:172
uint8_t status
Status flags.
Definition identify.h:4
Definition bus.h:77
Definition bus.h:86
Definition bus.h:202
Interface for a Joybus target, a device on the Joybus which responds to commands from a host.
Definition target.h:69
bool registered
Whether the target is currently registered on the bus.
Definition target.h:74
A Joybus instance.
Definition bus.h:96