libjoybus
Joybus implementation for 32-bit MCUs
Loading...
Searching...
No Matches
identify.h
Go to the documentation of this file.
6
7#pragma once
8
9#include <stdbool.h>
10#include <stdint.h>
11
12/*
13 * Joybus device type flags.
14 *
15 * The first two bytes of the identify response contain the device type flags.
16 *
17 * The following flags map to the little-endian representation of the first two
18 * bytes of the identify response. We're using a little-endian representation,
19 * since modern microcontrollers are pretty much all little-endian by default.
20 * This helps us avoid byte swapping when parsing the identify response, we can
21 * cast the bytes to a joybus_id struct and use these masks as-is.
22 */
23
24// Non-GameCube device types
25#define JOYBUS_TYPE_N64_MASK 0x1f07
26#define JOYBUS_TYPE_N64_ABSOLUTE 0x0001
27#define JOYBUS_TYPE_N64_RELATIVE 0x0002
28#define JOYBUS_TYPE_N64_JOYPORT 0x0004
29#define JOYBUS_TYPE_N64_VRU 0x0100
30#define JOYBUS_TYPE_N64_KEYBOARD 0x0200
31#define JOYBUS_TYPE_GBA_CABLE 0x0400
32#define JOYBUS_TYPE_N64_RTC 0x1000
33#define JOYBUS_TYPE_N64_EEPROM_16K 0x4000
34#define JOYBUS_TYPE_N64_EEPROM 0x8000
35
36// GameCube device types
37#define JOYBUS_TYPE_GCN_MASK 0x0018
38#define JOYBUS_TYPE_GCN_STANDARD 0x0001
39#define JOYBUS_TYPE_GCN_WIRELESS_STATE 0x0002
40#define JOYBUS_TYPE_GCN_DEVICE 0x0008
41#define JOYBUS_TYPE_GCN_NO_MOTOR 0x0020
42#define JOYBUS_TYPE_GCN_WIRELESS_RECEIVED 0x0040
43#define JOYBUS_TYPE_GCN_WIRELESS 0x0080
44#define JOYBUS_TYPE_GCN_WIRELESS_ID_FIXED 0x1000
45#define JOYBUS_TYPE_GCN_KEYBOARD 0x2000
46#define JOYBUS_TYPE_GCN_WIRELESS_ORIGIN 0x2000
47#define JOYBUS_TYPE_GCN_WIRELESS_ID_MASK 0xC000
48
49/*
50 * Joybus device status flags.
51 *
52 * The last byte of the identify response contains the device "status" flags.
53 */
54
55// Status flags for N64 controllers with a Joyport
56#define JOYBUS_STATUS_N64_PAK_PRESENT 0x01
57#define JOYBUS_STATUS_N64_PAK_PULLED 0x02
58#define JOYBUS_STATUS_N64_ADDR_CHECKSUM_ERROR 0x04
59
60// Status flags for N64 Voice Recognition Unit
61#define JOYBUS_STATUS_N64_VRU_INITIALIZED 0x01
62
63// Status flags for non-wireless GameCube controllers
64#define JOYBUS_STATUS_GCN_ANALOG_MODE_MASK 0x07
65#define JOYBUS_STATUS_GCN_MOTOR_STATE_MASK 0x18
66#define JOYBUS_STATUS_GCN_NEED_ORIGIN 0x20
67#define JOYBUS_STATUS_GCN_ERROR_LATCHED 0x40
68#define JOYBUS_STATUS_GCN_ERROR 0x80
69#define JOYBUS_STATUS_GCN_MOTOR_STATE_SHIFT 3
70#define JOYBUS_STATUS_GCN_ANALOG_MODE_SHIFT 0
71
72// Status flags for wireless GameCube controllers
73#define JOYBUS_STATUS_GCN_WIRELESS_ID_MASK 0xFF
74
75/*
76 * Complete type flags a device reports at power on.
77 *
78 * Most controllers keep the type field constant, but since wireless GameCube
79 * controllers use the status field to hold the wireless ID, they add flags
80 * to the type field at runtime instead to indicate their state.
81 */
82
84#define JOYBUS_DEVICE_N64_CONTROLLER (JOYBUS_TYPE_N64_ABSOLUTE | JOYBUS_TYPE_N64_JOYPORT)
85
87#define JOYBUS_DEVICE_N64_MOUSE (JOYBUS_TYPE_N64_RELATIVE)
88
90#define JOYBUS_DEVICE_GCN_CONTROLLER (JOYBUS_TYPE_GCN_DEVICE | JOYBUS_TYPE_GCN_STANDARD)
91
93#define JOYBUS_DEVICE_GCN_WAVEBIRD (JOYBUS_TYPE_GCN_DEVICE | JOYBUS_TYPE_GCN_WIRELESS | JOYBUS_TYPE_GCN_NO_MOTOR)
94
98struct joybus_id {
100 uint16_t type;
101
103 uint8_t status;
104} __attribute__((packed));
105
112static inline void joybus_id_clear_type_flags(struct joybus_id *id, uint16_t flags)
113{
114 id->type &= ~flags;
115}
116
123static inline void joybus_id_set_type_flags(struct joybus_id *id, uint16_t flags)
124{
125 id->type |= flags;
126}
127
134static inline void joybus_id_clear_status_flags(struct joybus_id *id, uint8_t flags)
135{
136 id->status &= ~flags;
137}
138
145static inline void joybus_id_set_status_flags(struct joybus_id *id, uint8_t flags)
146{
147 id->status |= flags;
148}
149
156static inline uint16_t joybus_id_get_wireless_id(const struct joybus_id *id)
157{
158 return (uint16_t)((id->type & 0xC000) >> 6 | id->status);
159}
160
167static inline void joybus_id_set_wireless_id(struct joybus_id *id, uint16_t wireless_id)
168{
169 id->type = (id->type & ~0xC000) | ((uint16_t)((wireless_id >> 2) & 0xC0) << 8);
170 id->status = wireless_id & 0xFF;
171}
172
179static inline bool joybus_id_n64_pak_changed(const struct joybus_id *id)
180{
182}
static void joybus_id_set_wireless_id(struct joybus_id *id, uint16_t wireless_id)
Set the 10-bit wireless ID in an "identify" buffer.
Definition identify.h:167
#define JOYBUS_STATUS_N64_PAK_PRESENT
Pak present.
Definition identify.h:56
static uint16_t joybus_id_get_wireless_id(const struct joybus_id *id)
Get the 10-bit wireless ID from an "identify" buffer.
Definition identify.h:156
static void joybus_id_clear_status_flags(struct joybus_id *id, uint8_t flags)
Clear status flags in an "identify" buffer.
Definition identify.h:134
#define JOYBUS_STATUS_N64_PAK_PULLED
Pak removal/change detected.
Definition identify.h:57
static void joybus_id_clear_type_flags(struct joybus_id *id, uint16_t flags)
Clear type flags in an "identify" buffer.
Definition identify.h:112
static void joybus_id_set_status_flags(struct joybus_id *id, uint8_t flags)
Set status flags in an "identify" buffer.
Definition identify.h:145
static bool joybus_id_n64_pak_changed(const struct joybus_id *id)
Check if the pak changed flag is set in an "identify" buffer.
Definition identify.h:179
static void joybus_id_set_type_flags(struct joybus_id *id, uint16_t flags)
Set type flags in an "identify" buffer.
Definition identify.h:123
Represents the 3-byte ID field from an "identify" buffer.
Definition identify.h:98
uint8_t status
Status flags.
Definition identify.h:103
uint16_t type
Type flags.
Definition identify.h:100