117
Jun. 16, 2017 Page 1 of 117 Rev 1.00 AN0015 Application Note for 32-bit NuMicro ® Family Document Information 摘要 本文介紹如何用NuMicro ® USB 2.0全速裝置來實作各種USB類別的 應用裝置。 適用範圍 NuMicro ® 全系列USB 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全速裝置之實作

NuMicro® USB 2.0全速裝置之實作 - nuvoton.com · Jun. 16, 2017 Page 1 of 117 Rev 1.00 AN0015 Application Note for 32-bit NuMicro® Family Document Information 摘要 本文介紹如何用NuMicro®

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

  • 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) {