libdragon
Loading...
Searching...
No Matches
Files | Data Structures | Macros | Typedefs | Enumerations | Functions
Joybus Subsystem

Joybus peripheral interface. More...

Files

file  joybus.c
 Joybus Subsystem.
 
file  joybus_accessory.c
 Joybus Accessory utilities.
 
file  joybus_accessory_internal.h
 Joybus accessory internal utilities.
 
file  joybus_internal.h
 Joybus internal API.
 
file  joybus.h
 Joybus Subsystem.
 
file  joybus_accessory.h
 Joybus accessory utilities.
 

Data Structures

union  joybus_transfer_pak_status_t
 Joybus N64 Transfer Pak Status wrapper. More...
 

Macros

#define JOYBUS_ACCESSORY_TRANSFER_BANK_SIZE   0x4000
 Size of Transfer Pak bank area in bytes.
 
#define JOYBUS_ACCESSORY_TRANSFER_BANK_MASK   0x3FFF
 Mask for Transfer Pak bank area address.
 
#define JOYBUS_PORT_COUNT   5
 Count of Joybus ports.
 
#define joybus_exec_cmd_struct(port, cmd)
 Execute a Joybus command struct synchronously.
 

Typedefs

typedef uint16_t joybus_identifier_t
 Joypad Identifier type.
 
typedef void(* joybus_callback_t) (uint64_t *out_dwords, void *ctx)
 Callback function signature for joybus_exec_async.
 

Enumerations

enum  joybus_accessory_io_status_t { JOYBUS_ACCESSORY_IO_STATUS_OK = 0 , JOYBUS_ACCESSORY_IO_STATUS_NO_DEVICE = -1 , JOYBUS_ACCESSORY_IO_STATUS_NO_PAK = -2 , JOYBUS_ACCESSORY_IO_STATUS_BAD_CRC = -3 }
 Joybus accessory read/write status values. More...
 

Functions

uint16_t joybus_accessory_calculate_addr_checksum (uint16_t addr)
 Applies the checksum to a Joybus N64 accessory read/write address.
 
uint8_t joybus_accessory_calculate_data_crc (const uint8_t *data)
 Calculates the CRC8 checksum for a Joybus N64 accessory read/write data block.
 
joybus_accessory_io_status_t joybus_accessory_compare_data_crc (const uint8_t *data, uint8_t data_crc)
 Calculates the CRC8 checksum for an accessory read/write data block and compares it against the provided checksum.
 
void joybus_accessory_read_async (int port, uint16_t addr, joybus_callback_t callback, void *ctx)
 Asynchronously perform a Joybus N64 accessory read command.
 
void joybus_accessory_write_async (int port, uint16_t addr, const uint8_t *data, joybus_callback_t callback, void *ctx)
 Asynchronously perform a Joybus N64 accessory write command.
 
int joybus_accessory_read (int port, uint16_t addr, uint8_t *data)
 Synchronously perform a Joybus N64 accessory read command.
 
int joybus_accessory_write (int port, uint16_t addr, const uint8_t *data)
 Synchronously perform a Joybus N64 accessory write command.
 
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.
 
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.
 

Joybus N64 accessory address masks

#define JOYBUS_ACCESSORY_ADDR_MASK_OFFSET   0xFFE0
 Mask for Joybus N64 accessory read/write address offset.
 
#define JOYBUS_ACCESSORY_ADDR_MASK_CHECKSUM   0x001F
 Mask for Joybus N64 accessory read/write address checksum.
 

Joybus N64 accessory known address values

#define JOYBUS_ACCESSORY_ADDR_LABEL   0x0000
 Controller Pak label address.
 
#define JOYBUS_ACCESSORY_ADDR_PROBE   0x8000
 Accessory probe address.
 
#define JOYBUS_ACCESSORY_ADDR_RUMBLE_MOTOR   0xC000
 Rumble Pak motor control address.
 
#define JOYBUS_ACCESSORY_ADDR_BIO_PULSE   0xC000
 Bio Sensor pulse read address.
 
#define JOYBUS_ACCESSORY_ADDR_SNAP_STATE   0xC000
 Pokemon Snap Station state address.
 
#define JOYBUS_ACCESSORY_ADDR_TRANSFER_BANK   0xA000
 Transfer Pak bank selection address.
 
#define JOYBUS_ACCESSORY_ADDR_TRANSFER_STATUS   0xB000
 Transfer Pak status registers address.
 
