summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-03-02 20:45:33 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-03-02 20:45:33 +0000
commit776d015cc492cb9c682bb1d223011b7a808011e8 (patch)
tree61e3270b59b1442872779f0ea86ea237d6c92513
parentb3ab7884110b6e3849add5573d1f2a96c7603cd4 (diff)
downloadrockbox-776d015cc492cb9c682bb1d223011b7a808011e8.tar.gz
rockbox-776d015cc492cb9c682bb1d223011b7a808011e8.zip
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
-rw-r--r--apps/debug_menu.c15
-rw-r--r--firmware/logf.c10
-rw-r--r--firmware/usb.c2
-rw-r--r--firmware/usbstack/usb_core.c14
-rw-r--r--firmware/usbstack/usb_serial.c119
-rw-r--r--firmware/usbstack/usb_serial.h3
6 files changed, 143 insertions, 20 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index bb9a00c57b..f448d30b3c 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -2357,6 +2357,18 @@ static bool dbg_scrollwheel(void)
2357} 2357}
2358#endif 2358#endif
2359 2359
2360#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF)
2361extern bool usb_core_serial_enabled;
2362
2363static bool logf_usb_serial(void)
2364{
2365 usb_core_serial_enabled = !usb_core_serial_enabled;
2366 gui_syncsplash(HZ, "USB logf %s",
2367 usb_core_serial_enabled?"enabled":"disabled");
2368 return false;
2369}
2370#endif
2371
2360 2372
2361/****** The menu *********/ 2373/****** The menu *********/
2362struct the_menu_item { 2374struct the_menu_item {
@@ -2436,6 +2448,9 @@ static const struct the_menu_item menuitems[] = {
2436 {"logf", logfdisplay }, 2448 {"logf", logfdisplay },
2437 {"logfdump", logfdump }, 2449 {"logfdump", logfdump },
2438#endif 2450#endif
2451#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF)
2452 {"logf over usb",logf_usb_serial },
2453#endif
2439#ifdef CPU_BOOST_LOGGING 2454#ifdef CPU_BOOST_LOGGING
2440 {"cpu_boost log",cpu_boost_log}, 2455 {"cpu_boost log",cpu_boost_log},
2441#endif 2456#endif
diff --git a/firmware/logf.c b/firmware/logf.c
index 2056db5cc4..da05a0a0c7 100644
--- a/firmware/logf.c
+++ b/firmware/logf.c
@@ -32,6 +32,11 @@
32#include "logf.h" 32#include "logf.h"
33#include "serial.h" 33#include "serial.h"
34 34
35#ifdef HAVE_USBSTACK
36#include "usb_core.h"
37#include "usbstack/usb_serial.h"
38#endif
39
35/* Only provide all this if asked to */ 40/* Only provide all this if asked to */
36#ifdef ROCKBOX_HAS_LOGF 41#ifdef ROCKBOX_HAS_LOGF
37 42
@@ -107,6 +112,11 @@ void _logf(const char *format, ...)
107 serial_tx(ptr); 112 serial_tx(ptr);
108 serial_tx("\r\n"); 113 serial_tx("\r\n");
109#endif 114#endif
115#ifdef USB_SERIAL
116 usb_serial_send(ptr,len);
117 usb_serial_send("\r\n",2);
118#endif
119
110 va_end(ap); 120 va_end(ap);
111 if(len < MAX_LOGF_ENTRY) 121 if(len < MAX_LOGF_ENTRY)
112 /* pad with spaces up to the MAX_LOGF_ENTRY byte border */ 122 /* pad with spaces up to the MAX_LOGF_ENTRY byte border */
diff --git a/firmware/usb.c b/firmware/usb.c
index 5f6cffd5b2..529ecb773b 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -192,7 +192,6 @@ static void usb_thread(void)
192 usb_state = USB_POWERED; 192 usb_state = USB_POWERED;
193#ifdef HAVE_USBSTACK 193#ifdef HAVE_USBSTACK
194 usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,false); 194 usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,false);
195 usb_core_enable_protocol(USB_DRIVER_SERIAL,false);/* TODO: add debug setting */
196 usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,true); 195 usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,true);
197 usb_enable(true); 196 usb_enable(true);
198#endif 197#endif
@@ -202,7 +201,6 @@ static void usb_thread(void)
202 { 201 {
203#ifdef HAVE_USBSTACK 202#ifdef HAVE_USBSTACK
204 usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,true); 203 usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,true);
205 usb_core_enable_protocol(USB_DRIVER_SERIAL,false);/* TODO: add debug setting */
206 usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,false); 204 usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,false);
207 usb_enable(true); 205 usb_enable(true);
208#else 206#else
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 60a88e9490..218b297455 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -286,7 +286,8 @@ static bool initialized = false;
286static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; 286static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
287 287
288static bool usb_core_storage_enabled = false; 288static bool usb_core_storage_enabled = false;
289static bool usb_core_serial_enabled = false; 289/* Next one is non-static, to enable setting it from the debug menu */
290bool usb_core_serial_enabled = false;
290static bool usb_core_charging_enabled = false; 291static bool usb_core_charging_enabled = false;
291#if defined(USB_BENCHMARK) 292#if defined(USB_BENCHMARK)
292static bool usb_core_benchmark_enabled = false; 293static bool usb_core_benchmark_enabled = false;
@@ -405,6 +406,11 @@ void usb_core_init(void)
405 406
406void usb_core_exit(void) 407void usb_core_exit(void)
407{ 408{
409#ifdef USB_SERIAL
410 if(usb_core_serial_enabled)
411 usb_serial_exit();
412#endif
413
408 if (initialized) { 414 if (initialized) {
409 usb_drv_exit(); 415 usb_drv_exit();
410 } 416 }
@@ -444,15 +450,21 @@ void usb_core_handle_transfer_completion(struct usb_transfer_completion_event_da
444void usb_core_enable_protocol(int driver,bool enabled) 450void usb_core_enable_protocol(int driver,bool enabled)
445{ 451{
446 switch(driver) { 452 switch(driver) {
453#ifdef USB_STORAGE
447 case USB_DRIVER_MASS_STORAGE: 454 case USB_DRIVER_MASS_STORAGE:
448 usb_core_storage_enabled = enabled; 455 usb_core_storage_enabled = enabled;
449 break; 456 break;
457#endif
458#ifdef USB_SERIAL
450 case USB_DRIVER_SERIAL: 459 case USB_DRIVER_SERIAL:
451 usb_core_serial_enabled = enabled; 460 usb_core_serial_enabled = enabled;
452 break; 461 break;
462#endif
463#ifdef USB_CHARGING_ONLY
453 case USB_DRIVER_CHARGING_ONLY: 464 case USB_DRIVER_CHARGING_ONLY:
454 usb_core_charging_enabled = enabled; 465 usb_core_charging_enabled = enabled;
455 break; 466 break;
467#endif
456 } 468 }
457} 469}
458 470
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index 77878092d7..5aca36b59a 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -16,46 +16,127 @@
16 * KIND, either express or implied. 16 * KIND, either express or implied.
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#include "string.h"
19#include "system.h" 20#include "system.h"
20#include "usb_core.h" 21#include "usb_core.h"
21#include "usb_drv.h" 22#include "usb_drv.h"
23#include "kernel.h"
22 24
23//#define LOGF_ENABLE 25//#define LOGF_ENABLE
24#include "logf.h" 26#include "logf.h"
25 27
26#ifdef USB_SERIAL 28#ifdef USB_SERIAL
27 29
28static unsigned char _transfer_buffer[16]; 30#define BUFFER_SIZE 16384 /* No larger, because of controller limitations */
29static unsigned char* transfer_buffer; 31static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32)));
32static unsigned char* send_buffer;
33
34static unsigned char _receive_buffer[512] __attribute__((aligned(32)));
35static unsigned char* receive_buffer;
36static bool busy_sending = false;
37static int buffer_start;
38static int buffer_length;
39static bool active = false;
40
41static struct mutex sendlock;
30 42
31/* called by usb_code_init() */ 43/* called by usb_code_init() */
32void usb_serial_init(void) 44void usb_serial_init(void)
33{ 45{
34 logf("serial: init"); 46 logf("serial: init");
35 transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer); 47 send_buffer = (void*)UNCACHED_ADDR(&_send_buffer);
48 receive_buffer = (void*)UNCACHED_ADDR(&_receive_buffer);
49 busy_sending = false;
50 buffer_start = 0;
51 buffer_length = 0;
52 active = true;
53 mutex_init(&sendlock);
54}
55
56void usb_serial_exit(void)
57{
58 active = false;
59}
60
61static 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
76void usb_serial_send(unsigned char *data,int length)
77{
78 if(!active)
79 return;
80 mutex_lock(&sendlock);
81 if(buffer_start+buffer_length > BUFFER_SIZE)
82 {
83 /* current buffer wraps, so new data can't */
84 int available_space = BUFFER_SIZE - buffer_length;
85 length=MIN(length,available_space);
86 memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE],data,MIN(length,available_space));
87 buffer_length+=length;
88 }
89 else
90 {
91 /* current buffer doesn't wrap, so new data might */
92 int available_end_space = (BUFFER_SIZE - (buffer_start + buffer_length));
93 int first_chunk = MIN(length,available_end_space);
94 memcpy(&send_buffer[buffer_start + buffer_length],data,first_chunk);
95 length-=first_chunk;
96 buffer_length+=first_chunk;
97 if(length>0)
98 {
99 /* wrap */
100 memcpy(&send_buffer[0],&data[first_chunk],MIN(length,buffer_start));
101 buffer_length+=MIN(length,buffer_start);
102 }
103 }
104 if(busy_sending)
105 {
106 /* Do nothing. The transfer completion handler will pick it up */
107 }
108 else
109 {
110 sendout();
111 }
112 mutex_unlock(&sendlock);
36} 113}
37 114
38/* called by usb_core_transfer_complete() */ 115/* called by usb_core_transfer_complete() */
39void usb_serial_transfer_complete(bool in, int status, int length) 116void usb_serial_transfer_complete(bool in, int status, int length)
40{ 117{
41 int i;
42 switch (in) { 118 switch (in) {
43 case false: 119 case false:
44 logf("serial: %s", transfer_buffer); 120 logf("serial: %s", receive_buffer);
45 /* Data received. Send it back */ 121 /* Data received. TODO : Do something with it ? */
46 for(i=0;i<length;i++) { 122 usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer);
47 if(transfer_buffer[i]>0x40 && transfer_buffer[i]<0x5b)
48 transfer_buffer[i]+=0x20;
49 else if(transfer_buffer[i]>0x60 && transfer_buffer[i]<0x7b)
50 transfer_buffer[i]-=0x20;
51 }
52 usb_drv_send_nonblocking(EP_SERIAL, transfer_buffer, length);
53 break; 123 break;
54 124
55 case true: 125 case true:
56 /* Data sent out (maybe correctly, but we don't actually care. 126 mutex_lock(&sendlock);
57 * Re-prime read endpoint */ 127 /* Data sent out. Update circular buffer */
58 usb_drv_recv(EP_SERIAL, transfer_buffer, sizeof _transfer_buffer); 128 if(status == 0)
129 {
130 buffer_start = (buffer_start + length)%BUFFER_SIZE;
131 buffer_length -= length;
132 }
133 busy_sending = false;
134
135 if(buffer_length!=0)
136 {
137 sendout();
138 }
139 mutex_unlock(&sendlock);
59 break; 140 break;
60 } 141 }
61} 142}
@@ -68,8 +149,12 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req)
68 case USB_REQ_SET_CONFIGURATION: 149 case USB_REQ_SET_CONFIGURATION:
69 logf("serial: set config"); 150 logf("serial: set config");
70 /* prime rx endpoint */ 151 /* prime rx endpoint */
71 usb_drv_recv(EP_SERIAL, transfer_buffer, sizeof _transfer_buffer); 152 usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer);
72 handled = true; 153 handled = true;
154
155 /* we come here too after a bus reset, so reset some data */
156 busy_sending = false;
157 sendout();
73 break; 158 break;
74 159
75 default: 160 default:
diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h
index 60cede9bda..bcb0648af5 100644
--- a/firmware/usbstack/usb_serial.h
+++ b/firmware/usbstack/usb_serial.h
@@ -22,8 +22,11 @@
22#include "usb_ch9.h" 22#include "usb_ch9.h"
23 23
24void usb_serial_init(void); 24void usb_serial_init(void);
25void usb_serial_exit(void);
25void usb_serial_transfer_complete(bool in, int status, int length); 26void usb_serial_transfer_complete(bool in, int status, int length);
26bool usb_serial_control_request(struct usb_ctrlrequest* req); 27bool usb_serial_control_request(struct usb_ctrlrequest* req);
27 28
29void usb_serial_send(unsigned char *data,int length);
30
28#endif 31#endif
29 32