How to Implement an USB2.0 / USB3.0 Serial Gadget

How to Implement an USB2.0 / USB3.0 Serial Gadget

This article provides how to allow the USB2.0/USB3.0 device controller act as a serial port device on SP7350 platforms.

 

Table of Contents

Kernel Setup

Enter the kernel configuration by running the following command in the top directory of project.

# make kconfig

 

  1. Select submenus for USB 2.0 controller : Device Drivers > USB support > USB Gadget Support > USB Peripheral Controller. Select <*> for “Sunplus USB 2.0 Device Controller“.

image-20240617-063128.png

 

  1. Select submenus for USB 3.0 controller : Device Drivers > USB support. Select <*> for “DesignWare USB3 DRD Core Support“ and select “Dual Role mode“ for “Deware USB3 DRD Core Support“.

image-20240617-063459.png

 

  1. Select submenus for USB Gadget configfs : Device Drivers > USB support > USB Gadget Support. Select <M> for “USB Gadget functions configurable through configfs“. Select [*] for “Generic serial bulk in/out”, “Abstract Control Model (CDC ACM)“ or “Object Exchange Model (CDC OBEX)“.

image-20240617-063816.png

 

  1. Execute the make command to build the Linux image.

ConfigFS (CDC ACM)

Configure serial gadget through configfs saved as a file named setup_serial.

#!/bin/sh USB2_ACM_EN=on USB3_ACM_EN=on KERNEL_PATH=/lib/modules/`uname -r`/kernel GADGET_PATH=$KERNEL_PATH/drivers/usb/gadget FUNCTION_PATH=$GADGET_PATH/function COMPOSITE=$GADGET_PATH/libcomposite.ko U_SERIAL=$FUNCTION_PATH/u_serial.ko insmod $COMPOSITE insmod $U_SERIAL # disable debug message echo 0 > /sys/module/sunplus_udc/parameters/dmsg if [ ! -d /sys/kernel/config ] then mkdir -p /sys/kernel/config fi if ! mountpoint -q /sys/kernel/config then mount -t configfs none /sys/kernel/config fi if [ $USB2_ACM_EN = on ] then cd /sys/kernel/config/usb_gadget # create gadget folder mkdir g1 cd g1 # setup gadget echo 64 > bMaxPacketSize0 echo 0x200 > bcdUSB # composite class echo 0x02 > bDeviceClass mkdir -p configs/c.1 mkdir -p configs/c.1/strings/0x409 echo "USB2.0 Serial Console" > configs/c.1/strings/0x409/configuration mkdir strings/0x409 echo "1234" > strings/0x409/serialnumber echo "Sunplus" > strings/0x409/manufacturer echo "SP7350" > strings/0x409/product mkdir functions/acm.gs0 ln -s functions/acm.gs0 configs/c.1 # bind UDC echo "f8102800.usb" > UDC fi if [ $USB3_ACM_EN = on ] then cd /sys/kernel/config/usb_gadget # create gadget folder if [ $USB2_ACM_EN = on ] then mkdir g2 cd g2 else mkdir g1 cd g1 fi # setup gadget echo 64 > bMaxPacketSize0 echo 0x300 > bcdUSB # composite class echo 0x02 > bDeviceClass mkdir -p configs/c.1 mkdir -p configs/c.1/strings/0x409 echo "USB3.0 Serial Console" > configs/c.1/strings/0x409/configuration mkdir strings/0x409 echo "5678" > strings/0x409/serialnumber echo "Sunplus" > strings/0x409/manufacturer echo "SP7350" > strings/0x409/product mkdir functions/acm.gs1 ln -s functions/acm.gs1 configs/c.1 # bind UDC echo "f80a1000.dwc3" > UDC fi

 

Test (CDC ACM) Configuartions

Use sh setup_serial command to configure USB 2.0 and USB3.0 device controllers as serial gadgets.

# sh setup_serial

 

ttyGS0 and ttyGS1 in /dev are represented for the USB2.0 serial gadget and the USB3.0 one.

image-20240731-104346.png

 