#define JOYBUS_ACCESSORY_ADDR_TRANSFER_CART   0xC000
 Transfer Pak GB cartridge read/write address.
 

Joybus N64 accessory probe values

#define JOYBUS_ACCESSORY_PROBE_ABSENT   0x00
 Absent accessory identifier value.
 
#define JOYBUS_ACCESSORY_PROBE_RUMBLE_PAK   0x80
 Rumble Pak identifier value.
 
#define JOYBUS_ACCESSORY_PROBE_BIO_SENSOR   0x81
 Bio Sensor identifier value.
 
#define JOYBUS_ACCESSORY_PROBE_TRANSFER_PAK_ON   0x84
 Transfer Pak power-on identifier value.
 
#define JOYBUS_ACCESSORY_PROBE_SNAP_STATION   0x85
 Pokemon Snap Station identifier value.
 
#define JOYBUS_ACCESSORY_PROBE_TRANSFER_PAK_OFF   0xFE
 Transfer Pak power-off identifier value.
 

Joybus N64 Snap Station state values

#define JOYBUS_SNAP_STATION_STATE_IDLE   0x00
 Snap Station "Idle" state.
 
#define JOYBUS_SNAP_STATION_STATE_PRE_SAVE   0xCC
 Snap Station "Pre-Save" state.
 
#define JOYBUS_SNAP_STATION_STATE_POST_SAVE   0x33
 Snap Station "Post-Save" state.
 
#define JOYBUS_SNAP_STATION_STATE_RESET_CONSOLE   0x5A
 Snap Station "Reset Console" state.
 
#define JOYBUS_SNAP_STATION_STATE_PRE_ROLL   0x01
 Snap Station "Pre-Roll" state.
 
#define JOYBUS_SNAP_STATION_STATE_CAPTURE_PHOTO   0x02
 Snap Station "Capture Photo" state.
 
#define JOYBUS_SNAP_STATION_STATE_POST_ROLL   0x04
 Snap Station "Post-Roll" state.
 
#define JOYBUS_SNAP_STATION_STATE_BUSY   0x08
 Snap Station "Busy" state.
 

Joybus N64 Transfer Pak status flags

#define JOYBUS_TRANSFER_PAK_STATUS_ACCESS   (1<<0)
 Transfer Pak "Access" status bit.
 
#define JOYBUS_TRANSFER_PAK_STATUS_BOOTING   (1<<2)
 Transfer Pak "Booting" status bit.
 
#define JOYBUS_TRANSFER_PAK_STATUS_RESET   (1<<3)
 Transfer Pak "Reset" status bit.
 
#define JOYBUS_TRANSFER_PAK_STATUS_CART_PULLED   (1<<6)
 Transfer Pak "Cart Pulled" status bit.
 
#define JOYBUS_TRANSFER_PAK_STATUS_POWER   (1<<7)
 Transfer Pak "Powered-On" status bit.
 

Joybus payload sizes

#define JOYBUS_BLOCK_SIZE   64
 Size of a Joybus input/output block in bytes.
 
#define JOYBUS_BLOCK_DWORDS   ( JOYBUS_BLOCK_SIZE / sizeof(uint64_t) )
 Size of a Joybus input/output block in double-words.
 
#define JOYBUS_ACCESSORY_DATA_SIZE   32
 Size of a Joybus N64 accessory read/write payload in bytes.
 

Joybus identifier values

#define JOYBUS_IDENTIFIER_UNKNOWN   0x0000
 Joybus identifier for an unknown or malfunctioning device.
 
#define JOYBUS_IDENTIFIER_NONE   0xFFFF
 Joybus identifier for a port with no device connected.
 
#define JOYBUS_IDENTIFIER_N64_VOICE_RECOGNITION   0x0001
 Joybus identifier for the Nintendo 64 voice recognition peripheral (NUS-020).
 
#define JOYBUS_IDENTIFIER_N64_RANDNET_KEYBOARD   0x0002
 Joybus identifier for the Nintendo 64 Randnet keyboard peripheral (RND-001).
 
#define JOYBUS_IDENTIFIER_64GB_LINK_CABLE   0x0003
 Joybus identifier for the unreleased 64GB Link Cable.
 
#define JOYBUS_IDENTIFIER_GBA_LINK_CABLE   0x0004
 Joybus identifier for a Game Boy Advance Link Cable (DOL-011).
 
#define JOYBUS_IDENTIFIER_CART_RTC   0x0010
 Joybus identifier for cartridge-based real-time clock.
 
