update(cherryusb): add config for mcxn947 usbdev and usbhost
This commit is contained in:
parent
679761983d
commit
b462daf57e
|
@ -184,6 +184,32 @@ menu "On-chip Peripheral Drivers"
|
|||
default y
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_USB
|
||||
bool "Enable USB"
|
||||
default n
|
||||
if BSP_USING_USB
|
||||
config BSP_USING_USB_DEVICE
|
||||
bool "Enable USB Device, default is msc ramdisk"
|
||||
default n
|
||||
select RT_USING_CHERRYUSB
|
||||
select RT_CHERRYUSB_DEVICE
|
||||
select RT_CHERRYUSB_DEVICE_SPEED_HS
|
||||
select RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
|
||||
select RT_CHERRYUSB_DEVICE_MSC
|
||||
select RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
|
||||
config BSP_USING_USB_HOST
|
||||
bool "Enable USB Host"
|
||||
default n
|
||||
select RT_USING_CHERRYUSB
|
||||
select RT_CHERRYUSB_HOST
|
||||
select RT_CHERRYUSB_HOST_EHCI_MCX
|
||||
select RT_CHERRYUSB_HOST_CDC_ACM
|
||||
select RT_CHERRYUSB_HOST_HID
|
||||
select RT_CHERRYUSB_HOST_MSC
|
||||
select RT_CHERRYUSB_HOST_CDC_RNDIS
|
||||
endif
|
||||
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ cwd = GetCurrentDir()
|
|||
# add the general drivers.
|
||||
src = Split("""
|
||||
board.c
|
||||
cherryusb_port.c
|
||||
usb_phy.c
|
||||
MCUX_Config/board/clock_config.c
|
||||
MCUX_Config/board/pin_mux.c
|
||||
""")
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024/04/23 sakumisu first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <board.h>
|
||||
|
||||
/* low level init here, this has implemented in cherryusb */
|
||||
|
||||
/* low level deinit here, this has implemented in cherryusb */
|
||||
|
||||
#ifdef RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
|
||||
int cherryusb_devinit(void)
|
||||
{
|
||||
extern void msc_ram_init(uint8_t busid, uintptr_t reg_base);
|
||||
|
||||
msc_ram_init(0, USBHS1__USBC_BASE);
|
||||
return 0;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(cherryusb_devinit);
|
||||
#endif
|
||||
|
||||
#ifdef RT_CHERRYUSB_HOST
|
||||
#include "usbh_core.h"
|
||||
|
||||
int cherryusb_hostinit(void)
|
||||
{
|
||||
usbh_initialize(0, USBHS1__USBC_BASE);
|
||||
return 0;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(cherryusb_hostinit);
|
||||
#endif
|
|
@ -120,6 +120,13 @@ SECTIONS
|
|||
__rt_init_start = .;
|
||||
KEEP(*(SORT(.rti_fn*)))
|
||||
__rt_init_end = .;
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(8);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
} > m_text
|
||||
|
||||
.ARM.extab :
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __USB_H__
|
||||
#define __USB_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*!
|
||||
* @addtogroup usb_drv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief Defines USB stack major version */
|
||||
#define USB_STACK_VERSION_MAJOR (2UL)
|
||||
/*! @brief Defines USB stack minor version */
|
||||
#define USB_STACK_VERSION_MINOR (10UL)
|
||||
/*! @brief Defines USB stack bugfix version */
|
||||
#define USB_STACK_VERSION_BUGFIX (0U)
|
||||
|
||||
/*! @brief USB stack version definition */
|
||||
#define USB_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
|
||||
|
||||
/*! @brief USB stack component version definition, changed with component in yaml together */
|
||||
#define USB_STACK_COMPONENT_VERSION \
|
||||
MAKE_VERSION(USB_STACK_VERSION_MAJOR, USB_STACK_VERSION_MINOR, USB_STACK_VERSION_BUGFIX)
|
||||
|
||||
/*
|
||||
* Component ID used by tools
|
||||
*
|
||||
* FSL_COMPONENT_ID "middleware.usb.stack_common"
|
||||
*/
|
||||
|
||||
/*! @brief USB error code */
|
||||
typedef enum _usb_status
|
||||
{
|
||||
kStatus_USB_Success = 0x00U, /*!< Success */
|
||||
kStatus_USB_Error, /*!< Failed */
|
||||
|
||||
kStatus_USB_Busy, /*!< Busy */
|
||||
kStatus_USB_InvalidHandle, /*!< Invalid handle */
|
||||
kStatus_USB_InvalidParameter, /*!< Invalid parameter */
|
||||
kStatus_USB_InvalidRequest, /*!< Invalid request */
|
||||
kStatus_USB_ControllerNotFound, /*!< Controller cannot be found */
|
||||
kStatus_USB_InvalidControllerInterface, /*!< Invalid controller interface */
|
||||
|
||||
kStatus_USB_NotSupported, /*!< Configuration is not supported */
|
||||
kStatus_USB_Retry, /*!< Enumeration get configuration retry */
|
||||
kStatus_USB_TransferStall, /*!< Transfer stalled */
|
||||
kStatus_USB_TransferFailed, /*!< Transfer failed */
|
||||
kStatus_USB_AllocFail, /*!< Allocation failed */
|
||||
kStatus_USB_LackSwapBuffer, /*!< Insufficient swap buffer for KHCI */
|
||||
kStatus_USB_TransferCancel, /*!< The transfer cancelled */
|
||||
kStatus_USB_BandwidthFail, /*!< Allocate bandwidth failed */
|
||||
kStatus_USB_MSDStatusFail, /*!< For MSD, the CSW status means fail */
|
||||
kStatus_USB_EHCIAttached,
|
||||
kStatus_USB_EHCIDetached,
|
||||
kStatus_USB_DataOverRun, /*!< The amount of data returned by the endpoint exceeded
|
||||
either the size of the maximum data packet allowed
|
||||
from the endpoint or the remaining buffer size. */
|
||||
} usb_status_t;
|
||||
|
||||
/*! @brief USB host handle type define */
|
||||
typedef void *usb_host_handle;
|
||||
|
||||
/*! @brief USB device handle type define. For device stack it is the whole device handle; for host stack it is the
|
||||
* attached device instance handle*/
|
||||
typedef void *usb_device_handle;
|
||||
|
||||
/*! @brief USB OTG handle type define */
|
||||
typedef void *usb_otg_handle;
|
||||
|
||||
/*! @brief USB controller ID */
|
||||
typedef enum _usb_controller_index
|
||||
{
|
||||
kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
|
||||
kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
|
||||
to be used in the future. */
|
||||
kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
|
||||
kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U */
|
||||
|
||||
kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */
|
||||
kUSB_ControllerLpcIp3511Fs1 = 5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511
|
||||
IPs, this is reserved to be used in the future. */
|
||||
|
||||
kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */
|
||||
kUSB_ControllerLpcIp3511Hs1 = 7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511
|
||||
IPs, this is reserved to be used in the future. */
|
||||
|
||||
kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */
|
||||
kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved
|
||||
to be used in the future. */
|
||||
|
||||
kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */
|
||||
kUSB_ControllerIp3516Hs1 = 11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs,
|
||||
this is reserved to be used in the future. */
|
||||
kUSB_ControllerDwc30 = 12U, /*!< DWC3 0U */
|
||||
kUSB_ControllerDwc31 = 13U, /*!< DWC3 1U Currently, there are no platforms which have two Dwc IPs, this is reserved
|
||||
to be used in the future.*/
|
||||
} usb_controller_index_t;
|
||||
|
||||
/**
|
||||
* @brief USB stack version fields
|
||||
*/
|
||||
typedef struct _usb_version
|
||||
{
|
||||
uint8_t major; /*!< Major */
|
||||
uint8_t minor; /*!< Minor */
|
||||
uint8_t bugfix; /*!< Bug fix */
|
||||
} usb_version_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* __USB_H__ */
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
|
||||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
/* data align size when use dma */
|
||||
#ifndef CONFIG_USB_ALIGN_SIZE
|
||||
#define CONFIG_USB_ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
/* attribute data into no cache ram */
|
||||
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".NonCacheable")))
|
||||
|
||||
/* ================= USB Device Stack Configuration ================ */
|
||||
|
||||
/* Ep0 in and out transfer buffer */
|
||||
#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN
|
||||
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512
|
||||
#endif
|
||||
|
||||
/* Setup packet log for debug */
|
||||
// #define CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
|
||||
/* Send ep0 in data from user buffer instead of copying into ep0 reqdata
|
||||
* Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE
|
||||
*/
|
||||
// #define CONFIG_USBDEV_EP0_INDATA_NO_COPY
|
||||
|
||||
/* Check if the input descriptor is correct */
|
||||
// #define CONFIG_USBDEV_DESC_CHECK
|
||||
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MAX_LUN
|
||||
#define CONFIG_USBDEV_MSC_MAX_LUN 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MAX_BUFSIZE
|
||||
#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
|
||||
#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
|
||||
#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */
|
||||
// #define CONFIG_USBDEV_MSC_POLLING
|
||||
|
||||
/* move msc read & write from isr to thread */
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
|
||||
#endif
|
||||
|
||||
/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/
|
||||
#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
|
||||
#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC
|
||||
#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
|
||||
#endif
|
||||
|
||||
#define CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
|
||||
/* ================ USB HOST Stack Configuration ================== */
|
||||
|
||||
#define CONFIG_USBHOST_MAX_RHPORTS 1
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 8
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_HID_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_MSC_CLASS 2
|
||||
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
|
||||
|
||||
#define CONFIG_USBHOST_DEV_NAMELEN 16
|
||||
|
||||
#ifndef CONFIG_USBHOST_PSC_PRIO
|
||||
#define CONFIG_USBHOST_PSC_PRIO 0
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
|
||||
// #define CONFIG_USBHOST_MSOS_ENABLE
|
||||
#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE
|
||||
#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00
|
||||
#endif
|
||||
|
||||
/* Ep0 max transfer buffer */
|
||||
#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
|
||||
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_MSC_TIMEOUT
|
||||
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size,
|
||||
* you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow.
|
||||
*/
|
||||
#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE
|
||||
#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048)
|
||||
#endif
|
||||
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
|
||||
#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE
|
||||
#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048)
|
||||
#endif
|
||||
|
||||
#define CONFIG_USBHOST_BLUETOOTH_HCI_H4
|
||||
// #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG
|
||||
|
||||
#ifndef CONFIG_USBHOST_BLUETOOTH_TX_SIZE
|
||||
#define CONFIG_USBHOST_BLUETOOTH_TX_SIZE 2048
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_BLUETOOTH_RX_SIZE
|
||||
#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
#ifndef CONFIG_USBDEV_MAX_BUS
|
||||
#define CONFIG_USBDEV_MAX_BUS 1 // for now, bus num must be 1 except hpm ip
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 6
|
||||
#endif
|
||||
|
||||
/* ---------------- FSDEV Configuration ---------------- */
|
||||
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
|
||||
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
|
||||
*/
|
||||
// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
|
||||
/* IN Endpoints Max packet Size / 4 */
|
||||
// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
|
||||
// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
#ifndef CONFIG_USBHOST_MAX_BUS
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
#endif
|
||||
|
||||
/* ---------------- EHCI Configuration ---------------- */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_OFFSET (0x100)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_EHCI_QTD_NUM 3
|
||||
#define CONFIG_USB_EHCI_ITD_NUM 20
|
||||
// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
// #define CONFIG_USB_EHCI_ISO
|
||||
// #define CONFIG_USB_EHCI_WITH_OHCI
|
||||
|
||||
/* ---------------- OHCI Configuration ---------------- */
|
||||
#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0)
|
||||
|
||||
/* ---------------- XHCI Configuration ---------------- */
|
||||
#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
/* largest non-periodic USB packet used / 4 */
|
||||
// #define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
|
||||
/* largest periodic USB packet used / 4 */
|
||||
// #define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
|
||||
/*
|
||||
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
|
||||
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
|
||||
*/
|
||||
// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE) / 4)
|
||||
|
||||
/* ---------------- MUSB Configuration ---------------- */
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
#define CONFIG_USB_EHCI_NXP (1)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 - 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "usb.h"
|
||||
#include "fsl_device_registers.h"
|
||||
|
||||
#include "usb_phy.h"
|
||||
|
||||
void *USB_EhciPhyGetBase(uint8_t controllerId)
|
||||
{
|
||||
void *usbPhyBase = NULL;
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
#if defined(USBPHY_STACK_BASE_ADDRS)
|
||||
uint32_t usbphy_base[] = USBPHY_STACK_BASE_ADDRS;
|
||||
#else
|
||||
uint32_t usbphy_base[] = USBPHY_BASE_ADDRS;
|
||||
#endif
|
||||
uint32_t *temp;
|
||||
if (controllerId < (uint8_t)kUSB_ControllerEhci0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((controllerId == (uint8_t)kUSB_ControllerEhci0) || (controllerId == (uint8_t)kUSB_ControllerEhci1))
|
||||
{
|
||||
controllerId = controllerId - (uint8_t)kUSB_ControllerEhci0;
|
||||
}
|
||||
else if ((controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs0) ||
|
||||
(controllerId == (uint8_t)kUSB_ControllerLpcIp3511Hs1))
|
||||
{
|
||||
controllerId = controllerId - (uint8_t)kUSB_ControllerLpcIp3511Hs0;
|
||||
}
|
||||
else if ((controllerId == (uint8_t)kUSB_ControllerIp3516Hs0) || (controllerId == (uint8_t)kUSB_ControllerIp3516Hs1))
|
||||
{
|
||||
controllerId = controllerId - (uint8_t)kUSB_ControllerIp3516Hs0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (controllerId < (sizeof(usbphy_base) / sizeof(usbphy_base[0])))
|
||||
{
|
||||
temp = (uint32_t *)usbphy_base[controllerId];
|
||||
usbPhyBase = (void *)temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return usbPhyBase;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief ehci phy initialization.
|
||||
*
|
||||
* This function initialize ehci phy IP.
|
||||
*
|
||||
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
|
||||
* @param[in] freq the external input clock.
|
||||
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
|
||||
*
|
||||
* @retval kStatus_USB_Success cancel successfully.
|
||||
* @retval kStatus_USB_Error the freq value is incorrect.
|
||||
*/
|
||||
uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
|
||||
{
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
USBPHY_Type *usbPhyBase;
|
||||
|
||||
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
|
||||
if (NULL == usbPhyBase)
|
||||
{
|
||||
return (uint8_t)kStatus_USB_Error;
|
||||
}
|
||||
|
||||
#if ((defined FSL_FEATURE_SOC_ANATOP_COUNT) && (FSL_FEATURE_SOC_ANATOP_COUNT > 0U))
|
||||
ANATOP->HW_ANADIG_REG_3P0.RW =
|
||||
(ANATOP->HW_ANADIG_REG_3P0.RW &
|
||||
(~(ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x1F) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_ILIMIT_MASK))) |
|
||||
ANATOP_HW_ANADIG_REG_3P0_OUTPUT_TRG(0x17) | ANATOP_HW_ANADIG_REG_3P0_ENABLE_LINREG_MASK;
|
||||
ANATOP->HW_ANADIG_USB2_CHRG_DETECT.SET =
|
||||
ANATOP_HW_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B_MASK | ANATOP_HW_ANADIG_USB2_CHRG_DETECT_EN_B_MASK;
|
||||
#endif
|
||||
|
||||
#if (defined USB_ANALOG)
|
||||
USB_ANALOG->INSTANCE[controllerId - (uint8_t)kUSB_ControllerEhci0].CHRG_DETECT_SET =
|
||||
USB_ANALOG_CHRG_DETECT_CHK_CHRG_B(1) | USB_ANALOG_CHRG_DETECT_EN_B(1);
|
||||
#endif
|
||||
|
||||
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
|
||||
|
||||
usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
|
||||
#endif
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
|
||||
/* PWD register provides overall control of the PHY power state */
|
||||
usbPhyBase->PWD = 0U;
|
||||
if (((uint8_t)kUSB_ControllerIp3516Hs0 == controllerId) || ((uint8_t)kUSB_ControllerIp3516Hs1 == controllerId) ||
|
||||
((uint8_t)kUSB_ControllerLpcIp3511Hs0 == controllerId) ||
|
||||
((uint8_t)kUSB_ControllerLpcIp3511Hs1 == controllerId))
|
||||
{
|
||||
usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_CLKGATE_MASK;
|
||||
usbPhyBase->CTRL_SET = USBPHY_CTRL_SET_ENAUTOCLR_PHY_PWD_MASK;
|
||||
}
|
||||
if (NULL != phyConfig)
|
||||
{
|
||||
/* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
|
||||
usbPhyBase->TX =
|
||||
((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
|
||||
(USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
|
||||
USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
|
||||
}
|
||||
#endif
|
||||
|
||||
return (uint8_t)kStatus_USB_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief ehci phy initialization for suspend and resume.
|
||||
*
|
||||
* This function initialize ehci phy IP for suspend and resume.
|
||||
*
|
||||
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
|
||||
* @param[in] freq the external input clock.
|
||||
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
|
||||
*
|
||||
* @retval kStatus_USB_Success cancel successfully.
|
||||
* @retval kStatus_USB_Error the freq value is incorrect.
|
||||
*/
|
||||
uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig)
|
||||
{
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
USBPHY_Type *usbPhyBase;
|
||||
|
||||
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
|
||||
if (NULL == usbPhyBase)
|
||||
{
|
||||
return (uint8_t)kStatus_USB_Error;
|
||||
}
|
||||
|
||||
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
|
||||
usbPhyBase->TRIM_OVERRIDE_EN = 0x001fU; /* override IFR value */
|
||||
#endif
|
||||
|
||||
#if ((defined USBPHY_CTRL_AUTORESUME_EN_MASK) && (USBPHY_CTRL_AUTORESUME_EN_MASK > 0U))
|
||||
usbPhyBase->CTRL_CLR |= USBPHY_CTRL_AUTORESUME_EN_MASK;
|
||||
#else
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTO_PWRON_PLL_MASK;
|
||||
#endif
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK;
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK; /* support LS device. */
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; /* support external FS Hub with LS device connected. */
|
||||
/* PWD register provides overall control of the PHY power state */
|
||||
usbPhyBase->PWD = 0U;
|
||||
#if (defined USBPHY_ANACTRL_PFD_CLKGATE_MASK)
|
||||
/* now the 480MHz USB clock is up, then configure fractional divider after PLL with PFD
|
||||
* pfd clock = 480MHz*18/N, where N=18~35
|
||||
* Please note that USB1PFDCLK has to be less than 180MHz for RUN or HSRUN mode
|
||||
*/
|
||||
usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_FRAC(24); /* N=24 */
|
||||
usbPhyBase->ANACTRL |= USBPHY_ANACTRL_PFD_CLK_SEL(1); /* div by 4 */
|
||||
|
||||
usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_DEV_PULLDOWN_MASK;
|
||||
usbPhyBase->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK;
|
||||
while (0U == (usbPhyBase->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
if (NULL != phyConfig)
|
||||
{
|
||||
/* Decode to trim the nominal 17.78mA current source for the High Speed TX drivers on USB_DP and USB_DM. */
|
||||
usbPhyBase->TX =
|
||||
((usbPhyBase->TX & (~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK))) |
|
||||
(USBPHY_TX_D_CAL(phyConfig->D_CAL) | USBPHY_TX_TXCAL45DP(phyConfig->TXCAL45DP) |
|
||||
USBPHY_TX_TXCAL45DM(phyConfig->TXCAL45DM)));
|
||||
}
|
||||
#endif
|
||||
|
||||
return (uint8_t)kStatus_USB_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief ehci phy de-initialization.
|
||||
*
|
||||
* This function de-initialize ehci phy IP.
|
||||
*
|
||||
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
|
||||
*/
|
||||
void USB_EhciPhyDeinit(uint8_t controllerId)
|
||||
{
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
USBPHY_Type *usbPhyBase;
|
||||
|
||||
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
|
||||
if (NULL == usbPhyBase)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#if ((!(defined FSL_FEATURE_SOC_CCM_ANALOG_COUNT)) && (!(defined FSL_FEATURE_SOC_ANATOP_COUNT)))
|
||||
usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* power down PLL */
|
||||
usbPhyBase->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* disable USB clock output from USB PHY PLL */
|
||||
#endif
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* set to 1U to gate clocks */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief ehci phy disconnect detection enable or disable.
|
||||
*
|
||||
* This function enable/disable host ehci disconnect detection.
|
||||
*
|
||||
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
|
||||
* @param[in] enable
|
||||
* 1U - enable;
|
||||
* 0U - disable;
|
||||
*/
|
||||
void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable)
|
||||
{
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
USBPHY_Type *usbPhyBase;
|
||||
|
||||
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
|
||||
if (NULL == usbPhyBase)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (0U != enable)
|
||||
{
|
||||
usbPhyBase->CTRL |= USBPHY_CTRL_ENHOSTDISCONDETECT_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbPhyBase->CTRL &= (~USBPHY_CTRL_ENHOSTDISCONDETECT_MASK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
#if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U))
|
||||
void USB_PhyDeviceForceEnterFSMode(uint8_t controllerId, uint8_t enable)
|
||||
{
|
||||
USBPHY_Type *usbPhyBase;
|
||||
|
||||
usbPhyBase = (USBPHY_Type *)USB_EhciPhyGetBase(controllerId);
|
||||
if (NULL == usbPhyBase)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (0U != enable)
|
||||
{
|
||||
uint32_t delay = 1000000;
|
||||
usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
|
||||
while ((0U != (usbPhyBase->USB1_VBUS_DET_STAT & USBPHY_USB1_VBUS_DET_STAT_VBUS_VALID_3V_MASK)) && (0U != delay))
|
||||
{
|
||||
delay--;
|
||||
}
|
||||
usbPhyBase->USB1_LOOPBACK_SET = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
usbPhyBase->DEBUG0_CLR = USBPHY_DEBUG0_CLKGATE_MASK;
|
||||
usbPhyBase->USB1_LOOPBACK_CLR = USBPHY_USB1_LOOPBACK_UTMI_TESTSTART_MASK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016 - 2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __USB_PHY_H__
|
||||
#define __USB_PHY_H__
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
typedef struct _usb_phy_config_struct
|
||||
{
|
||||
uint8_t D_CAL; /* Decode to trim the nominal 17.78mA current source */
|
||||
uint8_t TXCAL45DP; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DP output pin */
|
||||
uint8_t TXCAL45DM; /* Decode to trim the nominal 45-Ohm series termination resistance to the USB_DM output pin */
|
||||
} usb_phy_config_struct_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
/*!
|
||||
* @brief EHCI PHY get USB phy bass address.
|
||||
*
|
||||
* This function is used to get USB phy bass address.
|
||||
*
|
||||
* @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
|
||||
*
|
||||
* @retval USB phy bass address.
|
||||
*/
|
||||
extern void *USB_EhciPhyGetBase(uint8_t controllerId);
|
||||
|
||||
/*!
|
||||
* @brief EHCI PHY initialization.
|
||||
*
|
||||
* This function initializes the EHCI PHY IP.
|
||||
*
|
||||
* @param[in] controllerId EHCI controller ID; See the #usb_controller_index_t.
|
||||
* @param[in] freq The external input clock.
|
||||
*
|
||||
* @retval kStatus_USB_Success Cancel successfully.
|
||||
* @retval kStatus_USB_Error The freq value is incorrect.
|
||||
*/
|
||||
extern uint32_t USB_EhciPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig);
|
||||
|
||||
/*!
|
||||
* @brief ehci phy initialization for suspend and resume.
|
||||
*
|
||||
* This function initialize ehci phy IP for suspend and resume.
|
||||
*
|
||||
* @param[in] controllerId ehci controller id, please reference to #usb_controller_index_t.
|
||||
* @param[in] freq the external input clock.
|
||||
* for example: if the external input clock is 16M, the parameter freq should be 16000000.
|
||||
*
|
||||
* @retval kStatus_USB_Success cancel successfully.
|
||||
* @retval kStatus_USB_Error the freq value is incorrect.
|
||||
*/
|
||||
extern uint32_t USB_EhciLowPowerPhyInit(uint8_t controllerId, uint32_t freq, usb_phy_config_struct_t *phyConfig);
|
||||
|
||||
/*!
|
||||
* @brief EHCI PHY deinitialization.
|
||||
*
|
||||
* This function deinitializes the EHCI PHY IP.
|
||||
*
|
||||
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
|
||||
*/
|
||||
extern void USB_EhciPhyDeinit(uint8_t controllerId);
|
||||
|
||||
/*!
|
||||
* @brief EHCI PHY disconnect detection enable or disable.
|
||||
*
|
||||
* This function enable/disable the host EHCI disconnect detection.
|
||||
*
|
||||
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
|
||||
* @param[in] enable
|
||||
* 1U - enable;
|
||||
* 0U - disable;
|
||||
*/
|
||||
extern void USB_EhcihostPhyDisconnectDetectCmd(uint8_t controllerId, uint8_t enable);
|
||||
#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
|
||||
#if ((defined FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE) && (FSL_FEATURE_USBHSD_HAS_EXIT_HS_ISSUE > 0U))
|
||||
/*!
|
||||
* @brief Force the PHY enter FS Mode
|
||||
*
|
||||
* on RT500 and RT600, the device doesn't enter FS Mode after vbus is invalide and the controller works as HS.
|
||||
*
|
||||
* @param[in] controllerId EHCI controller ID; See #usb_controller_index_t.
|
||||
* @param[in] enable
|
||||
* 1U - enable;
|
||||
* 0U - disable;
|
||||
*/
|
||||
extern void USB_PhyDeviceForceEnterFSMode(uint8_t controllerId, uint8_t enable);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USB_PHY_H__ */
|
Loading…
Reference in New Issue