summaryrefslogtreecommitdiffstats
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.tar.bz2
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 @@
#ifdef USB_SERIAL
+/* serial interface */
+struct usb_interface_descriptor __attribute__((aligned(2)))
+ interface_descriptor =
+{
+ .bLength = sizeof(struct usb_interface_descriptor),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = USB_CLASS_CDC_DATA,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0
+};
+
+struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
+{
+ .bLength = sizeof(struct usb_endpoint_descriptor),
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 0,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = 0,
+ .bInterval = 0
+};
+
#define BUFFER_SIZE 512 /* Max 16k because of controller limitations */
static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32)));
static unsigned char* send_buffer;
@@ -38,8 +63,66 @@ static int buffer_start;
static int buffer_length;
static bool active = false;
+static int usb_endpoint;
+static int usb_interface;
+
static struct mutex sendlock;
+static void sendout(void)
+{
+ if(buffer_start+buffer_length > BUFFER_SIZE)
+ {
+ /* Buffer wraps. Only send the first part */
+ usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start],
+ (BUFFER_SIZE - buffer_start));
+ }
+ else
+ {
+ /* Send everything */
+ usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start],
+ buffer_length);
+ }
+ busy_sending=true;
+}
+
+int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
+ int interface_number,int endpoint)
+{
+ endpoint_descriptor.wMaxPacketSize=max_packet_size;
+ interface_descriptor.bInterfaceNumber=interface_number;
+
+
+ memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
+ dest+=sizeof(struct usb_interface_descriptor);
+
+ endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
+ memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
+ dest+=sizeof(struct usb_endpoint_descriptor);
+
+ endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
+ memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
+ return sizeof(struct usb_interface_descriptor) +
+ 2 * sizeof(struct usb_endpoint_descriptor);
+}
+
+void usb_serial_init_connection(int interface,int endpoint)
+{
+ usb_interface = interface;
+ usb_endpoint = endpoint;
+
+ /* prime rx endpoint */
+ usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer);
+
+ /* we come here too after a bus reset, so reset some data */
+ mutex_lock(&sendlock);
+ busy_sending = false;
+ if(buffer_length>0)
+ {
+ sendout();
+ }
+ mutex_unlock(&sendlock);
+}
+
/* called by usb_code_init() */
void usb_serial_init(void)
{
@@ -53,26 +136,11 @@ void usb_serial_init(void)
mutex_init(&sendlock);
}
-void usb_serial_exit(void)
+void usb_serial_disconnect(void)
{
active = false;
}
-static void sendout(void)
-{
- if(buffer_start+buffer_length > BUFFER_SIZE)
- {
- /* Buffer wraps. Only send the first part */
- usb_drv_send_nonblocking(EP_SERIAL, &send_buffer[buffer_start],(BUFFER_SIZE - buffer_start));
- }
- else
- {
- /* Send everything */
- usb_drv_send_nonblocking(EP_SERIAL, &send_buffer[buffer_start],buffer_length);
- }
- busy_sending=true;
-}
-
void usb_serial_send(unsigned char *data,int length)
{
if(!active)
@@ -85,13 +153,14 @@ void usb_serial_send(unsigned char *data,int length)
/* current buffer wraps, so new data can't */
int available_space = BUFFER_SIZE - buffer_length;
length=MIN(length,available_space);
- memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE],data,length);
+ memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE],
+ data,length);
buffer_length+=length;
}
else
{
/* current buffer doesn't wrap, so new data might */
- int available_end_space = (BUFFER_SIZE - (buffer_start + buffer_length));
+ int available_end_space = (BUFFER_SIZE - (buffer_start+buffer_length));
int first_chunk = MIN(length,available_end_space);
memcpy(&send_buffer[buffer_start + buffer_length],data,first_chunk);
length-=first_chunk;
@@ -121,7 +190,7 @@ void usb_serial_transfer_complete(bool in, int status, int length)
case false:
logf("serial: %s", receive_buffer);
/* Data received. TODO : Do something with it ? */
- usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer);
+ usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer);
break;
case true:
@@ -148,26 +217,9 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req)
{
bool handled = false;
switch (req->bRequest) {
- case USB_REQ_SET_CONFIGURATION:
- logf("serial: set config");
- /* prime rx endpoint */
- usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer);
- handled = true;
-
- /* we come here too after a bus reset, so reset some data */
- mutex_lock(&sendlock);
- busy_sending = false;
- if(buffer_length>0)
- {
- sendout();
- }
- mutex_unlock(&sendlock);
- break;
-
default:
logf("serial: unhandeld req %d", req->bRequest);
}
-
return handled;
}