diff options
| author | Frank Gevaerts <frank@gevaerts.be> | 2008-03-02 20:45:33 +0000 |
|---|---|---|
| committer | Frank Gevaerts <frank@gevaerts.be> | 2008-03-02 20:45:33 +0000 |
| commit | 776d015cc492cb9c682bb1d223011b7a808011e8 (patch) | |
| tree | 61e3270b59b1442872779f0ea86ea237d6c92513 /firmware/usbstack | |
| parent | b3ab7884110b6e3849add5573d1f2a96c7603cd4 (diff) | |
| download | rockbox-776d015cc492cb9c682bb1d223011b7a808011e8.zip rockbox-776d015cc492cb9c682bb1d223011b7a808011e8.tar.gz rockbox-776d015cc492cb9c682bb1d223011b7a808011e8.tar.bz2 rockbox-776d015cc492cb9c682bb1d223011b7a808011e8.tar.xz | |
implement logf over usb-serial. Needs USB_SERIAL defined in usb_core.h to work, and needs to be enabled in the debug menu.
It stops sending data after a while for unknown reasons.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16486 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/usbstack')
| -rw-r--r-- | firmware/usbstack/usb_core.c | 14 | ||||
| -rw-r--r-- | firmware/usbstack/usb_serial.c | 119 | ||||
| -rw-r--r-- | firmware/usbstack/usb_serial.h | 3 |
3 files changed, 118 insertions, 18 deletions
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index 60a88e9..218b297 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c @@ -286,7 +286,8 @@ static bool initialized = false; static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; static bool usb_core_storage_enabled = false; -static bool usb_core_serial_enabled = false; +/* Next one is non-static, to enable setting it from the debug menu */ +bool usb_core_serial_enabled = false; static bool usb_core_charging_enabled = false; #if defined(USB_BENCHMARK) static bool usb_core_benchmark_enabled = false; @@ -405,6 +406,11 @@ void usb_core_init(void) void usb_core_exit(void) { +#ifdef USB_SERIAL + if(usb_core_serial_enabled) + usb_serial_exit(); +#endif + if (initialized) { usb_drv_exit(); } @@ -444,15 +450,21 @@ void usb_core_handle_transfer_completion(struct usb_transfer_completion_event_da void usb_core_enable_protocol(int driver,bool enabled) { switch(driver) { +#ifdef USB_STORAGE case USB_DRIVER_MASS_STORAGE: usb_core_storage_enabled = enabled; break; +#endif +#ifdef USB_SERIAL case USB_DRIVER_SERIAL: usb_core_serial_enabled = enabled; break; +#endif +#ifdef USB_CHARGING_ONLY case USB_DRIVER_CHARGING_ONLY: usb_core_charging_enabled = enabled; break; +#endif } } diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c index 7787809..5aca36b 100644 --- a/firmware/usbstack/usb_serial.c +++ b/firmware/usbstack/usb_serial.c @@ -16,46 +16,127 @@ * KIND, either express or implied. * ****************************************************************************/ +#include "string.h" #include "system.h" #include "usb_core.h" #include "usb_drv.h" +#include "kernel.h" //#define LOGF_ENABLE #include "logf.h" #ifdef USB_SERIAL -static unsigned char _transfer_buffer[16]; -static unsigned char* transfer_buffer; +#define BUFFER_SIZE 16384 /* No larger, because of controller limitations */ +static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32))); +static unsigned char* send_buffer; + +static unsigned char _receive_buffer[512] __attribute__((aligned(32))); +static unsigned char* receive_buffer; +static bool busy_sending = false; +static int buffer_start; +static int buffer_length; +static bool active = false; + +static struct mutex sendlock; /* called by usb_code_init() */ void usb_serial_init(void) { logf("serial: init"); - transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer); + send_buffer = (void*)UNCACHED_ADDR(&_send_buffer); + receive_buffer = (void*)UNCACHED_ADDR(&_receive_buffer); + busy_sending = false; + buffer_start = 0; + buffer_length = 0; + active = true; + mutex_init(&sendlock); +} + +void usb_serial_exit(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) + return; + mutex_lock(&sendlock); + if(buffer_start+buffer_length > BUFFER_SIZE) + { + /* 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,MIN(length,available_space)); + buffer_length+=length; + } + else + { + /* current buffer doesn't wrap, so new data might */ + 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; + buffer_length+=first_chunk; + if(length>0) + { + /* wrap */ + memcpy(&send_buffer[0],&data[first_chunk],MIN(length,buffer_start)); + buffer_length+=MIN(length,buffer_start); + } + } + if(busy_sending) + { + /* Do nothing. The transfer completion handler will pick it up */ + } + else + { + sendout(); + } + mutex_unlock(&sendlock); } /* called by usb_core_transfer_complete() */ void usb_serial_transfer_complete(bool in, int status, int length) { - int i; switch (in) { case false: - logf("serial: %s", transfer_buffer); - /* Data received. Send it back */ - for(i=0;i<length;i++) { - if(transfer_buffer[i]>0x40 && transfer_buffer[i]<0x5b) - transfer_buffer[i]+=0x20; - else if(transfer_buffer[i]>0x60 && transfer_buffer[i]<0x7b) - transfer_buffer[i]-=0x20; - } - usb_drv_send_nonblocking(EP_SERIAL, transfer_buffer, length); + logf("serial: %s", receive_buffer); + /* Data received. TODO : Do something with it ? */ + usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer); break; case true: - /* Data sent out (maybe correctly, but we don't actually care. - * Re-prime read endpoint */ - usb_drv_recv(EP_SERIAL, transfer_buffer, sizeof _transfer_buffer); + mutex_lock(&sendlock); + /* Data sent out. Update circular buffer */ + if(status == 0) + { + buffer_start = (buffer_start + length)%BUFFER_SIZE; + buffer_length -= length; + } + busy_sending = false; + + if(buffer_length!=0) + { + sendout(); + } + mutex_unlock(&sendlock); break; } } @@ -68,8 +149,12 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req) case USB_REQ_SET_CONFIGURATION: logf("serial: set config"); /* prime rx endpoint */ - usb_drv_recv(EP_SERIAL, transfer_buffer, sizeof _transfer_buffer); + usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer); handled = true; + + /* we come here too after a bus reset, so reset some data */ + busy_sending = false; + sendout(); break; default: diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h index 60cede9..bcb0648 100644 --- a/firmware/usbstack/usb_serial.h +++ b/firmware/usbstack/usb_serial.h @@ -22,8 +22,11 @@ #include "usb_ch9.h" void usb_serial_init(void); +void usb_serial_exit(void); void usb_serial_transfer_complete(bool in, int status, int length); bool usb_serial_control_request(struct usb_ctrlrequest* req); +void usb_serial_send(unsigned char *data,int length); + #endif |