USB CDC-ACM class

This commit is contained in:
ksb 2009-07-11 14:30:53 +00:00
parent 195c23aaa4
commit 659b3fb7d3
5 changed files with 476 additions and 0 deletions

View file

@ -0,0 +1,126 @@
#include "descriptors.h"
#include <contiki-conf.h>
#include <cdc.h>
#include <usb-arch.h>
const struct usb_st_device_descriptor device_descriptor =
{
sizeof(struct usb_st_device_descriptor),
DEVICE,
0x0210,
CDC,
0,
0,
CTRL_EP_SIZE,
0xffff,
0xffff,
0x0030,
2,
1,
3,
1
};
const struct configuration_st {
struct usb_st_configuration_descriptor configuration;
struct usb_st_interface_descriptor comm;
struct usb_cdc_header_func_descriptor header;
struct usb_cdc_abstract_ctrl_mgmnt_func_descriptor abstract_ctrl;
struct usb_cdc_union_func_descriptor union_descr;
struct usb_cdc_call_mgmnt_func_descriptor call_mgmt;
#if 1
struct usb_st_endpoint_descriptor ep_notification;
#endif
struct usb_st_interface_descriptor data;
struct usb_st_endpoint_descriptor ep_in;
struct usb_st_endpoint_descriptor ep_out;
} BYTE_ALIGNED configuration_block =
{
/* Configuration */
{
sizeof(configuration_block.configuration),
CONFIGURATION,
sizeof(configuration_block),
2,
1,
0,
0x80,
50
},
{
sizeof(configuration_block.comm),
INTERFACE,
0,
0,
1,
CDC,
ABSTRACT_CONTROL_MODEL,
V_25TER_PROTOCOL,
0
},
{
sizeof(configuration_block.header),
CS_INTERFACE,
CDC_FUNC_DESCR_HEADER,
0x0110
},
{
sizeof(configuration_block.abstract_ctrl),
CS_INTERFACE,
CDC_FUNC_DESCR_ABSTRACT_CTRL_MGMNT,
0
},
{
sizeof(configuration_block.union_descr),
CS_INTERFACE,
CDC_FUNC_DESCR_UNION,
0, /* Master */
{1} /* Slave */
},
{
sizeof(configuration_block.call_mgmt),
CS_INTERFACE,
CDC_FUNC_DESCR_CALL_MGMNT,
0x02,
1 /* data interface */
},
{
sizeof(configuration_block.ep_notification),
ENDPOINT,
0x83,
0x03,
USB_EP3_SIZE,
100
},
{
sizeof(configuration_block.data),
INTERFACE,
1,
0,
2,
CDC_DATA,
0,
TRANSPARENT_PROTOCOL,
0
},
{
sizeof(configuration_block.ep_in),
ENDPOINT,
0x81,
0x02,
USB_EP1_SIZE,
0
},
{
sizeof(configuration_block.ep_out),
ENDPOINT,
0x02,
0x02,
USB_EP2_SIZE,
0
}
};
const struct usb_st_configuration_descriptor const *configuration_head =
(struct usb_st_configuration_descriptor const*)&configuration_block;

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<descriptors>
<languages>
<lang id="en">0x0409</lang>
<lang id="sv">0x041d</lang>
</languages>
<strings>
<string> <!-- 1 -->
<lang id="en">Serial interface</lang>
<lang id="sv">Serieport</lang>
</string>
<string> <!-- 2 -->
<lang>Fluffware</lang>
</string>
<string> <!-- 3 -->
<lang>0.01</lang>
</string>
</strings>
</descriptors>

View file