After connecting the USB2.0 serial gadget and the USB3.0 one to a Windows PC with USB cables, “USB Serial Device (COM6)“ (USB2.0 serial gadget) and “USB Serial Device (COM7)“ (USB3.0 serial gadget) will show up in “Ports (COM & LPT)” in Device Manager. “Prolific UBS-to-Serial Comm Port (COM9)” is the default terminal (UART0) of the SP7350 platform.

image-20240731-104632.png

 

Serial Device Test

Use the communication tool of Tera Term for the test with the Windows PC.

TX Test for USB2.0 Serial Gadget

  1. Use the following command to transfer characters of “SP7350 USB2.0 Serial Gadget TX Test“ from ttyGS0 (USB2.0 serial gadget) to COM6.

# echo "SP7350 USB2.0 Serial Gadget TX Test" > /dev/ttyGS0

 

  1. The characters will be received by COM6 open by Tera Term.

image-20240801-014318.png

 

TX Test for USB3.0 Serial Gadget

  1. Use the following command to transfer characters of “SP7350 USB3.0 Serial Gadget TX Test“ from ttyGS1 (USB3.0 serial gadget) to COM7.

# echo "SP7350 USB3.0 Serial Gadget TX Test" > /dev/ttyGS1

 

  1. The characters will be received by COM7 open by Tera Term.

image-20240801-014623.png

 

RX Test for USB2.0 Serial Gadget

  1. Use the following command to be ready to receive characters transferred from COM6 through ttyGS0 (USB2.0 serial gadget).

# cat /dev/ttyGS0

 

  1. Input the characters of “SP7350 USB2.0 Serial Gadget RX Test" in COM6 open by Tera Term and press “Enter”.

SP7350 USB2.0 Serial Gadget RX Test

 

  1. The characters will be received by ttyGS0.

image-20240801-015016.png

 

RX Test for USB3.0 Serial Gadget

  1. Use the following command to be ready to receive characters transferred from COM7 through ttyGS1 (USB3.0 serial gadget).

# cat /dev/ttyGS1

 

  1. Input the characters of “SP7350 USB3.0 Serial Gadget RX Test" in COM7 open by Tera Term and press “Enter”.

SP7350 USB3.0 Serial Gadget RX Test

 

  1. The characters will be received by ttyGS1.

image-20240801-015327.png

 

Clear ConfigFS Configuration

The following script can be used to clear configfs configuration of the gadget.

#!/bin/sh addr1="g1" addr2="g2" arr=("addr1" "addr2") GADGET=/sys/kernel/config/usb_gadget CONFIG=configs/c.1 for i in "${arr[@]}"; do if [ -d $GADGET/${!i} ] then if [ -d $GADGET/${!i}/$CONFIG ] then if [ ${!i} == $addr1 ] && [ -d $GADGET/${!i}/$CONFIG/acm.gs0 ] then rm $GADGET/${!i}/$CONFIG/acm.gs0 elif [ ${!i} == $addr2 ] && [ -d $GADGET/${!i}/$CONFIG/acm.gs1 ] then rm $GADGET/${!i}/$CONFIG/acm.gs1 fi if [ -d $GADGET/${!i}/$CONFIG/strings/0x409 ] then rmdir $GADGET/${!i}/$CONFIG/strings/0x409 fi rmdir $GADGET/${!i}/$CONFIG fi if [ -d $GADGET/${!i}/functions/acm.gs0 ] then rmdir $GADGET/${!i}/functions/acm.gs0 elif [ -d $GADGET/${!i}/functions/acm.gs1 ] then rmdir $GADGET/${!i}/functions/acm.gs1 fi if [ -d $GADGET/${!i}/strings/0x409 ] then rmdir $GADGET/${!i}/strings/0x409 fi rmdir $GADGET/${!i} fi done if grep -q "^"usb_f_acm"" /proc/modules then rmmod usb_f_acm fi if grep -q "^"u_serial"" /proc/modules then rmmod u_serial fi if grep -q "^"libcomposite"" /proc/modules then rmmod libcomposite fi

 

Related content