#define JOYBUS_IDENTIFIER_CART_EEPROM_4KBIT   0x0080
 Joybus identifier for cartridge-based 4Kbit EEPROM save type.
 
#define JOYBUS_IDENTIFIER_CART_EEPROM_16KBIT   0x00C0
 Joybus identifier for cartridge-based 16Kbit EEPROM save type.
 
#define JOYBUS_IDENTIFIER_N64_CONTROLLER   0x0500
 Joybus identifier for a standard Nintendo 64 controller (NUS-005).
 
#define JOYBUS_IDENTIFIER_N64_MOUSE   0x0200
 Joybus identifier for the Nintendo 64 mouse peripheral (NUS-017).
 

Joybus identifier bitfield for GameCube peripherals

Note that for GameCube peripherals, the Joybus identifier is interpreted as a bitfield rather than a single value.

In particular, Wavebird controllers will return a different identifiers depending on wireless state.

To identify a device that acts like a standard GameCube controller, check the JOYBUS_IDENTIFIER_MASK_PLATFORM and the JOYBUS_IDENTIFIER_MASK_GCN_CONTROLLER values.

#define JOYBUS_IDENTIFIER_MASK_PLATFORM   0x1800
 Joybus identifier platform bitfield mask.
 
#define JOYBUS_IDENTIFIER_PLATFORM_GCN   0x0800
 GameCube Joybus identifier platform value.
 
#define JOYBUS_IDENTIFIER_MASK_GCN_CONTROLLER   0x0100
 Joybus identifier GameCube standard controller flag.
 
#define JOYBUS_IDENTIFIER_MASK_GCN_NORUMBLE   0x2000
 Joybus identifier GameCube rumble support flag.
 
#define JOYBUS_IDENTIFIER_MASK_GCN_WIRELESS   0x8000
 Joybus identifier GameCube wireless flag.
 

Joybus identify status values

#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_MASK   0x03
 Joybus identify status byte mask for N64 accessory presence values.
 
#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_UNSUPPORTED   0x00
 Joybus identify status for an N64 controller that does not support accessories.
 
#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_PRESENT   0x01
 Joybus identify status for an N64 controller with an accessory present.
 
#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_ABSENT   0x02
 Joybus identify status for an N64 controller with no accessory present.
 
#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_CHANGED   0x03
 Joybus identify status for an N64 controller with an accessory present that has changed since it was last identified.
 
#define JOYBUS_IDENTIFY_STATUS_VOICE_RECOGNITON_READY   0x01
 Joybus identify status bit for a VRU/VRS that is initialized and ready.
 
#define JOYBUS_IDENTIFY_STATUS_COMMAND_CHECKSUM_ERROR   0x04
 Joybus identify status bit that signifies the previous accessory command had a checksum error.
 
#define JOYBUS_IDENTIFY_STATUS_GCN_RUMBLE_ACTIVE   0x08
 Joybus identify status bit for GameCube controllers that indicates whether the rumble motor is currently active.
 
#define JOYBUS_IDENTIFY_STATUS_EEPROM_BUSY   0x80
 Joybus identify status bit for EEPROM devices that indicates a write is in-progress.
 

Detailed Description

Joybus peripheral interface.

The Joybus subsystem is in charge of communication with all controllers, accessories, and peripherals plugged into the N64 controller ports as well as some peripherals on the cartridge. The Joybus subsystem is responsible for communicating with the serial interface (SI) registers to send commands to controllers (including Controller Paks, Rumble Paks, and Transfer Paks), the VRU, EEPROM save memory, and the cartridge-based real-time clock.

This module implements just the low-level protocol. You should use it only to implement an unsupported peripherals. Otherwise, refer to the higher-level modules such as:

For controllers: Controller Subsystem.

For EEPROM, RTC and other peripherals: Peripherals Subsystem.

Internally, the JoyBus subsystem communicates with the PIF controller via the SI DMA, via the JoyBus protocol which is a standard master/slave binary protocol. Each message of the protocol is a block of 64 bytes, and can contain multiple commands. Currently, there are no macros or functions to help composing a JoyBus message, so higher-level libraries currently hard code the binary messages.

All communications is made asynchronously because SI DMA is quite slow: its completion is bound to the PIF actually processing the data, rather than just being the memory transfer. A queue of pending JoyBus messages is kept in a ring buffer, and is then executed under interrupt when the previous SI DMA completes. The internal entry point is joybus_exec_async, that schedules a message to be sent to PIF, and calls a callback with the reply whenever it is available. A blocking API (joybus_exec) is made available for simpler usage.


