September 2008
MSP430 USB Communications Device Class (CDC) API
User’s Guide, v0.7
MSP430 Contents 1 Introduction ...3 2 Operation ...3 2.1 System Description ...3 2.2 Stack Organization ...42.3 Source File Organization...5
2.4 Use of MCU Resources...5
2.5 Configuration of Endpoints ...6
2.6 Descriptors ...6
2.6.1 Configurations ...7
2.6.2 Serial Numbers...7
2.6.3 Configuration Constants in descriptors.c...7
2.7 Data Transmission/Reception Interface ...7
2.8 Power Management ...9 2.9 Clock System ...9 2.10 Version ...9 2.11 Host Considerations ...10 2.11.1 Microsoft Windows ...10 2.11.2 Apple MacOS ...10 2.11.3 Linux ...10
3 API Function Calls ...10
3.1 MSP430 USB Module Management ...10
3.1.1 BYTE USB_init()...10
3.1.2 BYTE USB_enable(WORD freq) ...11
3.1.3 BYTE USB_disable(void)(not implemented in v0.7) ...11
3.1.4 BYTE USB_setEnabledEvents(BYTE events) ...12
3.1.5 BYTE USB_getEnabledEvents(void)...12
3.2 USB Connection Management...13
3.2.1 BYTE USB_reset() ...13
3.2.2 BYTE USB_connect()...14
3.2.3 BYTE USB_disconnect(void)...14
3.2.4 BYTE USB_forceRemoteWakeup(void) ...15
3.2.5 BYTE USB_connectionStatus()...15
3.3 CDC Management and Data Handling...16
3.3.1 BYTE USBCDC_sendData(BYTE * data, WORD size, BYTE portNum) ...16
3.3.2 BYTE USBCDC_receiveData(BYTE * data, WORD size, BYTE portNum)...17
3.3.3 BYTE USBCDC_abortSend(WORD* size, BYTE portNum)...18
3.3.4 BYTE USBCDC_abortReceive(WORD* size, BYTE portNum)(not implemented in v0.7)...19
3.3.6 BYTE USBCDC_portStatus(BYTE portNum, WORD* bytesSent, WORD*
bytesReceived)(not implemented in v0.7) ...20
3.3.7 BYTE USBCDC_getPortSettings(LONG rate, BYTE format, BYTE parity, BYTE dataBits, BYTE portNum)(not implemented in v0.7)...20
4 Event-Handling...21 4.1 void USB_handleClockEvent(void) ...22 4.1.1 void USB_handleVbusOnEvent(void)...23 4.1.2 void USB_handleVbusOffEvent(void)...23 4.1.3 void USB_handleResetEvent(void) ...23 4.1.4 void USB_handleSuspendEvent(void) ...23 4.1.5 void USB_handleResumeEvent(void) ...24
4.1.6 void USB_handleDataReceived(BYTE portNum)...24
4.1.7 void USB_handleSendCompleted(BYTE portNum) ...24
4.1.8 void USB_handleReceiveCompleted(BYTE portNum) ...24
5 Operation Examples ...24
5.1 Initialization...25
5.2 Handling a VBUS-On Event ...25
5.3 Sending Data...26
5.4 Receiving Data ...26
6 Configuration Constants ...27
7 References...28
Figures Figure 1. USB Software Stack with CDC API ...4
Figure 2. USB Initialization ...25
Figure 3. handleVbusOnEvent()...25
Tables Table 1. Files in the API Stack ...5
Table 2. Endpoint Usage ...6
Table 3. USB Module Management Call Summary ...10
Table 4. Parameters for USB_init()...11
Table 5. Parameters for USB_enable()...11
Table 6. Parameters for USB_disable()...11
Table 7. Parameters for USB_setEnabledEvents() ...12
Table 8. Parameters for USB_getEnabledEvents()...13
Table 9. USB Connection Management Call Summary ...13
Table 10. Parameters for USB_reset () ...13
Table 11. Parameters for USB_connect() ...14
Table 12. Parameters for USB_disconnect() ...14
Table 13. Parameters for USB_forceRemoteWakeup() ...15
Table 14. Parameters for USB_connectionStatus()...15
Table 15. CDC Management and Data Handling Call Summary ...16
Table 16. Parameters for USBCDC_sendData() ...17
Table 17. Parameters for USBCDC_receiveData() ...18
Table 18. Parameters for USBCDC_abortSend() ...18
Table 21. Parameters for USBCDC_portStatus() ...20
Table 22. Parameters for USBCDC_getPortSettings() ...21
Table 23. Event Handler Summary...22
Table 24. Configuration Constants ...27
1 Introduction
The USB CDC API (USB Communications Device Class Application Programming Interface) for the MSP430 is a turnkey API that makes it easy to implement a simple data connection over USB between an MSP430-based device and a USB host. It abstracts the user from the USB protocol, making the connection as simple as using a UART while still providing a sufficient amount of configuration. To the USB host, the connection appears as a virtual COM port, which is a very simple and commonly-used interface. To the MSP430’s software, it appears as a simple data port that is accessible with simple API calls, such as “open/close the connection”, “send/receive data”, etc.
Up to three data connections (i.e., three COM ports on the host associated with three conceptual ports within the MSP430) can be established simultaneously using this API. (Note: v0.7 only supports a single port connection.)
All usage of the API should be supportable via the provided calls, and the user should not need to modify the API source. However, the source is made available to the user to assist in
understanding the entire system, if needed.
Note: v0.7 of this API is a preliminary version that has been readied for use with pre-production samples of the MSP430TC0701 device. This specification reflects what v1.0 is intended to become. Some features defined in this user’s guide are not yet implemented, and these are marked with notes in italics.
While it is intended to keep the v1.0 definition similar to what is defined here, the existing function calls are subject to change and should be used for evaluation purposes only. No guarantees are made for future compatibility.
2 Operation
2.1 System
Description
The purpose of this API is the establishment of a COM port on the USB host, through which an application on the host can communicate with an MSP430 over USB. On the MSP430 side, each PC COM port is associated with a virtual port, through which data is transceived with the host.
(The term COM port is specific to the Windows group of operating systems, but the MacOS, Linux, and other PC-oriented operating systems provide similar mechanisms. The term COM port will be used throughout this document to refer to all of them.)
The COM port software mechanism is a popular means of communicating with a peripheral from a PC, due to its simplicity. It was originally designed for communication over the RS232 port, but it has now grown beyond these hardware limitations. Often today it is used in the form of a “virtual” COM port operating over USB or Bluetooth, interfaces which by now have mostly replaced RS232 on the PC back panel.
Historically, COM ports were used in telecom applications, including modems and early
networking applications. Although these applications for COM ports have all but been replaced by other uses, this telecom influence exists to this day. For example, programs whose primary function is to interface with COM ports are still referred to as “terminal” applications, a term derived from these early roots.
One means of establishing a virtual COM port interface over USB is with the Communications Device Class (CDC) protocol, which was established by the USB Implementers’ Forum. The major OSes have already included support for this protocol as part of their basic installations; and so for most applications, the end user need not install custom kernel drivers. This leads to greater system stability, less hassle for the end user, and considerably less hassle for the OEM, in terms of development cost and end user support.
The scope of the CDC spec is much wider than virtual COM ports, supporting a wide variety of communications equipment. As a result, this API supports only a subset of the CDC spec. Specifically, it supports the Abstract Communication Model (ACM) of the PSTN subclass. The ACM provides for a control mechanism using common V.250 AT commands. This is sufficient to establish a fully-functional virtual COM port interface.
Up to three data connections can be established using this current version of this API. Each connection represents a data link between a COM port on the PC, and conceptual “ports” within the API. (Note: v0.7 only supports a single port.) Simple calls are available to transceive data with the USB host, at a level of complexitiy similar to that of a basic UART.
2.2 Stack
Organization
A code stack using this API is shown in Fig. 1.
Application
CDC API
MSP430 header file
Modification unnecessary
User-customized event handling
API Event Handlers
User code
USB API
The USB functionality is almost fully contained within the API, allowing the user to focus on data handling rather than protocol.
Some calls are common to any USB interface, such as initialization, connecting to the USB, etc. These are located within the USB API and made available to the application. Other calls are specific to the CDC; the CDC interfaces with the USB API to actualize the CDC protocol. The USB API is shared among all USB device class API stacks distributed by TI for the MSP430, easing the development of composite devices with multiple device class APIs.
Interrupt handling (that is, the USB interrupt service routine) is performed within the API, as opposed to user-defined application space. However, the API provides to the application a means of responding to interrupts through “events”. These are occurrences for which the developer can add custom handling to the handling already implemented by the API. Handling of events is implemented through placeholder functions defined in application space, but called from within the USB ISR. These functions can be customized to the application. For example, if a power event has been detected that has disrupted USB operation, the application may choose to investigate the problem or alert the end user of a low battery. See Sec. 4 for more information about event handler functions.
2.3
Source File Organization
Source and header files that comprise the API stack are shown in Table 1. Table 1. Files in the API Stack
User-Modify?
Filename Description
main.c User application.
usb_eventHandling.c Event-handling placeholder functions.
Application-specific
Yes
descriptors.c File containing functions that reply to the host’s GetDescriptor requests. A default descriptor set is provided, which can be customized directly or with the MSP430 USB Descriptor Tool. This file also contains the configuration constants, as described in Sec. 6
usbcdc.c CDC-related functions.
usb.c All non-CDC and non-HID, USB-level functions; descriptor handling; API-defined calls made from ISR vector. API stack No
usbisr.c USB interrupt service routine handler and related functions. MSP430
header file
No I.e., MSP430xx55x2.h Standard header file for the MSP430 device derivative being used. This is included in the software development environment, outside this API.
2.4
Use of MCU Resources
Within the API, two resources are used without restriction -- the USB module (with its associated pins), and two DMA channels. (Note: v0.7 does not use the DMA for data transfers.) Generally speaking, the application should avoid direct writing to either the USB module or the DMA modules control of the selected channels.
The pins associated with the USB module can be used as special I/O pins when not used for USB. The application has permission to manipulate these pins directly only when the USB module has been disabled using the USB_disable() call. Once the USB module is enabled using USB_enable(), the API has the right to control these pins.
Two DMA channels must be assigned to the API, one for transmit and one for receive. The channels are assigned using the configuration constants USB_DMA_TX and USB_DMA_RX The API v0.7 uses approximately 3.7K bytes of code memory and 500 bytes of data memory.
2.5
Configuration of Endpoints
The CDC specification provides for a management element, and optionally a notification element that the device can use to alert the host. The former is predefined to use control endpoint 0, while the latter can use an interrupt or bulk endpoint. The PSTN subclass of the CDC, which defines the Abstract Control Model implemented by this API, provides for an additional pair of pipes to exchange data with the host.
The API implements this structure as shown in Table 2. Table 2. Endpoint Usage
Endpoint Transfer Type Purpose
Control endpoint 0 (input/output) Control Management element Input endpoint 2 (IN2) Interrupt Notification element Input/output endpoint 3 (IN3/OUT3) Bulk For port #1
Input/output endpoint _ (IN_/OUT_) Bulk For port #2(not supported in v0.7)
Input/output endpoint _ (IN_/OUT_) Bulk For port #3 (not supported in v0.7)
2.6 Descriptors
The USB descriptors reported by the CDC API to the USB host reflect the requirements of the CDC specification as implemented by the API. The code that does this is contained in the file descriptors.c.
In their unmodified form as distributed by TI, the API’s descriptor handlers are sufficient for application development. They report the device using TI’s vendor ID, a product ID specific to this API, and TI-specific vendor/product strings. For production purposes, however, they should be customized. In almost all cases, at least the device descriptor and string descriptors will need to be customized. TI has provided the MSP430 USB Descriptor Tool as an open-source solution to help with this customization. The tool quickly modifies descriptors.c using a
graphical interface, saving time and greatly reducing the chance for unnecessary errors. (Note: As of September 2008, the MSP430 USB Descriptor Tool has not yet been developed.
Modifications of the descriptors is not necessary for evaluation of this API, only for release of a product.)
2.6.1 Configurations
The API’s default descriptor set provides for a single USB configuration. If more than one configuration is desired, it is up to the user to create it. The provided configuration, including the interface and endpoint descriptors beneath it in the descriptor tree, are specific to the CDC implementation established by this API. With the exception of the fields that report power consumption, there should be no need to change them.
The default configuration descriptor provides string descriptors for the configuration/interface descriptors. Although the configuration descriptor should not change, these string descriptors should be customized prior to release of a USB product.
2.6.2 Serial
Numbers
The iSerialNumber field in the device descriptor determines whether the USB device intends to report a unique serial number to the host. If null, this indicates to the host that it will not report one. If it contains an index to a valid string descriptor, this string descriptor’s contents are considered to be the serial number.
The serial number cannot be determined at compile time, because it is specific to an individual MSP430 device and derived from the device ID, read by the API at run-time. The default descriptor structures in descriptors.c include a string descriptor for the serial number, equipped with a dummy eight-bit value. This dummy serial number descriptor is indexed by
iSerialNumber, which means that the host will expect the descriptor to be reported at this index. When the host issues a GET_DESCRIPTORS request, the API uses this descriptor structure and determines whether the iSerialNumber field is non-null; if so, it fetches the die ID for the individual MSP430 device and substitutes it into this dummy descriptor, prior to reporting it to the host.
As a result, the default behavior is to report a serial number specific to the individual MSP430 device. If a serial number is not desired, iSerialNumber needs to be set to null. The API will then exclude the serial number string descriptor.
(Note: v0.7 of the API does not reflect this behavior – it merely sends what is specified in descriptors.c.)
2.6.3 Configuration Constants in descriptors.c
Some elements of the API are controlled through configuration constants. These are compile-time controls that do not change during operation. (See Sec. 6) Some of the descriptor
information is implemented using configuration constants, which is intended to make it easier to make changes to the descriptors, and also makes the information available to the API code, should it be necessary. (Note: v0.7 of the API does not implement the configuration constants.)
2.7
Data Transmission/Reception Interface
(Note: While the data transmission/reception scheme in v1.0 will bear many similarities to the one in v0.7, there will be differences. This section discusses what is implemented in v0.7 and what is planned for v1.0.)
The API provides a simple scheme of transmitting and receiving data with the USB host, using commands such as “send data” and “receive data”. In so doing, it abstracts the user from the USB and CDC protocols, handling these functions automatically.
From the application’s perspective, communication with the USB host occurs via a port within the API, which is associated with a particular COM port on the USB host. (While, v0.7 supports only one COM port, v1.0 will support more, according to the constant USB_MAX_PORTCOUNT in descriptors.c.)
An important factor in the tranceiving of USB data is the maximum packet size. v0.7 fixes this at 64 bytes, while v1.0 will allow this to be adjusted with the configuration constant
USB_MAX_PACKET_SIZE. If data sizes larger than the packet size are to be sent, then after the API has finished loading USB_MAX_PACKET_SIZE bytes into the buffers, the application must wait until this data has been sent over the bus before loading data again. Similarly, if data sizes larger than the packet size are to be received, then after this much data has been removed from the buffers, the application must wait until more has been received over the bus. The API ensures that the application has control during these wait periods so that the USB operation does not monopolize the CPU’s time.
Data can be sent through a port with the function USBCDC_SendData() and received with the function USBCDC_ReceiveData(). Each of these functions exchanges the data with a location in memory, the address and size of which is passed into the function call by the application. If the size value passed to USBCDC_SendData() is less than 64 bytes, the function writes the data to the USB buffers and initiates the transfer, and then the function returns. If the size value passed to USBCDC_SendData() is greater than 64 bytes, the function sends the first 64 bytes, flags an interrupt to be generated when the buffer is once again empty, and the function returns. At this point, a send operation is said to be underway. When the first 64 bytes have been
transmitted and the buffer is empty, an interrupt is generated and the next 64 bytes are sent. This process repeats until all the data has been sent, at which point the send operation is said to be completed.
In this way, using send operations, data sizes larger than 64 bytes can be sent by the
application using a single function call. While the operation is underway, no new operations for that port can be started. If one is attempted, USBCDC_SendData() returns the value
kUSBCDC_portBusyError. A send operation can be aborted using USBCDC_abortSend(). In contrast, the USBCDC_ReceiveData() function is only capable of receiving up to 64 bytes. When the function is called, the received data is copied out of the USB buffers and the function returns. As more data is received over the bus, new calls to USBCDC_ReceiveData() must be made. v1.0 will provide more control for automatic receive operations greater than 64 bytes, similar to that currently provided for send operations. .
A function call USBCDC_portStatus() will be available in v1.0 to indicate whether an operation is still underway.
When a send operation completes, there is a pair of events, SendCompleteEvent and ReceiveCompleteEvent, which can generate a user-handlable event, when enabled.
If a receive operation is not underway for a given port, and data arrives that is designated for that port, it generates a DataReceivedEvent, and the transfer of any data over USB – either send/receive, and for any port, or even responding to any kind of USB requests from the host -- is halted until either a receive operation is begun (at which point the data is immediately
transferred to memory) or the data is rejected with USBCDC_rejectData(). Until one of these actions is taken, the packet that delivered the data will remain in the USB buffers; all attempts by the host to send a packet to this device will be NAK’ed, and although send operations can be initiated by the MSP430 application, no progress will be made in transferring data to the host. A port may have one send operation and one receive operation – but not more than one of either -- simultaneously.
2.8 Power
Management
The MSP430’s USB module has an integrated LDO regulator that reduces the 5V VBUS power supply from the USB to 3.3V. The MSP430 can then be powered from the USB. Further, the output of this LDO is such that it may be possible to supply the entire system outside the MSP430.
The MSP430 has the ability to detect when VBUS has been made available to it and
automatically enable/disable the LDO accordingly, generating an interrupt to let software know of the change. This makes it easy to prevent unnecessary drain on the system’s power supply, which is important in battery-powered applications.
The current version of the API supports the automatic enabling/disabling of the 3.3V LDO.
2.9 Clock
System
MSP430 devices supporting USB include a PLL that generates a USB clock from a high-speed crystal on the XT1/XT2 oscillator. A wide range of crystal frequencies is supported. The API must be told at what frequency the crystal oscillator is operating, so that it can configure the dividers in the PLL.
The current version of the API supports the configuration of frequencies by having the application pass a constant that reflects the frequency of the crystal. 43 discrete crystal frequencies between 1.5-32MHz are supported, using values in the MSP430 header file. (Note: v0.7 of the API, designed specifically for the MSP430TC0701, uses XT1 as the source clock for the PLL. This has been done to work around a TC0701 errata item, and the hardware distributed with the TC0701 has a high-frequency crystal on XT1 instead of XT2. See the TC0701 errata document.)
2.10 Version
It is possible to identify the version of the API when the device is plugged into a PC, using the OS. In Windows, this is done by opening the Device Manager and selecting the virtual COM port within the “Ports” section. (The Device Manager is Windows’ mechanism to manage peripherals on the system, and can be opened by right-clicking on “My Computer” and pressing the “Device Manager” button in the “Hardware” tab.)
2.11 Host Considerations
2.11.1 Microsoft Windows
Windows responds to the descriptors reported by this API by establishing a “COM port” link, similar to what it does with legacy RS232 hardware serial ports.
The most basic Windows application that can utilize a COM port is Hyperterminal, which is a part of any Windows installation. An MSP430 board loaded with this API, attached to a Windows-equipped USB host, will allow communication with Hyperterminal, once the proper COM port has been chosen within Hyperterminal.
The CDC class is supported by Windows XP and Vista.
2.11.2 Apple MacOS
2.11.3 Linux
3
API Function Calls
3.1
MSP430 USB Module Management
These calls configure and manage the MSP430’s USB module. They are shared among all USB APIs distributed by TI for the MSP430, and they are all defined within the usb.c source file.
Table 3. USB Module Management Call Summary
Function Description
BYTE USB_init() Initializes the USB hardware interface by configuring interrupts, power, and clocks, but does not activate the PLL or transceiver.
BYTE USB_enable(WORD freq) Activates the USB module, PLL, and transceiver.
BYTE USB_disable() Disable USB module, PLL, and transceiver. (not supported
in v0.7)
BYTE USB_setEnabledEvents(WORD events) Enables/disables various USB events BYTE USB_getEnabledEvents() Returns the status of USB event enabling
3.1.1 BYTE
USB_init()
Description
Initializes the USB module by configuring power and clocks, and secures the assocated pins for USB rather than general I/O usage. This should be called prior to any other API functions. Note that this does not enable the USB module (that is, does not set USB_EN bit). Rather, it prepares the USB module to detect the application of power to VBUS, after which the application may choose to enable the module and connect to USB. As such, power consumption does not increase when this function is executed.
Parameters
Table 4. Parameters for USB_init() returns kUSB_succeed
Usage Example
result = USB_init();
if (USB_connectionStatus() & kUSBvbusPresent) result = USB_enable(USBPLL_SETCLK_1_5);
3.1.2 BYTE USB_enable(WORD freq)
Description
Enables the USB module, which includes activating the PLL and setting the USB_EN bit. Power consumption increases as a result of this operation.
Parameters
Table 5. Parameters for USB_enable()
word freq The frequency of the crystal sourcing the PLL. This value should be taken from the MSP430 header file, in the section specifying values to be assigned to the USBPLLDIVB register.
returns kUSB_succeed
Usage Example
result = USB_enable(USBPLL_SETCLK_1_5);
3.1.3 BYTE
USB_disable(void)
(not implemented in v0.7)
Description
Disables the USB module and PLL. If the USB is not enabled when this call is made, no error is returned – the call simply exits with success.
Parameters
Table 6. Parameters for USB_disable() Returns kUSB_succeed
Usage Example
result = USB_disable();
3.1.4 BYTE USB_setEnabledEvents(BYTE events)
Description
Enables/disables various USB events. The events byte takes effect as-is; all ‘1’ values are enabled, and all ‘0’ values are disabled (there are no bit-wise operations). By default (that is, prior to any call to this function), all events are disabled.
The status of event enabling can be read with the USB_getEnabledEvents() function. Parameters
Table 7. Parameters for USB_setEnabledEvents() word events kUSB_clockFaultEvent
kUSB_VbusOnEvent kUSB_VbusOffEvent kUSB_UsbResetEvent kUSB_UsbSuspendEvent kUSB_UsbResumeEvent kUSB_dataReceivedEvent kUSB_sendCompletedEvent kUSB_receiveCompletedEvent Returns kUSB_succeed Usage Example result = USB_SetEnabledEvents(kUSB_VbusOnEvent|kUSB_sendCompletedEvent);
3.1.5 BYTE
USB_getEnabledEvents(void)
DescriptionReturns which events are enabled and which are disabled. The definition of events is the same as for USB_EnableEvents() above.
If the bit is set, the event is enabled. If cleared, the event is disabled. By default (that is, prior to calling USB_setEnabledEvents), all events are disabled.
Parameters
Table 8. Parameters for USB_getEnabledEvents() Returns kUSB_clockFaultEvent kUSB_VbusOnEvent kUSB_VbusOffEvent kUSB_UsbResetEvent kUSB_UsbSuspendEvent kUSB_UsbResumeEvent Usage Example result = USB_GetEnabledEvents();
3.2
USB Connection ManagementThese calls pertain to the USB connection with the host. They are shared among all USB APIs distributed by TI for the MSP430 and are defined within the usb.c source file.
Table 9. USB Connection Management Call Summary
Function Description
BYTE USB_reset() Resets the USB module and the internal state of the API. BYTE USB_connect() Instructs USB module to make itself available to the PC for
connection, by pulling the PUR pin high.
BYTE USB_disconnect() Forces a disconnect from the PC by pulling the PUR pin low BYTE USB_forceRemoteWakeup() Forces a remote wakeup of the USB host
BYTE USB_connectionStatus() Returns the status of the USB connection
3.2.1 BYTE
USB_reset()
Description
Resets the USB module and also the internal state of the API. The interrupt register is cleared to make sure no interrupts are pending. All open send/receive operations are aborted (their corresponding data locations are left intact).
Parameters
Table 10. Parameters for USB_reset () returns kUSB_succeed
Usage Example
result = USB_reset();
3.2.2 BYTE
USB_connect()
Description
Instructs the USB module to make itself available to the PC for connection, by pulling the D+ signal high using the PUR pin. If this function is called while the USB module is not enabled or while VBUS is not present, the PUR pin is still pulled high, and the call exits with success. Parameters
Table 11. Parameters for USB_connect() Returns kUSB_succeed
Usage Example
if(USB_connectionStatus() & kUSBvbusPresent) { result = USB_enable(); result = USB_connect(); }
3.2.3 BYTE
USB_disconnect(void)
DescriptionForces a logical disconnect from the USB host by pulling the PUR pin low, removing the pullup on the D+ signal. The USB module and PLL remain enabled. If the USB is not connected when this call is made, no error is returned – the call simply exits with success after clearing the bit that pulls PUR high.
Parameters
Table 12. Parameters for USB_disconnect() Returns kUSB_succeed
Usage Example
result = USB_disconnect();
3.2.4 BYTE
USB_forceRemoteWakeup(void)
Description
Forces a remote wakeup of the USB host. The user must ensure that the configuration
constant USB_SUPPORT_REMOTE_WAKEUP reflects that this capability exists, prior to calling this function. (v0.7 does not support configuration constants. Default descriptors report to the host that remote wakeup is supported, so this function may be called.)
Parameters
Table 13. Parameters for USB_forceRemoteWakeup() Returns kUSB_succeed
kUSB_notSuspended
Usage Example
#pragma vector=PORT1_VECTOR __interrupt void Port1_ISR (void) {
// ISR entered because of an edge event on P1
P1IFG &= ~0x10; // IFG Cleared
if(USB_connectionStatus() & kUSBsuspended) result = USB_forceRemoteWakeup();
}
3.2.5 BYTE
USB_connectionStatus()
Description
Returns the status of the USB connection. Generally, the USB connection is either active or in suspend mode.
Parameters
Table 14. Parameters for USB_connectionStatus() Returns kUSB_vbusPresent
kUSB_suspended
kUSB_connectNoVBUS (not implemented in v0.7) kUSB_enumerated
Usage Example
if(USB_connectionStatus() & kUSBsuspended) result = USB_forceRemoteWakeup();
3.3
CDC Management and Data Handling
These calls are specific to the Communications Device Class. They are defined within the usbcdc.c source file.
Table 15. CDC Management and Data Handling Call Summary
Function Description
BYTE USBCDC_sendData(const BYTE* data, WORD size, BYTE portNum, BYTE DMA_ch) (refer Note 1)
Sends data to the USB host
BYTE USBCDC_receiveData(BYTE* data, WORD size, BYTE portNum, BYTE DMA_ch) (refer Note 1)
Receives data from the USB host
BYTE USBCDC_abortsend(WORD* size, BYTE portNum) (refer Note 2) Aborts an active send operation
BYTE USBCDC_abortsend(WORD* size, BYTE portNum) (refer Note 2) Aborts an active receive operation
BYTE USBCDC_rejectData() Rejects payload data residing in the USB buffer, for which a receive operation has not yet been initiated
USBCDC_getPortSettings(LONG rate, BYTE format, BYTE parity, BYTE dataBits, BYTE portNum)
3.3.1 BYTE
USBCDC_sendData(BYTE
* data, WORD size, BYTE portNum)
Description
Sends data over port portNum, of size size and starting at address data. If size is larger than the USB buffer space, the function handles all packetization and buffer management. If size is less than or equal to the value specified by the configuration constant
USB_MAX_PACKET_SIZE, then all the data is immediately transferred to the USB buffer, and when the function returns, the send operation will be complete. The function will return with the code kUSBCDC_sendComplete, and a call to USBCDC_portStatus() after the return will show the kUSBCDC_waitingForSend bit to be cleared.
If size is greater than USB_MAX_PACKET_SIZE, then USB_MAX_PACKET_SIZE bytes are sent and the function returns; the remaining data will be sent as buffer space becomes available. It does this by setting up a sequence in which USB interrupts indicate that the buffer is empty, and more data-in-waiting is sent by the ISR. When the function returns, it does so with the value kUSBCDC_sendStarted, and the send operation is said to be still underway. During this time, a call to USBCDC_portStatus() will return with the kUSBCDC_waitingForSend bit set. Once the operation is completed, this bit will be return cleared. The handleSendCompleted() event will also be generated when the event has completed.
(Note: v0.7 fixes the packet size to 64 bytes, rather than deriving it from USB_MAX_PACKET_SIZE.)
(Note: v0.7 does not support the USBCDC_portStatus() call.)
If a send operation is already in progress for this port (USBCDC_portStatus() returns kUSBCDC_waitingForSend), then this call will return kPortBusyError.
A receive operation can occur simultaneous to a send operation for this port.
If the device gets suspended by the USB host, any active send operations are dormant, and will resume if or when the device is resumed. If this behavior isn’t desired, the application should respond to a suspend event by aborting any active send operations.
Parameters
Table 16. Parameters for USBCDC_sendData() byte* data An array of data to be sent
word size Number of bytes to be sent, starting from address data. byte portNum Which port the data should be transmitted over
Returns kUSBCDC_sendStarted kUSBCDC_sendComplete kUSBCDC_portBusyError
Usage Example
if(!(USB_connectionStatus() & kUSBCDC_waitingForSend)) result = USBCDC_sendData(data,32,1,0x01);
3.3.2 BYTE
USBCDC_receiveData(BYTE * data, WORD size, BYTE portNum)
Description
Receives size bytes over port portNum, of size size, into memory starting at address data. If less than size bytes are currently in the receive buffer, then only the available data is copied to data. The number of bytes received is returned. If more than size bytes remain in the buffer, additional calls to USBCDC_receiveData() are required to retrieve them.
(In v1.0, this function will provide support for automatic reception of data sizes larger than USB_MAX_PACKET_SIZE, similar to what is provided for sending data.)
Parameters
Table 17. Parameters for USBCDC_receiveData() byte* data An array that will contains the data received. word size Number of bytes to be received
byte portNum Which port to receive from Returns Number of bytes actually received
Usage Example
3.3.3 BYTE
USBCDC_abortSend(WORD* size, BYTE portNum)
Description
Aborts an active send operation on port portNum. Returns the number of bytes that were sent prior to the abort, in size.
An application may choose to call this function in response to the device being suspended by the USB host. Otherwise, when the device is resumed, the operation will automatically commence sending its data.
An application may also choose to call this function if the send operation doesn’t happen as quickly as required by the application, perhaps due to an overloaded bus.
Parameters
Table 18. Parameters for USBCDC_abortSend() word* size Number of bytes that were sent prior to the abort action. byte portNum The port for which the send should be aborted
Usage Example
// abort a previously-established send operation
If (USBCDC_portStatus(1, bytesSent,bytesReceived) & kUSBCDC_waitingForSend) Result = USBCDC_abortSend(size,1);
3.3.4 BYTE
USBCDC_abortReceive(WORD* size, BYTE portNum)
(not implemented in
v0.7)
DescriptionAborts an active receive operation on port portNum. Returns the number of bytes that were received and transferred to the data location established for this receive operation.
An application may choose to call this function if it decides it no longer wants to receive data from the USB host, if the host for whatever reason has stopped sending the expected data and wishes to recover by freeing the memory originally assigned for this data.
Parameters
Table 19. Parameters for USBCDC_abortReceive()
word* size Number of bytes that were received and are waiting at the assigned address.
byte portNum The port for which the send should be aborted Returns kUSB_succeed
Usage Example
// abort a previously-established receive operation
If (USBCDC_portStatus(1,bytesSent,bytesReceived) & kUSBCDC_waitingForReceive) Result = USBCDC_abortReceive(size,1);
3.3.5 BYTE
USBCDC_rejectData()
Description
This function rejects payload data that has been received from the host for a port that does not have an active receive operation underway. The USB buffers are effectively purged, and the data lost. This frees the USB path to resume communication.
Parameters
Table 20. Parameters for USBCDC_rejectData() Returns kUSB_succeed
Usage Example
// Reject data residing in the USB buffer (and obstructing flow of incoming data // for other ports)
3.3.6 BYTE
USBCDC_portStatus(BYTE portNum, WORD* bytesSent, WORD*
bytesReceived)
(not implemented in v0.7)
Description
Indicates the status of the port portNum. If a send operation is active for this port, the function also returns the number of bytes that have been transmitted to the host. If a receiver operation is active for this port, the function also returns the number of bytes that have been received from the host and are waiting at the assigned address.
Parameters
Table 21. Parameters for USBCDC_portStatus() byte portNum Port number for which status is being retrieved.
word* bytesSent If a send operation is underway, the number of bytes that have been transferred to the host is returned in this location. If no send operation is underway, this returns zero.
word* bytesReceived If a receive operation is underway, the number of bytes that have been transferred to the assigned memory location is returned in this location. If no receive operation is underway, this returns zero.
Returns kUSBCDC_waitingForSend (indicates that a call to USBCDC_SendData()
has been made, for which data transfer has not been completed)
kUSBCDC_waitingForReceive (indicates that a receive operation has been
initiated, but not all data has yet been received)
kUSBCDC_dataWaiting (indicates that data has been received from the
host, waiting in the USB receive buffers)
Usage Example
bytes_sendA = USBCDC_sendData(dataA,8,1,0xFF);
while(USBCDC_portStatus(1,bytesSent,bytesReceived) & kUSBCDC_waitingForSend); bytes_sendB = USBCDC_sendData(dataB,8,1,0xFF);
3.3.7 BYTE
USBCDC_getPortSettings(LONG rate, BYTE format, BYTE parity, BYTE
dataBits, BYTE portNum)
(not implemented in v0.7)
Description
If the CPU is exchanging data directly with port portNum, this function most likely serves no purpose. However, if the software is written such that the port data is being transceived via one of the MSP430’s hardware UARTs, it might be desirable to configure that UART according to the information received by this function.
Parameters
Table 22. Parameters for USBCDC_getPortSettings()
long rate Baud rate. This is the parameter defined in the PSTN subclass spec as
dwDTERate.
byte format The number of stop bits: 0: 1 stop bit
1: 1.5 stop bits 2: 2 stop bits
This is the parameter defined in the PSTN subclass spec as bCharFormat. byte parity The type of parity to be used:
0: None 1: Odd 2: Even 3: Mark 4: Space
This is the parameter defined in the PSTN subclass spec as bParityType. byte databits The number of data bits to be used (5, 6, 7, 8, or 16). This is the parameter
defined in the PSTN sublcass spec as bDataBits. byte portNum The number of the port being queried.
Returns kUSB_succeed
kUSB_dataNotReceivedFromHost
Usage Example
4 Event-Handling
The USB interrupt service routine (ISR) is contained within the API, and is not intended to be modified by the API user. Rather, it provides event handling within the application. Various events are defined, most of which are called directly from the ISR in response to various
interrupt types. For each event type, a placeholder function is defined in USB_eventHandling.c. As distributed by TI, the API software has no code inside these function definitions – they are empty functions. The user may write handlers for the various event types with which the function is associated.
Generally speaking, parameters are not passed in or out of the event-handling functions. However, a few of the functions are specific to a particular port, and in these cases, the port number is passed into the function.
Event-handling calls are generally called from the ISR. As such, general interrupts are disabled prior to entering the handler function, and any precautions about good ISR coding apply to event handler functions as well. Notably, it is recommended that code be kept as short as possible to avoid delays in handling other interrupts. If more functionality is required, one option is to set a flag and let code outside the handler pick up the flag and handle the desired functionality. The event handler should never enable general interrupts, as unpredictable operation could result.
Table 23. Event Handler Summary
Event Handler functions Interrupt source Event Description
VOID USB_handleClockEvent() USBVECINT_PLL_RANGE USB-PLL failed (out of range) VOID USB_handleVbusOnEvent() USBVECINT_PWR_VBUSOn Indicates that a valid voltage is now
available on the VBUS pin VOID USB_handleVbusOffEvent() USBVECINT_PWR_VBUSOff Indicates that a valid voltage is no
longer available on the VBUS pin VOID USB_handleResetEvent() USBVECINT_RSTR Indicates that the USB host has
initiated a port reset
VOID USB_handleSuspendEvent() USBVECINT_SUSR Indicates that the USB host has put this device into suspend mode VOID USB_handleResumeEvent() USBVECINT_RESR Indicates that the USB host has
resumed this device from suspend mode
VOID USB_handleDataReceived(BYTE portNum)
Interrupt for the output endpoint associated with this port
Indicates that data has been received for port portNum, for which no data receive operation is underway VOID USB_handleSendCompleted(BYTE
portNum)
Interrupt for the input endpoint associated with this port
Indicates that a send operation on port portNum has just been completed VOID
USB_handleReceiveCompleted(BYTE portNum)
Interrupt for the output endpoint associated with this port
Indicates that a send operation on port portNum has just been completed
4.1 void
USB_handleClockEvent(void)
Description
If this function gets executed, it’s a sign that the output of the USB PLL has failed. This event will occur even if no USB connection was established, if the event is enabled. This event may have occurred because the high-frequency crystal has failed.
If this event occurs while the USB device is actively connected to the USB host, it probably means the host will soon consider this device non-operational, if it has not already done so by the time this call is executed. As a result, it will most likely suspend the device. After re-establishing the clock, it may be necessary to call USB_reset() to perform a logical
4.1.1 void
USB_handleVbusOnEvent(void)
Description
If this function gets executed, it indicates that a valid voltage has just been applied to the VBUS pin. This generally means that the device has been attached to an active USB host.
The MSP430 hardware and API automatically enable the 3.3V LDO. No action is required by the application in order to enable USB operation; the USB module is enabled by the API prior to the event handler function being executed.
4.1.2 void
USB_handleVbusOffEvent(void)
Description
If this function gets executed, it indicates that a valid voltage has just been removed from the VBUS pin. If power has been applied to the VUSB pin from another source, then the USB operation is unaffected. However, if the USB module was being powered from the 3.3V LDO, then the USB module has likely been powered down, and the connection has been lost. The API responds by disabling the USB module and PLL, and then it calls this event handling function, if enabled.
Interrupt enable for VBUS on event is enabled to automatically detect valid VBUS voltage and to initialize the USB module appropriately. Software may wish to inform the user of the situation.
4.1.3 void
USB_handleResetEvent(void)
Description
If this function gets executed, it indicates that the USB host has issued a reset of this USB device. The API handles this event automatically, and no action is required by the application to maintain USB operation. It is provided to the application for informational purposes.
4.1.4 void
USB_handleSuspendEvent(void)
Description
If this function gets executed, it indicates that the USB host has chosen to suspend this USB device. When this occurs, it is important that this USB device not consume more than 500uA, per the USB 2.0 specification. The API automatically shuts down the PLL, a significant source of current draw, when a suspend event occurs. To replace it, it selects the XT??
(low-frequency) clock source to drive the USB module. It then calls this event handler.
The application developer should be aware of how much current the system is drawing from VBUS. Code should be written for this function that reduces current draw from VBUS to within the 500uA limit.
4.1.5 void
USB_handleResumeEvent(void)
Description
If this function gets executed, it indicates that the USB host has chosen to resume this USB device from suspend mode. When this occurs, the device is no longer restricted to drawing under 500uA from VBUS. The MSP430 hardware and API automatically re-start the PLL, and active operation automatically resumes.
Upon being resumed, the device is no longer restricted to drawing less than 500uA from VBUS. Therefore, the application may use this event handler to activate functions that were shut down during suspend.
4.1.6 void USB_handleDataReceived(BYTE portNum)
Description
This event indicates that data has been received for port portNum, but no data receive operation is underway. Effectively, the API doesn’t know what to do with this data and is asking for
instructions. Either a receive operation can be initiated, or the data can be rejected by calling USBCDC_rejectData(). Until one of these is performed, USB transactions cannot continue; any packets received from the USB host will be NAK’ed, and while send operations can be initiated, they will not make any progress in transferring their data to the host.
Therefore, it is critical that this event be handled immediately, ideally within this handler function. If this function is exited without one of these actions being taken, a call to USBCDC_portStatus() for this port (but not any other ports) will return kUSBDataWaiting, which is another point at which the application could begin a receive operation or reject the data.
4.1.7 void
USB_handleSendCompleted(BYTE portNum)
Description
This event indicates that a send operation on port port has just been completed.
4.1.8 void
USB_handleReceiveCompleted(BYTE portNum)
Description
This event indicates that a receive operation on port port has just been completed. The data can be retrieved. It is located at the address assigned when the fetch was initiated. If the event occurs, it means that the full size that was requested by the fetch was indeed received.
5 Operation
Examples
5.1 Initialization
When the program starts, it should prepare the USB module for operation. These are settings that must be made prior to a USB connection.
USB_init()
Program Start
USB_setEnabledEvents()
Figure 2. USB InitializationNote that events are enabled after initialization. Prior to this, no event can be generated, including the detection of a VBUS-on event. Once this event is enabled (within
USB_setEnabledEvents() ), a valid voltage on VBUS, if it exists, will immediately generate a VBUS-on event.
5.2
Handling a VBUS-On Event
In most cases, the VBUS pin on the MSP430 is attached to the VBUS 5V supply on the USB cable, supplied from the host. When 5V is seen on this pin, it’s a sign that a physical connection to the host has been initiated. In most cases, a device will then want to indicate its presence to the host so that it can be enumerated by it. Fig. ?? shows a typical handler for a VBUS-on event.
USB_enable()
HandleVbusOnEvent handler
Begin send/receive operations
USB_connect()
Figure 3. handleVbusOnEvent()
Enabling the USB module activates the PLL, which consumes a signficant amount of current. It is best to wait with this operation until after VBUS has become available.
The connect operation activates the pullup resistor, signalling to the host the presence of this device.
5.3 Sending
Data
When the application decides it is ready to send data to a port, it should first prepare the data and then begin a send operation.
If there is to be a continuous flow of data, in which the memory location is a buffer continually loaded from a data source, the USBCDC_sendData() call could be placed inside
handleSendCompleteEvent(). This way, when the initial send is finished, a second one will automatically begin.
5.4 Receiving
Data
An application can choose to initiate a receive operation in one of two ways.
One is to begin a receive operation immediately after enabling the USB module; this way data is automatically transferred to the assigned memory location. In this case, it is also beneficial to begin a receive operation within handleReceiveCompleteEvent(), since the occurrence of this event means there is no longer an active receive operation for this port, and any further data received for this port will generate a handleDataReceivedEvent().
An alternative, simpler method is to begin all receive operations within the
handleDataReceivedEvent() function, since this function will automatically be called whenever data is received from the host and no receive operation is underway. USB operation halts completely until this event is handled, so if this method is used, it’s important to execute the handling quickly.
6 Configuration
Constants
A few constants are located in descriptors.c that control operation of the API. These are
implemented as constants rather than function parameters because their values are considered to be compile-time constants that do not change during operation. In most cases it is best to rely on the default values, however modification is possible.
(Note: The configuration constants have not been implemented in v0.7.) The constants that may be modified as shown in Table 24.
Table 24. Configuration Constants
Constant Description
USB_VID Four-digit hex value reflecting the USB vendor ID, as assigned by the USB-IF USB_PID Four-digit hex value reflecting this device’s product ID, as assigned by the OEM USB_MAX_PACKET_SIZE This is the size of packets that are used to exchange serial data over USB. Larger
packets are more efficient when transceiving large chunks of data. The downside to large packets is that if the USB is crowded, then large packets may waste
bandwidth. It must also be considered how much endpoint buffer space is available, especially when using multiple interfaces.
USB_NUM_CONFIGURATIONS The current version of the API restricts this value to 1.
USB_INT_TRANFER_INTERVAL Indicates how often, in terms of USB frames, the host should poll for interrupt transfers.
USB_SUPPORT_REMOTE_WAKEUP Boolean that supports whether the device will support the remote wakeup feature. USBCDC_PORTCOUNT This is the number of data ports that will be established with the USB host over the CDC protocol, and therefore the number of COM ports that will be available to the host application and to the MSP430 application. Up to three ports can be supported.
This value will affect the number of interface descriptors reported to the host. USB_STR_INDEX_DEV Decimal value indicating the string index within the string descriptor that contains the
vendor string. This string is often displayed to the end user by the OS. If no string is desired, this index should be assigned a value of 0.
USB_STR_INDEX_PROD Decimal value indicating the string index within the string descriptor that contains the product string. This string is often displayed to the end user by the OS. If no string is desired, this index should be assigned a value of 0.
USB_STR_INDEX_SERNUM Decimal value indicating the string index within the string descriptor that contains the serial number string. A serial number plays an important role in helping the OS identify this individual device, and helps it associate specific settings with this device. A specific combination of VID, PID, and serial number should be unique to any USB device in existence. If no serial number is desired, this index should be assigned a value of 0.
USB_DMA_TX Selects the DMA channel to be used for transmit operations. Must reflect a channel that is implemented in the chosen MSP430 derivative, and must be different than the channel used for receive operations. 0x00 for ch. 0, 0x01 for ch. 1, up to 0x07 for ch. 7
USB_DMA_RX Selects the DMA channel to be used for receive operations. Must reflect a channel that is implemented in the chosen MSP430 derivative, and must be different than the channel used for transmit operations. 0x00 for ch. 0, 0x01 for ch. 1, up to 0x07 for ch. 7
7 References
• MSP430 5xx User’s Guide
• USB 2.0 specification (http://www.usb.org/developers/docs/)
• Communications Device Class specification and PSTN Subclass specification (http://www.usb.org/developers/devclass_docs#approved)