summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_serial.c
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-03-06 21:25:09 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-03-06 21:25:09 +0000
commitf0b4a32d6f983b1bece0b8cb2f2da1fdd23b012e (patch)
tree90f36c9f421c174d0385268ea47f0013b0c8cd8c /firmware/usbstack/usb_serial.c
parent5f83f0e4d2aaad77bda682cfd81a7ebb111a6024 (diff)
downloadrockbox-f0b4a32d6f983b1bece0b8cb2f2da1fdd23b012e.tar.gz
rockbox-f0b4a32d6f983b1bece0b8cb2f2da1fdd23b012e.zip
reorganise the usb stack to provide a clean separation between core and class drivers
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16541 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/usbstack/usb_serial.c')
-rw-r--r--firmware/usbstack/usb_serial.c124
1 files changed, 88 insertions, 36 deletions
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index 8c86932a31..55b76adc69 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -27,6 +27,31 @@
27 27
28#ifdef USB_SERIAL 28#ifdef USB_SERIAL
29 29
30/* serial interface */
31struct usb_interface_descriptor __attribute__((aligned(2)))
32 interface_descriptor =
33{
34 .bLength = sizeof(struct usb_interface_descriptor),
35 .bDescriptorType = USB_DT_INTERFACE,
36 .bInterfaceNumber = 0,
37 .bAlternateSetting = 0,
38 .bNumEndpoints = 2,
39 .bInterfaceClass = USB_CLASS_CDC_DATA,
40 .bInterfaceSubClass = 0,
41 .bInterfaceProtocol = 0,
42 .iInterface = 0
43};
44
45struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
46{
47 .bLength = sizeof(struct usb_endpoint_descriptor),
48 .bDescriptorType = USB_DT_ENDPOINT,
49 .bEndpointAddress = 0,
50 .bmAttributes = USB_ENDPOINT_XFER_BULK,
51 .wMaxPacketSize = 0,
52 .bInterval = 0
53};
54
30#define BUFFER_SIZE 512 /* Max 16k because of controller limitations */ 55#define BUFFER_SIZE 512 /* Max 16k because of controller limitations */
31static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32))); 56static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32)));
32static unsigned char* send_buffer; 57static unsigned char* send_buffer;
@@ -38,8 +63,66 @@ static int buffer_start;
38static int buffer_length; 63static int buffer_length;
39static bool active = false; 64static bool active = false;
40 65
66static int usb_endpoint;
67static int usb_interface;
68
41static struct mutex sendlock; 69static struct mutex sendlock;
42 70
71static void sendout(void)
72{
73 if(buffer_start+buffer_length > BUFFER_SIZE)
74 {
75 /* Buffer wraps. Only send the first part */
76 usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start],
77 (BUFFER_SIZE - buffer_start));
78 }
79 else
80 {
81 /* Send everything */
82 usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start],
83 buffer_length);
84 }
85 busy_sending=true;
86}
87
88int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
89 int interface_number,int endpoint)
90{
91 endpoint_descriptor.wMaxPacketSize=max_packet_size;
92 interface_descriptor.bInterfaceNumber=interface_number;
93
94
95 memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
96 dest+=sizeof(struct usb_interface_descriptor);
97
98 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
99 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
100 dest+=sizeof(struct usb_endpoint_descriptor);
101
102 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
103 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
104 return sizeof(struct usb_interface_descriptor) +
105 2 * sizeof(struct usb_endpoint_descriptor);
106}
107
108void usb_serial_init_connection(int interface,int endpoint)
109{
110 usb_interface = interface;
111 usb_endpoint = endpoint;
112
113 /* prime rx endpoint */
114 usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer);
115
116 /* we come here too after a bus reset, so reset some data */
117 mutex_lock(&sendlock);
118 busy_sending = false;
119 if(buffer_length>0)
120 {
121 sendout();
122 }
123 mutex_unlock(&sendlock);
124}
125
43/* called by usb_code_init() */ 126/* called by usb_code_init() */
44void usb_serial_init(void) 127void usb_serial_init(void)
45{ 128{
@@ -53,26 +136,11 @@ void usb_serial_init(void)
53 mutex_init(&sendlock); 136 mutex_init(&sendlock);
54} 137}
55 138
56void usb_serial_exit(void) 139void usb_serial_disconnect(void)
57{ 140{
58 active = false; 141 active = false;
59} 142}
60 143
61static void sendout(void)
62{
63 if(buffer_start+buffer_length > BUFFER_SIZE)
64 {
65 /* Buffer wraps. Only send the first part */
66 usb_drv_send_nonblocking(EP_SERIAL, &send_buffer[buffer_start],(BUFFER_SIZE - buffer_start));
67 }
68 else
69 {
70 /* Send everything */
71 usb_drv_send_nonblocking(EP_SERIAL, &send_buffer[buffer_start],buffer_length);
72 }
73 busy_sending=true;
74}
75
76void usb_serial_send(unsigned char *data,int length) 144void usb_serial_send(unsigned char *data,int length)
77{ 145{
78 if(!active) 146 if(!active)
@@ -85,13 +153,14 @@ void usb_serial_send(unsigned char *data,int length)
85 /* current buffer wraps, so new data can't */ 153 /* current buffer wraps, so new data can't */
86 int available_space = BUFFER_SIZE - buffer_length; 154 int available_space = BUFFER_SIZE - buffer_length;
87 length=MIN(length,available_space); 155 length=MIN(length,available_space);
88 memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE],data,length); 156 memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE],
157 data,length);
89 buffer_length+=length; 158 buffer_length+=length;
90 } 159 }
91 else 160 else
92 { 161 {
93 /* current buffer doesn't wrap, so new data might */ 162 /* current buffer doesn't wrap, so new data might */
94 int available_end_space = (BUFFER_SIZE - (buffer_start + buffer_length)); 163 int available_end_space = (BUFFER_SIZE - (buffer_start+buffer_length));
95 int first_chunk = MIN(length,available_end_space); 164 int first_chunk = MIN(length,available_end_space);
96 memcpy(&send_buffer[buffer_start + buffer_length],data,first_chunk); 165 memcpy(&send_buffer[buffer_start + buffer_length],data,first_chunk);
97 length-=first_chunk; 166 length-=first_chunk;
@@ -121,7 +190,7 @@ void usb_serial_transfer_complete(bool in, int status, int length)
121 case false: 190 case false:
122 logf("serial: %s", receive_buffer); 191 logf("serial: %s", receive_buffer);
123 /* Data received. TODO : Do something with it ? */ 192 /* Data received. TODO : Do something with it ? */
124 usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer); 193 usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer);
125 break; 194 break;
126 195
127 case true: 196 case true:
@@ -148,26 +217,9 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req)
148{ 217{
149 bool handled = false; 218 bool handled = false;
150 switch (req->bRequest) { 219 switch (req->bRequest) {
151 case USB_REQ_SET_CONFIGURATION:
152 logf("serial: set config");
153 /* prime rx endpoint */
154 usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer);
155 handled = true;
156
157 /* we come here too after a bus reset, so reset some data */
158 mutex_lock(&sendlock);
159 busy_sending = false;
160 if(buffer_length>0)
161 {
162 sendout();
163 }
164 mutex_unlock(&sendlock);
165 break;
166
167 default: 220 default:
168 logf("serial: unhandeld req %d", req->bRequest); 221 logf("serial: unhandeld req %d", req->bRequest);
169 } 222 }
170
171 return handled; 223 return handled;
172} 224}
173 225