diff options
Diffstat (limited to 'firmware/usbstack/usb_serial.c')
-rw-r--r-- | firmware/usbstack/usb_serial.c | 124 |
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 */ | ||
31 | struct 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 | |||
45 | struct 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 */ |
31 | static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32))); | 56 | static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32))); |
32 | static unsigned char* send_buffer; | 57 | static unsigned char* send_buffer; |
@@ -38,8 +63,66 @@ static int buffer_start; | |||
38 | static int buffer_length; | 63 | static int buffer_length; |
39 | static bool active = false; | 64 | static bool active = false; |
40 | 65 | ||
66 | static int usb_endpoint; | ||
67 | static int usb_interface; | ||
68 | |||
41 | static struct mutex sendlock; | 69 | static struct mutex sendlock; |
42 | 70 | ||
71 | static 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 | |||
88 | int 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 | |||
108 | void 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() */ |
44 | void usb_serial_init(void) | 127 | void 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 | ||
56 | void usb_serial_exit(void) | 139 | void usb_serial_disconnect(void) |
57 | { | 140 | { |
58 | active = false; | 141 | active = false; |
59 | } | 142 | } |
60 | 143 | ||
61 | static 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 | |||
76 | void usb_serial_send(unsigned char *data,int length) | 144 | void 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 | ||