numicro® usb 2.0全速裝置之實作 - nuvoton.com · jun. 16, 2017 page 1 of 117 rev 1.00 an0015...
TRANSCRIPT
-
Jun. 16, 2017 Page 1 of 117 Rev 1.00
AN0015
Application Note for 32-bit NuMicro
Family
Document Information
NuMicro USB 2.0USB
NuMicroUSB 2.0
The information described in this document is the exclusive intellectual property of
Nuvoton Technology Corporation and shall not be reproduced without permission from Nuvoton.
Nuvoton is providing this document only for reference purposes of NuMicro microcontroller based system design. Nuvoton
assumes no responsibility for errors or omissions.
All data and specifications are subject to change without notice.
For additional information or questions, please contact: Nuvoton Technology Corporation.
www.nuvoton.com
NuMicro USB 2.0
http://www.nuvoton.com/ -
Jun. 16, 2017 Page 2 of 117 Rev 1.00
AN0015
Table of Contents
1 ............................................................................................................................................... 4
2 USB ...................................................................................................................................... 5
2.1 USB ....................................................................................................................................... 5
2.2 USB ............................................................................................................................... 7
2.2.1 USB ...................................................................................................................................... 7 2.2.2 USB .................................................................................................................................... 10
2.3 USB ................................................................................................................................. 11
2.3.1 (Device Descriptor) ......................................................................................................... 12 2.3.2 (Configuration Descriptor) .............................................................................................. 13 2.3.3 HID ..................................................................................................................... 16
2.4 USB(Request) ...................................................................................................................... 16
2.5 ..................................................................................................................................... 18
3 NANO100B USB 2.0 ................................................................................ 22
3.1 ............................................................................................................................................ 22
3.2 ..................................................................................................................................... 22
3.2.1 SIE(Serial Interface Engine) ............................................................................................................... 23 3.2.2 ............................................................................................................................................ 23 3.2.3 Buffer .......................................................................................................................................... 23 3.2.4 DPLL .................................................................................................................................................. 24 3.2.5 VBUS ...................................................................................................................... 24 3.2.6 ........................................................................................................................................ 24 3.2.7 .................................................................................................................................................... 25 3.2.8 USB ................................................................................................................................... 25
3.3 ................................................................................................................................. 26
3.3.1 USB_CTL ........................................................................................................................................... 27 3.3.2 USB_INTEN ...................................................................................................................................... 28 3.3.3 USB_INTSTSUSB_BUSSTS ......................................................................................................... 28 3.3.4 USB_FADDR ..................................................................................................................................... 30 3.3.5 USB_EPSTSUSB_EPSTS2 ............................................................................................................ 30 3.3.6 USB_BUFSEGUSB_BUFSEGx .................................................................................................... 31 3.3.7 USB_MXPLDx .................................................................................................................................. 32 3.3.8 USB_CFGx ......................................................................................................................................... 33
4 NANO100B USB2.0 ............................................................ 34
-
Jun. 16, 2017 Page 3 of 117 Rev 1.00
AN0015
4.1 USB ........................................................................................................................ 36
4.2 USB ........................................................................................................................ 41
4.2.1 USB ................................................................................................................................ 41 4.2.2 ............................................................................................................................................ 46 4.2.3 ................................................................................................................................................ 47
5 USB ............................................................................................................................ 52
5.1 HID............................................................................................................................................. 53
5.1.1 HID Transfer ....................................................................................................................................... 53 5.1.2 HID Mouse ......................................................................................................................................... 59 5.1.3 HID Keyboard .................................................................................................................................... 63
5.2 MSC ........................................................................................................................................... 67
5.2.1 ................................................................................................................................ 67 5.2.2 Endpoint .................................................................................................................................. 78 5.2.3 ................................................................................................................................ 80
5.3 CDC ........................................................................................................................................... 85
5.3.1 CDC ........................................................................................................................ 90 5.3.2 Endpoint .................................................................................................................................. 92 5.3.3 ................................................................................................................................ 97
5.4 UAC ........................................................................................................................................... 99
5.4.1 .............................................................................................................................. 101 5.4.2 Endpoint ................................................................................................................................ 106 5.4.3 .............................................................................................................................. 108
6 .......................................................................................................................................... 115
-
Jun. 16, 2017 Page 4 of 117 Rev 1.00
AN0015
1
NuMicroUSB2.0USB
USB
USBUSBUSB
USBUSBUSB Specification Revision
2.0 Cortex -M0 Nano100B NuMicro USB2.0
HID Transfer
HID Keyboard
HID Mouse
MSC
VCOM
Audio
-
Jun. 16, 2017 Page 5 of 117 Rev 1.00
AN0015
2 USB
(Universal Serial BusUSB)
USB(
)USB
(Tiered Star Network)
5HubHub128
7128USB
127127USB
0USBUSB0
USB(USB Devices)USB
Function()USBUSB(Cable)
USB(Port)RS-232
(Device)
USB(Device Driver)USB
USB(Class)USB (CDC)
(HID)(MSC)USB(UAC)USB
USB
(Low-Speed Devices) 1.5 Mbps
(Full-Speed Devices) 12 Mbps
(High-Speed Devices)USB2.0 480 Mbps
(Endpoint)(Virtual Pipe)
(
Descriptor)USB(Control)(Interrupt)(Bulk)
(Isochronous)
USBUSBUSB
USBUSB Specification Revision 2.0
2.1 USB
USB+5(VBus)(GND)D+D-
(Twisted Pair)D+D-
NRZI(Non-Return-To-Zero Inverted)
USBD+D-
(Idle)(Suspend)(Resume)(Start of Packet)
-
Jun. 16, 2017 Page 6 of 117 Rev 1.00
AN0015
(End of Packet)(Disconnect)(Connect)(Reset) 1
Idle (D+) - (D-) > 200 mvJ State
Suspend Idle3ms
Resume (D-) - (D+) > 200 mvK State
Start-of-Packet (SOP) IdleResume
End-of-Packet (EOP) D+D-2bit3bitIdle
Single-ended 0 (SE0) D+D- < VSE (min)VSE (min)0.8v
Disconnect SE02.5us
Connect D+D-2.5us
Reset D+D-2.5us
1 USB
USBNRZI1
0 1NRZI 1
1 NRZI
NRZI1
(Bit Stuffing)10
2
-
Jun. 16, 2017 Page 7 of 117 Rev 1.00
AN0015
2 NRZI
2.2 USB
USB
USBUSBUSB(Transfer)
(Transaction)(Transaction)(Packet)(Packet)
USB 3USB Transfer-Transaction-Packet
3 USB Transfer-Transaction-Packet
2.2.1 USB
USB
(Sync)PID(Address)(Endpoint)(Frame Number)
(Data)CRC
SYNCSYNC32bitSYNC
8BitPIDTokenDataHandshakeSpecial16
PID 2PID8BitsBit4Bit
4BitPIDLSBMSB
-
Jun. 16, 2017 Page 8 of 117 Rev 1.00
AN0015
PID4Bit=10014Bit0110PID10010110Special
USB2.0PIDPING()SPLIT(USB
)PRE(USB)ERR()OUTSETUP
IN
CRC
TokenToken
TokenData
HandshakeHandshakeData
HostDeviceOUTDeviceHostIN
PID PID PID
Token OUT 0001B Endpoint
IN 1001B Endpoint
SOF 0101B 11BitFrame number
Frame
SETUP 1101B Endpoint
Setup
Data DATA0 0011B
DATA1 1011B
DATA2 0111B High speed
MDATA 1111B High speed
Handshake ACK 0010B
NAK 1010B
STALL 1110B
Stall
NYET 0110B High speed
Special PRE 1100B Low speed
-
Jun. 16, 2017 Page 9 of 117 Rev 1.00
AN0015
ERR 1100B High speed
SPLIT 1000B High speed
PING 0100B High speed
Reserved 0000B
2 PID
2.2.1.1 Token
TokenSYNCPIDADDRENDPFrame NumberCRC5PID
OUTINSOFSETUPADDR7Bits127
OUTSETUP
INFrame NumberSOF
CRC 4 5USBToken
OUT IN
SOF SOF(Frame) 1ms SOF
Frame SOF
SETUP(Setup stage)SETUP 8 Bytes
2.4
4 INOUT SETUP Token
5 SOF Token
2.2.1.2 Data
DataTokenData
1024 BytesPIDDataDATA0DATA1DATA0DATA1
CRC 64
Data
-
Jun. 16, 2017 Page 10 of 117 Rev 1.00
AN0015
6 Data
2.2.1.3 Handshake
(Isochronous)USBHandshake
HandshakePID 7ACK
NAKSTALL
7 Handshake
2.2.2 USB
USB(Endpoint)
USB
(Control)(Interrupt)(Bulk)(Isochronous)
3
(Stage)
(Control)
Setup Token
(Stage)SetupData()Status
(Transcation)
USB
(1) Setup 8 Bytes
(2) Data USB USB
(3) Status
Data
Handshake
Data(IN
OUT
)
Token
Data
Handshake
Status Token
Data
-
Jun. 16, 2017 Page 11 of 117 Rev 1.00
AN0015
Handshake
(Interrupt)
Data(IN
OUT)
Token USB1.1USB2.0
(Polling)
Data
Handshake
(Bulk) Data(IN
OUT)
Token
()
USB
Data
Handshake
(Isochronous)
Data(IN
OUT)
Token
USB
USB
Data
3
2.3 USB
USB
8 (Device
Descriptor)(Configuration Descriptor)(Interface Descriptor)
(Class-specific Descriptors) (Endpoint Descriptor) (String
Descriptor)
USB
USBUSB
USBUSB
HID(Report)
(Physical)HID
(Report)
-
Jun. 16, 2017 Page 12 of 117 Rev 1.00
AN0015
8
2.3.1 (Device Descriptor)
USBUSB(HIDMSC...)
USB18 Bytes
4
(Byte)
bLength 0 1 byte
bDescriptorType 1 1 ( = 1)
bcdUSB 2 2 USB0x0110USB1.1
bDeviceClass 4 1 USB(USB-IF)
0
-
Jun. 16, 2017 Page 13 of 117 Rev 1.00
AN0015
bDeviceSubClass 5 1 USB
00
bDeviceProtocol 6 1 USB(USB-IF)
0
bMaxPacketSize0 7 1
idVendor 8 2 (VID)USB(USB-IF)
idProduct 10 2 (PID)
bcdDevice 12 2 4
BCD
iManufacturer 14 1 USB
iProduct 15 1 USB
iSerialNumber 16 1 USB
bNumConfigurations 17 1
4
2.3.2 (Configuration Descriptor)
(Interface)(Class)
(Endpoint)(IAD)
USB 5
(Byte)
bLength 0 1 byte
bDescriptorType 1 1 ( = 2)
bTotalLength 2 2
-
Jun. 16, 2017 Page 14 of 117 Rev 1.00
AN0015
bNumInterfaces 4 1
bConfigurationValue 5 1 Set_Configuration
iConfiguration 6 1
bmAttributes 7 1
Bit7 Bit6 Bit5 Bit4~ Bit0
1
0
bMaxPower 8 1 (2mA)=50100mA
5
9 Bytes
6
(Byte)
bLength 0 1 9
bDescriptorType 1 1 ( = 4)
bInterfaceNumber 2 1 0
bAlternateSetting 3 1
bNumEndpoints 4 1
bInterfaceClass 5 1 USB(USB-IF)
bInterfaceSubClass 6 1 USB(USB-IF)
bInterfaceProtocol 7 1 USB(USB-IF)
iInterface 8 1 USB
6
-
Jun. 16, 2017 Page 15 of 117 Rev 1.00
AN0015
7
(Byte)
bLength 0 1 7
bDescriptorType 1 1 ( = 5)
bEndpointAddress 2 1
Bit[3:0]
Bit[6:4]
Bit[7]=1Bit[7]=0(0
)
bmAttributes 3 1
Bit[1: 0]:00
Bit[1: 0]:01
Bit[1: 0]:10
Bit[1: 0]:11
wMaxPacketSize 4 2
bInterval 6 1 (ms)1~255ms
1
1 255
7
UNICODEGet
Descriptor Request
8
(Byte)
bLength 0 1
bDescriptorType 1 1 ( = 3)
wLANGID 2 2 0x0409
bLength 4 1
-
Jun. 16, 2017 Page 16 of 117 Rev 1.00
AN0015
bDescriptorType 5 1
bString 6 8
bLength 14 1
bDescriptorType 15 1
bString 16 32
8
2.3.3 HID
HIDHIDHIDHID
HID
HIDUSB.orgDevice Class Definition
for HID 1.11
2.4 USB(Request)
USB
(Request)USB
(SetupDataStatus)
HOST8 BytesSetup
(Device/Interface/Endpoint) 9
Setup 9USB 10USB(
USB Specification Revision 2.0)
Setup80 06 00 01 00 00 12 001BytebmRequestType=0x80
2BytebRequest=0x06
0x06Get_Descriptor34 BytewValue
0x0001
78 BytewLength0x0012Data
18
(Byte)
0 bmRequestType 1 D7
D[6:5]
D[4:0]
0: 00
0000
01
0001
-
Jun. 16, 2017 Page 17 of 117 Rev 1.00
AN0015
1: 10
0010
11
0011
1 bRequest 1 D[7:0] ( 9)
2 wValue 2 D[15:0]
4 wIndex 2 D[15:0]
6 wLength 2 D[15:0]Data
Data
9 Setup
9 USB
-
Jun. 16, 2017 Page 18 of 117 Rev 1.00
AN0015
10 Setup
2.5
USBUSB
-
Jun. 16, 2017 Page 19 of 117 Rev 1.00
AN0015
HIDMSCWindowsINF
usbser.sysCDCINFUSB
(USB-IF)VID/PID
WindowsVID/PID
USBPIDWindows
VCOMNuvoton"NuvotonCDC.inf"Strings
VIDPIDUSBVID/PID 10
VID/PID
;
; Windows USB CDC Driver Setup File for Nuvoton-CDC (XP/2000)
;
;
[Version]
Signature = "$Windows NT$"
Provider = %COMPANY%
DriverVer = 10/02/2014,1.0.0.1
CatalogFile = NuvotonCDC.cat
Class = Ports
ClassGuid = {4D36E978-E325-11CE-BFC1-08002BE10318}
[Manufacturer]
%MFGNAME% = Devices,NT,NTamd64
;--------------------------------------------------------------------------
; Files
;--------------------------------------------------------------------------
[DestinationDirs]
DefaultDestDir = 12
;--------------------------------------------------------------------------
; Device driver
;--------------------------------------------------------------------------
[NuvotonCDC_DEV.NT]
Include = mdmcpq.inf
CopyFiles = FakeModemCopyFileSection
AddReg = NuvotonCDC_DEV.NT.AddReg
[NuvotonCDC_DEV.NT.AddReg]
-
Jun. 16, 2017 Page 20 of 117 Rev 1.00
AN0015
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[NuvotonCDC_DEV.NT.Services]
AddService=usbser, 0x00000002, DriverService
;--------------------------------------------------------------------------
; Services
;--------------------------------------------------------------------------
[DriverService]
DisplayName = %SERVICE%
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %12%\usbser.sys
;--------------------------------------------------------------------------
; Devices
;--------------------------------------------------------------------------
[Devices.NT]
%DESCRIPTION% = NuvotonCDC_DEV, USB\VID_0416&PID_5011
[Devices.NTamd64]
%DESCRIPTION% = NuvotonCDC_DEV, USB\VID_0416&PID_5011
;--------------------------------------------------------------------------
; Strings
;--------------------------------------------------------------------------
[Strings]
COMPANY = "Nuvoton Co., Ltd."
MFGNAME = "www.nuvoton.com"
DESCRIPTION = "Nuvoton Virtual Com Port"
SERVICE = "USB RS-232 Emulation Driver"
-
Jun. 16, 2017 Page 21 of 117 Rev 1.00
AN0015
BSP VID PID
USBD_HID_Transfer 0x0416 0x5020
USBD_HID_Mouse 0x0416 0x8240
USBD_HID_Keyboard 0x0416 0x0123
USBD_Mass_Storage_Flash 0x0416 0x501E
USBD_VCOM_SerialEmulator 0x0416 0x5011
USBD_Audio_Speaker 0x0416 0x1284
10 VID/PID
-
Jun. 16, 2017 Page 22 of 117 Rev 1.00
AN0015
3 Nano100B USB 2.0
Cortex -M0 Nano100B NuMicro USB2.0
Nano100BUSBUSB2.0PHY
USB2.0 Full Speed
APB BusUSB PHYUSB BusCPU
APB Bus512Bytes SRAM(Buffer)IN
OUTAPBSIE(Serial Interface Engine)SRAMSRAM
USBD_BUFSEGxSRAM
USB8INOUT
USB_MXPLDxUSB_MXPLDx
Handshake
TranscationBuffer
4USB(IN ACK
OUT ACK)BUS(SuspendResume)
USB_INTSTSUSB_EPSTS
USB
DRVSE0(USB_CTL[4])1USBD+D-
DRVSE0(USB_CTL[4])0USB
3.1
Nano100B USB2.0
USB 2.0 Full Speed
4 (WAKEUPFLDETUSB BUS)
4
USB 3ms(Suspend)
8
512-Byte SRAM(Buffer)
3.2
Nano100B USB2.0 11
Nano100B USB
-
Jun. 16, 2017 Page 23 of 117 Rev 1.00
AN0015
RXDP
RXDM
S0
S1
Transceiver
USB_D+
USB_D-
SIE
VBUS
Detection
De-bouncingDPLL
Endpoint
Control
Buffer
Control
SRAM
(512
Bytes)
APB Bus
USB
control
and
status
registers
Interrupt
control
Clock
GeneratorNVIC
VBUS
Detection
USB_VBUS
11 Nano100B USB
3.2.1 SIE(Serial Interface Engine)
SIE(Serial Interface EngineSIE)SIEUSB
USBUSBSIE
SOPEOPRESETRESUME
Clock Data
NRZI /
CRC( Token Data)
Packet ID (PID)
/
3.2.2
Nano100B USB2.08INOUT
2
Transcation
Buffer
3.2.3 Buffer
Nano100B USB2.0512 BytesSRAMUSB BufferSETUP Token
8Buffer
USB_BUFSEGx
USB_MXPLDxUSB Buffer0SETUP
BufferIN BufferOUT Buffer
-
Jun. 16, 2017 Page 24 of 117 Rev 1.00
AN0015
12USB_BUFSEGxUSB_MXPLDx
SRAM BufferBUFSEG00x08hMXPLD0 0x40h
0BufferUSB_BASE+0x108hUSB_BASE+0x147h
12 Buffer
3.2.4 DPLL
USB12MHzDPLLClock48MHzPHY
RXDPRXDM12MHzUSBDPLL
3.2.5 VBUS
USBUSBVBUS
USBVBUSUSB
10msFLDET(USB_BUSSTS[4])USB
3.2.6
14(WAKEUPFLDETUSB BUS)
WAKEUPClock(Power DownCLK_PWRCON
)FLDETUSBUSBMCU
USB(IN ACKOUT ACK)BUSMCUUSB BUS
(Suspend)(Resume)NVICUSB_INTEN
USB
WAKEUPNano100BPower DownNano100B
-
Jun. 16, 2017 Page 25 of 117 Rev 1.00
AN0015
Power DownUSB_VBUSUSB_D+USB_D-
Nano100B(USB)USB20msUSB
Wake-up 13WAKEUP
13 USB Wake-up
3.2.7
Nano100BPower DownUSBPHY
(Suspend)PHY_EN(USB_CTL[1])0
3.2.8 USB
USB_INTSTSUSB Transcation
USBUSB_INTSTSCPU(
)USB_INTSTS
INOUT( 14 15)
USB
MAXPLDx
In_RdyIN Token
In_Rdy
(Transcation)(Transcation)
CLRRDY(USB_CFGx[15])1In_RdyOut_Rdy
-
Jun. 16, 2017 Page 26 of 117 Rev 1.00
AN0015
USB_IRQ
In_Rdy
Data In
SETUP PID Data Setup ACK PID IN PID NAK PID IN PID Data 0/1 ACK PIDUSB
Bus Packets
Setup Received Setup Handled by Firmware
Set by Hardware Clear by Firmware
Set by writing
USBD_MXPLDx
register
Clear by Hardware
14 Data In
USBOUT
(Transcation)MAXPLDx
Out_Rdy
(Transcation)(Transcation)MAXPLDx
Out_Rdy(Transcation)
USB_IRQ
Out_Rdy
OUT PID Data 0/1 ACK PID OUT PID NAK PID OUT PID Data 0/1 ACK PIDUSB
Bus Packets
Read Data from Buffer
Set by Hardware Clear by Firmware
Set by writing
USBD_MXPLDx registerClear by HardwareClear by Hardware
15 Data Out
3.3
Nano100B USB2.0 11 12 11
SETUP TokenBufferBuffer
R/W
USB_BA = 0x4006_0000
USB_CTL USB_BA+0x00 R/W USB 0x0000_0900
-
Jun. 16, 2017 Page 27 of 117 Rev 1.00
AN0015
USB_BUSSTS USB_BA+0x04 R USB Bus 0x0000_0000
USB_INTEN USB_BA+0x08 R/W Enable 0x0000_0000
USB_INTSTS USB_BA+0x0C R/W 0x0000_0000
USB_FADDR USB_BA+0x10 R/W 0x0000_0000
USB_EPSTS USB_BA+0x14 R 0x0000_0000
USB_BUFSEG USB_BA+0x18 R/W Setup TokenBuffer
0x0000_0000
USB_BUFSEGx USB_BA+0x20 R/W x Buffer 0x0000_0000
USB_MXPLDx USB_BA+0x24 R/W x 0x0000_0000
USB_CFGx USB_BA+0x28 R/W x 0x0000_0000
11 USB
Nano100B USB2.0 512 Bytes SRAM( 12) USB Buffer
SETUP 8 Buffer
USB_BA = 0x4006_0000
SRAM USB_BA + 0100h ~
USB_BA + 02FFh 512-Bytes USB SRAM Buffer
12 USB Buffer
3.3.1 USB_CTL
USB_CTLUSB
1. USB_EN(USB_CTL[0])Enable USB
2. PHY_EN(USB_CTL[1])Enable PHY
3. PWRDB(USB_CTL[2]) PHY
4. DPPU_EN(USB_CTL[3])Enable USB_D+ Pull-up
5. DRVSE0(USB_CTL[4])SE0 USB_D+ USB_D- Low Bit USB
DRVSE0(USB_CTL[4]) 1 USB
DRVSE0(USB_CTL[4]) 0 USB
USB
6. RWAKEUP(USB_CTL[8])USB K
-
Jun. 16, 2017 Page 28 of 117 Rev 1.00
AN0015
7. WAKEUP_EN(USB_CTL[9])Enable
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
Reserved WAKEUP_EN RWAKEUP
7 6 5 4 3 2 1 0
Reserved DRVSE0 DPPU_EN PWRDB PHY_EN USB_EN
3.3.2 USB_INTEN
USBEnableUSBUSB BusUSB
USBEnable
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
Reserved
7 6 5 4 3 2 1 0
Reserved WAKEUP_IE FLDET_IE USBEVT_IE BUSEVT_IE
3.3.3 USB_INTSTS USB_BUSSTS
USB_BUSSTSUSB_INTSTS
USB_INTSTS[0:3]
1. BUS_STS(USB_INTSTS[0]) 1 USB Bus
USB_BUSSTS[2:0] USB Bus TIMEOUT(USB_BUSSTS[3])
Timeout IN Token ACK 18 12M
Clock Timeout
2. USB_STS(USB_INTSTS[1]) 1 USB
SETUP(USB_INTSTS[31]) EPEVT7~EPEVT0(USB_INTSTS[23:16]) SETUP
SETUP(USB_INTSTS[31]) 1 SETUP
SETUP Buffer USB
EPEVT7~EPEVT0(USB_INTSTS[23:16]) 1
USB_EPSTS
-
Jun. 16, 2017 Page 29 of 117 Rev 1.00
AN0015
3. FLD_STS(USB_INTSTS[2]) 1 FLDET(USB_BUSSTS[4]) USB
4. WKEUP_STS(USB_INTSTS[3]) 1
Register Offset R/W Description Reset Value
USB_INTSTS USB_BA+0x0C R/W Interrupt Event Status Register 0x0000_0000
31 30 29 28 27 26 25 24
SETUP Reserved
23 22 21 20 19 18 17 16
EPEVT7 EPEVT6 EPEVT5 EPEVT4 EPEVT3 EPEVT2 EPEVT1 EPEVT0
15 14 13 12 11 10 9 8
Reserved
7 6 5 4 3 2 1 0
Reserved WKEUP_STS FLD_STS USB_STS BUS_STS
Register Offset R/W Description Reset Value
USB_BUSSTS USB_BA+0x04 R USB Bus Status Register 0x0000_0000
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
Reserved
7 6 5 4 3 2 1 0
Reserved FLDET TIMEOUT RESUME SUSPEND USBRST
-
Jun. 16, 2017 Page 30 of 117 Rev 1.00
AN0015
3.3.4 USB_FADDR
USB
USB
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
Reserved
7 6 5 4 3 2 1 0
Reserved FADDR
3.3.5 USB_EPSTS USB_EPSTS2
USB_EPSTSUSB_EPSTS28IN
ACKIN NACKOUT DATA0 ACKOUT DATA1 ACKSETUP ACKIsochronous transfer
endOVERRUN(USB_EPSTS[7])MXPLDx
Setup8 Bytes
1. IN ACK IN Token USB ACK
USB USB IN ACK CPU
2. IN NACK IN Token MXPLDx USB
NACK IN NACK
3. OUT DATA0 ACK OUT Token DATA0 TokenUSB
ACK OUT DATA0 ACK
4. OUT DATA1 ACK OUT Token DATA1 TokenUSB
ACK OUT DATA1 ACK
5. SETUP ACK 8 Bytes SETUP USBUSB
ACK USB SETUP ACK CPU
6. Isochronous transfer end
-
Jun. 16, 2017 Page 31 of 117 Rev 1.00
AN0015
Register Offset R/W Description Reset Value
USB_EPSTS USB_BA+0x14 R Endpoint Status Register 0x0000_0000
31 30 29 28 27 26 25 24
EPSTS5 EPSTS4
23 22 21 20 19 18 17 16
EPSTS3 EPSTS2
15 14 13 12 11 10 9 8
EPSTS1 EPSTS0
7 6 5 4 3 2 1 0
OVERRUN Reserved
Register Offset R/W Description Reset Value
USB_EPSTS2 USB_BA+0x1C R Endpoint Status Register 0x0000_0000
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
Reserved
7 6 5 4 3 2 1 0
EPSTS7 EPSTS6
3.3.6 USB_BUFSEG USB_BUFSEGx
USB_BUFSEGSETUPSRAMUSB_BUFSEGx(x=0~7)
INOUT BufferSRAM
SETUP BufferSRAM0USB_BUFSEG0
Register Offset R/W Description Reset Value
USB_BUFSEG USB_BA+0x18 R/W Setup Token Buffer Segmentation Register 0x0000_0000
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
-
Jun. 16, 2017 Page 32 of 117 Rev 1.00
AN0015
Reserved
15 14 13 12 11 10 9 8
Reserved BUFSEG
7 6 5 4 3 2 1 0
BUFSEG Reserved
Register Offset R/W Description Reset Value
USB_BUFSEG0 USB_BA+0x20 R/W Endpoint 0 Buffer Segmentation Register 0x0000_0000
USB_BUFSEG1 USB_BA+0x30 R/W Endpoint 1 Buffer Segmentation Register 0x0000_0000
USB_BUFSEG2 USB_BA+0x40 R/W Endpoint 2 Buffer Segmentation Register 0x0000_0000
USB_BUFSEG3 USB_BA+0x50 R/W Endpoint 3 Buffer Segmentation Register 0x0000_0000
USB_BUFSEG4 USB_BA+0x60 R/W Endpoint 4 Buffer Segmentation Register 0x0000_0000
USB_BUFSEG5 USB_BA+0x70 R/W Endpoint 5 Buffer Segmentation Register 0x0000_0000
USB_BUFSEG6 USB_BA+0x80 R/W Endpoint 6 Buffer Segmentation Register 0x0000_0000
USB_BUFSEG7 USB_BA+0x90 R/W Endpoint 7 Buffer Segmentation Register 0x0000_0000
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
Reserved BUFSEG
7 6 5 4 3 2 1 0
BUFSEG Reserved
3.3.7 USB_MXPLDx
USB_MXPLDxUSB(IN Token)
(OUT Token)(IN
Token)(OUT Token)
IN Token
OUT TokenUSBMXPLD(USB_MXPLDx[7:0])
-
Jun. 16, 2017 Page 33 of 117 Rev 1.00
AN0015
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
MXPLD
7 6 5 4 3 2 1 0
MXPLD
3.3.8 USB_CFGx
USB_CFGxUSB
1. EP_NUM(USB_CFGx[3:0])
2. ISOCH(USB_CFGx[4])
3. EPMODE(USB_CFGx[6:5]) IN OUT
4. DSQ_SYNC(USB_CFGx[7]) DATA0 DATA1 PID IN Token
ACK Token
PID
5. CSTALL SSTALL SSTALL(USB_CFGx[9]) 1USB
STALL SSTALL(USB_CFGx[9]) 0 STALL
SSTALL(USB_CFGx[9]) CSTALL(USB_CFGx[8]) 1
31 30 29 28 27 26 25 24
Reserved
23 22 21 20 19 18 17 16
Reserved
15 14 13 12 11 10 9 8
Reserved SSTALL CSTALL
7 6 5 4 3 2 1 0
DSQ_SYNC EPMODE ISOCH EP_NUM
-
Jun. 16, 2017 Page 34 of 117 Rev 1.00
AN0015
4 Nano100B USB2.0
Cortex -M0 Nano100B NuMicro USB2.0
Nano100BUSB2.0BSP USB
(MSC)HIDUSBUARTVirtual COM(CDC)
Nano100BUSBAPI
FunctionUSB
USBUSB
USBUSB 13 14
USB Driver
USB
(API)
usbd(.c,.h) USBUSB Specification RevisionUSB
13
USB
USBD_HID_Transfer descriptors.c
HID
hid_transfer.c HID
hid_transfer.h HID
main.c USB
USBD_HID_Mouse descriptors.c
HID
hid_mouse.c HID
hid_mouse.h HID
main.c USB
-
Jun. 16, 2017 Page 35 of 117 Rev 1.00
AN0015
USBD_HID_Keyboard descriptors.c
HID
hid_kb.c HID
hid_kb.h HID
main.c USB
GPIO PB15
A
USBD_Mass_Storage_Flash descriptors.c
MassStorage.c MSC
MassStorage.h Mass Storage UFI
main.c USB MSC
Nano100BData Flash
USB
USBD_VCOM_SerialEmulator descriptors.c
vcom_serial.c CDC
vcom_serial.h CDC
main.c USB
COM Port
USBD_Audio_Speaker descriptors.c
usbd_audio.c UAC
usbd_audio.h UAC
main.c USB SpeakerRecorder
USB
-
Jun. 16, 2017 Page 36 of 117 Rev 1.00
AN0015
14
4.1 USB
USBUSB
USB 15API
APIusbd.c
USBD_Open USBUSB PHY
USB_D+USB PHYSE0
USBD_Start USB(WAKEUPFLDETUSBBUS)
SysTick Timer100ms(USB)
USBD_GetSetupPacket SETUP
USBD_ProcessSetupPacket SETUP
USBD_GetDescriptor GetDescriptor
USBD_StandardRequest
USBD_PrepareCtrlIn Control IN
USBD_CtrlIn Control IN
USBD_PrepareCtrlOut Control OUT
USBD_CtrlOut Control OUT
USBD_SwReset ProtocolUSB0
USBD_SetVendorRequest USBVendor
USBD_LockEpStall SET FEATUREStall Clear
StallUSB
USBD_SetStall USBStallSTALL Token
USBD_ClearStall USBStallACK/NAK Token
-
Jun. 16, 2017 Page 37 of 117 Rev 1.00
AN0015
USBD_IRQHandler (ISR)USB
15 API
USB
USBD_ProcessSetupPacket()USBD_PrepareCtrlIn()USBD_PrepareCtrlOut()USBD_CtrlIn()
USBD_CtrlOut()USBD_ProcessSetupPacketUSBD_PrepareCtrlIn
USBD_PrepareCtrlOut
void USBD_ProcessSetupPacket(void)
{
/* SETUP BufferSETUP */
USBD_MemCopy(g_usbd_SetupPacket, (uint8_t *)USBD_BUF_BASE, 8);
/* */
switch (g_usbd_SetupPacket[0] & 0x60) {
/* USB */
case REQ_STANDARD: { // Standard
USBD_StandardRequest();
break;
}
/* USB */
case REQ_CLASS: {
if (g_usbd_pfnClassRequest != NULL) {
g_usbd_pfnClassRequest();
}
break;
}
/* Vendor */
case REQ_VENDOR: {
if (g_usbd_pfnVendorRequest != NULL) {
g_usbd_pfnVendorRequest();
}
break;
}
default: { // reserved
/* Setup error, stall the device */
USBD_SET_EP_STALL(EP0);
USBD_SET_EP_STALL(EP1);
break;
}
-
Jun. 16, 2017 Page 38 of 117 Rev 1.00
AN0015
}
}
USBUSBRead/Write3
SetupDataStatus 16Read/Write
Read/Write
Write
1. Setup SETUP TokenUSB USB 8
Bytes SETUP Buffer
2. Data OUT Token 0USB
OUT Buffer
3. StatusUSB 0
Read
1. Setup SETUP TokenUSB USB 8
Bytes SETUP buffer
2. Data IN Token 0USB
IN Buffer NACK
3. Status 0 USB
16 ReadWrite
SetupDataStatus
Firmware
void USBD_StandardRequest(void)
{
/* */
g_usbd_CtrlInPointer = 0;
-
Jun. 16, 2017 Page 39 of 117 Rev 1.00
AN0015
g_usbd_CtrlInSize = 0;
if (g_usbd_SetupPacket[0] & 0x80) {
/* Device - > Host */
switch (g_usbd_SetupPacket[1]) {
case GET_CONFIGURATION: {
/* IN Buffer */
M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig;
/* Data */
USBD_SET_DATA1(EP0); /* DATA1 PID */
USBD_SET_PAYLOAD_LEN(EP0, 1); /* 1 */
/* Status */
USBD_PrepareCtrlOut(0,0); /* Control OUT */
break;
}
case GET_DESCRIPTOR: {
/* */
USBD_GetDescriptor();
break;
}
} else {
/* Host- > Device */
switch (g_usbd_SetupPacket[1]) {
case SET_ADDRESS: {
/* SET_ADDRESSData */
g_usbd_UsbAddr = g_usbd_SetupPacket[2];
/* Status */
USBD_SET_DATA1(EP0); /* DATA1 PID */
USBD_SET_PAYLOAD_LEN(EP0, 0); /* 0 */
break;
}
case SET_INTERFACE: {
/* SET_INTERFACEData */
g_usbd_UsbAltInterface = g_usbd_SetupPacket[2];
if (g_usbd_pfnSetInterface != NULL)
g_usbd_pfnSetInterface(g_usbd_UsbAltInterface);
/* Status */
USBD_SET_DATA1(EP0); /* DATA1 PID */
USBD_SET_PAYLOAD_LEN(EP0, 0); /* 0 */
break;
-
Jun. 16, 2017 Page 40 of 117 Rev 1.00
AN0015
}
}
}
USBD_CtrlOutUSBD_CtrlIn
void USBD_CtrlIn(void)
{
if(g_usbd_CtrlInSize) { /* */
/* */
if(g_usbd_CtrlInSize > g_usbd_CtrlMaxPktSize) {
/* > MXPLD BytesIN Buffer */
USBD_MemCopy((uint8_t *)USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0),
(uint8_t *)g_usbd_CtrlInPointer, g_usbd_CtrlMaxPktSize);
/* MXPLD */
USBD_SET_PAYLOAD_LEN(EP0, g_usbd_CtrlMaxPktSize);
g_usbd_CtrlInPointer += g_usbd_CtrlMaxPktSize;
g_usbd_CtrlInSize -= g_usbd_CtrlMaxPktSize;
} else {
/*
-
Jun. 16, 2017 Page 41 of 117 Rev 1.00
AN0015
{
uint32_t u32Size;
/* */
if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit) {
u32Size = USBD_GET_PAYLOAD_LEN(EP1);
/* Buffer */
USBD_MemCopy((uint8_t *)g_usbd_CtrlOutPointer, (uint8_t *)USBD_BUF_BASE +
USBD_GET_EP_BUF_ADDR(EP1), u32Size);
g_usbd_CtrlOutPointer += u32Size;
g_usbd_CtrlOutSize += u32Size;
}
if(g_usbd_CtrlOutSize < g_usbd_CtrlOutSizeLimit)
USBD_SET_PAYLOAD_LEN(EP1, g_usbd_CtrlMaxPktSize); /* */
}
4.2 USB
USBUSB
Nano100BBSPUSBUSB
USBUSB
4.2.1 USB
USBClockPLL Clock48MHzUSBEnable
PLLUSBD_EN(APBCLK[27])USB ClockUSB_N
(CLKDIV[7:4])USB ClockUSB Clock
void SYS_Init(void)
{
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable external 12MHz HXT */
CLK_EnableXtalRC(CLK_PWRCTL_HXT_EN_Msk);
CLK_EnablePLL(CLK_PLLCTL_PLL_SRC_HXT, 96000000);
/* Waiting for clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_HXT_STB_Msk | CLK_CLKSTATUS_PLL_STB_Msk);
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_PLL, CLK_HCLK_CLK_DIVIDER(3));
-
Jun. 16, 2017 Page 42 of 117 Rev 1.00
AN0015
/* Select IP clock source */
CLK_SetModuleClock(USBD_MODULE, 0, CLK_USB_CLK_DIVIDER(2));
/* Enable IP clock */
CLK_EnableModuleClock(USBD_MODULE);
/* Select IP clock source */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_UART_CLK_DIVIDER(1));
/* Enable IP clock */
CLK_EnableModuleClock(UART0_MODULE);
/*-------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*-------------------------------------------------------------------------*/
/* Set PA multi-function pins for UART0 RXD and TXD */
SYS->PA_H_MFP &= ~( SYS_PA_H_MFP_PA15_MFP_Msk | SYS_PA_H_MFP_PA14_MFP_Msk);
SYS->PA_H_MFP |= (SYS_PA_H_MFP_PA15_MFP_UART0_TX| SYS_PA_H_MFP_PA14_MFP_UART0_RX);
/* Lock protected registers */
SYS_LockReg();
}
g_usbd_pfnVendorRequest g_usbd_pfnClassRequest g_usbd_pfnSetInterfaceUSB
(Request)g_usbd_sInfoUSB
USB
S_USBD_INFO_T *g_usbd_sInfo;
VENDOR_REQ g_usbd_pfnVendorRequest = NULL;
CLASS_REQ g_usbd_pfnClassRequest = NULL;
SET_INTERFACE_REQ g_usbd_pfnSetInterface = NULL;
void USBD_Open(S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface)
{
g_usbd_sInfo = param;
g_usbd_pfnClassRequest = pfnClassReq;
g_usbd_pfnSetInterface = pfnSetInterface;
/* get EP0 maximum packet size */
g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7];
/* Initial USB engine */
USBD->CTL = 0x29f;
-
Jun. 16, 2017 Page 43 of 117 Rev 1.00
AN0015
USBD->PDMA |= USBD_PDMA_BYTEM_Msk;
/* Force SE0, and then clear it to connect*/
USBD_SET_SE0();
}
USB_CTLUSBCPU
ByteWord(4 Bytes)SRAMUSBUSB PHY
USB_D+USB PHYSE0USB Device
void USBD_Open(S_USBD_INFO_T *param, CLASS_REQ pfnClassReq, SET_INTERFACE_REQ pfnSetInterface)
{
g_usbd_sInfo = param;
g_usbd_pfnClassRequest = pfnClassReq;
g_usbd_pfnSetInterface = pfnSetInterface;
/* get EP0 maximum packet size */
g_usbd_CtrlMaxPktSize = g_usbd_sInfo->gu8DevDesc[7];
/* Initial USB engine */
USBD->CTL = 0x29f;
USBD->PDMA |= USBD_PDMA_BYTEM_Msk;
/* Force SE0, and then clear it to connect*/
USBD_SET_SE0();
}
USBUSB
USBUSBD_IRQHandlerNano100BUSB
USB_INTSTSUSB
USB_EPSTSUSB_INTSTS
(EPx_Handler)USB_BUSSTSUSBUSB
void USBD_IRQHandler(void)
{
uint32_t u32IntSts = USBD_GET_INT_FLAG();
uint32_t u32State = USBD_GET_BUS_STATE();
/* */
if(u32IntSts & USBD_INTSTS_FLDET)
{
/* */
USBD_CLR_INT_FLAG(USBD_INTSTS_FLDET);
if(USBD_IS_ATTACHED())
-
Jun. 16, 2017 Page 44 of 117 Rev 1.00
AN0015
{
/* USB USBPHY */
USBD_ENABLE_USB();
}
else
{
/* USB USB */
USBD_DISABLE_USB();
}
}
/* USB */
if(u32IntSts & USBD_INTSTS_BUS)
{
/* USB */
USBD_CLR_INT_FLAG(USBD_INTSTS_BUS);
if(u32State & USBD_STATE_USBRST)
{
/* USB */
USBD_ENABLE_USB();
USBD_SwReset();
}
if(u32State & USBD_STATE_SUSPEND)
{
/* USB,PHY */
USBD_DISABLE_PHY();
}
if(u32State & USBD_STATE_RESUME)
{
/* USB PHY */
USBD_ENABLE_USB();
}
}
/* USB */
if(u32IntSts & USBD_INTSTS_USB)
{
/* SETUP */
if(u32IntSts & USBD_INTSTS_SETUP)
{
-
Jun. 16, 2017 Page 45 of 117 Rev 1.00
AN0015
/* SETUP */
USBD_CLR_INT_FLAG(USBD_INTSTS_SETUP);
/* Ready */
USBD_STOP_TRANSACTION(EP0);
USBD_STOP_TRANSACTION(EP1);
/* Setup Packet */
USBD_ProcessSetupPacket();
}
/* */
if(u32IntSts & USBD_INTSTS_EP0) /* EP0IN */
{
/* EP0 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP0);
/* */
USBD_CtrlIn();
}
if(u32IntSts & USBD_INTSTS_EP1) /* EP1OUT */
{
/* EP1 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP1);
/* Device */
USBD_CtrlOut();
}
if(u32IntSts & USBD_INTSTS_EP2)
{
/* EP2 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP2);
/* EP2 */
EP2_Handler();
}
if(u32IntSts & USBD_INTSTS_EP3)
{
/* EP3 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP3);
-
Jun. 16, 2017 Page 46 of 117 Rev 1.00
AN0015
/* EP3 */
EP3_Handler();
}
/* */
if(u32IntSts & USBD_INTSTS_EP4)
{
/* EP4 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP4);
}
if(u32IntSts & USBD_INTSTS_EP5)
{
/* EP5 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP5);
}
if(u32IntSts & USBD_INTSTS_EP6)
{
/* EP6 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP6);
}
if(u32IntSts & USBD_INTSTS_EP7)
{
/* EP7 */
USBD_CLR_INT_FLAG(USBD_INTSTS_EP7);
}
}
}
4.2.2
USB
USB_CFGxEP_NUM
USBD_MXPLDUSB
HID Transfer
HID_Init()
HID_Init()
void HID_Init(void)
{
-
Jun. 16, 2017 Page 47 of 117 Rev 1.00
AN0015
/* Init setup packet buffer */
/* Buffer range for setup packet -> [0 ~ 0x7] */
USBD->BUFSEG = SETUP_BUF_BASE;
/*****************************************************/
/* EP0 ==> control IN endpoint, address 0 */
USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
/* Buffer range for EP0 */
USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE);
/* EP1 ==> control OUT endpoint, address 0 */
USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
/* Buffer range for EP1 */
USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE);
/*****************************************************/
/* EP2 ==> Interrupt IN endpoint, address 1 */
USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM);
/* Buffer range for EP2 */
USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE);
/* EP3 ==> Interrupt OUT endpoint, address 2 */
USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | INT_OUT_EP_NUM);
/* Buffer range for EP3 */
USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE);
/* trigger to receive OUT data */
USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
}
4.2.3
USBUSB
USBdescriptors.c
s_usbd_infoHID
USB
typedef struct s_usbd_info {
uint8_t *gu8DevDesc; /* */
uint8_t *gu8ConfigDesc; /* */
uint8_t **gu8StringDesc; /* */
uint8_t **gu8HidReportDesc; /* */
uint32_t *gu32HidReportSize; /* */
uint32_t *gu32ConfigHidDescIdx; /* HID */
-
Jun. 16, 2017 Page 48 of 117 Rev 1.00
AN0015
} S_USBD_INFO_T;
S_USBD_INFO_T gsInfo = {
gu8DeviceDescriptor,
gu8ConfigDescriptor,
gpu8UsbString,
gu8UsbHidReport,
gu32UsbHidReportLen,
gu32ConfigHidDescIdx,
};
HID Transfer
/* */
uint8_t gu8DeviceDescriptor[] = {
LEN_DEVICE, /* bLength */
DESC_DEVICE, /* bDescriptorType */
0x10, 0x01, /* bcdUSB */
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
EP0_MAX_PKT_SIZE, /* bMaxPacketSize0 */
/* idVendor */
USBD_VID & 0x00FF,
(USBD_VID & 0xFF00) >> 8,
/* idProduct */
USBD_PID & 0x00FF,
(USBD_PID & 0xFF00) >> 8,
0x00, 0x00, /* bcdDevice */
0x01, /* iManufacture */
0x02, /* iProduct */
0x00, /* iSerialNumber - no serial */
0x01 /* bNumConfigurations */
};
/* */
uint8_t gu8ConfigDescriptor[] = {
LEN_CONFIG, /* bLength */
DESC_CONFIG, /* bDescriptorType */
/* wTotalLength */
(LEN_CONFIG+LEN_INTERFACE+LEN_HID+LEN_ENDPOINT*2) & 0x00FF,
((LEN_CONFIG+LEN_INTERFACE+LEN_HID+LEN_ENDPOINT*2) & 0xFF00) >> 8,
-
Jun. 16, 2017 Page 49 of 117 Rev 1.00
AN0015
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80 | (USBD_SELF_POWERED 8,
/* : Interrupt in. */
LEN_ENDPOINT, /* bLength */
DESC_ENDPOINT, /* bDescriptorType */
(INT_IN_EP_NUM | EP_INPUT), /* bEndpointAddress */
EP_INT, /* bmAttributes */
/* wMaxPacketSize */
EP2_MAX_PKT_SIZE & 0x00FF,
(EP2_MAX_PKT_SIZE & 0xFF00) >> 8,
HID_DEFAULT_INT_IN_INTERVAL, /* bInterval */
/* : Interrupt out. */
LEN_ENDPOINT, /* bLength */
DESC_ENDPOINT, /* bDescriptorType */
(INT_OUT_EP_NUM | EP_OUTPUT), /* bEndpointAddress */
-
Jun. 16, 2017 Page 50 of 117 Rev 1.00
AN0015
EP_INT, /* bmAttributes */
/* wMaxPacketSize */
EP3_MAX_PKT_SIZE & 0x00FF,
(EP3_MAX_PKT_SIZE & 0xFF00) >> 8,
HID_DEFAULT_INT_IN_INTERVAL /* bInterval */
};
/* */
uint8_t *gpu8UsbString[4] = {
gu8StringLang,
gu8VendorStringDesc,
gu8ProductStringDesc,
NULL,
};
/* USB Language */
uint8_t gu8StringLang[4] = {
4, /* bLength */
DESC_STRING, /* bDescriptorType */
0x09, 0x04
};
/* USB Vendor */
uint8_t gu8VendorStringDesc[] = {
16,
DESC_STRING,
'N', 0, 'u', 0, 'v', 0, 'o', 0, 't', 0, 'o', 0, 'n', 0
};
/* USB Product */
uint8_t gu8ProductStringDesc[] = {
26, /* bLength */
DESC_STRING, /* bDescriptorType */
'H', 0, 'I', 0, 'D', 0, ' ', 0, 'T', 0, 'r', 0, 'a', 0, 'n', 0, 's', 0, 'f', 0, 'e', 0, 'r', 0
};
uint8_t *gu8UsbHidReport[3] = {
HID_DeviceReportDescriptor, /* HID transfer */
NULL,
NULL,
};
-
Jun. 16, 2017 Page 51 of 117 Rev 1.00
AN0015
uint32_t gu32UsbHidReportLen[3] = {
sizeof(HID_DeviceReportDescriptor), /* HID transfer */
0,
0,
};
uint32_t gu32ConfigHidDescIdx[3] = {
(LEN_CONFIG+LEN_INTERFACE), /* HID transfer*/
0,
0,
};
/* HID Transfer */
uint8_t HID_DeviceReportDescriptor[] =
{
0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1)
0x09, 0x01, // Usage (Vendor Usage 1)
0xA1, 0x01, // Collection (Application)
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum //64 input usages total (0x01 to 0x40)
0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00)
0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF
0x75, 0x08, // Report Size: 8-bit field size
0x95, 0x40, // Report Count: Make sixty-four 8-bit fields (the next time the parser hits an "Input",
// "Output", or "Feature" item)
0x81, 0x00, // Input (Data, Array, Abs): Instantiates input packet fields based on the
// above report size, count, logical min/max, and usage.
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum //64 output usages total (0x01 to 0x40)
0x91, 0x00, // Output (Data, Array, Abs): Instantiates output packet fields. Uses same
// report size and count as "Input" fields, since nothing new/different was
// specified to the parser since the "Input" item.
0xC0 // End Collection
};
-
Jun. 16, 2017 Page 52 of 117 Rev 1.00
AN0015
5 USB
USB(Class)(HID)
(MSC)USB(CDC)USB(UAC)
USBUSBRS232
Nano100B 16USB
17USB
Endpoint
NuMicro Nano130
Nano100BBSP\SampleCode\StdDriver
17 USB
-
Jun. 16, 2017 Page 53 of 117 Rev 1.00
AN0015
USB
HID USBD_HID_Transfer HIDUSB
USBD_HID_Keyboard GPIO PB15A
USBD_HID_Mouse
MSC USBD_Mass_Storage_Flash Nano100B Data Flash
CDC USBD_VCOM_SerialEmulator COM Port
COM Port
UAC USBD_Audio_Speaker USB AudioNAU8822()
16 Nano100B USB
5.1 HID
USBHID(Human Interface Device)HID
HIDHID
HIDHID
64KBytes()HID
HID
HID(Report Descriptor)
5.1.1 HID Transfer
HID Transfer
HID TransferWindowsHID
HID TransferMicrosoftVisual C++HID Transfer
ReportHIDHID
TransferHID
HID TransferWindowsTool\debug\HIDTransferTest.exe
HID Transfer 18
-
Jun. 16, 2017 Page 54 of 117 Rev 1.00
AN0015
18 HIDTransferTest.exe
5.1.1.1
HID
void HID_ClassRequest(void)
{
uint8_t buf[8];
USBD_GetSetupPacket(buf);
if (buf[0] & 0x80) { /* Device - > Host */
/* Device to host */
switch (buf[1]) {
case GET_REPORT:
case GET_IDLE:
case GET_PROTOCOL:
default: {
/* Setup error, stall the device */
USBD_SetStall(0);
break;
}
}
-
Jun. 16, 2017 Page 55 of 117 Rev 1.00
AN0015
} else {
/* Host to device */
switch (buf[1]) {
case SET_REPORT: {
if (buf[3] == 3) {
/* Request Type = Feature */
USBD_SET_DATA1(EP1);
USBD_SET_PAYLOAD_LEN(EP1, 0);
}
break;
}
case SET_IDLE: {
/* Status stage */
USBD_SET_DATA1(EP0);
USBD_SET_PAYLOAD_LEN(EP0, 0);
break;
}
case SET_PROTOCOL:
default: {
// Stall
/* Setup error, stall the device */
USBD_SetStall(0);
break;
}
}
}
}
5.1.1.2 Endpoint
HID Transfer01
IN/OUTUSB
2INEP2_HandlerHID3
OUTEP3_HandlerHID
/* */
#define EP0_MAX_PKT_SIZE 8
#define EP1_MAX_PKT_SIZE EP0_MAX_PKT_SIZE
#define EP2_MAX_PKT_SIZE 64
#define EP3_MAX_PKT_SIZE 64
/* USB Buffer */
#define SETUP_BUF_BASE 0
-
Jun. 16, 2017 Page 56 of 117 Rev 1.00
AN0015
#define SETUP_BUF_LEN 8
#define EP0_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
#define EP0_BUF_LEN EP0_MAX_PKT_SIZE
#define EP1_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
#define EP1_BUF_LEN EP1_MAX_PKT_SIZE
#define EP2_BUF_BASE (EP1_BUF_BASE + EP1_BUF_LEN)
#define EP2_BUF_LEN EP2_MAX_PKT_SIZE
#define EP3_BUF_BASE (EP2_BUF_BASE + EP2_BUF_LEN)
#define EP3_BUF_LEN EP3_MAX_PKT_SIZE
/* */
#define INT_IN_EP_NUM 0x01
#define INT_OUT_EP_NUM 0x02
void HID_Init(void)
{
/* Init setup packet buffer */
/* Buffer range for setup packet -> [0 ~ 0x7] */
USBD->BUFSEG = SETUP_BUF_BASE;
/*****************************************************/
/* EP0 ==> control IN endpoint, address 0 */
USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
/* Buffer range for EP0 */
USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE);
/* EP1 ==> control OUT endpoint, address 0 */
USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
/* Buffer range for EP1 */
USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE);
/*****************************************************/
/* EP2 ==> Interrupt IN endpoint, address 1 */
USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM);
/* Buffer range for EP2 */
USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE);
/* EP3 ==> Interrupt OUT endpoint, address 2 */
USBD_CONFIG_EP(EP3, USBD_CFG_EPMODE_OUT | INT_OUT_EP_NUM);
/* Buffer range for EP3 */
USBD_SET_EP_BUF_ADDR(EP3, EP3_BUF_BASE);
-
Jun. 16, 2017 Page 57 of 117 Rev 1.00
AN0015
/* trigger to receive OUT data */
USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
}
EP2_HandlerEP3_Handler23EP2_HandlerHID_SetInReport
EP3_HandlerHID_GetOutReport
/* 2 */
void EP2_Handler(void) /* Interrupt IN handler */
{
HID_SetInReport();
}
/* 3 */
void EP3_Handler(void) /* Interrupt OUT handler */
{
uint8_t *ptr;
ptr = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP3));
HID_GetOutReport(ptr, USBD_GET_PAYLOAD_LEN(EP3));
USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
}
5.1.1.3
HIDHIDHIDHID
HID
/* USB HID */
uint8_t gu8ConfigDescriptor[] = {
/* */
LEN_CONFIG, /* bLength */
DESC_CONFIG, /* bDescriptorType */
/* wTotalLength */
(LEN_CONFIG+LEN_INTERFACE+LEN_HID+LEN_ENDPOINT*2) & 0x00FF,
((LEN_CONFIG+LEN_INTERFACE+LEN_HID+LEN_ENDPOINT*2) & 0xFF00) >> 8,
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80 | (USBD_SELF_POWERED
-
Jun. 16, 2017 Page 58 of 117 Rev 1.00
AN0015
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* HID */
LEN_HID, /* Size of this descriptor in UINT8s. */
DESC_HID, /* HID descriptor type. */
0x10, 0x01, /* HID Class Spec. release number. */
0x00, /* H/W target country. */
0x01, /* Number of HID class descriptors to follow. */
DESC_HID_RPT, /* Descriptor type. */
/* Total length of report descriptor. */
sizeof(HID_DeviceReportDescriptor) & 0x00FF,
(sizeof(HID_DeviceReportDescriptor) & 0xFF00) >> 8,
/* 2: ININT_IN_EP_NUM */
LEN_ENDPOINT, /* bLength */
DESC_ENDPOINT, /* bDescriptorType */
(INT_IN_EP_NUM | EP_INPUT), /* bEndpointAddress */
EP_INT, /* bmAttributes */
/* wMaxPacketSize */
EP2_MAX_PKT_SIZE & 0x00FF,
(EP2_MAX_PKT_SIZE & 0xFF00) >> 8,
HID_DEFAULT_INT_IN_INTERVAL, /* bInterval */
/* 3: OUTINT_OUT_EP_NUM */
LEN_ENDPOINT, /* bLength */
DESC_ENDPOINT, /* bDescriptorType */
(INT_OUT_EP_NUM | EP_OUTPUT), /* bEndpointAddress */
EP_INT, /* bmAttributes */
/* wMaxPacketSize */
EP3_MAX_PKT_SIZE & 0x00FF,
(EP3_MAX_PKT_SIZE & 0xFF00) >> 8,
HID_DEFAULT_INT_IN_INTERVAL /* bInterval */
};
/* HID Transfer */
-
Jun. 16, 2017 Page 59 of 117 Rev 1.00
AN0015
uint8_t HID_DeviceReportDescriptor[] =
{
0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1)
0x09, 0x01, // Usage (Vendor Usage 1)
0xA1, 0x01, // Collection (Application)
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum //64 input usages total (0x01 to 0x40)
0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00)
0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF)
0x75, 0x08, // (8) (bits)
0x95, 0x40, // (64) (fields)
0x81, 0x00, // Input (Data, Array, Abs): Instantiates input packet fields based on the
// above report size, count, logical min/max, and usage.
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum //64 output usages total (0x01 to 0x40)
0x91, 0x00, // Output (Data, Array, Abs): Instantiates output packet fields. Uses same
// report size and count as "Input" fields, since nothing new/different was
// specified to the parser since the "Input" item.
0xC0 // End Collection
};
5.1.2 HID Mouse
HID
HID
4 BytesXYXY
5.1.2.1
HID Transfer5.1.1.1
5.1.2.2 Endpoint
HID Mouse01IN/OUT
USB2
IN
/* */
#define EP0_MAX_PKT_SIZE 8
#define EP1_MAX_PKT_SIZE EP0_MAX_PKT_SIZE
#define EP2_MAX_PKT_SIZE 8
/* USB Buffer */
#define SETUP_BUF_BASE 0
-
Jun. 16, 2017 Page 60 of 117 Rev 1.00
AN0015
#define SETUP_BUF_LEN 8
#define EP0_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
#define EP0_BUF_LEN EP0_MAX_PKT_SIZE
#define EP1_BUF_BASE (SETUP_BUF_BASE + SETUP_BUF_LEN)
#define EP1_BUF_LEN EP1_MAX_PKT_SIZE
#define EP2_BUF_BASE (EP1_BUF_BASE + EP1_BUF_LEN)
#define EP2_BUF_LEN EP2_MAX_PKT_SIZE
/* */
#define INT_IN_EP_NUM 0x01
void HID_Init(void)
{
/* Init setup packet buffer */
/* Buffer range for setup packet -> [0 ~ 0x7] */
USBD->BUFSEG = SETUP_BUF_BASE;
/*****************************************************/
/* EP0 ==> control IN endpoint, address 0 */
USBD_CONFIG_EP(EP0, USBD_CFG_CSTALL | USBD_CFG_EPMODE_IN | 0);
/* Buffer range for EP0 */
USBD_SET_EP_BUF_ADDR(EP0, EP0_BUF_BASE);
/* EP1 ==> control OUT endpoint, address 0 */
USBD_CONFIG_EP(EP1, USBD_CFG_CSTALL | USBD_CFG_EPMODE_OUT | 0);
/* Buffer range for EP1 */
USBD_SET_EP_BUF_ADDR(EP1, EP1_BUF_BASE);
/*****************************************************/
/* EP2 ==> Interrupt IN endpoint, address 1 */
USBD_CONFIG_EP(EP2, USBD_CFG_EPMODE_IN | INT_IN_EP_NUM);
/* Buffer range for EP2 */
USBD_SET_EP_BUF_ADDR(EP2, EP2_BUF_BASE);
/* Start to send IN data */
g_u8EP2Ready = 1;
}
HID TransferHID MouseXY
HID MouseHID_UpdateMouseDataXY
2IN
/* */
signed char mouse_table[] = {-16, -16, -16, 0, 16, 16, 16, 0};
-
Jun. 16, 2017 Page 61 of 117 Rev 1.00
AN0015
uint8_t mouse_idx = 0;
uint8_t move_len, mouse_mode=1;
uint8_t volatile g_u8EP2Ready = 0;
void HID_UpdateMouseData(void)
{
uint8_t *buf;
if (g_u8EP2Ready) {
buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2));
mouse_mode ^= 1;
if (mouse_mode) {
if (move_len > 14) {
/* */
buf[0] = 0x00;
buf[1] = mouse_table[mouse_idx & 0x07]; /* X */
buf[2] = mouse_table[(mouse_idx + 2) & 0x07]; /* Y */
buf[3] = 0x00;
/* */
mouse_idx++;
/* reset */
move_len = 0;
}
} else {
/* */
buf[0] = buf[1] = buf[2] = buf[3] = 0;
}
/* */
move_len++;
g_u8EP2Ready = 0;
/* trigger IN transfer */
USBD_SET_PAYLOAD_LEN(EP2, 4);
}
}
5.1.2.3
HID InterfaceProtocol=HID_MOUSE(0x02)
bInterfaceSubClass=0x0BootHID
/* USB HID */
uint8_t gu8ConfigDescriptor[] = {
-
Jun. 16, 2017 Page 62 of 117 Rev 1.00
AN0015
/* */
LEN_CONFIG, /* bLength */
DESC_CONFIG, /* bDescriptorType */
/* wTotalLength */
LEN_CONFIG_AND_SUBORDINATE & 0x00FF,
(LEN_CONFIG_AND_SUBORDINATE & 0xFF00) >> 8,
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80 | (USBD_SELF_POWERED 8,
/* 2: ININT_IN_EP_NUM */
LEN_ENDPOINT, /* bLength */
DESC_ENDPOINT, /* bDescriptorType */
(INT_IN_EP_NUM | EP_INPUT), /* bEndpointAddress */
EP_INT, /* bmAttributes */
/* wMaxPacketSize */
EP2_MAX_PKT_SIZE & 0x00FF,
-
Jun. 16, 2017 Page 63 of 117 Rev 1.00
AN0015
(EP2_MAX_PKT_SIZE & 0xFF00) >> 8,
HID_DEFAULT_INT_IN_INTERVAL /* bInterval */
};
/* HID Mouse */
uint8_t HID_MouseReportDescriptor[] = {
0x05, 0x01, /* Usage Page(Generic Desktop Controls) */
0x09, 0x02, /* Usage(Mouse) */
0xA1, 0x01, /* Collection(Application) */
0x09, 0x01, /* Usage(Pointer) */
0xA1, 0x00, /* Collection(Physical) */
0x05, 0x09, /* Usage Page(Button) */
0x19, 0x01, /* Usage Minimum(0x1) */
0x29, 0x03, /* Usage Maximum(0x3) */
0x15, 0x00, /* Logical Minimum(0x0) */
0x25, 0x01, /* Logical Maximum(0x1) */
/* , */
0x75, 0x01, /* Report Size(0x1) */
0x95, 0x03, /* Report Count(0x3) */
0x81, 0x02, /* Input(3 button bit) */
0x75, 0x05, /* Report Size(0x5) */
0x95, 0x01, /* Report Count(0x1) */
0x81, 0x01, /* Input(5 bit padding) */
0x05, 0x01, /* Usage Page(Generic Desktop Controls) */
/* X,Y */
0x09, 0x30, /* Usage(X) */
0x09, 0x31, /* Usage(Y) */
0x09, 0x38, /* Usage(Wheel) */
0x15, 0x81, /* Logical Minimum(0x81)(-127) */
0x25, 0x7F, /* Logical Maximum(0x7F)(127) */
/* */
0x75, 0x08, /* Report Size(0x8) */
0x95, 0x03, /* Report Count(0x3) */
0x81, 0x06, /* Input(1 byte wheel) */
0xC0, /* End Collection */
0xC0, /* End Collection */
};
5.1.3 HID Keyboard
HID KeyboardGPIO PinHighLow
A
-
Jun. 16, 2017 Page 64 of 117 Rev 1.00
AN0015
5.1.3.1
HIDHID
5.1.1.1
5.1.3.2 Endpoint
HID Keyboard01IN/OUT
USB2
IN Endpoint5.1.2HID
Mouse
HID Keyboard 8 BytesHID_UpdateKbData2IN
A
void HID_UpdateKbData(void)
{
int32_t i;
uint8_t *buf;
uint32_t key = 0xF;
static uint32_t preKey;
if(g_u8EP2Ready){
buf = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP2));
/* If GPB15 = 0, just report it is key 'a' */
key = (PB->PIN & (1
-
Jun. 16, 2017 Page 65 of 117 Rev 1.00
AN0015
}
}
5.1.3.3
HID InterfaceProtocol=HID_KEYBOARD(0x01)
bInterfaceSubClass=0x0BootHID
/* USB HID */
uint8_t gu8ConfigDescriptor[] = {
/* */
LEN_CONFIG, /* bLength */
DESC_CONFIG, /* bDescriptorType */
/* wTotalLength */
LEN_CONFIG_AND_SUBORDINATE & 0x00FF,
(LEN_CONFIG_AND_SUBORDINATE & 0xFF00) >> 8,
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80 | (USBD_SELF_POWERED
-
Jun. 16, 2017 Page 66 of 117 Rev 1.00
AN0015
(sizeof(HID_KeyboardReportDescriptor) & 0xFF00) >> 8,
/* 2: ININT_IN_EP_NUM */
LEN_ENDPOINT, /* bLength */
DESC_ENDPOINT, /* bDescriptorType */
(INT_IN_EP_NUM | EP_INPUT), /* bEndpointAddress */
EP_INT, /* bmAttributes */
/* wMaxPacketSize */
EP2_MAX_PKT_SIZE & 0x00FF,
(EP2_MAX_PKT_SIZE & 0xFF00) >> 8,
HID_DEFAULT_INT_IN_INTERVAL /* bInterval */
};
/* HID Keyboard */
uint8_t HID_KeyboardReportDescriptor[] =
{
0x05, 0x01, /* Usage Page(Generic Desktop Controls) */
0x09, 0x06, /* Usage(Keyboard) */
0xA1, 0x01, /* Collection(Application) */
0x05, 0x07, /* Usage Page(Keyboard/Keypad) */
0x19, 0xE0, /* Usage Minimum(0xE0) */
0x29, 0xE7, /* Usage Maximum(0xE7) */
0x15, 0x00, /* Logical Minimum(0x0) */
0x25, 0x01, /* Logical Maximum(0x1) */
/* (8 Bytes) */
0x75, 0x01, /* Report Size(0x1) */
0x95, 0x08, /* Report Count(0x8) */
0x81, 0x02, /* Input (Data) => Modifier byte */
0x95, 0x01, /* Report Count(0x1) */
0x75, 0x08, /* Report Size(0x8) */
0x81, 0x01, /* Input (Constant) => Reserved byte */
0x95, 0x05, /* Report Count(0x5) */
0x75, 0x01, /* Report Size(0x1) */
0x05, 0x08, /* Usage Page(LEDs) */
0x19, 0x01, /* Usage Minimum(0x1) */
0x29, 0x05, /* Usage Maximum(0x5) */
0x91, 0x02, /* Output (Data) => LED report */
0x95, 0x01, /* Report Count(0x1) */
0x75, 0x03, /* Report Size(0x3) */
0x91, 0x01, /* Output (Constant) => LED report padding */
0x95, 0x06, /* Report Count(0x6) */
-
Jun. 16, 2017 Page 67 of 117 Rev 1.00
AN0015
0x75, 0x08, /* Report Size(0x8) */
0x15, 0x00, /* Logical Minimum(0x0) */
0x25, 0x65, /* Logical Maximum(0x65) */
0x05, 0x07, /* Usage Page(Keyboard/Keypad) */
0x19, 0x00, /* Usage Minimum(0x0) */
0x29, 0x65, /* Usage Maximum(0x65) */
0x81, 0x00, /* Input (Data) */
0xC0, /* End Collection */
};
5.2 MSC
USB(Mass Storage Class)
USBBulk Only
Bulk Only(CBW)(INOUT)
(CSW)Bulk-Only Mass Storage ResetGet Max LUN
UFIUSB Mass Storage Class
USB MSC
5.2.1
MSC_ClassRequestMSCBulk-Only Mass Storage ResetReset
Get Max LUNMSC_ProcessCmdUFI
void MSC_ClassRequest(void)
{
uint8_t buf[8];
USBD_GetSetupPacket(buf);
if (buf[0] & 0x80) { /* request data transfer direction */
// Device to host
switch (buf[1]) {
case GET_MAX_LUN: {
if ((((buf[3]
-
Jun. 16, 2017 Page 68 of 117 Rev 1.00
AN0015
else {/* Invalid Get MaxLun command */
USBD_SetStall(0);
}
break;
}
default: {
/* Setup error, stall the device */
USBD_SetStall(0);
break;
}
}
} else {
/* Host to device */
switch (buf[1]) {
case BULK_ONLY_MASS_STORAGE_RESET: {
if ((((buf[3]
-
Jun. 16, 2017 Page 69 of 117 Rev 1.00
AN0015
break;
}
}
}
}
void MSC_ProcessCmd(void)
{
uint8_t u8Len;
int32_t i;
uint32_t Hcount, Dcount;
if (g_u8EP3Ready) {
g_u8EP3Ready = 0;
if (g_u8BulkState == BULK_CBW) {
u8Len = USBD_GET_PAYLOAD_LEN(EP3);
/* Check Signature & length of CBW */
/* Bulk Out buffer */
if ((*(uint32_t *) ((uint32_t)USBD_BUF_BASE + g_u32BulkBuf0) != CBW_SIGNATURE) ||
(u8Len != 31))
{
/* Invalid CBW */
g_u8Prevent = 1;
USBD_SET_EP_STALL(EP2);
USBD_SET_EP_STALL(EP3);
USBD_LockEpStall((1
-
Jun. 16, 2017 Page 70 of 117 Rev 1.00
AN0015
case UFI_PREVENT_ALLOW_MEDIUM_REMOVAL: {
if (g_sCBW.au8Data[2] & 0x01) {
g_au8SenseKey[0] = 0x05; //INVALID COMMAND
g_au8SenseKey[1] = 0x24;
g_au8SenseKey[2] = 0;
g_u8Prevent = 1;
} else
g_u8Prevent = 0;
g_u8BulkState = BULK_IN;
MSC_AckCmd();
return;
}
case UFI_TEST_UNIT_READY: {
if (Hcount != 0) {
if (g_sCBW.bmCBWFlags == 0) { /* Ho > Dn (Case 9) */
g_u8Prevent = 1;
USBD_SET_EP_STALL(EP3);
g_sCSW.bCSWStatus = 0x1;
g_sCSW.dCSWDataResidue = Hcount;
}
}
else { /* Hn == Dn (Case 1) */
if (g_u8Remove) {
g_sCSW.dCSWDataResidue = 0;
g_sCSW.bCSWStatus = 1;
g_au8SenseKey[0] = 0x02; /* Not ready */
g_au8SenseKey[1] = 0x3A;
g_au8SenseKey[2] = 0;
g_u8Prevent = 1;
}
else {
g_sCSW.dCSWDataResidue = 0;
g_sCSW.bCSWStatus = 0;
}
}
g_u8BulkState = BULK_IN;
MSC_AckCmd();
return;
}
case UFI_START_STOP: {
if ((g_sCBW.au8Data[2] & 0x03) == 0x2) {
-
Jun. 16, 2017 Page 71 of 117 Rev 1.00
AN0015
g_u8Remove = 1;
}
}
case UFI_VERIFY_10: {
g_u8BulkState = BULK_IN;
MSC_AckCmd();
return;
}
case UFI_REQUEST_SENSE: {
if ((Hcount > 0) && (Hcount 0) {
if (g_u32Length > EP2_MAX_PKT_SIZE)
g_u8Size = EP2_MAX_PKT_SIZE;
else
g_u8Size = g_u32Length;
/* Bulk IN buffer */
-
Jun. 16, 2017 Page 72 of 117 Rev 1.00
AN0015
USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + g_u32BulkBuf1),
(uint8_t *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0);
MSC_Read();
}
return;
}
case UFI_READ_CAPACITY: {
if (g_u32Length == 0) {
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = MassCMD_BUF;
}
MSC_ReadCapacity();
g_u8BulkState = BULK_IN;
if (g_u32Length > 0) {
if (g_u32Length > EP2_MAX_PKT_SIZE)
g_u8Size = EP2_MAX_PKT_SIZE;
else
g_u8Size = g_u32Length;
/* Bulk IN buffer */
USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1),
(uint8_t *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0);
MSC_Read();
}
return;
}
case UFI_MODE_SELECT_6:
case UFI_MODE_SELECT_10: {
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = MassCMD_BUF;
if (g_u32Length > 0) {
USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE);
g_u8BulkState = BULK_OUT;
-
Jun. 16, 2017 Page 73 of 117 Rev 1.00
AN0015
}
return;
}
case UFI_MODE_SENSE_6: {
*(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+0) = 0x3;
*(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+1) = 0x0;
*(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+2) = 0x0;
*(uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1+3) = 0x0;
USBD_SET_PAYLOAD_LEN(EP2, 4);
g_u8BulkState = BULK_IN;
g_sCSW.bCSWStatus = 0;
g_sCSW.dCSWDataResidue = Hcount - 4;;
return;
}
case UFI_MODE_SENSE_10: {
if (g_u32Length == 0) {
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32Address = MassCMD_BUF;
}
MSC_ModeSense10();
g_u8BulkState = BULK_IN;
if (g_u32Length > 0) {
if (g_u32Length > EP2_MAX_PKT_SIZE)
g_u8Size = EP2_MAX_PKT_SIZE;
else
g_u8Size = g_u32Length;
/* Bulk IN buffer */
USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1),
(uint8_t *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf0);
MSC_Read();
}
return;
}
case UFI_INQUIRY: {
if ((Hcount > 0) && (Hcount
-
Jun. 16, 2017 Page 74 of 117 Rev 1.00
AN0015
USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1),
(uint8_t *)g_au8InquiryID, Hcount);
USBD_SET_PAYLOAD_LEN(EP2, Hcount);
g_u8BulkState = BULK_IN;
g_sCSW.bCSWStatus = 0;
g_sCSW.dCSWDataResidue = 0;
return;
}
else {
USBD_SET_EP_STALL(EP2);
g_u8Prevent = 1;
g_sCSW.bCSWStatus = 0x01;
g_sCSW.dCSWDataResidue = 0;
g_u8BulkState = BULK_IN;
MSC_AckCmd();
return;
}
}
case UFI_READ_12:
case UFI_READ_10: {
/* Check if it is a new transfer */
if(g_u32Length == 0) {
Dcount = (get_be32(&g_sCBW.au8Data[4])>>8) * 512;
if (g_sCBW.bmCBWFlags == 0x80) { /* IN */
if (Hcount == Dcount) { /* Hi == Di (Case 6)*/
}
/* Hn < Di (Case 2) || Hi < Di (Case 7) */
else if (Hcount < Dcount) {
if (Hcount) { /* Hi < Di (Case 7) */
g_u8Prevent = 1;
g_sCSW.bCSWStatus = 0x01;
g_sCSW.dCSWDataResidue = 0;
}
else { /* Hn < Di (Case 2) */
g_u8Prevent = 1;
g_sCSW.bCSWStatus = 0x01;
g_sCSW.dCSWDataResidue = 0;
g_u8BulkState = BULK_IN;
MSC_AckCmd();
return;
-
Jun. 16, 2017 Page 75 of 117 Rev 1.00
AN0015
}
}
/* Hi > Dn (Case 4) || Hi > Di (Case 5) */
else if (Hcount > Dcount) {
g_u8Prevent = 1;
g_sCSW.bCSWStatus = 0x01;
g_sCSW.dCSWDataResidue = 0;
}
}
else { /* Ho Di (Case 10) */
g_u8Prevent = 1;
USBD_SET_EP_STALL(EP3);
g_sCSW.bCSWStatus = 0x01;
g_sCSW.dCSWDataResidue = Hcount;
g_u8BulkState = BULK_IN;
MSC_AckCmd();
return;
}
}
/* Get LBA address */
g_u32Address = get_be32(&g_sCBW.au8Data[0]);
g_u32LbaAddress = g_u32Address * UDC_SECTOR_SIZE;
g_u32Length = g_sCBW.dCBWDataTransferLength;
g_u32BytesInStorageBuf = g_u32Length;
i = g_u32Length;
if (i > STORAGE_BUFFER_SIZE)
i = STORAGE_BUFFER_SIZE;
MSC_ReadMedia(g_u32Address * UDC_SECTOR_SIZE, i,
(uint8_t *)STORAGE_DATA_BUF);
g_u32BytesInStorageBuf = i;
g_u32LbaAddress += i;
g_u32Address = STORAGE_DATA_BUF;
/* Indicate the next packet should be Bulk IN Data packet */
g_u8BulkState = BULK_IN;
if (g_u32BytesInStorageBuf > 0) {
/* Set the packet size */
-
Jun. 16, 2017 Page 76 of 117 Rev 1.00
AN0015
if (g_u32BytesInStorageBuf > EP2_MAX_PKT_SIZE)
g_u8Size = EP2_MAX_PKT_SIZE;
else
g_u8Size = g_u32BytesInStorageBuf;
/* Prepare the first data packet (DATA1) */
/* Bulk IN buffer */
USBD_MemCopy((uint8_t *)((uint32_t)USBD_BUF_BASE + g_u32BulkBuf1),
(uint8_t *)g_u32Address, g_u8Size);
g_u32Address += g_u8Size;
/* kick - start */
USBD_SET_EP_BUF_ADDR(EP2, g_u32BulkBuf1);
/* Trigger to send out the data packet */
USBD_SET_PAYLOAD_LEN(EP2, g_u8Size);
g_u32Length -= g_u8Size;
g_u32BytesInStorageBuf -= g_u8Size;
}
return;
}
case UFI_WRITE_12:
case UFI_WRITE_10: {
if (g_u32Length == 0) {