#ifndef GUARD_LIBRFU_H #define GUARD_LIBRFU_H #include "global.h" #include "main.h" #define LIBRFU_VERSION 1026 /* TODOs: * - documentation * - check if any field needs to be volatile * - check if field names make sense */ // -------------------------------------------------------------------------- // // Restrictions When Using RFU // // -------------------------------------------------------------------------- /* The following restrictions apply when using RFU. (a) The timer for Sound DMA uses only 0 (b) The prescaler for the timer count for the Sound DMA uses 59.5 ns. (c) The sound sampling rate is Max36.314KHz. These types of DMA can be operated on a maximum CPU cycle of 42 cycles. Calculate the number of the transferable DMA count based on this 42 cycles and the access cycles of the destination and source. For example, if both the CPU internal RAM --> VRAM have a one cycle access, then a 21 count DMA can occur. If RFU is used outside of these restrictions, problems, such as the loss of data caused by the failure of the AGB, as a clock slave, to notify that data has been received from the RFU, will occur. When this problem occurs, the REQ callback will send a REQ_commandID=ID_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA_REQ notification. (When using Link Manager, the LMAN call back will send a LMAN_msg=LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA notification.) */ // REQ-COMMAND (STWI) ID CODE LIST // REQ Command ID returned by the REQ callback #define ID_RESET_REQ 0x0010 #define ID_LINK_STATUS_REQ 0x0011 #define ID_VERSION_STATUS_REQ 0x0012 // not defined in SDK header #define ID_SYSTEM_STATUS_REQ 0x0013 #define ID_SLOT_STATUS_REQ 0x0014 // not defined in SDK header #define ID_CONFIG_STATUS_REQ 0x0015 // not defined in SDK header #define ID_GAME_CONFIG_REQ 0x0016 #define ID_SYSTEM_CONFIG_REQ 0x0017 #define ID_SC_START_REQ 0x0019 #define ID_SC_POLL_REQ 0x001a #define ID_SC_END_REQ 0x001b #define ID_SP_START_REQ 0x001c #define ID_SP_POLL_REQ 0x001d #define ID_SP_END_REQ 0x001e #define ID_CP_START_REQ 0x001f #define ID_CP_POLL_REQ 0x0020 #define ID_CP_END_REQ 0x0021 #define ID_DATA_TX_REQ 0x0024 #define ID_DATA_TX_AND_CHANGE_REQ 0x0025 #define ID_DATA_RX_REQ 0x0026 #define ID_MS_CHANGE_REQ 0x0027 // When returned by the REQ callback, this ID indicates that execution of rfu_REQ_changeMasterSlave has finished. // This ID is returned by both the REQ callback and the MSC callback. // When returned by the MSC callback, this is notification that after the AGB has been made into the clock slave, the MC_Timer expired and the RFU returned the AGB to be the clock master. #define ID_DISCONNECT_REQ 0x0030 #define ID_TEST_MODE_REQ 0x0031 // not defined in SDK header #define ID_CPR_START_REQ 0x0032 #define ID_CPR_POLL_REQ 0x0033 #define ID_CPR_END_REQ 0x0034 #define ID_UNK35_REQ 0x0035 // not defined in SDK header #define ID_UNK36_REQ 0x0036 // not defined in SDK header #define ID_RESUME_RETRANSMIT_AND_CHANGE_REQ 0x0037 #define ID_STOP_MODE_REQ 0x003d #define ID_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA_REQ 0x00ff // When the AGB is the clock slave, the RFU generates an informational notice, and an automatically started DMA, such as HDMA, is generated at the instant the AGB is being returned as the clock master. This ID is notified by a REQ callback when the exchange of this information (REQ command) fails. // REQ Command ID returned by the MSC callback #define ID_DISCONNECTED_AND_CHANGE_REQ 0x0029 #define ID_DATA_READY_AND_CHANGE_REQ 0x0028 #define ID_DRAC_REQ_WITH_ACK_FLAG 0x0128 // -------------------------------------------------------------------------- // // Data Definitions // // -------------------------------------------------------------------------- #define RFU_ID 0x00008001 // ID number of AGB-RFU device: ID returned by execution of rfu_REQBN_softReset_and_checkID. #define RFU_MBOOT_DOWNLOADER_SERIAL_NO 0x0000 // The game serial number of the multi-boot downloader (programs that boot without a Game Pak) #define RFU_API_BUFF_SIZE_RAM 0x0e64 // Necessary size for buffer specified by rfu_initializeAPI (fast communication version that operates the library SIO interrupt routines in RAM) #define RFU_API_BUFF_SIZE_ROM 0x0504 // Necessary size for buffer specified by rfu_initializeAPI (fast communication version that operates the library SIO interrupt routines in ROM) #define RFU_CHILD_MAX 4 // Maximum number of slaves that can be connected to one parent device #define RFU_GAME_NAME_LENGTH 13 // Possible length of game name set by rfu_REQB_configGameData #define RFU_USER_NAME_LENGTH 8 // Possible length of user name set by rfu_REQB_configGameData #define RFU_H_DMA_MAX_CPU_CYCLE 42 // Maximum number of CPU cycles for H-DMA or DMA that starts with V-Blank that can operate when using RFU // Value to determine the level of the icon that displays the link strength of the wireless status (value of rfuLinkStatus->strength[0-3]) #define RFU_LINK_ICON_LEVEL4_MAX 255 // 90% -100% (If the value is betwen 229 and 255, the icon level is 4) #define RFU_LINK_ICON_LEVEL4_MIN 229 #define RFU_LINK_ICON_LEVEL3_MAX 228 // 50% - 89% (If the value is betwen 127 and 228, the icon level is 3) #define RFU_LINK_ICON_LEVEL3_MIN 127 #define RFU_LINK_ICON_LEVEL2_MAX 126 // 10% - 49% (If the value is betwen 25 and 126, the icon level is 2) #define RFU_LINK_ICON_LEVEL2_MIN 25 #define RFU_LINK_ICON_LEVEL1_MAX 24 // 0% - 9% (If the value is betwen 0 and 24, the icon level is 1) #define RFU_LINK_ICON_LEVEL1_MIN 0 // ******************************************************* // Definition Data for Arguments Used in Library Functions // ******************************************************* // Specified by u16 mbootFlag in rfu_REQ_configGameData #define RFU_MBOOT_FLAG 0x01 // Enabling this flag, allows connection to a multi-boot program. // AvailSlot (number of slots available for connection) used in u16 availSlotFlag in rfu_REQ_configSystem #define AVAIL_SLOT4 0x0000 #define AVAIL_SLOT3 0x0001 #define AVAIL_SLOT2 0x0002 #define AVAIL_SLOT1 0x0003 // u8 connTypeFlag specified by rfu_setRecvBuffer #define TYPE_UNI 0x10 // UNI-type #define TYPE_NI 0x20 // NI-type // u8 connTypeFlag specified by rfu_clearSlot #define TYPE_UNI_SEND 0x01 // UNI-type send #define TYPE_UNI_RECV 0x02 // UNI-type receive #define TYPE_NI_SEND 0x04 // NI-type send #define TYPE_NI_RECV 0x08 // NI-type receive // ******************************************************* // Definition Data Returned by Return Values for Library Functions // ******************************************************* // The function doesn't have return value. // Value of u8 *status for rfu_REQ_pollConnectParent (Connection Trial Status) // #define CP_STATUS_DONE 0x00 // Connection successful // #define CP_STATUS_IN_PROCESS 0x01 // Connecting // #define CP_STATUS_SLOT_CLOSED 0x02 // Parent device is not in connection mode with child device // #define CP_STATUS_DISCONNECTED 0x03 // Disconnected by parent device while connecting // #define CP_STATUS_UNKNOWN 0xff // Cannot read status due to REQ-API execution error // The function doesn't exist. // Value of u8 *status argument for rfu_REQ_pollRecoveryConnect (Link Restore Status) // #define RC_STATUS_DONE 0x00 // Connection restore successful // #define RC_STATUS_FAILED 0x01 // Connection restore failure (meaningless to try anymore) // #define RC_STATUS_SEARCHING_PARENT 0x02 // Searching for parent device // #define RC_STATUS_UNKNOWN 0xff // Cannot read status due to REQ-API execution error // Value of u8 *linkLossReason argument for rfu_REQBN_watchLink (Reason for Link Loss) #define REASON_DISCONNECTED 0x00 // State of complete disconnection with rfuLL_disconnect and no possibility of restoring the link (can detect only child device) #define REASON_LINK_LOSS 0x01 // State of link loss that allows for the possibility for the link to be restored // ******************************************************* // Definition Data Returned with Return Values for Library Functions // ******************************************************* // Value returned by rfu_getMasterSlave #define AGB_CLK_SLAVE 0 // AGB clock slave #define AGB_CLK_MASTER 1 // AGB clock master // ******************************************************* // Error Code Group for Library Functions // ******************************************************* // Error codes returned by u16 REQ_result with a REQ callback when a REQ-API function is executed #define ERR_REQ_CMD 0x0000 #define ERR_REQ_CMD_CLOCK_DRIFT (ERR_REQ_CMD | 0x0001) // Clock drift occurs when a REQ command is sent #define ERR_REQ_CMD_SENDING (ERR_REQ_CMD | 0x0002) // The next command cannot be issued because a REQ command is being sent #define ERR_REQ_CMD_ACK_REJECTION (ERR_REQ_CMD | 0x0003) // The REQ command was refused when issued #define ERR_REQ_CMD_CLOCK_SLAVE (ERR_REQ_CMD | 0x0004) // Issuing the REQ command was attempted but failed because the AGB is the clock slave #define ERR_REQ_CMD_IME_DISABLE (ERR_REQ_CMD | 0x0006) // Issuing the REQ command was attempted but failed because the IME register is 0 #define ERR_PID_NOT_FOUND 0x0100 // The specified PID does not exist in the gRfuLinkStatus->partner[0-3].id list // Error code returned by the return value of rfu_initializeAPI #define ERR_RFU_API_BUFF_SIZE 0x0001 #define ERR_RFU_API_BUFF_ADR 0x0002 // Error codes returned by return values for rfu_REQBN_softReset_and_checkID #define ERR_ID_CHECK_IME_DISABLE 0xffffffff // ID check could not be executed because REG_IME=0 when executing rfu_REQBN_softReset_and_checkID // Error codes returned by rfu_getConnectParentStatus and rfu_CHILD_getConnectRecoveryStatus #define ERR_REQ_CMD_ID (ERR_REQ_CMD | 0x0010) // A required REQ command was not executed within this function execution // Error codes returned by rfu_NI_setSendData, rfu_UNI_setSendData, and rfu_NI_CHILD_setSendGameName #define ERR_MODE 0x0300 #define ERR_MODE_NOT_PARENT (ERR_MODE | 0x0000) // not in SDK #define ERR_MODE_NOT_CONNECTED (ERR_MODE | 0x0001) // RFU is not in connection mode (parent or child) #define ERR_SLOT 0x0400 #define ERR_SLOT_NO (ERR_SLOT | 0x0000) // The specified slot number is not right #define ERR_SLOT_NOT_CONNECTED (ERR_SLOT | 0x0001) // The specified slot is not connected #define ERR_SLOT_BUSY (ERR_SLOT | 0x0002) // The specified slot is already communicating #define ERR_SLOT_NOT_SENDING (ERR_SLOT | 0x0003) // The specified slot is not currently sending (Note: This is returned by rfu_UNI_re_setSendData) #define ERR_SLOT_TARGET (ERR_SLOT | 0x0004) // The specified target slot is not right #define ERR_SUBFRAME_SIZE 0x0500 // The specified subframe size is either larger than the remaining communication frame size or smaller than the link layer subframe header size // Error code returned by rfu_clearSlot, rfu_setRecvBuffer, and rfu_changeSendTarget #define ERR_COMM_TYPE 0x0600 // The specified communication format is not right // Error code returned by rfu_REQ_recvData (when receiving NI-type or UNI-type data) #define ERR_DATA_RECV 0x0700 // Error notification is issued in the following format. // "ERR_DATA_RECV | (slot number issuing error with 0x0010<recv.errorCode. // Error code during NI-type communication (code entered into gRfuSlotStatusNI[x]->recv.errorCode) #define ERR_RECV_BUFF_OVER (ERR_DATA_RECV | 0x0001) // The receive data size is larger than the receive buffer (Note: This error is used for both NI and UNI) #define ERR_RECV_REPLY_SUBFRAME_SIZE (ERR_DATA_RECV | 0x0002) // All frames are already in use by other communications, and a subframe for reception response could not be secured // Error code during UNI-type communication (code entered into gRfuSlotStatusUNI[x]->recv.errorCode) #define ERR_RECV_DATA_OVERWRITED (ERR_DATA_RECV | 0x0008) // Received new data when gRfuSlotStatusUNI[x]->recv.newDataFlag=1 // not in SDK header #define ERR_RECV_UNK (ERR_DATA_RECV | 0x0001 | 0x0008) // ******************************************************* // Definition Data Used by Global Variables in the Library // ******************************************************* // gRfuLinkStatus------------------------------------------- // Connection status (refer to gRfuLinkStatus->parentChild) #define MODE_NEUTRAL 0xff // Initialization #define MODE_CHILD 0x00 // Child #define MODE_PARENT 0x01 // Parent // gRfuSlotStatusNI,UNI----------------------------------- // Definition data for NI-(Numbered Information) and UNI-(Un-Numbered Information) type communication // Definition data common to NI- and UNI-type communication #define LLF_P_SIZE 87 // Maximum link layer communication frame size for the Parent (Maximum number of bytes per transmission) #define LLF_C_SIZE 16 // " " for the Child #define LLSF_P_HEADER_SIZE 3 // Header size used by one link layer subframe (NI or UNI frame) for the Parent #define LLSF_C_HEADER_SIZE 2 // " " for the Child // Link Layer Communication Code #define LCOM_NULL 0x0000 #define LCOM_NI_START 0x0001 #define LCOM_NI 0x0002 #define LCOM_NI_END 0x0003 #define LCOM_UNI 0x0004 // Flag for Slot Status Data #define SLOT_BUSY_FLAG 0x8000 // Slot in use #define SLOT_SEND_FLAG 0x0020 // Send #define SLOT_RECV_FLAG 0x0040 // Receive // NI- and UNI-type shared slot stand-by data (same state as gRfuSlotStatusNI[x]->send or ->recv.state or gRfuSlotStatusUNI) #define SLOT_STATE_READY 0x0000 // Slot initialization // Status data for NI-type communication (gRfuSlotStatusNI[x]->send or ->recv.state) #define SLOT_STATE_SEND_START (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NI_START) // Start transmission #define SLOT_STATE_SENDING (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NI) // Transmitting #define SLOT_STATE_SEND_LAST (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NI_END) // Verify transmission end #define SLOT_STATE_SEND_NULL (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_NULL) // Send NULL subframe to notify end of transmission #define SLOT_STATE_SEND_SUCCESS ( SLOT_SEND_FLAG | 0x006) // Transmission successful #define SLOT_STATE_SEND_FAILED ( SLOT_SEND_FLAG | 0x007) // Transmission failed // Distinction of slot where transmission succeeded/failed compares gRfuSlotStatusNI[x]->send.bmSlot and same bmSlot_org #define SLOT_STATE_RECV_START (SLOT_BUSY_FLAG | SLOT_RECV_FLAG | LCOM_NI_START) // Start reception #define SLOT_STATE_RECEIVING (SLOT_BUSY_FLAG | SLOT_RECV_FLAG | LCOM_NI) // Receiving #define SLOT_STATE_RECV_LAST (SLOT_BUSY_FLAG | SLOT_RECV_FLAG | LCOM_NI_END) // Verify reception end #define SLOT_STATE_RECV_SUCCESS ( SLOT_RECV_FLAG | 0x006) // Reception successful #define SLOT_STATE_RECV_FAILED ( SLOT_RECV_FLAG | 0x007) // Reception failed #define SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN (SLOT_RECV_FLAG | 0x008) // The data was received successful, but because the end of the communication was incomplete, whether the transmission side status is successful or failed is unknown #define SLOT_STATE_RECV_IGNORE ( SLOT_RECV_FLAG | 0x009) // Ignore reception (refer to gRfuSlotStatusNI[x]->recv.errorCode for reason for ignoring) // Status data for UNI-type communication (refer to gRfuSlotStatusUNI[x]->send.state) #define SLOT_STATE_SEND_UNI (SLOT_BUSY_FLAG | SLOT_SEND_FLAG | LCOM_UNI) // Transmitting // the following structs are not documented in SDK struct RfuPacket8 { u8 data[0x74]; }; struct RfuPacket32 { u32 command; u32 data[0x1C]; }; union RfuPacket { struct RfuPacket32 rfuPacket32; struct RfuPacket8 rfuPacket8; }; struct STWIStatus { vs32 state; u8 reqLength; u8 reqNext; u8 reqActiveCommand; u8 ackLength; u8 ackNext; u8 ackActiveCommand; u8 timerSelect; u8 unk_b; #if LIBRFU_VERSION >= 1026 s32 timerState; #else u32 timerState; #endif vu8 timerActive; u8 unk_11; vu16 error; vu8 msMode; u8 recoveryCount; u8 unk_16; u8 unk_17; void (*callbackM)(); void (*callbackS)(u16); void (*callbackID)(void); union RfuPacket *txPacket; union RfuPacket *rxPacket; vu8 sending; }; // This struct is used as u8 array in SDK. struct RfuIntrStruct { union RfuPacket rxPacketAlloc; union RfuPacket txPacketAlloc; u8 ALIGNED(2) block1[0x960]; // size of librfu_intr.s binary struct STWIStatus block2; }; // Data Structure for Transmitting UNI-Type Data struct UNISend { u16 state; // Slot communication state (SLOT_STATE_READY, SLOT_STATE_SEND_UNI) u8 dataReadyFlag; // Flag indicating transmission data is prepared (0: data sent; 1: transmission data ready) // Set with rfu_UNI_re_setSendData or rfu_UNI_readySendData, cleared when data is sent with rfu_REQ_sendData. u8 bmSlot; // Expresses transmission destination slot as bits u16 payloadSize; // Payload size of 1 transmission. "size" specified by rfu_UNI_setSendData or rfu_UNI_re_setSendData is used. const void *src; // Beginning address of transmission data }; // Data Structure for Receiving UNI Data struct UNIRecv { u16 state; // Slot communication state (SLOT_STATE_READY, SLOT_STATE_RECEIVING, SLOT_STATE_RECV_IGNORE) u16 errorCode; // Error code during reception u16 dataSize; // Size of receive data u8 newDataFlag; // Flag indicating whether receive data has newly arrived (0: no newly arrived data; 1: newly arrived data) // The flag is cleared with rfu_UNI_clearRecvNewDataFlag; it is set when data is received with rfu_REQ_recvData. u8 dataBlockFlag; // Flag for unreferenced receive data overwrite block (default is 0 Note: not used) }; // Slot Status Data Structure for UNI-Type Communication struct RfuSlotStatusUNI { struct UNISend send; // Transmission Status struct UNIRecv recv; // Reception Status void *recvBuffer; // Reception Buffer Address u32 recvBufferSize; // Reception Buffer Size }; #define WINDOW_COUNT 4 struct NIComm { u16 state; // Communication state of slot u16 failCounter; // Count of failed transmissions/receptions (Count is increased when transmission/reception of data does not succeed within 1PF=16.7 ms) const u8 *now_p[WINDOW_COUNT]; // Address of current send/receive (The data is divided into WINDOW_COUNT blocks and sent in payloadSize units.) u32 remainSize; // Size of remaining communication data u16 errorCode; // Error code u8 bmSlot; // Expresses the current communication slot in bits // (When sending from the Master, because multiple slaves can be specified with bmSlot, communications are terminated based on the failCounter for each child device) // Parameters used inside the Library u8 recvAckFlag[WINDOW_COUNT]; u8 ack; u8 phase; u8 n[WINDOW_COUNT]; // Parameters indicating the current communication content const void *src; // Start address transmission data (valid only for transmitting device) u8 bmSlotOrg; // Expresses the communication source slot at the beginning of the transmission in bits (valid only for transmitting device) u8 dataType; // Transmission/reception data type (0: User data; 1: Game identification information) u16 payloadSize; // Payload size for one transmission u32 dataSize; // Size of transmission/reception data // Calculated by subtracting link layer header size from subFrameSize specified by the rfu_NI_setSendData function }; struct RfuSlotStatusNI { struct NIComm send; // Transmission Status struct NIComm recv; // Reception Status void *recvBuffer; // Reception Buffer Address u32 recvBufferSize; // Reception Buffer Size }; // Game Identification Information Data Structure struct RfuTgtData { u16 id; // ID of parent candidate ID of connection partner u8 slot; // Slot number where parent candidate can enter Connection slot number u8 mbootFlag; // Flag to indicate whether or not the parent candidate Flag to indicate whether or not the connection partner // is multiboot program for download is multiboot program for download u16 serialNo; // Game serial number of parent candidate Game serial number of connection partner u8 gname[RFU_GAME_NAME_LENGTH + 2]; // Game name of parent candidate Game name of connection partner u8 uname[RFU_USER_NAME_LENGTH + 1]; // User name for parent candidate User name for connection partner }; struct RfuLinkStatus { u8 parentChild; // Connection status (0x01:MODE_PARENT 0x00:MODE_CHILD 0xff:MODE_NEUTRAL) u8 connCount; // Number of connections u8 connSlotFlag; // Flag to indicate in bits the connection slot (0x01<