Data Structure Documentation

◆ joybus_transfer_pak_status_t

union joybus_transfer_pak_status_t

Joybus N64 Transfer Pak Status wrapper.

Type union that unpacks the raw Transfer Pak status byte to conveniently access the flags through a struct. If you prefer bitwise operations, you can use JOYBUS_TRANSFER_PAK_STATUS values as masks.

Data Fields
uint8_t raw Transfer Pak raw status byte.
unsigned access: 1 Transfer Pak "Access" status bit.
unsigned __pad0__: 1 Unused padding.
unsigned booting: 1 Transfer Pak "Booting" status bit.
unsigned reset: 1 Transfer Pak "Reset" status bit.
unsigned __pad1__: 2 Unused padding.
unsigned cart_pulled: 1 Transfer Pak "Cart Pulled" status bit.
unsigned power: 1 Transfer Pak "Powered-On" status bit.

Macro Definition Documentation

◆ JOYBUS_ACCESSORY_PROBE_ABSENT

#define JOYBUS_ACCESSORY_PROBE_ABSENT   0x00

Absent accessory identifier value.

For Rumble Pak, Transfer Pak, and Snap Station, you must write the expected identifier to the probe address and then read it back. If the expected accessory is not connected, this value will be returned.

◆ JOYBUS_ACCESSORY_PROBE_TRANSFER_PAK_ON

#define JOYBUS_ACCESSORY_PROBE_TRANSFER_PAK_ON   0x84

Transfer Pak power-on identifier value.

When this value is written to the probe address, the Transfer Pak will power on and respond to probe reads with this value.

If the accessory is not a Transfer Pak or the Transfer Pak is not powered on, the probe read will return the JOYBUS_ACCESSORY_PROBE_ABSENT value.

◆ JOYBUS_ACCESSORY_PROBE_TRANSFER_PAK_OFF

#define JOYBUS_ACCESSORY_PROBE_TRANSFER_PAK_OFF   0xFE

Transfer Pak power-off identifier value.

When this value is written to the probe address, the Transfer Pak will power off and respond to probe reads with the JOYBUS_ACCESSORY_PROBE_ABSENT value.

◆ JOYBUS_PORT_COUNT

#define JOYBUS_PORT_COUNT   5

Count of Joybus ports.

The N64 has four joypad ports, plus one additional port exposed on the cartridge connector for EEPROM and real-time clock support.

◆ JOYBUS_IDENTIFIER_N64_VOICE_RECOGNITION

#define JOYBUS_IDENTIFIER_N64_VOICE_RECOGNITION   0x0001

Joybus identifier for the Nintendo 64 voice recognition peripheral (NUS-020).

Also known as VRU in North America and VRS in Japan.

◆ JOYBUS_IDENTIFIER_MASK_PLATFORM

#define JOYBUS_IDENTIFIER_MASK_PLATFORM   0x1800

Joybus identifier platform bitfield mask.

Bits 11-12 of the Joybus identifier signify the intended platform:

  • Bit 11 is set for GameCube devices.
  • Bit 12 is zero for all known devices.

◆ JOYBUS_IDENTIFIER_PLATFORM_GCN

#define JOYBUS_IDENTIFIER_PLATFORM_GCN   0x0800

GameCube Joybus identifier platform value.

Bit 11 of the Joybus identifier is one for GameCube devices. Bit 12 of the Joybus identifier is zero for all known devices.

◆ JOYBUS_IDENTIFIER_MASK_GCN_CONTROLLER

#define JOYBUS_IDENTIFIER_MASK_GCN_CONTROLLER   0x0100

Joybus identifier GameCube standard controller flag.

For GameCube platform devices, this bit is set if the device acts like a standard controller.

◆ JOYBUS_IDENTIFIER_MASK_GCN_NORUMBLE

#define JOYBUS_IDENTIFIER_MASK_GCN_NORUMBLE   0x2000

Joybus identifier GameCube rumble support flag.

For GameCube controllers, this bit is set if the controller DOES NOT support rumble functionality.

◆ JOYBUS_IDENTIFIER_MASK_GCN_WIRELESS

#define JOYBUS_IDENTIFIER_MASK_GCN_WIRELESS   0x8000

Joybus identifier GameCube wireless flag.

For GameCube controllers, this bit is set if the controller is a wireless controller.

◆ JOYBUS_IDENTIFY_STATUS_ACCESSORY_UNSUPPORTED