@ -0,0 +1,110 @@
#include <cdc-acm.h>
#include <cdc.h>
#include <usb-api.h>
#include <usb-core.h>
#include <stdio.h>
static uint8_t usb_ctrl_data_buffer[32];
static void
encapsulated_command(uint8_t *data, unsigned int length)
{
printf("Got CDC command: length %d\n", length);
usb_send_ctrl_status();
}
static void
set_line_encoding(uint8_t *data, unsigned int length)
{
if (length == 7) {
static const char parity_char[] = {'N', 'O', 'E', 'M', 'S'};
static const char *stop_bits_str[] = {"1","1.5","2"};
const struct usb_cdc_line_coding *coding =
(const struct usb_cdc_line_coding *)usb_ctrl_data_buffer;
char parity = ((coding->bParityType > 4)
? '?' : parity_char[coding->bParityType]);
const char *stop_bits = ((coding->bCharFormat > 2)
? "?" : stop_bits_str[coding->bCharFormat]);
printf("Got CDC line coding: %ld/%d/%c/%s\n",
coding->dwDTERate, coding->bDataBits, parity, stop_bits);
usb_send_ctrl_status();
} else {
usb_error_stall();
}
}
static unsigned int
handle_cdc_acm_requests()
{
printf("CDC request %02x %02x\n", usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest);
switch(usb_setup_buffer.bmRequestType) {
case 0x21: /* CDC interface OUT requests */
/* Check if it's the right interface */
if (usb_setup_buffer.wIndex != 0) return 0;
switch(usb_setup_buffer.bRequest) {
case SET_CONTROL_LINE_STATE:
if (usb_setup_buffer.wValue & 0x02) {
puts("Carrier on");
} else {
puts("Carrier off");
}
if (usb_setup_buffer.wValue & 0x01) {
puts("DTE on");
} else {
puts("DTE off");
}
usb_send_ctrl_status();
return 1;
case SEND_ENCAPSULATED_COMMAND:
{
unsigned int len = usb_setup_buffer.wLength;
if (len > sizeof(usb_ctrl_data_buffer))
len = sizeof(usb_ctrl_data_buffer);
usb_get_ctrl_data(usb_ctrl_data_buffer, len,
encapsulated_command);
}
return 1;
case SET_LINE_CODING:
{
unsigned int len = usb_setup_buffer.wLength;
if (len > sizeof(usb_ctrl_data_buffer))
len = sizeof(usb_ctrl_data_buffer);
usb_get_ctrl_data(usb_ctrl_data_buffer, len,
set_line_encoding);
}
return 1;
}
break;
case 0xa1: /* CDC interface IN requests */
if (usb_setup_buffer.wIndex != 0) return 0;
switch(usb_setup_buffer.bRequest) {
case GET_ENCAPSULATED_RESPONSE:
printf("CDC response");
usb_send_ctrl_status();
return 1;
}
}
return 0;
}
static const struct USBRequestHandler cdc_acm_request_handler =
{
0x21, 0x7f,
0x00, 0x00,
handle_cdc_acm_requests
};
static struct USBRequestHandlerHook cdc_acm_request_hook =
{
NULL,
&cdc_acm_request_handler
};
void
usb_cdc_acm_setup()
{
usb_register_request_handler(&cdc_acm_request_hook);
}

View file

@ -0,0 +1,7 @@
#ifndef __CDC_ACM_H__UFV6K50827__
#define __CDC_ACM_H__UFV6K50827__
void
usb_cdc_acm_setup();
#endif /* __CDC_ACM_H__UFV6K50827__ */

View file

