diff options
-rw-r--r-- | firmware/usbstack/usb_serial.c | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c index febd052057..d091ef3fc6 100644 --- a/firmware/usbstack/usb_serial.c +++ b/firmware/usbstack/usb_serial.c | |||
@@ -71,7 +71,10 @@ static unsigned char receive_buffer[32] | |||
71 | 71 | ||
72 | static bool busy_sending = false; | 72 | static bool busy_sending = false; |
73 | static int buffer_start; | 73 | static int buffer_start; |
74 | /* The number of bytes to transfer that haven't been given to the USB stack yet */ | ||
74 | static int buffer_length; | 75 | static int buffer_length; |
76 | /* The number of bytes to transfer that have been given to the USB stack */ | ||
77 | static int buffer_transitlength; | ||
75 | static bool active = false; | 78 | static bool active = false; |
76 | 79 | ||
77 | static int ep_in, ep_out; | 80 | static int ep_in, ep_out; |
@@ -79,23 +82,6 @@ static int usb_interface; | |||
79 | 82 | ||
80 | static struct mutex sendlock SHAREDBSS_ATTR; | 83 | static struct mutex sendlock SHAREDBSS_ATTR; |
81 | 84 | ||
82 | static void sendout(void) | ||
83 | { | ||
84 | if(buffer_start+buffer_length > BUFFER_SIZE) | ||
85 | { | ||
86 | /* Buffer wraps. Only send the first part */ | ||
87 | usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], | ||
88 | (BUFFER_SIZE - buffer_start)); | ||
89 | } | ||
90 | else | ||
91 | { | ||
92 | /* Send everything */ | ||
93 | usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], | ||
94 | buffer_length); | ||
95 | } | ||
96 | busy_sending=true; | ||
97 | } | ||
98 | |||
99 | int usb_serial_request_endpoints(struct usb_class_driver *drv) | 85 | int usb_serial_request_endpoints(struct usb_class_driver *drv) |
100 | { | 86 | { |
101 | ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); | 87 | ep_in = usb_core_request_endpoint(USB_DIR_IN, drv); |
@@ -141,6 +127,17 @@ int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size) | |||
141 | return (dest - orig_dest); | 127 | return (dest - orig_dest); |
142 | } | 128 | } |
143 | 129 | ||
130 | /* called by usb_core_control_request() */ | ||
131 | bool usb_serial_control_request(struct usb_ctrlrequest* req) | ||
132 | { | ||
133 | bool handled = false; | ||
134 | switch (req->bRequest) { | ||
135 | default: | ||
136 | logf("serial: unhandeld req %d", req->bRequest); | ||
137 | } | ||
138 | return handled; | ||
139 | } | ||
140 | |||
144 | void usb_serial_init_connection(void) | 141 | void usb_serial_init_connection(void) |
145 | { | 142 | { |
146 | /* prime rx endpoint */ | 143 | /* prime rx endpoint */ |
@@ -164,6 +161,7 @@ void usb_serial_init(void) | |||
164 | busy_sending = false; | 161 | busy_sending = false; |
165 | buffer_start = 0; | 162 | buffer_start = 0; |
166 | buffer_length = 0; | 163 | buffer_length = 0; |
164 | buffer_transit_length = 0; | ||
167 | active = true; | 165 | active = true; |
168 | mutex_init(&sendlock); | 166 | mutex_init(&sendlock); |
169 | } | 167 | } |
@@ -173,6 +171,24 @@ void usb_serial_disconnect(void) | |||
173 | active = false; | 171 | active = false; |
174 | } | 172 | } |
175 | 173 | ||
174 | static void sendout(void) | ||
175 | { | ||
176 | if(buffer_start+buffer_length > BUFFER_SIZE) | ||
177 | { | ||
178 | /* Buffer wraps. Only send the first part */ | ||
179 | buffer_transitlength=BUFFER_SIZE - buffer_start; | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | /* Send everything */ | ||
184 | buffer_transitlength=buffer_length; | ||
185 | } | ||
186 | usb_drv_send_nonblocking(ep_in, &send_buffer[buffer_start], | ||
187 | buffer_transitlength); | ||
188 | buffer_length-=buffer_transitlength; | ||
189 | busy_sending=true; | ||
190 | } | ||
191 | |||
176 | void usb_serial_send(unsigned char *data,int length) | 192 | void usb_serial_send(unsigned char *data,int length) |
177 | { | 193 | { |
178 | if(!active) | 194 | if(!active) |
@@ -180,21 +196,22 @@ void usb_serial_send(unsigned char *data,int length) | |||
180 | if(length<=0) | 196 | if(length<=0) |
181 | return; | 197 | return; |
182 | mutex_lock(&sendlock); | 198 | mutex_lock(&sendlock); |
183 | if(buffer_start+buffer_length > BUFFER_SIZE) | 199 | int freestart=(buffer_start+buffer_length+buffer_transitlength)%BUFFER_SIZE; |
200 | if(buffer_start+buffer_transit_length+buffer_length > BUFFER_SIZE) | ||
184 | { | 201 | { |
185 | /* current buffer wraps, so new data can't */ | 202 | /* current buffer wraps, so new data can't */ |
186 | int available_space = BUFFER_SIZE - buffer_length; | 203 | int available_space = BUFFER_SIZE - buffer_length - buffer_transitlength; |
187 | length=MIN(length,available_space); | 204 | length=MIN(length,available_space); |
188 | memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE], | 205 | memcpy(&send_buffer[freestart], |
189 | data,length); | 206 | data,length); |
190 | buffer_length+=length; | 207 | buffer_length+=length; |
191 | } | 208 | } |
192 | else | 209 | else |
193 | { | 210 | { |
194 | /* current buffer doesn't wrap, so new data might */ | 211 | /* current buffer doesn't wrap, so new data might */ |
195 | int available_end_space = (BUFFER_SIZE - (buffer_start+buffer_length)); | 212 | int available_end_space = (BUFFER_SIZE - (buffer_start+buffer_length+buffer_transit_length)); |
196 | int first_chunk = MIN(length,available_end_space); | 213 | int first_chunk = MIN(length,available_end_space); |
197 | memcpy(&send_buffer[buffer_start + buffer_length],data,first_chunk); | 214 | memcpy(&send_buffer[freestart],data,first_chunk); |
198 | length-=first_chunk; | 215 | length-=first_chunk; |
199 | buffer_length+=first_chunk; | 216 | buffer_length+=first_chunk; |
200 | if(length>0) | 217 | if(length>0) |
@@ -223,6 +240,8 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length) | |||
223 | case USB_DIR_OUT: | 240 | case USB_DIR_OUT: |
224 | logf("serial: %s", receive_buffer); | 241 | logf("serial: %s", receive_buffer); |
225 | /* Data received. TODO : Do something with it ? */ | 242 | /* Data received. TODO : Do something with it ? */ |
243 | |||
244 | /* Get the next bit */ | ||
226 | usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer); | 245 | usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer); |
227 | break; | 246 | break; |
228 | 247 | ||
@@ -232,7 +251,7 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length) | |||
232 | if(status == 0) | 251 | if(status == 0) |
233 | { | 252 | { |
234 | buffer_start = (buffer_start + length)%BUFFER_SIZE; | 253 | buffer_start = (buffer_start + length)%BUFFER_SIZE; |
235 | buffer_length -= length; | 254 | buffer_transitlength -= length; |
236 | } | 255 | } |
237 | busy_sending = false; | 256 | busy_sending = false; |
238 | 257 | ||
@@ -245,15 +264,5 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length) | |||
245 | } | 264 | } |
246 | } | 265 | } |
247 | 266 | ||
248 | /* called by usb_core_control_request() */ | ||
249 | bool usb_serial_control_request(struct usb_ctrlrequest* req) | ||
250 | { | ||
251 | bool handled = false; | ||
252 | switch (req->bRequest) { | ||
253 | default: | ||
254 | logf("serial: unhandeld req %d", req->bRequest); | ||
255 | } | ||
256 | return handled; | ||
257 | } | ||
258 | 267 | ||
259 | #endif /*USB_SERIAL*/ | 268 | #endif /*USB_SERIAL*/ |