-
Notifications
You must be signed in to change notification settings - Fork 297
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: sakumisu <[email protected]>
- Loading branch information
Showing
3 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright (c) 2025, sakumisu | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#ifndef USB_OTG_H | ||
#define USB_OTG_H | ||
|
||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief usb otg controller hardware or gpio id simulator init. | ||
* | ||
* @return On success will return 0, and others indicate fail. | ||
*/ | ||
int usb_otg_init(uint8_t busid); | ||
/** | ||
* @brief usb otg controller hardware or gpio id simulator deinit. | ||
* | ||
* @return On success will return 0, and others indicate fail. | ||
*/ | ||
int usb_otg_deinit(uint8_t busid); | ||
/** | ||
* @brief get current role mode. | ||
* | ||
* @return return USBOTG_MODE_HOST or USBOTG_MODE_DEVICE. | ||
*/ | ||
uint8_t usbotg_get_current_mode(uint8_t busid); | ||
|
||
/* called by user */ | ||
void USBOTG_IRQHandler(uint8_t busid); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* USB_OTG_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/* | ||
* Copyright (c) 2025, sakumisu | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include "usbotg_core.h" | ||
|
||
struct usbotg_core_priv { | ||
uint8_t busid; | ||
uint32_t reg_base; | ||
usb_osal_sem_t change_sem; | ||
usb_osal_thread_t change_thread; | ||
bool usbh_initialized; | ||
bool usbd_initialized; | ||
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base); | ||
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base); | ||
} g_usbotg_core[CONFIG_USBHOST_MAX_BUS]; | ||
|
||
static void usbotg_host_initialize(uint8_t busid) | ||
{ | ||
if (g_usbotg_core[busid].usbd_initialized) { | ||
g_usbotg_core[busid].usbd_initialized = false; | ||
usbd_deinitialize(busid); | ||
} | ||
if (g_usbotg_core[busid].usbh_initialize && !g_usbotg_core[busid].usbh_initialized) { | ||
g_usbotg_core[busid].usbh_initialized = true; | ||
g_usbotg_core[busid].usbh_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base); | ||
} | ||
} | ||
|
||
static void usbotg_device_initialize(uint8_t busid) | ||
{ | ||
if (g_usbotg_core[busid].usbh_initialized) { | ||
g_usbotg_core[busid].usbh_initialized = false; | ||
usbh_deinitialize(busid); | ||
} | ||
if (g_usbotg_core[busid].usbd_initialize && !g_usbotg_core[busid].usbd_initialize) { | ||
g_usbotg_core[busid].usbd_initialized = true; | ||
g_usbotg_core[busid].usbd_initialize(g_usbotg_core[busid].busid, g_usbotg_core[busid].reg_base); | ||
} | ||
} | ||
|
||
static void usbotg_rolechange_thread(void *argument) | ||
{ | ||
uint8_t busid = (uint8_t)(uintptr_t)argument; | ||
|
||
usb_otg_init(busid); | ||
|
||
while (1) { | ||
if (usb_osal_sem_take(g_usbotg_core[busid].change_sem, USB_OSAL_WAITING_FOREVER) == 0) { | ||
if (usbotg_get_current_mode(busid) == USBOTG_MODE_HOST) { | ||
usbotg_host_initialize(busid); | ||
} else if (usbotg_get_current_mode(busid) == USBOTG_MODE_DEVICE) { | ||
usbotg_device_initialize(busid); | ||
} | ||
} | ||
} | ||
} | ||
|
||
int usbotg_initialize(uint8_t otg_mode, uint8_t busid, uint32_t reg_base, | ||
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base), | ||
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base)) | ||
{ | ||
char thread_name[32] = { 0 }; | ||
|
||
if (busid >= CONFIG_USBHOST_MAX_BUS) { | ||
USB_LOG_ERR("bus overflow\r\n"); | ||
while (1) { | ||
} | ||
} | ||
|
||
g_usbotg_core[busid].busid = busid; | ||
g_usbotg_core[busid].reg_base = reg_base; | ||
g_usbotg_core[busid].usbh_initialize = usbh_initialize; | ||
g_usbotg_core[busid].usbd_initialize = usbd_initialize; | ||
|
||
if (otg_mode == USBOTG_MODE_OTG) { | ||
g_usbotg_core[busid].change_sem = usb_osal_sem_create(0); | ||
if (g_usbotg_core[busid].change_sem == NULL) { | ||
USB_LOG_ERR("Failed to create change_sem\r\n"); | ||
return -1; | ||
} | ||
|
||
snprintf(thread_name, 32, "usbotg%u", busid); | ||
g_usbotg_core[busid].change_thread = usb_osal_thread_create(thread_name, CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO, usbotg_rolechange_thread, (void *)(uintptr_t)busid); | ||
if (g_usbotg_core[busid].change_thread == NULL) { | ||
USB_LOG_ERR("Failed to create usbotg thread\r\n"); | ||
return -1; | ||
} | ||
} else { | ||
if (otg_mode == USBOTG_MODE_HOST) { | ||
usbotg_host_initialize(busid); | ||
} else if (otg_mode == USBOTG_MODE_DEVICE) { | ||
usbotg_device_initialize(busid); | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int usbotg_deinitialize(uint8_t busid, uint32_t reg_base) | ||
{ | ||
if (g_usbotg_core[busid].usbd_initialized) { | ||
g_usbotg_core[busid].usbd_initialized = false; | ||
usbd_deinitialize(busid); | ||
} | ||
|
||
if (g_usbotg_core[busid].usbh_initialized) { | ||
g_usbotg_core[busid].usbh_initialized = false; | ||
usbh_deinitialize(busid); | ||
} | ||
|
||
if (g_usbotg_core[busid].change_sem) { | ||
usb_otg_deinit(busid); | ||
usb_osal_sem_delete(g_usbotg_core[busid].change_sem); | ||
} | ||
|
||
if (g_usbotg_core[busid].change_thread) { | ||
usb_osal_thread_delete(g_usbotg_core[busid].change_thread); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
void usbotg_trigger_role_change(uint8_t busid) | ||
{ | ||
usb_osal_sem_give(g_usbotg_core[busid].change_sem); | ||
} | ||
|
||
void USBOTG_IRQHandler(uint8_t busid) | ||
{ | ||
if (usbotg_get_current_mode(busid) == USBOTG_MODE_HOST) { | ||
USBH_IRQHandler(busid); | ||
} else if (usbotg_get_current_mode(busid) == USBOTG_MODE_DEVICE) { | ||
USBD_IRQHandler(busid); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/* | ||
* Copyright (c) 2025, sakumisu | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#ifndef USBOTG_CORE_H | ||
#define USBOTG_CORE_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define USBOTG_MODE_UNKNOWN 0 | ||
#define USBOTG_MODE_OTG 1 | ||
#define USBOTG_MODE_HOST 2 | ||
#define USBOTG_MODE_DEVICE 3 | ||
|
||
#include "usbd_core.h" | ||
#include "usbh_core.h" | ||
#include "usb_otg.h" | ||
|
||
int usbotg_initialize(uint8_t otg_mode, uint8_t busid, uint32_t reg_base, | ||
int (*usbh_initialize)(uint8_t busid, uint32_t reg_base), | ||
int (*usbd_initialize)(uint8_t busid, uint32_t reg_base)); | ||
int usbotg_deinitialize(uint8_t busid, uint32_t reg_base); | ||
|
||
/* called by user */ | ||
void usbotg_trigger_role_change(uint8_t busid); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* USBOTG_CORE_H */ |