@ -0,0 +1,214 @@
#ifndef __CDC_H__K1Q26ESJOC__
#define __CDC_H__K1Q26ESJOC__
#include <usb.h>
/* Communication Class */
/* Class code */
#define CDC 0x02
/* Interface subclass codes */
#define CDC_RESERVED 0x00
#define DIRECT_LINE_CONTROL_MODEL 0x01
#define ABSTRACT_CONTROL_MODEL 0x02
#define TELEPHONE_CONTROL_MODEL 0x03
#define MULTI_CHANNEL_CONTROL_MODEL 0x04
#define CAPI_CONTROL_MODEL 0x05
#define ETHERNET_NETWORKING_CONTROL_MODEL 0x06
#define ATM_NETWORKING_CONTROL_MODEL 0x07
/* Protocols */
#define V_25TER_PROTOCOL 0x01
/* Requests */
#define SEND_ENCAPSULATED_COMMAND 0x00
#define GET_ENCAPSULATED_RESPONSE 0x01
#define SET_COMM_FEATURE 0x02
#define GET_COMM_FEATURE 0x03
#define CLEAR_COMM_FEATURE 0x04
#define SET_AUX_LINE_STATE 0x10
#define SET_HOOK_STATE 0x11
#define PULSE_SETUP 0x12
#define SEND_PULSE 0x13
#define SET_PULSE_TIME 0x14
#define RING_AUX_JACK 0x15
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
#define SEND_BREAK 0x23
#define SET_RINGER_PARMS 0x30
#define GET_RINGER_PARMS 0x31
#define SET_OPERATION_PARMS 0x32
#define GET_OPERATION_PARMS 0x33
#define SET_LINE_PARMS 0x34
#define GET_LINE_PARMS 0x35
#define DIAL_DIGITS 0x36
#define SET_UNIT_PARAMETER 0x37
#define GET_UNIT_PARAMETER 0x38
#define CLEAR_UNIT_PARAMETER 0x39
#define GET_PROFILE 0x3a
#define SET_ETHERNET_MULTICAST_FILTERS 0x40
#define GET_ETHERNET_MULTICAST_FILTERS 0x41
#define GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x42
#define SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x43
#define GET_ETHERNET_STATISTIC 0x44
#define SET_ATM_D ATA_FORMAT 0x50
#define GET_ATM_DEVICE_STATISTICS 0x51
#define SET_ATM_DEFAULT_VC 0x52
#define GET_ATM_VC_STATISTICS 0x53
/* Notifications */
#define NETWORK_CONNECTION 0x00
#define RESPONSE_AVAILABLE 0x01
#define AUX_JACK_HOOK_STATE 0x08
#define RING_DETECT 0x09
#define SERIAL_STATE 0x20
#define CALL_STATE_CHANGE 0x28
#define LINE_STATE_CHANGE 0x29
#define CONNECTION_SPEED_CHANGE 0x2a
/* Data interface */
/* Class code */
#define CDC_DATA 0x0a
/* Protocols */
#define I_430_PROTOCOL 0x30
#define ISO_IEC_3_1993_PROTOCOL 0x31
#define TRANSPARENT_PROTOCOL 0x32
#define Q_921M_PROTOCOL 0x50
#define Q_921_PROTOCOL 0x51
#define Q_921TM_PROTOCOL 0x52
#define V_42BIS_PROTOCOL 0x90
#define Q_931_PROTOCOL 0x91
#define V_120_PROTOCOL 0x93
#define CDC_PROTOCOL 0xfe
/* Descriptor subtypes */
#define CDC_FUNC_DESCR_HEADER 0x00
#define CDC_FUNC_DESCR_CALL_MGMNT 0x01
#define CDC_FUNC_DESCR_ABSTRACT_CTRL_MGMNT 0x02
#define CDC_FUNC_DESCR_DIRECT_LINE_MGMNT 0x03
#define CDC_FUNC_DESCR_RINGER_MGMNT 0x04
#define CDC_FUNC_DESCR_TEL_STATE 0x05
#define CDC_FUNC_DESCR_UNION 0x06
#define CDC_FUNC_DESCR_COUNTRY 0x07
#define CDC_FUNC_DESCR_TEL_MODE 0x08
#define CDC_FUNC_DESCR_USB_TERM 0x09
#define CDC_FUNC_DESCR_NET_TERM 0x0a
#define CDC_FUNC_DESCR_PROTOCOL_UNIT 0x0b
#define CDC_FUNC_DESCR_EXTENSION_UNIT 0x0c
#define CDC_FUNC_DESCR_MULTICH_MGMNT 0x0d
#define CDC_FUNC_DESCR_CAPI_MGMNT 0x0e
#define CDC_FUNC_DESCR_ETHERNET 0x0f
#define CDC_FUNC_DESCR_ATM 0x10
struct usb_cdc_header_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_HEADER subtype */
Uint16 bcdCDC; /* Revision of class specification */
} BYTE_ALIGNED;
struct usb_cdc_call_mgmnt_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_CALL_MGMNT subtype */
Uchar bmCapabilities; /* Capabilities */
Uchar bDataInterface; /* Management data interface */
} BYTE_ALIGNED;
struct usb_cdc_abstract_ctrl_mgmnt_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_ABSTRACT_CTRL_MGMNT subtype*/
Uchar bmCapabilities; /* Capabilities */
} BYTE_ALIGNED;
struct usb_cdc_direct_line_mgmnt_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_DIRECT_LINE_MGMNT subtype*/
Uchar bmCapabilities; /* Capabilities */
} BYTE_ALIGNED;
struct usb_cdc_ringer_mgmnt_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_RINGER_MGMNT subtype*/
Uchar bRingerVolSteps; /* Ringer volume steps */
Uchar bNumRingerPatterns; /* Number of ringer patterns supported */
} BYTE_ALIGNED;
struct usb_cdc_tel_mode_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_TEL_MODE subtype*/
Uchar bmCapabilities; /* Capabilities */
} BYTE_ALIGNED;
struct usb_cdc_tel_state_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_TEL_STATE subtype*/
Uchar bmCapabilities; /* Capabilities */
} BYTE_ALIGNED;
struct usb_cdc_union_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_UNION subtype*/
Uchar bMasterInterface; /* Master interface for union */
Uchar bSlaveInterface[1]; /* Slave interfaces in union */
} BYTE_ALIGNED;
struct usb_cdc_country_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_COUNTRY subtype*/
Uchar iCountryCodeRelDate; /* Release date for country codes */
Uint16 wCountryCode[1]; /* Country codes */
} BYTE_ALIGNED;
struct usb_cdc_ethernet_func_descriptor
{
Uchar bLength; /* Size of this descriptor in bytes */
Uchar bDescriptorType; /* CS_INTERFACE descriptor type */
Uchar bDescriptorSubtype; /* CDC_FUNC_DESCR_ETHERNET subtype*/
Uchar iMACAddress; /* MAC address string descriptor */
Uint32 bmEthernetStatistics; /* Supported statistics */
Uint16 wMaxSegmentSize;
Uint16 wNumberMCFilters; /* Number of multicast filters */
Uchar bNumberPowerFilters; /* Number of wake-up pattern filters */;
} BYTE_ALIGNED;
struct usb_cdc_line_coding
{
Uint32 dwDTERate;
Uchar bCharFormat;
Uchar bParityType;
Uchar bDataBits;
} BYTE_ALIGNED;
#endif /* __CDC_H__K1Q26ESJOC__ */