summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usbstack/usb_serial.c')
-rw-r--r--firmware/usbstack/usb_serial.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index d091ef3fc6..08cc6f1d28 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -56,7 +56,7 @@ static struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descr
56 .bInterval = 0 56 .bInterval = 0
57}; 57};
58 58
59#define BUFFER_SIZE 512 59#define BUFFER_SIZE 150
60#if CONFIG_CPU == IMX31L 60#if CONFIG_CPU == IMX31L
61static unsigned char send_buffer[BUFFER_SIZE] 61static unsigned char send_buffer[BUFFER_SIZE]
62 USBDEVBSS_ATTR __attribute__((aligned(32))); 62 USBDEVBSS_ATTR __attribute__((aligned(32)));
@@ -69,7 +69,8 @@ static unsigned char receive_buffer[32]
69 USB_DEVBSS_ATTR __attribute__((aligned(32))); 69 USB_DEVBSS_ATTR __attribute__((aligned(32)));
70#endif 70#endif
71 71
72static bool busy_sending = false; 72static void sendout(void);
73
73static int buffer_start; 74static int buffer_start;
74/* The number of bytes to transfer that haven't been given to the USB stack yet */ 75/* The number of bytes to transfer that haven't been given to the USB stack yet */
75static int buffer_length; 76static int buffer_length;
@@ -80,8 +81,6 @@ static bool active = false;
80static int ep_in, ep_out; 81static int ep_in, ep_out;
81static int usb_interface; 82static int usb_interface;
82 83
83static struct mutex sendlock SHAREDBSS_ATTR;
84
85int usb_serial_request_endpoints(struct usb_class_driver *drv) 84int usb_serial_request_endpoints(struct usb_class_driver *drv)
86{ 85{
87 ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); 86 ep_in = usb_core_request_endpoint(USB_DIR_IN, drv);
@@ -144,26 +143,22 @@ void usb_serial_init_connection(void)
144 usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer); 143 usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer);
145 144
146 /* we come here too after a bus reset, so reset some data */ 145 /* we come here too after a bus reset, so reset some data */
147 mutex_lock(&sendlock); 146 buffer_transitlength = 0;
148 busy_sending = false;
149 if(buffer_length>0) 147 if(buffer_length>0)
150 { 148 {
151 sendout(); 149 sendout();
152 } 150 }
153 active=true; 151 active=true;
154 mutex_unlock(&sendlock);
155} 152}
156 153
157/* called by usb_code_init() */ 154/* called by usb_code_init() */
158void usb_serial_init(void) 155void usb_serial_init(void)
159{ 156{
160 logf("serial: init"); 157 logf("serial: init");
161 busy_sending = false;
162 buffer_start = 0; 158 buffer_start = 0;
163 buffer_length = 0; 159 buffer_length = 0;
164 buffer_transit_length = 0; 160 buffer_transitlength = 0;
165 active = true; 161 active = true;
166 mutex_init(&sendlock);
167} 162}
168 163
169void usb_serial_disconnect(void) 164void usb_serial_disconnect(void)
@@ -173,7 +168,7 @@ void usb_serial_disconnect(void)
173 168
174static void sendout(void) 169static void sendout(void)
175{ 170{
176 if(buffer_start+buffer_length > BUFFER_SIZE) 171 if(buffer_start+buffer_length >= BUFFER_SIZE)
177 { 172 {
178 /* Buffer wraps. Only send the first part */ 173 /* Buffer wraps. Only send the first part */
179 buffer_transitlength=BUFFER_SIZE - buffer_start; 174 buffer_transitlength=BUFFER_SIZE - buffer_start;
@@ -183,10 +178,12 @@ static void sendout(void)
183 /* Send everything */ 178 /* Send everything */
184 buffer_transitlength=buffer_length; 179 buffer_transitlength=buffer_length;
185 } 180 }
186 usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], 181 if(buffer_transitlength>0)
187 buffer_transitlength); 182 {
188 buffer_length-=buffer_transitlength; 183 buffer_length-=buffer_transitlength;
189 busy_sending=true; 184 usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start],
185 buffer_transitlength);
186 }
190} 187}
191 188
192void usb_serial_send(unsigned char *data,int length) 189void usb_serial_send(unsigned char *data,int length)
@@ -195,9 +192,8 @@ void usb_serial_send(unsigned char *data,int length)
195 return; 192 return;
196 if(length<=0) 193 if(length<=0)
197 return; 194 return;
198 mutex_lock(&sendlock);
199 int freestart=(buffer_start+buffer_length+buffer_transitlength)%BUFFER_SIZE; 195 int freestart=(buffer_start+buffer_length+buffer_transitlength)%BUFFER_SIZE;
200 if(buffer_start+buffer_transit_length+buffer_length > BUFFER_SIZE) 196 if(buffer_start+buffer_transitlength+buffer_length >= BUFFER_SIZE)
201 { 197 {
202 /* current buffer wraps, so new data can't */ 198 /* current buffer wraps, so new data can't */
203 int available_space = BUFFER_SIZE - buffer_length - buffer_transitlength; 199 int available_space = BUFFER_SIZE - buffer_length - buffer_transitlength;
@@ -209,7 +205,7 @@ void usb_serial_send(unsigned char *data,int length)
209 else 205 else
210 { 206 {
211 /* current buffer doesn't wrap, so new data might */ 207 /* current buffer doesn't wrap, so new data might */
212 int available_end_space = (BUFFER_SIZE - (buffer_start+buffer_length+buffer_transit_length)); 208 int available_end_space = (BUFFER_SIZE - (buffer_start+buffer_length+buffer_transitlength));
213 int first_chunk = MIN(length,available_end_space); 209 int first_chunk = MIN(length,available_end_space);
214 memcpy(&send_buffer[freestart],data,first_chunk); 210 memcpy(&send_buffer[freestart],data,first_chunk);
215 length-=first_chunk; 211 length-=first_chunk;
@@ -221,7 +217,7 @@ void usb_serial_send(unsigned char *data,int length)
221 buffer_length+=MIN(length,buffer_start); 217 buffer_length+=MIN(length,buffer_start);
222 } 218 }
223 } 219 }
224 if(busy_sending) 220 if(buffer_transitlength>0)
225 { 221 {
226 /* Do nothing. The transfer completion handler will pick it up */ 222 /* Do nothing. The transfer completion handler will pick it up */
227 } 223 }
@@ -229,7 +225,6 @@ void usb_serial_send(unsigned char *data,int length)
229 { 225 {
230 sendout(); 226 sendout();
231 } 227 }
232 mutex_unlock(&sendlock);
233} 228}
234 229
235/* called by usb_core_transfer_complete() */ 230/* called by usb_core_transfer_complete() */
@@ -246,20 +241,21 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length)
246 break; 241 break;
247 242
248 case USB_DIR_IN: 243 case USB_DIR_IN:
249 mutex_lock(&sendlock);
250 /* Data sent out. Update circular buffer */ 244 /* Data sent out. Update circular buffer */
251 if(status == 0) 245 if(status == 0)
252 { 246 {
253 buffer_start = (buffer_start + length)%BUFFER_SIZE; 247 if(length!=buffer_transitlength)
254 buffer_transitlength -= length; 248 {
249 /* do something? */
250 }
251 buffer_start = (buffer_start + buffer_transitlength)%BUFFER_SIZE;
252 buffer_transitlength = 0;
255 } 253 }
256 busy_sending = false;
257 254
258 if(buffer_length>0) 255 if(buffer_length>0)
259 { 256 {
260 sendout(); 257 sendout();
261 } 258 }
262 mutex_unlock(&sendlock);
263 break; 259 break;
264 } 260 }
265} 261}