From b23af8c13197ae0cbf9af46f979575aa67be5bd5 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Fri, 25 Jun 2021 17:01:15 -0400 Subject: [PATCH] usb: modified usbIsReady() to return the speed selected by the host device. --- include/core/usb.h | 11 ++++++++++- include/tasks.hpp | 7 +++---- romfs/i18n/en-US/tasks.json | 5 ++++- source/core/usb.c | 26 +++++++++++++++++++++++--- source/tasks.cpp | 22 +++++++++++++++------- 5 files changed, 55 insertions(+), 16 deletions(-) diff --git a/include/core/usb.h b/include/core/usb.h index 16cefba..c104c03 100644 --- a/include/core/usb.h +++ b/include/core/usb.h @@ -33,6 +33,14 @@ extern "C" { #define USB_TRANSFER_BUFFER_SIZE 0x800000 /* 8 MiB. */ +/// Used to indicate the USB speed selected by the host device. +typedef enum { + UsbHostSpeed_None = 0, + UsbHostSpeed_FullSpeed = 1, ///< USB 1.x. + UsbHostSpeed_HighSpeed = 2, ///< USB 2.0. + UsbHostSpeed_SuperSpeed = 3 ///< USB 3.0. +} UsbHostSpeed; + /// Initializes the USB interface, input and output endpoints and allocates an internal transfer buffer. bool usbInitialize(void); @@ -43,7 +51,8 @@ void usbExit(void); void *usbAllocatePageAlignedBuffer(size_t size); /// Used to check if the console has been connected to a USB host device and if a valid USB session has been established. -bool usbIsReady(void); +/// Returns a value from the UsbHostSpeed enum. +u8 usbIsReady(void); /// Sends file properties to the host device before starting a file data transfer. Must be called before usbSendFileData(). /// If 'nsp_header_size' is greater than zero, NSP transfer mode will be enabled. The file will be treated as a NSP and this value will be taken as its full Partition FS header size. diff --git a/include/tasks.hpp b/include/tasks.hpp index ca54045..2e7e4fb 100644 --- a/include/tasks.hpp +++ b/include/tasks.hpp @@ -53,7 +53,7 @@ namespace nxdt::tasks typedef brls::Event GameCardStatusEvent; typedef brls::Event TitleEvent; typedef brls::Event UmsEvent; - typedef brls::Event UsbHostEvent; + typedef brls::Event UsbHostEvent; /* Status info task. */ /* Its event returns a pointer to a StatusInfoData struct. */ @@ -175,9 +175,8 @@ namespace nxdt::tasks { private: UsbHostEvent usb_host_event; - - bool cur_usb_host_status = false; - bool prev_usb_host_status = false; + UsbHostSpeed cur_usb_host_speed = UsbHostSpeed_None; + UsbHostSpeed prev_usb_host_speed = UsbHostSpeed_None; protected: void run(retro_time_t current_time) override; diff --git a/romfs/i18n/en-US/tasks.json b/romfs/i18n/en-US/tasks.json index bece869..ed91612 100644 --- a/romfs/i18n/en-US/tasks.json +++ b/romfs/i18n/en-US/tasks.json @@ -1,6 +1,9 @@ { "notifications": { "gamecard": "Gamecard status change detected!", - "user_titles": "User titles updated!" + "user_titles": "User titles updated!", + "ums_device": "USB Mass Storage devices updated!", + "usb_host_connected": "USB host connected!", + "usb_host_disconnected": "USB host disconnected!" } } diff --git a/source/core/usb.c b/source/core/usb.c index db7acc7..820f2ce 100644 --- a/source/core/usb.c +++ b/source/core/usb.c @@ -305,10 +305,30 @@ void *usbAllocatePageAlignedBuffer(size_t size) return memalign(USB_TRANSFER_ALIGNMENT, size); } -bool usbIsReady(void) +u8 usbIsReady(void) { - bool ret = false; - SCOPED_TRY_LOCK(&g_usbInterfaceMutex) ret = (g_usbHostAvailable && g_usbSessionStarted); + u8 ret = UsbHostSpeed_None; + + SCOPED_TRY_LOCK(&g_usbInterfaceMutex) + { + if (!g_usbHostAvailable || !g_usbSessionStarted) break; + + switch(g_usbEndpointMaxPacketSize) + { + case USB_FS_EP_MAX_PACKET_SIZE: /* USB 1.x. */ + ret = UsbHostSpeed_FullSpeed; + break; + case USB_HS_EP_MAX_PACKET_SIZE: /* USB 2.0. */ + ret = UsbHostSpeed_HighSpeed; + break; + case USB_SS_EP_MAX_PACKET_SIZE: /* USB 3.0. */ + ret = UsbHostSpeed_SuperSpeed; + break; + default: + break; + } + } + return ret; } diff --git a/source/tasks.cpp b/source/tasks.cpp index e17345b..32c3a3d 100644 --- a/source/tasks.cpp +++ b/source/tasks.cpp @@ -76,6 +76,7 @@ namespace nxdt::tasks status_info_data->ip_addr = NULL; } + /* Fire task event. */ this->status_info_event.fire(status_info_data); } @@ -96,7 +97,7 @@ namespace nxdt::tasks { brls::RepeatingTask::run(current_time); - this->cur_gc_status = (GameCardStatus)gamecardGetStatus(); + this->cur_gc_status = static_cast(gamecardGetStatus()); if (this->cur_gc_status != this->prev_gc_status) { brls::Logger::debug("Gamecard status change triggered: {}.", this->cur_gc_status); @@ -201,12 +202,14 @@ namespace nxdt::tasks if (umsIsDeviceInfoUpdated()) { + brls::Logger::debug("UMS device info updated."); + brls::Application::notify("tasks/notifications/ums_device"_i18n); + /* Update UMS device vector. */ this->PopulateUmsDeviceVector(); /* Fire task event. */ this->ums_event.fire(&(this->ums_devices)); - brls::Logger::debug("UMS device info updated."); } } @@ -249,12 +252,17 @@ namespace nxdt::tasks { brls::RepeatingTask::run(current_time); - this->cur_usb_host_status = usbIsReady(); - if (this->cur_usb_host_status != this->prev_usb_host_status) + this->cur_usb_host_speed = static_cast(usbIsReady()); + if (this->cur_usb_host_speed != this->prev_usb_host_speed) { - this->prev_usb_host_status = this->cur_usb_host_status; - this->usb_host_event.fire(this->cur_usb_host_status); - brls::Logger::debug("USB host status change triggered: {}.", this->cur_usb_host_status); + brls::Logger::debug("USB host speed changed: {}.", this->cur_usb_host_speed); + brls::Application::notify(this->cur_usb_host_speed ? "tasks/notifications/usb_host_connected"_i18n : "tasks/notifications/usb_host_disconnected"_i18n); + + /* Update previous USB host speed. */ + this->prev_usb_host_speed = this->cur_usb_host_speed; + + /* Fire task event. */ + this->usb_host_event.fire(this->cur_usb_host_speed); } } }