diff --git a/apps/plugin.c b/apps/plugin.c
index b47dd95..dd470d5 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -790,6 +790,8 @@ static const struct plugin_api rockbox_api = {
system_sound_play,
keyclick_click,
#endif
+ usb_serial_send,
+ usb_serial_recv,
};
int plugin_load(const char* plugin, const void* parameter)
diff --git a/apps/plugin.h b/apps/plugin.h
index e9c0c64..de2d011 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -924,6 +924,8 @@ struct plugin_api {
void (*system_sound_play)(enum system_sound sound);
void (*keyclick_click)(int button);
#endif
+ void (*usb_serial_send)(const unsigned char *buf, int length);
+ int (*usb_serial_recv)(unsigned char *buf, int length);
};
/* plugin header */
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index e715909..be52e81 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -73,6 +73,10 @@ static bool active = false;
static int ep_in, ep_out;
static int usb_interface;
+struct semaphore recv_sema;
+struct mutex recv_mutex;
+int recv_len;
+
int usb_serial_request_endpoints(struct usb_class_driver *drv)
{
ep_in = usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK, USB_DIR_IN, drv);
@@ -128,8 +132,8 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req, unsigned char* dest
void usb_serial_init_connection(void)
{
- /* prime rx endpoint */
- usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer);
+ semaphore_init(&recv_sema, 1, 0);
+ mutex_init(&recv_mutex);
/* we come here too after a bus reset, so reset some data */
buffer_transitlength = 0;
@@ -218,11 +222,8 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length)
switch (dir) {
case USB_DIR_OUT:
- logf("serial: %s", receive_buffer);
- /* Data received. TODO : Do something with it ? */
-
- /* Get the next bit */
- usb_drv_recv(ep_out, receive_buffer, sizeof receive_buffer);
+ recv_len = status == 0 ? -1 : length;
+ semaphore_release(&recv_sema);
break;
case USB_DIR_IN:
@@ -240,3 +241,13 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length)
break;
}
}
+
+void usb_serial_recv(unsigned char *data, int length)
+{
+ mutex_lock(&recv_mutex);
+ usb_drv_recv(ep_out, data, length);
+ semaphore_wait(&recv_sema);
+ int len = recv_len;
+ mutex_unlock(&recv_mutex);
+ return len;
+}
diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h
index f1a603c..f664481 100644
--- a/firmware/usbstack/usb_serial.h
+++ b/firmware/usbstack/usb_serial.h
@@ -33,6 +33,7 @@ void usb_serial_transfer_complete(int ep,int dir, int status, int length);
bool usb_serial_control_request(struct usb_ctrlrequest* req, unsigned char *dest);
void usb_serial_send(const unsigned char *data, int length);
+int usb_serial_recv(unsigned char *data, int length); /* return length or -1 */
#endif