USB CDC-ACM class
This commit is contained in:
parent
195c23aaa4
commit
659b3fb7d3
5 changed files with 476 additions and 0 deletions
126
cpu/arm/common/usb/cdc-acm/cdc-acm-descriptors.c
Normal file
126
cpu/arm/common/usb/cdc-acm/cdc-acm-descriptors.c
Normal 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;
|
19
cpu/arm/common/usb/cdc-acm/cdc-acm-string-descriptors.xml
Normal file
19
cpu/arm/common/usb/cdc-acm/cdc-acm-string-descriptors.xml
Normal 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>
|
110
cpu/arm/common/usb/cdc-acm/cdc-acm.c
Normal file
110
cpu/arm/common/usb/cdc-acm/cdc-acm.c
Normal 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);
|
||||
}
|
7
cpu/arm/common/usb/cdc-acm/cdc-acm.h
Normal file
7
cpu/arm/common/usb/cdc-acm/cdc-acm.h
Normal 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__ */
|
214
cpu/arm/common/usb/cdc-acm/cdc.h
Normal file
214
cpu/arm/common/usb/cdc-acm/cdc.h
Normal 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__ */
|
Loading…
Reference in a new issue