📄 cdc-serial.dir
字号:
// Bulk-OUT endpoint standard descriptor
{
sizeof(USBEndpointDescriptor),
USBGenericDescriptor_ENDPOINT,
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_OUT,
CDCDSerialDriverDescriptors_DATAOUT),
USBEndpointDescriptor_BULK,
MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(
CDCDSerialDriverDescriptors_DATAOUT),
USBEndpointDescriptor_MAXBULKSIZE_FS),
0 // Must be 0 for full-speed bulk endpoints
},
// Bulk-IN endpoint descriptor
{
sizeof(USBEndpointDescriptor),
USBGenericDescriptor_ENDPOINT,
USBEndpointDescriptor_ADDRESS(USBEndpointDescriptor_IN,
CDCDSerialDriverDescriptors_DATAIN),
USBEndpointDescriptor_BULK,
MIN(BOARD_USB_ENDPOINTS_MAXPACKETSIZE(
CDCDSerialDriverDescriptors_DATAIN),
USBEndpointDescriptor_MAXBULKSIZE_FS),
0 // Must be 0 for full-speed bulk endpoints
},
\endcode
!String Descriptors
Several descriptors (device, configuration, interface, etc.) can specify the
index of a string descriptor to comment their use.
The actual string code is defined:
productStringDescriptor.
!!Class-specific Requests
The CDC specification defines a set of #class-specific requests# for devices
implementing the ACM. This section details these requests. Please refer to
section 3.6.2.1 of the CDC spec. 1.1 for more information.
!SetLineCoding, GetLineCoding
These requests are sent by the host to modify or retrieve the configuration of
the serial line, which includes:
- Baudrate
- Number of stop bits
- Parity check
- Number of data bits
When the terminal application (such as HyperTerminal) on the host (PC) side
changes the setting of the COM port, a SetLineCoding request is sent with the
new parameters. The host may also retrieve the current setting using
GetLineCoding, not modifying them if they are correct.
When a SET_LINE_CODING request is received, the %device should read the new
parameters. Then program the new parameters in the USART. A callback must be
provided to the USBD_Read function.
See CDCDSerialDriver_SetLineCoding.
The code handling GET_LINE_CODING shall simply invoke the USBD_Write function
to send the current settings of the USART to the host.
See CDCDSerialDriver_GetLineCoding.
!SetControlLineState
This request is sent by the host to notify the %device of two state changes.
The first bit (D0) of the wValue field of the request indicates whether or not
a terminal is connected to the virtual COM port. Bit D1 indicates that the
USART should enable/disable its carrier signal to start/stop receiving and
transmitting data.
In practice, the USB to serial converter should operate only when those two
bits are set. Otherwise, it should not transmit or receive data.
Since the SET_CONTROL_LINE_STATE request does not have a data payload, the
%device only has to acknowledge the request by sending a ZLP (zero-length
packet), using the USBD_Write method.
See CDCDSerialDriver_SetControlLineState.
Before that, the wValue field should be parsed to retrieve the new control
line state. A single boolean variable can be used to keep track of the
connection state. If both the D0 and D1 bits are set, then the converter
should operate normally, i.e., forward data between the USART and the USB
host. Otherwise, it should stop its activity.
!!Notifications
Notifications are sent by the %device when an event, such as a serial line
state change, has occurred. In this example, they are transmitted through a
dedicated Interrupt IN endpoint. A special header must precede the data
payload of each notification. This header has the same format of a SETUP
request, so the USBGenericRequest structure defined in the
"AT91 USB device framework" can be used.
Note that the %device should only send a notification when there is a state
change, and not continuously. This does not really matter in practice, but
only sending notifications sporadically will reduce the stress on the %device.
When the serial state is changed by CDCDSerialDriver_SetSerialState, the
notification is sent to the host.
!!!CDC Serial Driver API
- CDCDSerialDriver_Initialize
- CDCDSerialDriver_RequestHandler
- CDCDSerialDriver_Read
- CDCDSerialDriver_Write
- CDCDSerialDriver_GetSerialState
- CDCDSerialDriver_SetSerialState
!!!Main Application
The job of the main application is to bridge the USART and the USB. This means
that data read from one end must be forwarded to the other end. This section
describes several possibilities to do this.
!!USB Operation
Reading data coming from the host is done using the CDCDSerialDriver_Read.
Since this is an asynchronous function, it does not block the execution flow.
This means that other actions (like reading data from the USART) can be
performed while the transfer is going on. Whenever some data is sent by the
host, the transfer terminates and the associated callback function is invoked.
This callback (UsbDataReceived) can be programmed to forward the received data
through the USART.
Likewise, the CDCDSerialDriver_Write function can be called as soon as there
is data to transmit, again without block the program flow. However, there
cannot be two write operations at the same time, so the program must check
whether or not the last transfer is complete. This can be done by checking the
result code of the CDCDSerialDriver_Write method. If USB_STATUS_LOCKED is
returned, then there is already another operation in progress. The %device
will have to buffer the data retrieved from the USART until the endpoint
becomes free again.
!!USART Operation
The USART peripheral present on AT91 chips can be used in two different ways.
The classic way is to read and write one byte at a time in the correct
registers to send and receive data.
A more powerful method is available on AT91SAM chips, by using the embedded
Peripheral DMA Controller (PDC). The PDC can take care of transfers between
the processor, memory and %peripherals, thus freeing the processor to perform
other tasks. Since the PDC interrupt happens on the buffer full, Some timer
can be used to check if there is any data frags input from the USART.
!!!Using a Generic Host Driver
See "USB CDC Serial Host Driver".
!!!Add two or more ports in one USB device
See "USB Dual Port CDC Serial Device".
*/
/**
\page "USB CDC Serial Host Driver"
Both Microsoft Windows and Linux offer a generic driver for using a USB to
serial converter %device. This page details the steps required to make use
of them.
!!!Windows
On Microsoft Windows, the standard USB serial driver is named usbser.sys and
is part of the standard set of drivers. It has been available since Windows
98SE. However, conversely to other generic driver such as the one for Mass
Storage Devices (MSD), usbser.sys is not automatically loaded when a CDC
%device is plugged in.
!!Writing a Windows Driver File
For Windows to recognize the %device correctly, it is necessary to write a
.inf file. The Windows Driver Development Kit (DDK) contains information on
this topic. A basic driver, named 6119.inf in the example software provided,
will now be described. The driver file is made up of several sections.
The first section of the .inf file must be the #[Version]# section. It
contains information about the driver version, provider, release data, and so
on.
\code
[Version]
Signature="$Chicago$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%ATMEL%
DriverVer=09/12/2006,1.1.1.1
\endcode
The Signature attribute is mandatory and can be either "$Windows 95$",
"$Windows NT$" or "$Chicago$", depending on which Windows version(s) the
driver supports. "$Chicago$" is used to notify that every Windows version is
supported. Since in this example, the USB to serial converter is a virtual COM
port, the Class attribute should be equal to "Ports". The value of ClassGuid
depends on which class the %device uses. The Provider value indicates that the
string descriptor for the driver provider will be defined further, under the
tag ATMEL. Finally, the last tag show the driver version and release date. For
the version number, each digit is optional (except the first one), but must
not be null if present.
Next come two sections, #[SourceDisksNames]# and #[SourceDisksFiles]#. They
are used to specify the installation disks required and the location of each
needed files on these disks. But they are not implemented because the file
is offered by windows or its install disk automatically.
\code
;[SourceDisksNames]
;1="Windows Install CD"
;[SourceDisksFiles]
;usbser.sys=1
\endcode
The driver file must now specify where copied files will be stored, using the
#[DestinationDirs]# section.
\code
[DestinationDirs]
DefaultDestDir=12
\endcode
The target directory must be identified by its ID, which is system-defined.
The ID for the drivers directory is 12.
The #[Manufacturer]# section lists the possible manufacturers for all devices
supported by this driver. In this case, the only supported %device is an ATMEL
one, so this will be the only value.
\code
[Manufacturer]
%ATMEL%=AtmelMfg
\endcode
The attribute must be a string tag; its value must be the name of the Models
section in which all supported devices from this manufacturer will be listed.
In this case, it will be named AtmelMfg, which is the next section.
Each Models section must list the hardware ID of each supported %device. For
USB devices, the hardware ID is made up of the Vendor ID, the Product ID and
(optionally) the Device Release Number. Those values are extracted from the
%device descriptor provided during the enumeration phase.
\code
[AtmelMfg]
%USBtoSerialConverter%=USBtoSer.Install,USB\VID_03EB&PID_6119
\endcode
The attribute name is again a string tag, which will be used to describe the
%device. The value is comprised of both the %device install section name
(USBtoSer.Install) and the hardware ID. The hardware ID is the same as the one
defined in "CDC Serial Device IDs".
Now, the .inf file must detail the install section of each %device previously
listed. In this example, there is only one install section, named
#[USBtoSer.Install]#:
\code
[USBtoSer.Install]
CopyFiles=USBtoSer.CopyFiles
AddReg=USBtoSer.AddReg
[USBtoSer.CopyFiles]
usbser.sys,,,0x00000002
[USBtoSer.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
[USBtoSer.Install.Services]
AddService=usbser,0x00000002,USBtoSer.AddService
[USBtoSer.AddService]
DisplayName=%USBSer%
ServiceType=1r
StartType=3
ServiceBinary=%12%\usbser.sys
\endcode
The install section is actually divided in five. In the first section, two
other section names are specified: one for the list of files to copy, and one
for the keys to add to the Windows registry. There is only one file to copy,
usbser.sys; a flag (0x00000002) is used to specify that the user cannot skip
copying it. The registry keys are needed to install the driver on older
versions of Windows (such as Windows 98). For newer versions, the
#[USBtoSer.Install.Services]# registers the needed kernel services; each
service is actually listed in a section on its own.
Finally, the last section, [Strings], defines all the string constants used
through this file:
\code
[Strings]
ATMEL="ATMEL Corp."
USBtoSerialConverter="AT91 USB to Serial Converter"
USBSer="USB Serial Driver"
\endcode
!!Using the Driver
When a new %device is plugged in for the first time, Windows looks for an
appropriate specific or generic driver to use it. If it does not find one, the
user is asked what to do.
This is the case with the USB to serial converter, since there is no generic
driver for it. To install the custom driver given in the previous section,
Windows must be told where to look for it. This can be done by selecting the
second option, "Install from a list or specific location", when the driver
installation wizards pops up. It will then ask for the directory where the
driver is located. After that, it should recognize the "AT91 USB to Serial
Converter" driver as an appropriate one and display it in the list.
During the installation, the wizard asks for the location of the usbser.sys
file. If it is already installed on the system, it can be found in
"C:\Windows\System32\Drivers\". Otherwise, it is present on the Windows
installation CD.
Once the driver is installed properly, a new COM port is added to the system
and can be used with HyperTerminal, for example.
!!!Linux
Linux has two different generic drivers which are appropriate for a USB to
serial converter. The first one is an Abstract Control Model driver designed
for modem devices, and is simply named #acm#. The other one is a generic USB
to serial driver named #usbserial#.
If the support for the #acm# driver has been compiled in the kernel, Linux
will automatically load it. A new terminal %device will be created under
/dev/ttyACMx.
The usbserial driver must be loaded manually by using the modprobe command
with the vendor ID and product ID values used by the %device:
\code
modprobe usbserial vendor=0x03EB product=0x6119
\endcode
Once the driver is loaded, a new terminal entry appears and should be named
/dev/ttyUSBx.
*/
/**
\page "USB Dual Port CDC Serial Device"
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -