libdragon
Loading...
Searching...
No Matches
joybus.h
Go to the documentation of this file.
1
7#ifndef __LIBDRAGON_JOYBUS_H
8#define __LIBDRAGON_JOYBUS_H
9
10#include <assert.h>
11#include <stddef.h>
12#include <stdint.h>
13#include <string.h>
14
56#ifdef __cplusplus
57extern "C" {
58#endif
59
68#define JOYBUS_BLOCK_SIZE 64
72#define JOYBUS_BLOCK_DWORDS ( JOYBUS_BLOCK_SIZE / sizeof(uint64_t) )
76#define JOYBUS_ACCESSORY_DATA_SIZE 32
/* JOYBUS_PAYLOAD_SIZES */
78
85#define JOYBUS_PORT_COUNT 5
86
96typedef uint16_t joybus_identifier_t;
97
106#define JOYBUS_IDENTIFIER_UNKNOWN 0x0000
110#define JOYBUS_IDENTIFIER_NONE 0xFFFF
116#define JOYBUS_IDENTIFIER_N64_VOICE_RECOGNITION 0x0001
120#define JOYBUS_IDENTIFIER_N64_RANDNET_KEYBOARD 0x0002
124#define JOYBUS_IDENTIFIER_64GB_LINK_CABLE 0x0003
128#define JOYBUS_IDENTIFIER_GBA_LINK_CABLE 0x0004
132#define JOYBUS_IDENTIFIER_CART_RTC 0x0010
136#define JOYBUS_IDENTIFIER_CART_EEPROM_4KBIT 0x0080
140#define JOYBUS_IDENTIFIER_CART_EEPROM_16KBIT 0x00C0
144#define JOYBUS_IDENTIFIER_N64_CONTROLLER 0x0500
148#define JOYBUS_IDENTIFIER_N64_MOUSE 0x0200
175#define JOYBUS_IDENTIFIER_MASK_PLATFORM 0x1800
182#define JOYBUS_IDENTIFIER_PLATFORM_GCN 0x0800
188#define JOYBUS_IDENTIFIER_MASK_GCN_CONTROLLER 0x0100
194#define JOYBUS_IDENTIFIER_MASK_GCN_NORUMBLE 0x2000
200#define JOYBUS_IDENTIFIER_MASK_GCN_WIRELESS 0x8000
/* JOYBUS_IDENTIFIER_GCN_BITFIELD */
202
211#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_MASK 0x03
218#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_UNSUPPORTED 0x00
222#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_PRESENT 0x01
226#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_ABSENT 0x02
231#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_CHANGED 0x03
235#define JOYBUS_IDENTIFY_STATUS_VOICE_RECOGNITON_READY 0x01
240#define JOYBUS_IDENTIFY_STATUS_COMMAND_CHECKSUM_ERROR 0x04
245#define JOYBUS_IDENTIFY_STATUS_GCN_RUMBLE_ACTIVE 0x08
249#define JOYBUS_IDENTIFY_STATUS_EEPROM_BUSY 0x80
260typedef void (*joybus_callback_t)(uint64_t *out_dwords, void *ctx);
261
291void joybus_exec_async(const void * input, joybus_callback_t callback, void *ctx);
292
308void joybus_exec( const void* input, void* output );
309
345inline void joybus_exec_cmd(
346 int port,
347 size_t send_len,
348 size_t recv_len,
349 const void *send_data,
350 void *recv_data
351)
352{
353 // Validate the desired Joybus port offset
354 assert((port >= 0) && (port < JOYBUS_PORT_COUNT));
355 // Ensure the send_len and recv_len fit in the Joybus operation block
356 assert((port + send_len + recv_len) < (JOYBUS_BLOCK_SIZE - 4));
357 // Allocate the Joybus operation block input and output buffers
358 uint8_t input[JOYBUS_BLOCK_SIZE] = {0};
359 uint8_t output[JOYBUS_BLOCK_SIZE] = {0};
360 // Skip commands on ports before the desired port offset
361 size_t i = port;
362 // Set the command metadata
363 input[i++] = send_len;
364 input[i++] = recv_len;
365 // Copy the send_data into the input buffer
366 memcpy(&input[i], send_data, send_len);
367 i += send_len + recv_len;
368 // Close out the Joybus operation block
369 input[i] = 0xFE;
370 input[sizeof(input) - 1] = 0x01;
371 // Execute the Joybus operation synchronously
372 joybus_exec(input, output);
373 // Copy recv_data from the output buffer
374 memcpy(recv_data, &output[i - recv_len], recv_len);
375}
376
398#define joybus_exec_cmd_struct(port, cmd) \
399 joybus_exec_cmd( \
400 port, \
401 sizeof(cmd.send), \
402 sizeof(cmd.recv), \
403 (void *)&cmd.send, \
404 (void *)&cmd.recv \
405 )
406
407#ifdef __cplusplus
408}
409#endif
410
/* joybus */
412
413#endif
void joybus_exec_async(const void *input, joybus_callback_t callback, void *ctx)
Execute an asynchronous joybus message.
void joybus_exec(const void *input, void *output)
Write a 64-byte block of data to the PIF and read the 64-byte result.
Definition joybus.c:253
#define JOYBUS_BLOCK_SIZE
Size of a Joybus input/output block in bytes.
Definition joybus.h:68
#define JOYBUS_PORT_COUNT
Count of Joybus ports.
Definition joybus.h:85
void(* joybus_callback_t)(uint64_t *out_dwords, void *ctx)
Callback function signature for joybus_exec_async.
Definition joybus.h:260
void joybus_exec_cmd(int port, size_t send_len, size_t recv_len, const void *send_data, void *recv_data)
Execute a Joybus command synchronously on the given port.
Definition joybus.h:345
uint16_t joybus_identifier_t
Joypad Identifier type.
Definition joybus.h:96