#define JOYBUS_IDENTIFY_STATUS_ACCESSORY_UNSUPPORTED   0x00

Joybus identify status for an N64 controller that does not support accessories.

Some third-party controllers incorrectly use this status to mean absence of an accessory. Therefore, this value is treated as a synonym for JOYBUS_IDENTIFY_STATUS_ACCESSORY_ABSENT.

◆ joybus_exec_cmd_struct

#define joybus_exec_cmd_struct (   port,
  cmd 
)
Value:
port, \
sizeof(cmd.send), \
sizeof(cmd.recv), \
(void *)&cmd.send, \
(void *)&cmd.recv \
)
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

Execute a Joybus command struct synchronously.

This macro is a convenience wrapper around joybus_exec_cmd that uses the send and recv fields of the struct to set the proper arguments.

This is not a stable feature of the libdragon API and should be considered experimental!

The usage of this macro will likely change as a result of the ongoing effort to integrate the multitasking kernel with asynchronous operations.

Note
This operation is slow: it blocks until the command completes. Calling this multiple times per frame may cause audio and video stuttering.
Parameters
portThe Joybus port to execute the command on.
[in,out]cmdThe command struct to execute with.

Typedef Documentation

◆ joybus_identifier_t

typedef uint16_t joybus_identifier_t

Joypad Identifier type.

For known values, see JOYBUS_IDENTIFIER and JOYBUS_IDENTIFIER_GCN_BITFIELD.

Note
For GameCube peripherals, the Joybus identifier should be interpreted as a bitfield rather than a single value.

◆ joybus_callback_t

typedef void(* joybus_callback_t) (uint64_t *out_dwords, void *ctx)

Callback function signature for joybus_exec_async.

Note that this function will be called under interrupt, so your callback:

  • should not block or perform any intensive calculations
  • should not call non-reentrant functions such as malloc or free
  • should be careful accessing memory due to possible race conditions

Enumeration Type Documentation

◆ joybus_accessory_io_status_t

Joybus accessory read/write status values.

Enumerator
JOYBUS_ACCESSORY_IO_STATUS_OK 

Joybus accessory data communcation was successful.

JOYBUS_ACCESSORY_IO_STATUS_NO_DEVICE 

No N64 controller is connected.

JOYBUS_ACCESSORY_IO_STATUS_NO_PAK 

No N64 accessory is connected.

JOYBUS_ACCESSORY_IO_STATUS_BAD_CRC 

Joybus accessory communication was not successful.

Function Documentation

◆ joybus_accessory_calculate_addr_checksum()

uint16_t joybus_accessory_calculate_addr_checksum ( uint16_t  addr)

Applies the checksum to a Joybus N64 accessory read/write address.

When reading or writing a particular address on the accessory, the command will send the top 11 bits of a 16 bit address, plus a 5 bit checksum.

Parameters
addrThe address to calculate the checksum for.
Returns
The address with the checksum applied.

◆ joybus_accessory_calculate_data_crc()

uint8_t joybus_accessory_calculate_data_crc ( const uint8_t *  data)

Calculates the CRC8 checksum for a Joybus N64 accessory read/write data block.

Uses a CRC8 algorithm with a seed of 0x00 and a polynomial of 0x85.

Parameters
[in]dataThe 32-byte accessory read/write data block
Returns
The calculated CRC8 checksum for the data block

◆ joybus_accessory_compare_data_crc()

joybus_accessory_io_status_t joybus_accessory_compare_data_crc ( const uint8_t *  data,
uint8_t  data_crc 
)

Calculates the CRC8 checksum for an accessory read/write data block and compares it against the provided checksum.

Parameters
[in]dataThe 32-byte accessory read/write data block
data_crcThe CRC8 checksum to compare against
Return values
JOYBUS_ACCESSORY_IO_STATUS_OKThe checksums match.
JOYBUS_ACCESSORY_IO_STATUS_NO_PAKThe checksum indicates that no accessory is present.
JOYBUS_ACCESSORY_IO_STATUS_BAD_CRCThe data checksum does not match the provided checksum.

◆ joybus_accessory_read_async()

void joybus_accessory_read_async ( int  port,
uint16_t  addr,
joybus_callback_t  callback,
void *  ctx 
)

Asynchronously perform a Joybus N64 accessory read command.

Parameters
portThe controller port of the accessory to read from.
addrThe accessory address to read from.
callbackA function pointer to call when the operation completes.
ctxA user data pointer to pass into the callback function.

◆ joybus_accessory_write_async()

