mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 14:27:37 +08:00
RX65N USB Host Driver
This commit is contained in:
@@ -17,7 +17,8 @@ Contents
|
||||
- RSPI
|
||||
- RIIC
|
||||
- DTC
|
||||
- Debugging
|
||||
- USB Host
|
||||
- USB Host Hub
|
||||
- Debugging
|
||||
|
||||
Board Features
|
||||
@@ -225,6 +226,20 @@ RSPI
|
||||
For GRROSE board only channel 1 can be tested since RSPI channel1 pinout is only brought out as
|
||||
Pin number 2 and 3 in CN4 is used for MOSIB and MISOB respectively.
|
||||
|
||||
USB Host
|
||||
=============
|
||||
For the RX65N RSK2MB board, to be used as USB Device, the following Jumper settings need to be done
|
||||
|
||||
J7 Short Pin 1 & Pin 2
|
||||
J16 Short Pin 2 & Pin 3
|
||||
|
||||
USB Device
|
||||
=============
|
||||
For the RX65N RSK2MB board, to be used as USB Device, the following Jumper settings need to be done
|
||||
|
||||
J7 Short Pin 2 & Pin 3
|
||||
J16 Short Pin 1 & Pin 2
|
||||
|
||||
RTC
|
||||
==========
|
||||
|
||||
@@ -299,6 +314,76 @@ DTC Testing
|
||||
|
||||
DTC has been tested using RSPI driver.
|
||||
|
||||
USB Host Configurations
|
||||
--------------------------
|
||||
The following configurations need to be enabled for USB Host Mode driver to
|
||||
support USB HID Keyboard class and MSC Class.
|
||||
|
||||
CONFIG_USBHOST=y
|
||||
CONFIG_USBHOST_HIDKBD=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_EXAMPLES_HIDKBD=y
|
||||
|
||||
USB Host Driver Testing
|
||||
------------------------
|
||||
The Following Class Drivers were tested as mentioned below :
|
||||
|
||||
- USB HID Keyboard Class
|
||||
On the NuttX Console "hidkbd" application was executed
|
||||
|
||||
nsh> hidkbd
|
||||
The characters typed from the keyboard were executed correctly.
|
||||
|
||||
- USB MSC Class
|
||||
|
||||
The MSC device is enumerated as sda in /dev directory.
|
||||
|
||||
The block device is mounted using the command as mentioned below :
|
||||
|
||||
mount -t vfat /dev/sda /mnt
|
||||
|
||||
The MSC device is mounted in /dev directory
|
||||
|
||||
The copy command is executed to test the Read/Write functionality
|
||||
|
||||
cp /mnt/<file.txt> /mnt/file_copy.txt
|
||||
|
||||
USB Host Hub Configurations
|
||||
--------------------------
|
||||
The following configurations need to be enabled for USB Host Mode driver to
|
||||
support USB HID Keyboard class and MSC Class.
|
||||
|
||||
CONFIG_RX65N_USBHOST=y
|
||||
CONFIG_USBHOST_HUB=y
|
||||
CONFIG_USBHOST_ASYNCH=y
|
||||
CONFIG_USBHOST=y
|
||||
CONFIG_USBHOST_HIDKBD=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_EXAMPLES_HIDKBD=y
|
||||
|
||||
USB Host Hub Driver Testing
|
||||
------------------------
|
||||
The Following Class Drivers were tested as mentioned below :
|
||||
|
||||
- USB HID Keyboard Class
|
||||
On the NuttX Console "hidkbd" application was executed
|
||||
|
||||
nsh> hidkbd
|
||||
The characters typed from the keyboard were executed correctly.
|
||||
|
||||
- USB MSC Class
|
||||
The MSC device is enumerated as sda in /dev directory.
|
||||
|
||||
The block device is mounted using the command as mentioned below :
|
||||
|
||||
mount -t vfat /dev/sda /mnt
|
||||
|
||||
The MSC device is mounted in /dev directory
|
||||
|
||||
The copy command is executed to test the Read/Write functionality
|
||||
|
||||
cp /mnt/<file.txt> /mnt/file_copy.txt
|
||||
|
||||
Debugging
|
||||
==========
|
||||
|
||||
|
||||
@@ -32,8 +32,12 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/kthread.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/usb/usbhost.h>
|
||||
|
||||
#include "rx65n_usbhost.h"
|
||||
#include "rx65n_grrose.h"
|
||||
#include <rx65n_definitions.h>
|
||||
#ifdef CONFIG_LIB_BOARDCTL
|
||||
@@ -60,6 +64,165 @@
|
||||
# include <nuttx/i2c/i2c_master.h>
|
||||
# include "rx65n_riic.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#define NSH_HAVE_USBHOST 1
|
||||
|
||||
/* USB Host */
|
||||
|
||||
#ifndef CONFIG_USBHOST
|
||||
# undef NSH_HAVE_USBHOST
|
||||
#endif
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
# ifndef CONFIG_USBHOST_DEFPRIO
|
||||
# define CONFIG_USBHOST_DEFPRIO 100
|
||||
# endif
|
||||
# ifndef CONFIG_USBHOST_STACKSIZE
|
||||
# ifdef CONFIG_USBHOST_HUB
|
||||
# define CONFIG_USBHOST_STACKSIZE 1536
|
||||
# else
|
||||
# define CONFIG_USBHOST_STACKSIZE 1024
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
static struct usbhost_connection_s *g_usbconn;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_waiter
|
||||
*
|
||||
* Description:
|
||||
* Wait for USB devices to be connected.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
static int nsh_waiter(int argc, char *argv[])
|
||||
{
|
||||
struct usbhost_hubport_s *hport;
|
||||
|
||||
syslog(LOG_INFO, "nsh_waiter: Running\n\r");
|
||||
for (; ; )
|
||||
{
|
||||
/* Wait for the device to change state */
|
||||
|
||||
DEBUGVERIFY(CONN_WAIT(g_usbconn, &hport));
|
||||
syslog(LOG_INFO, "nsh_waiter: %s\n\r",
|
||||
hport->connected ? "Host:connected" : "Host:disconnected");
|
||||
|
||||
/* Did we just become connected? */
|
||||
|
||||
if (hport->connected && hport->port == 0)
|
||||
{
|
||||
/* Yes.. enumerate the newly connected device */
|
||||
|
||||
(void)CONN_ENUMERATE(g_usbconn, hport);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep the compiler from complaining */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_usbhostinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize SPI-based microSD.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
static int nsh_usbhostinitialize(void)
|
||||
{
|
||||
int pid;
|
||||
int ret;
|
||||
|
||||
/* First, register all of the class drivers needed to support the drivers
|
||||
* that we care about:
|
||||
*/
|
||||
|
||||
syslog(LOG_INFO, "Register class drivers\n\r");
|
||||
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
/* Initialize USB hub class support */
|
||||
|
||||
ret = usbhost_hub_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbhost_hub_initialize failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_MSC
|
||||
/* Register the USB host Mass Storage Class */
|
||||
|
||||
ret = usbhost_msc_initialize();
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to register the mass storage class: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_CDCACM
|
||||
/* Register the CDC/ACM serial class */
|
||||
|
||||
ret = usbhost_kbdinit();
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to register the KBD class: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_HIDKBD
|
||||
/* Register the HID KBD class */
|
||||
|
||||
ret = usbhost_kbdinit();
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to register the CDC/ACM serial class: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Then get an instance of the USB host interface */
|
||||
|
||||
g_usbconn = rx65n_usbhost_initialize(0);
|
||||
if (g_usbconn)
|
||||
{
|
||||
/* Start a thread to handle device connection. */
|
||||
|
||||
syslog(LOG_INFO, "Start nsh_waiter\n\r");
|
||||
|
||||
pid = kthread_create("usbhost", CONFIG_USBHOST_DEFPRIO,
|
||||
CONFIG_USBHOST_STACKSIZE,
|
||||
(main_t)nsh_waiter, (FAR char * const *)NULL);
|
||||
syslog(LOG_INFO, "USBHost: Created pid = %d\n\r", pid);
|
||||
return pid < 0 ? -ENOEXEC : OK;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
#else
|
||||
# define nsh_usbhostinitialize() (OK)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -230,6 +393,10 @@ int rx65n_bringup(void)
|
||||
(void)rx65n_dtc_initialize();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USBHOST)
|
||||
ret = nsh_usbhostinitialize();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RX65N_RSPI
|
||||
(void)rx65n_rspi_initialize();
|
||||
#endif
|
||||
|
||||
@@ -178,6 +178,26 @@ void r_usbdev_port_enable(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: r_usb_port_enable
|
||||
*
|
||||
* Description:
|
||||
* USB Enabling for RX65N RSK2MB
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_USBHOST)
|
||||
void r_usb_port_enable(void)
|
||||
{
|
||||
/* Set VBUS pin for USB */
|
||||
|
||||
MPC.P16PFS.BYTE = 0x11u;
|
||||
|
||||
/* PORT1.PMR.BYTE |= 0x40; */
|
||||
|
||||
PORT1.PMR.BIT.B6 = 1u;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sci0_init_port
|
||||
*
|
||||
|
||||
@@ -16,6 +16,8 @@ Contents
|
||||
- RSPI
|
||||
- RIIC
|
||||
- DTC
|
||||
- USB Host
|
||||
- USB Host Hub
|
||||
- Debugging
|
||||
|
||||
Board Features
|
||||
@@ -193,6 +195,20 @@ Channel1: Pin number 35 and 36 in JA3 is used for MOSIB and MISOB respectively
|
||||
Channel2: Pin number 18 and 19 in JA3 is used for MOSIC and MISOC respectively
|
||||
and for enabling these pin need to select DSW-SEL0 by making off SW4-4
|
||||
|
||||
USB Host
|
||||
=============
|
||||
For the RX65N RSK2MB board, to be used as USB Device, the following Jumper settings need to be done
|
||||
|
||||
J7 Short Pin 1 & Pin 2
|
||||
J16 Short Pin 2 & Pin 3
|
||||
|
||||
USB Device
|
||||
=============
|
||||
For the RX65N RSK2MB board, to be used as USB Device, the following Jumper settings need to be done
|
||||
|
||||
J7 Short Pin 2 & Pin 3
|
||||
J16 Short Pin 1 & Pin 2
|
||||
|
||||
RTC
|
||||
==========
|
||||
|
||||
@@ -272,6 +288,76 @@ DTC Testing
|
||||
|
||||
DTC has been tested using RSPI driver.
|
||||
|
||||
USB Host Configurations
|
||||
--------------------------
|
||||
The following configurations need to be enabled for USB Host Mode driver to
|
||||
support USB HID Keyboard class and MSC Class.
|
||||
|
||||
CONFIG_USBHOST=y
|
||||
CONFIG_USBHOST_HIDKBD=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_EXAMPLES_HIDKBD=y
|
||||
|
||||
USB Host Driver Testing
|
||||
------------------------
|
||||
The Following Class Drivers were tested as mentioned below :
|
||||
|
||||
- USB HID Keyboard Class
|
||||
On the NuttX Console "hidkbd" application was executed
|
||||
|
||||
nsh> hidkbd
|
||||
The characters typed from the keyboard were executed correctly.
|
||||
|
||||
- USB MSC Class
|
||||
|
||||
The MSC device is enumerated as sda in /dev directory.
|
||||
|
||||
The block device is mounted using the command as mentioned below :
|
||||
|
||||
mount -t vfat /dev/sda /mnt
|
||||
|
||||
The MSC device is mounted in /dev directory
|
||||
|
||||
The copy command is executed to test the Read/Write functionality
|
||||
|
||||
cp /mnt/<file.txt> /mnt/file_copy.txt
|
||||
|
||||
USB Host Hub Configurations
|
||||
--------------------------
|
||||
The following configurations need to be enabled for USB Host Mode driver to
|
||||
support USB HID Keyboard class and MSC Class.
|
||||
|
||||
CONFIG_RX65N_USBHOST=y
|
||||
CONFIG_USBHOST_HUB=y
|
||||
CONFIG_USBHOST_ASYNCH=y
|
||||
CONFIG_USBHOST=y
|
||||
CONFIG_USBHOST_HIDKBD=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_EXAMPLES_HIDKBD=y
|
||||
|
||||
USB Host Hub Driver Testing
|
||||
------------------------
|
||||
The Following Class Drivers were tested as mentioned below :
|
||||
|
||||
- USB HID Keyboard Class
|
||||
On the NuttX Console "hidkbd" application was executed
|
||||
|
||||
nsh> hidkbd
|
||||
The characters typed from the keyboard were executed correctly.
|
||||
|
||||
- USB MSC Class
|
||||
The MSC device is enumerated as sda in /dev directory.
|
||||
|
||||
The block device is mounted using the command as mentioned below :
|
||||
|
||||
mount -t vfat /dev/sda /mnt
|
||||
|
||||
The MSC device is mounted in /dev directory
|
||||
|
||||
The copy command is executed to test the Read/Write functionality
|
||||
|
||||
cp /mnt/<file.txt> /mnt/file_copy.txt
|
||||
|
||||
Debugging
|
||||
==========
|
||||
1. NuttX needs to be compiled in Cygwin environment on Windows.
|
||||
|
||||
@@ -32,8 +32,11 @@
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kthread.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/usb/usbhost.h>
|
||||
|
||||
#include "rx65n_usbhost.h"
|
||||
#include "rx65n_rsk2mb.h"
|
||||
#include <rx65n_definitions.h>
|
||||
#ifdef CONFIG_LIB_BOARDCTL
|
||||
@@ -60,10 +63,165 @@
|
||||
# include <nuttx/i2c/i2c_master.h>
|
||||
# include "rx65n_riic.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#define NSH_HAVE_USBHOST 1
|
||||
|
||||
/* USB Host */
|
||||
|
||||
#ifndef CONFIG_USBHOST
|
||||
# undef NSH_HAVE_USBHOST
|
||||
#endif
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
# ifndef CONFIG_USBHOST_DEFPRIO
|
||||
# define CONFIG_USBHOST_DEFPRIO 100
|
||||
# endif
|
||||
# ifndef CONFIG_USBHOST_STACKSIZE
|
||||
# ifdef CONFIG_USBHOST_HUB
|
||||
# define CONFIG_USBHOST_STACKSIZE 1536
|
||||
# else
|
||||
# define CONFIG_USBHOST_STACKSIZE 1024
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
static struct usbhost_connection_s *g_usbconn;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_waiter
|
||||
*
|
||||
* Description:
|
||||
* Wait for USB devices to be connected.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
static int nsh_waiter(int argc, char *argv[])
|
||||
{
|
||||
struct usbhost_hubport_s *hport;
|
||||
|
||||
syslog(LOG_INFO, "nsh_waiter: Running\n\r");
|
||||
for (; ; )
|
||||
{
|
||||
/* Wait for the device to change state */
|
||||
|
||||
DEBUGVERIFY(CONN_WAIT(g_usbconn, &hport));
|
||||
|
||||
/* Did we just become connected? */
|
||||
|
||||
if (hport->connected && hport->port == 0)
|
||||
{
|
||||
/* Yes.. enumerate the newly connected device */
|
||||
|
||||
(void)CONN_ENUMERATE(g_usbconn, hport);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep the compiler from complaining */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_usbhostinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize SPI-based microSD.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NSH_HAVE_USBHOST
|
||||
static int nsh_usbhostinitialize(void)
|
||||
{
|
||||
int pid;
|
||||
int ret;
|
||||
|
||||
/* First, register all of the class drivers needed to support the drivers
|
||||
* that we care about:
|
||||
*/
|
||||
|
||||
syslog(LOG_INFO, "Register class drivers\n\r");
|
||||
|
||||
#ifdef CONFIG_USBHOST_MSC
|
||||
/* Register the USB host Mass Storage Class */
|
||||
|
||||
printf ("USB Host MSC\n\r");
|
||||
ret = usbhost_msc_initialize();
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to register the mass storage class: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_CDCACM
|
||||
/* Register the CDC/ACM serial class */
|
||||
|
||||
printf ("USB Host CDCACM \n\r");
|
||||
ret = usbhost_kbdinit();
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to register the KBD class: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_HIDKBD
|
||||
/* Register the HID KBD class */
|
||||
|
||||
ret = usbhost_kbdinit();
|
||||
if (ret != OK)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to register the CDC/ACM serial class: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBHOST_HUB
|
||||
/* Initialize USB hub class support */
|
||||
|
||||
ret = usbhost_hub_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
uerr("ERROR: usbhost_hub_initialize failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Then get an instance of the USB host interface */
|
||||
|
||||
g_usbconn = rx65n_usbhost_initialize(0);
|
||||
if (g_usbconn)
|
||||
{
|
||||
/* Start a thread to handle device connection. */
|
||||
|
||||
syslog(LOG_INFO, "Start nsh_waiter\n\r");
|
||||
|
||||
pid = kthread_create("usbhost", CONFIG_USBHOST_DEFPRIO,
|
||||
CONFIG_USBHOST_STACKSIZE,
|
||||
(main_t)nsh_waiter, (FAR char * const *)NULL);
|
||||
syslog(LOG_INFO, "USBHost: Created pid = %d\n\r", pid);
|
||||
return pid < 0 ? -ENOEXEC : OK;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
#else
|
||||
# define nsh_usbhostinitialize() (OK)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rx65n_rspi_initialize
|
||||
*
|
||||
@@ -234,6 +392,11 @@ int rx65n_bringup(void)
|
||||
(void)rx65n_rspi_initialize();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USBHOST)
|
||||
ret = nsh_usbhostinitialize();
|
||||
printf ("USB Initialization done!!! with return value = %d\n\r", ret);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CDCACM) && !defined(CONFIG_CDCACM_CONSOLE)
|
||||
/* Initialize CDCACM */
|
||||
|
||||
|
||||
@@ -216,6 +216,33 @@ void r_usbdev_port_enable(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: r_usb_port_enable
|
||||
*
|
||||
* Description:
|
||||
* USB Enabling for RX65N RSK2MB
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_ARCH_BOARD_RX65N_RSK2MB)
|
||||
#if defined(CONFIG_USBHOST)
|
||||
void r_usb_port_enable(void)
|
||||
{
|
||||
/* Set VBUS pin for USB */
|
||||
|
||||
MPC.P16PFS.BYTE = 0x12u;
|
||||
|
||||
/* PORT1.PMR.BYTE |= 0x40; */
|
||||
|
||||
PORT1.PMR.BIT.B6 = 1u;
|
||||
|
||||
/* set USB0_OVRCURA pin */
|
||||
|
||||
MPC.P14PFS.BYTE = 0x12u;
|
||||
PORT1.PMR.BIT.B4 = 1u;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sci1_init_port
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user