1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 by Christian Gmeiner
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
26 #include "usb_serial.h"
33 /* serial interface */
34 static struct usb_interface_descriptor
__attribute__((aligned(2)))
35 interface_descriptor
=
37 .bLength
= sizeof(struct usb_interface_descriptor
),
38 .bDescriptorType
= USB_DT_INTERFACE
,
39 .bInterfaceNumber
= 0,
40 .bAlternateSetting
= 0,
42 .bInterfaceClass
= USB_CLASS_CDC_DATA
,
43 .bInterfaceSubClass
= 0,
44 .bInterfaceProtocol
= 0,
49 static struct usb_endpoint_descriptor
__attribute__((aligned(2))) endpoint_descriptor
=
51 .bLength
= sizeof(struct usb_endpoint_descriptor
),
52 .bDescriptorType
= USB_DT_ENDPOINT
,
53 .bEndpointAddress
= 0,
54 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
59 #define BUFFER_SIZE 512
60 static unsigned char send_buffer
[BUFFER_SIZE
]
61 USB_DEVBSS_ATTR
__attribute__((aligned(32)));
62 static unsigned char receive_buffer
[32]
63 USB_DEVBSS_ATTR
__attribute__((aligned(32)));
65 static void sendout(void);
67 static int buffer_start
;
68 /* The number of bytes to transfer that haven't been given to the USB stack yet */
69 static int buffer_length
;
70 /* The number of bytes to transfer that have been given to the USB stack */
71 static int buffer_transitlength
;
72 static bool active
= false;
74 static int ep_in
, ep_out
;
75 static int usb_interface
;
77 int usb_serial_request_endpoints(struct usb_class_driver
*drv
)
79 ep_in
= usb_core_request_endpoint(USB_DIR_IN
, drv
);
84 ep_out
= usb_core_request_endpoint(USB_DIR_OUT
, drv
);
87 usb_core_release_endpoint(ep_in
);
94 int usb_serial_set_first_interface(int interface
)
96 usb_interface
= interface
;
101 int usb_serial_get_config_descriptor(unsigned char *dest
,int max_packet_size
)
103 unsigned char *orig_dest
= dest
;
105 endpoint_descriptor
.wMaxPacketSize
=max_packet_size
;
106 interface_descriptor
.bInterfaceNumber
=usb_interface
;
108 memcpy(dest
,&interface_descriptor
,sizeof(struct usb_interface_descriptor
));
109 dest
+=sizeof(struct usb_interface_descriptor
);
111 endpoint_descriptor
.bEndpointAddress
= ep_in
;
112 memcpy(dest
,&endpoint_descriptor
,sizeof(struct usb_endpoint_descriptor
));
113 dest
+=sizeof(struct usb_endpoint_descriptor
);
115 endpoint_descriptor
.bEndpointAddress
= ep_out
;
116 memcpy(dest
,&endpoint_descriptor
,sizeof(struct usb_endpoint_descriptor
));
117 dest
+=sizeof(struct usb_endpoint_descriptor
);
119 return (dest
- orig_dest
);
122 /* called by usb_core_control_request() */
123 bool usb_serial_control_request(struct usb_ctrlrequest
* req
)
125 bool handled
= false;
126 switch (req
->bRequest
) {
128 logf("serial: unhandeld req %d", req
->bRequest
);
133 void usb_serial_init_connection(void)
135 /* prime rx endpoint */
136 usb_drv_recv(ep_out
, receive_buffer
, sizeof receive_buffer
);
138 /* we come here too after a bus reset, so reset some data */
139 buffer_transitlength
= 0;
147 /* called by usb_code_init() */
148 void usb_serial_init(void)
150 logf("serial: init");
153 buffer_transitlength
= 0;
157 void usb_serial_disconnect(void)
162 static void sendout(void)
164 if(buffer_start
+buffer_length
>= BUFFER_SIZE
)
166 /* Buffer wraps. Only send the first part */
167 buffer_transitlength
=BUFFER_SIZE
- buffer_start
;
171 /* Send everything */
172 buffer_transitlength
=buffer_length
;
174 if(buffer_transitlength
>0)
176 buffer_length
-=buffer_transitlength
;
177 usb_drv_send_nonblocking(ep_in
, &send_buffer
[buffer_start
],
178 buffer_transitlength
);
182 void usb_serial_send(unsigned char *data
,int length
)
188 int freestart
=(buffer_start
+buffer_length
+buffer_transitlength
)%BUFFER_SIZE
;
189 if(buffer_start
+buffer_transitlength
+buffer_length
>= BUFFER_SIZE
)
191 /* current buffer wraps, so new data can't */
192 int available_space
= BUFFER_SIZE
- buffer_length
- buffer_transitlength
;
193 length
=MIN(length
,available_space
);
194 memcpy(&send_buffer
[freestart
],
196 buffer_length
+=length
;
200 /* current buffer doesn't wrap, so new data might */
201 int available_end_space
= (BUFFER_SIZE
- (buffer_start
+buffer_length
+buffer_transitlength
));
202 int first_chunk
= MIN(length
,available_end_space
);
203 memcpy(&send_buffer
[freestart
],data
,first_chunk
);
205 buffer_length
+=first_chunk
;
209 memcpy(&send_buffer
[0],&data
[first_chunk
],MIN(length
,buffer_start
));
210 buffer_length
+=MIN(length
,buffer_start
);
213 if(buffer_transitlength
>0)
215 /* Do nothing. The transfer completion handler will pick it up */
223 /* called by usb_core_transfer_complete() */
224 void usb_serial_transfer_complete(int ep
,int dir
, int status
, int length
)
229 logf("serial: %s", receive_buffer
);
230 /* Data received. TODO : Do something with it ? */
232 /* Get the next bit */
233 usb_drv_recv(ep_out
, receive_buffer
, sizeof receive_buffer
);
237 /* Data sent out. Update circular buffer */
240 if(length
!=buffer_transitlength
)
244 buffer_start
= (buffer_start
+ buffer_transitlength
)%BUFFER_SIZE
;
245 buffer_transitlength
= 0;
257 #endif /*USB_SERIAL*/