void joybus_accessory_write_async ( int  port,
uint16_t  addr,
const uint8_t *  data,
joybus_callback_t  callback,
void *  ctx 
)

Asynchronously perform a Joybus N64 accessory write command.

Parameters
portThe controller port of the accessory to write to.
addrThe accessory address to write to.
[in]dataThe data to write to the accessory.
callbackA function pointer to call when the operation completes.
ctxA user data pointer to pass into the callback function.

◆ joybus_accessory_read()

int joybus_accessory_read ( int  port,
uint16_t  addr,
uint8_t *  data 
)

Synchronously perform a Joybus N64 accessory read command.

Parameters
portThe controller port of the accessory to read from.
addrThe accessory address to start reading from.
[out]dataThe 32 bytes of data that was read from the accessory.
Return values
JOYBUS_ACCESSORY_IO_STATUS_OKThe data was read successfully.
JOYBUS_ACCESSORY_IO_STATUS_NO_PAKNo accessory is present.
JOYBUS_ACCESSORY_IO_STATUS_BAD_CRCThe data was not read successfully.

◆ joybus_accessory_write()

int joybus_accessory_write ( int  port,
uint16_t  addr,
const uint8_t *  data 
)

Synchronously perform a Joybus N64 accessory write command.

Parameters
portThe controller port of the accessory to write to.
addrThe accessory address to start writing to.
[in]dataThe 32 bytes of data to write to the accessory.
Return values
JOYBUS_ACCESSORY_IO_STATUS_OKThe data was written successfully.
JOYBUS_ACCESSORY_IO_STATUS_NO_PAKNo accessory is present.
JOYBUS_ACCESSORY_IO_STATUS_BAD_CRCThe data was not written successfully.

◆ joybus_exec_async()

void joybus_exec_async ( const void *  input,
joybus_callback_t  callback,
void *  ctx 
)

Execute an asynchronous joybus message.

This function executes an asynchronous joybus protocol exchange, sending a message block (input), and receiving a reply (output). The message is sent in background and a completion function "callback" is called when the output is ready to be processed.

It is possible to schedule multiple joybus messages by calling this function multiple times. They will be automatically executed in order. The maximum number of pending messages at any given time is MAX_JOYBUS_MSGS.

Note
The callback function will be called under interrupt.
This function is not part of the public API yet because we want to evaluate the use of threading rather than asynchronous programming. It should only be used internally without exposing a asynchronous API externally.
Parameters
[in]inputThe input block (must be of JOYBUS_BLOCK_SIZE bytes). No specific alignment is required for this data block.
[in]callbackA callback completion function that will be called when the joybus command is finished. The function will receive a pointer to the output buffer and the opaque pointer to the callback's context. Can be NULL if no callback is required.
[in]ctxContext opaque pointer to pass to the callback. Can be NULL if no context is required.

◆ joybus_exec()

void joybus_exec ( const void *  input,
void *  output 
)

Write a 64-byte block of data to the PIF and read the 64-byte result.

This function is not a stable feature of the libdragon API and should be considered experimental!

The usage of this function will likely change as a result of the ongoing effort to integrate the multitasking kernel with asynchronous operations.

Parameters
[in]inputSource buffer for the input block to send to the PIF
[out]outputDestination buffer to place the output block from the PIF

◆ joybus_exec_cmd()

void joybus_exec_cmd ( int  port,
size_t  send_len,
size_t  recv_len,
const void *  send_data,
void *  recv_data 
)
inline

Execute a Joybus command synchronously on the given port.

For convenience, there is a joybus_exec_cmd_struct macro that uses the send and recv fields of a command struct to call this function with the proper send_len and recv_len arguments.

This function only sends a single command to a single port. For sending a command to multiple ports simultaneously, use joybus_exec instead.

For reading controllers, use the Joypad Subsystem instead.

This function is not a stable feature of the libdragon API and should be considered experimental!

The usage of this function will likely change as a result of the ongoing effort to integrate the multitasking kernel with asynchronous operations.

Note
This function is slow: it blocks until the command completes. Calling this function multiple times per frame may cause audio and video stuttering.
Parameters
portThe Joybus port (0-4) to send the command to.
send_lenNumber of bytes in the send_data request payload (including the command ID).
recv_lenNumber of bytes in the recv_data response payload.
[in]send_dataBuffer of send_len bytes to send to the Joybus device (including the command ID byte).
[out]recv_dataBuffer of recv_len bytes for the reply from the Joybus device.