mirror of
https://github.com/HackerN64/HackerOoT.git
synced 2026-01-21 10:37:37 -08:00
Add very basic UNFLoader support (#169)
* basic unfloader support (no gdb yet) * fix build issues
This commit is contained in:
@@ -251,3 +251,15 @@ endif
|
||||
# same as above and start listening to the IS-Viewer
|
||||
sc64v: sc64
|
||||
$(SC64_DEPLOYER) debug --isv 0x03FF0000
|
||||
|
||||
### UNFLoader Settings ###
|
||||
|
||||
# TODO: download this automatically
|
||||
UNFLOADER ?= UNFLoader
|
||||
|
||||
# upload the build
|
||||
unf: rom
|
||||
ifeq ($(UNFLOADER),)
|
||||
$(error sc64deployer path not set. Set UNFLOADER in the Makefile or define it as an environment variable)
|
||||
endif
|
||||
$(UNFLOADER) -r $(ROM) -d
|
||||
|
||||
@@ -84,4 +84,10 @@
|
||||
*/
|
||||
#define ENABLE_DEBUG_BOOT true
|
||||
|
||||
/**
|
||||
* Enable UNFLoader support
|
||||
* This is required to use the command system.
|
||||
*/
|
||||
#define ENABLE_UNF true
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#undef ENABLE_MOTION_BLUR_DEBUG
|
||||
#undef ENABLE_HACKER_DEBUG
|
||||
#undef ENABLE_PROFILER
|
||||
#undef ENABLE_UNF
|
||||
|
||||
#define SKIP_N64_BOOT_LOGO false
|
||||
#define BOOT_TO_SCENE false
|
||||
@@ -67,6 +68,7 @@
|
||||
#define ENABLE_MOTION_BLUR_DEBUG false
|
||||
#define ENABLE_HACKER_DEBUG false
|
||||
#define ENABLE_PROFILER false
|
||||
#define ENABLE_UNF false
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define NDEBUG
|
||||
|
||||
@@ -92,6 +92,12 @@ DECLARE_ROM_SEGMENT(debug)
|
||||
DECLARE_BSS_SEGMENT(debug)
|
||||
#endif
|
||||
|
||||
#if ENABLE_UNF
|
||||
DECLARE_SEGMENT(usb)
|
||||
DECLARE_ROM_SEGMENT(usb)
|
||||
DECLARE_BSS_SEGMENT(usb)
|
||||
#endif
|
||||
|
||||
// N64-only, these are not wrapped in an `#if PLATFORM_N64`
|
||||
// so that the N64DD code can always be built.
|
||||
DECLARE_SEGMENT(n64dd)
|
||||
|
||||
180
include/usb/debug.h
Normal file
180
include/usb/debug.h
Normal file
@@ -0,0 +1,180 @@
|
||||
#ifndef UNFL_DEBUG_H
|
||||
#define UNFL_DEBUG_H
|
||||
|
||||
/*********************************
|
||||
Settings macros
|
||||
*********************************/
|
||||
|
||||
// Enable/Disable debug
|
||||
#ifndef DEBUG_MODE
|
||||
#define DEBUG_MODE 1 // Enable/Disable debug mode
|
||||
#endif
|
||||
|
||||
// Settings
|
||||
#define DEBUG_INIT_MSG 1 // Print a message when debug mode has initialized
|
||||
#define AUTOPOLL_ENABLED 1 // Automatically poll the USB on a timer
|
||||
#define AUTOPOLL_TIME 200 // Time (in milliseconds) between auto polls
|
||||
#define USE_FAULTTHREAD 1 // Create a fault detection thread (libultra only)
|
||||
#define USE_RDBTHREAD 0 // Create a remote debugger thread
|
||||
#define OVERWRITE_OSPRINT 1 // Replaces osSyncPrintf calls with debug_printf (libultra only)
|
||||
#define MAX_COMMANDS 25 // The max amount of user defined commands possible
|
||||
|
||||
// USB thread definitions (libultra only)
|
||||
#define USB_THREAD_ID 14
|
||||
#define USB_THREAD_PRI 126
|
||||
#define USB_THREAD_STACK 0x2000
|
||||
|
||||
// Fault thread definitions (libultra only)
|
||||
#define FAULT_THREAD_ID 13
|
||||
#define FAULT_THREAD_PRI 125
|
||||
#define FAULT_THREAD_STACK 0x2000
|
||||
|
||||
// Remote debugger thread definitions (libultra only)
|
||||
#define RDB_THREAD_ID 15
|
||||
#define RDB_THREAD_PRI 124
|
||||
#define RDB_THREAD_STACK 0x2000
|
||||
|
||||
|
||||
/*********************************
|
||||
Debug Functions
|
||||
*********************************/
|
||||
|
||||
#if DEBUG_MODE
|
||||
|
||||
/*==============================
|
||||
debug_initialize
|
||||
Initializes the debug and USB library.
|
||||
Should be called last during game initialization.
|
||||
==============================*/
|
||||
|
||||
extern void debug_initialize();
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_printf
|
||||
Prints a formatted message to the developer's command prompt.
|
||||
Supports up to 256 characters.
|
||||
@param A string to print
|
||||
@param variadic arguments to print as well
|
||||
==============================*/
|
||||
|
||||
extern void debug_printf(const char* message, ...);
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_dumpbinary
|
||||
Dumps a binary file through USB
|
||||
@param The file to dump
|
||||
@param The size of the file
|
||||
==============================*/
|
||||
|
||||
extern void debug_dumpbinary(void* file, int size);
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_screenshot
|
||||
Sends the currently displayed framebuffer through USB.
|
||||
DOES NOT PAUSE DRAWING THREAD! Using outside the drawing
|
||||
thread may lead to a screenshot with visible tearing
|
||||
==============================*/
|
||||
|
||||
extern void debug_screenshot();
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_assert
|
||||
Halts the program if the expression fails.
|
||||
@param The expression to test
|
||||
==============================*/
|
||||
|
||||
#define debug_assert(expr) (expr) ? ((void)0) : _debug_assert(#expr, __FILE__, __LINE__)
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_64drivebutton
|
||||
Assigns a function to be executed when the 64drive button is pressed.
|
||||
@param The function pointer to execute
|
||||
@param Whether or not to execute the function only on pressing (ignore holding the button down)
|
||||
==============================*/
|
||||
|
||||
extern void debug_64drivebutton(void(*execute)(), char onpress);
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_pollcommands
|
||||
Check the USB for incoming commands.
|
||||
==============================*/
|
||||
|
||||
extern void debug_pollcommands();
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_addcommand
|
||||
Adds a command for the USB to read.
|
||||
@param The command name
|
||||
@param The command description
|
||||
@param The function pointer to execute
|
||||
==============================*/
|
||||
|
||||
extern void debug_addcommand(char* command, char* description, char*(*execute)());
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_parsecommand
|
||||
Stores the next part of the incoming command into the provided buffer.
|
||||
Make sure the buffer can fit the amount of data from debug_sizecommand!
|
||||
If you pass NULL, it skips this command.
|
||||
@param The buffer to store the data in
|
||||
==============================*/
|
||||
|
||||
extern void debug_parsecommand(void* buffer);
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_sizecommand
|
||||
Returns the size of the data from this part of the command.
|
||||
@return The size of the data in bytes, or 0
|
||||
==============================*/
|
||||
|
||||
extern int debug_sizecommand();
|
||||
|
||||
|
||||
/*==============================
|
||||
debug_printcommands
|
||||
Prints a list of commands to the developer's command prompt.
|
||||
==============================*/
|
||||
|
||||
extern void debug_printcommands();
|
||||
|
||||
|
||||
// Ignore this, use the macro instead
|
||||
extern void _debug_assert(const char* expression, const char* file, int line);
|
||||
|
||||
// Include usb.h automatically
|
||||
#include "usb.h"
|
||||
|
||||
#else
|
||||
|
||||
// Overwrite library functions with useless macros if debug mode is disabled
|
||||
#define debug_initialize()
|
||||
#define debug_printf (void)
|
||||
#define debug_screenshot(a, b, c)
|
||||
#define debug_assert(a)
|
||||
#define debug_pollcommands()
|
||||
#define debug_addcommand(a, b, c)
|
||||
#define debug_parsecommand(a) NULL
|
||||
#define debug_sizecommand() 0
|
||||
#define debug_printcommands()
|
||||
#define debug_64drivebutton(a, b)
|
||||
#define usb_initialize() 0
|
||||
#define usb_getcart() 0
|
||||
#define usb_write(a, b, c)
|
||||
#define usb_poll() 0
|
||||
#define usb_read(a, b)
|
||||
#define usb_skip(a)
|
||||
#define usb_rewind(a)
|
||||
#define usb_purge()
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
139
include/usb/usb.h
Normal file
139
include/usb/usb.h
Normal file
@@ -0,0 +1,139 @@
|
||||
#ifndef UNFL_USB_H
|
||||
#define UNFL_USB_H
|
||||
|
||||
/*********************************
|
||||
DataType macros
|
||||
*********************************/
|
||||
|
||||
// UNCOMMENT THE #DEFINE IF USING LIBDRAGON
|
||||
//#define LIBDRAGON
|
||||
|
||||
// Settings
|
||||
#define USE_OSRAW 0 // Use if you're doing USB operations without the PI Manager (libultra only)
|
||||
#define DEBUG_ADDRESS_SIZE 8*1024*1024 // Max size of USB I/O. The bigger this value, the more ROM you lose!
|
||||
#define CHECK_EMULATOR 0 // Stops the USB library from working if it detects an emulator to prevent problems
|
||||
|
||||
// Cart definitions
|
||||
#define CART_NONE 0
|
||||
#define CART_64DRIVE 1
|
||||
#define CART_EVERDRIVE 2
|
||||
#define CART_SC64 3
|
||||
|
||||
// Data types defintions
|
||||
#define DATATYPE_TEXT 0x01
|
||||
#define DATATYPE_RAWBINARY 0x02
|
||||
#define DATATYPE_HEADER 0x03
|
||||
#define DATATYPE_SCREENSHOT 0x04
|
||||
#define DATATYPE_HEARTBEAT 0x05
|
||||
#define DATATYPE_RDBPACKET 0x06
|
||||
|
||||
|
||||
/*********************************
|
||||
Convenience macros
|
||||
*********************************/
|
||||
|
||||
// Use these to conveniently read the header from usb_poll()
|
||||
#define USBHEADER_GETTYPE(header) (((header) & 0xFF000000) >> 24)
|
||||
#define USBHEADER_GETSIZE(header) (((header) & 0x00FFFFFF))
|
||||
|
||||
|
||||
/*********************************
|
||||
USB Functions
|
||||
*********************************/
|
||||
|
||||
/*==============================
|
||||
usb_initialize
|
||||
Initializes the USB buffers and pointers
|
||||
@return 1 if the USB initialization was successful, 0 if not
|
||||
==============================*/
|
||||
|
||||
extern char usb_initialize(void);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_getcart
|
||||
Returns which flashcart is currently connected
|
||||
@return The CART macro that corresponds to the identified flashcart
|
||||
==============================*/
|
||||
|
||||
extern char usb_getcart(void);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_write
|
||||
Writes data to the USB.
|
||||
Will not write if there is data to read from USB
|
||||
@param The DATATYPE that is being sent
|
||||
@param A buffer with the data to send
|
||||
@param The size of the data being sent
|
||||
==============================*/
|
||||
|
||||
extern void usb_write(int datatype, const void* data, int size);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_poll
|
||||
Returns the header of data being received via USB
|
||||
The first byte contains the data type, the next 3 the number of bytes left to read
|
||||
@return The data header, or 0
|
||||
==============================*/
|
||||
|
||||
extern unsigned long usb_poll(void);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_read
|
||||
Reads bytes from USB into the provided buffer
|
||||
@param The buffer to put the read data in
|
||||
@param The number of bytes to read
|
||||
==============================*/
|
||||
|
||||
extern void usb_read(void* buffer, int nbytes);
|
||||
|
||||
/*==============================
|
||||
usb_skip
|
||||
Skips a USB read by the specified amount of bytes
|
||||
@param The number of bytes to skip
|
||||
==============================*/
|
||||
|
||||
extern void usb_skip(int nbytes);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_rewind
|
||||
Rewinds a USB read by the specified amount of bytes
|
||||
@param The number of bytes to rewind
|
||||
==============================*/
|
||||
|
||||
extern void usb_rewind(int nbytes);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_purge
|
||||
Purges the incoming USB data
|
||||
==============================*/
|
||||
|
||||
extern void usb_purge(void);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_timedout
|
||||
Checks if the USB timed out recently
|
||||
@return 1 if the USB timed out, 0 if not
|
||||
==============================*/
|
||||
|
||||
extern char usb_timedout(void);
|
||||
|
||||
|
||||
/*==============================
|
||||
usb_sendheartbeat
|
||||
Sends a heartbeat packet to the PC
|
||||
This is done once automatically at initialization,
|
||||
but can be called manually to ensure that the
|
||||
host side tool is aware of the current USB protocol
|
||||
version.
|
||||
==============================*/
|
||||
|
||||
extern void usb_sendheartbeat(void);
|
||||
|
||||
#endif
|
||||
@@ -53,6 +53,7 @@
|
||||
include "$(BUILD_DIR)/src/libultra/gu/cosf.o"
|
||||
include "$(BUILD_DIR)/src/libultra/gu/libm_vals.o"
|
||||
include "$(BUILD_DIR)/src/libultra/gu/coss.o"
|
||||
include "$(BUILD_DIR)/src/libultra/os/settime.o"
|
||||
include "$(BUILD_DIR)/src/libultra/io/visetevent.o"
|
||||
#if DEBUG_FEATURES
|
||||
include "$(BUILD_DIR)/src/libultra/io/pfsisplug.o"
|
||||
|
||||
13
spec/spec
13
spec/spec
@@ -877,6 +877,19 @@ beginseg
|
||||
include "$(BUILD_DIR)/src/debug/profiler.o"
|
||||
#endif
|
||||
include "$(BUILD_DIR)/src/debug/inventory_editor.o"
|
||||
#if ENABLE_UNF
|
||||
include "$(BUILD_DIR)/src/debug/commands.o"
|
||||
#endif
|
||||
endseg
|
||||
#endif
|
||||
|
||||
#if ENABLE_UNF
|
||||
beginseg
|
||||
name "usb"
|
||||
compress
|
||||
include "$(BUILD_DIR)/src/usb/missing_libultra_functions.o"
|
||||
include "$(BUILD_DIR)/src/usb/usb.o"
|
||||
include "$(BUILD_DIR)/src/usb/debug.o"
|
||||
endseg
|
||||
#endif
|
||||
|
||||
|
||||
@@ -70,6 +70,14 @@ void Main_ThreadEntry(void* arg) {
|
||||
PRINTF("[HackerOoT:Info]: Completed!\n");
|
||||
#endif
|
||||
|
||||
#if ENABLE_UNF
|
||||
PRINTF("[HackerOoT:Info]: Loading 'usb' segment...\n");
|
||||
DMA_REQUEST_SYNC(_usbSegmentStart, (uintptr_t)_usbSegmentRomStart, _usbSegmentRomEnd - _usbSegmentRomStart,
|
||||
__BASE_FILE__, __LINE__);
|
||||
bzero(_usbSegmentBssStart, _usbSegmentBssEnd - _usbSegmentBssStart);
|
||||
PRINTF("[HackerOoT:Info]: Completed!\n");
|
||||
#endif
|
||||
|
||||
Main(arg);
|
||||
PRINTF(T("mainx 実行終了\n", "mainx execution finished\n"));
|
||||
}
|
||||
|
||||
@@ -474,6 +474,10 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_UNF
|
||||
void Commands_Init(void);
|
||||
#endif
|
||||
|
||||
void Graph_ThreadEntry(void* arg0) {
|
||||
GraphicsContext gfxCtx;
|
||||
GameState* gameState;
|
||||
@@ -489,6 +493,10 @@ void Graph_ThreadEntry(void* arg0) {
|
||||
PRINTF(T("グラフィックスレッド実行開始\n", "Start graphic thread execution\n"));
|
||||
Graph_Init(&gfxCtx);
|
||||
|
||||
#if ENABLE_UNF
|
||||
Commands_Init();
|
||||
#endif
|
||||
|
||||
while (nextOvl != NULL) {
|
||||
ovl = nextOvl;
|
||||
Overlay_LoadGameState(ovl);
|
||||
|
||||
41
src/debug/commands.c
Normal file
41
src/debug/commands.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "ultra64.h"
|
||||
#include "array_count.h"
|
||||
#include "usb/debug.h"
|
||||
#include "config.h"
|
||||
|
||||
#if ENABLE_UNF
|
||||
|
||||
typedef struct CommandDesc {
|
||||
char* name;
|
||||
char* desc;
|
||||
char* (*callback)(void);
|
||||
} CommandDesc;
|
||||
|
||||
char* command_example() {
|
||||
return "The example command executed successfully.";
|
||||
}
|
||||
|
||||
// to add a command, create the function and add an entry for it here, you shouldn't require any other change
|
||||
CommandDesc sCommandList[] = {
|
||||
{ "example", "example command", command_example },
|
||||
};
|
||||
|
||||
void Commands_Init(void) {
|
||||
debug_initialize();
|
||||
|
||||
if (ARRAY_COUNT(sCommandList) < MAX_COMMANDS) {
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sCommandList); i++) {
|
||||
CommandDesc* cmd = &sCommandList[i];
|
||||
|
||||
debug_addcommand(cmd->name, cmd->desc, cmd->callback);
|
||||
}
|
||||
|
||||
debug_printcommands();
|
||||
} else {
|
||||
debug_printf("Too many commands! Ignoring...");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "ultra64.h"
|
||||
#include "ultra64/bcp.h"
|
||||
|
||||
void* __printfunc = NULL;
|
||||
|
||||
typedef struct __osExceptionVector {
|
||||
u32 inst1; // lui $k0, %hi(__osException)
|
||||
u32 inst2; // addiu $k0, $k0, %lo(__osException)
|
||||
|
||||
1990
src/usb/debug.c
Normal file
1990
src/usb/debug.c
Normal file
File diff suppressed because it is too large
Load Diff
146
src/usb/missing_libultra_functions.c
Normal file
146
src/usb/missing_libultra_functions.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "ultra64.h"
|
||||
#include "ultra64/internal.h"
|
||||
|
||||
char* strpbrk(const char* string1, const char* string2) {
|
||||
char* b;
|
||||
|
||||
while (*string1) {
|
||||
b = (char*)string2;
|
||||
while (*b) {
|
||||
if (*b++ == *string1) {
|
||||
return (char*)string1;
|
||||
}
|
||||
}
|
||||
string1++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* strtok(char* string1, const char* string2) {
|
||||
static char* ptr = NULL;
|
||||
char* a;
|
||||
|
||||
if (string1 != NULL) {
|
||||
ptr = string1;
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
a = ptr;
|
||||
ptr = strpbrk(ptr, string2);
|
||||
if (ptr != NULL) {
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
char* strcpy(char* str1, const char* str2) {
|
||||
char* p;
|
||||
p = str1;
|
||||
while (*str2) {
|
||||
*p++ = *str2++;
|
||||
}
|
||||
*p = '\0';
|
||||
return str1;
|
||||
}
|
||||
|
||||
int strncmp(const char* s1, const char* s2, size_t n) {
|
||||
while (n && *s1 && (*s1 == *s2)) {
|
||||
++s1;
|
||||
++s2;
|
||||
--n;
|
||||
}
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return (*(unsigned char*)s1 - *(unsigned char*)s2);
|
||||
}
|
||||
}
|
||||
|
||||
#define WAIT_ON_IOBUSY(stat) \
|
||||
{ \
|
||||
stat = IO_READ(PI_STATUS_REG); \
|
||||
while (stat & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) \
|
||||
stat = IO_READ(PI_STATUS_REG); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
s32 __osPiRawReadIo(u32 devAddr, u32* data) {
|
||||
register u32 stat;
|
||||
|
||||
WAIT_ON_IOBUSY(stat);
|
||||
*data = IO_READ((u32)osRomBase | devAddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 __osPiRawWriteIo(u32 devAddr, u32 data) {
|
||||
register u32 stat;
|
||||
|
||||
WAIT_ON_IOBUSY(stat);
|
||||
IO_WRITE((u32)osRomBase | devAddr, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 osPiWriteIo(u32 devAddr, u32 data) {
|
||||
register s32 ret;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (devAddr & 0x3) {
|
||||
__osError(ERR_OSPIWRITEIO, 1, devAddr);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
__osPiGetAccess();
|
||||
ret = __osPiRawWriteIo(devAddr, data);
|
||||
__osPiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 osPiReadIo(u32 devAddr, u32* data) {
|
||||
register s32 ret;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (devAddr & 0x3) {
|
||||
__osError(ERR_OSPIREADIO, 1, devAddr);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
__osPiGetAccess();
|
||||
ret = __osPiRawReadIo(devAddr, data);
|
||||
__osPiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
s32 osPiStartDma(OSIoMesg* mb, s32 priority, s32 direction, u32 devAddr, void* dramAddr, u32 size, OSMesgQueue* mq) {
|
||||
register s32 ret;
|
||||
if (!__osPiDevMgr.active) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (direction == OS_READ) {
|
||||
mb->hdr.type = OS_MESG_TYPE_DMAREAD;
|
||||
} else {
|
||||
mb->hdr.type = OS_MESG_TYPE_DMAWRITE;
|
||||
}
|
||||
|
||||
mb->hdr.pri = priority;
|
||||
mb->hdr.retQueue = mq;
|
||||
mb->dramAddr = dramAddr;
|
||||
mb->devAddr = devAddr;
|
||||
mb->size = size;
|
||||
mb->piHandle = NULL;
|
||||
|
||||
if (priority == OS_MESG_PRI_HIGH) {
|
||||
ret = osJamMesg(osPiGetCmdQueue(), (OSMesg)mb, OS_MESG_NOBLOCK);
|
||||
} else {
|
||||
ret = osSendMesg(osPiGetCmdQueue(), (OSMesg)mb, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
1444
src/usb/usb.c
Normal file
1444
src/usb/usb.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user