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 | |
parent | b3ab7884110b6e3849add5573d1f2a96c7603cd4 (diff) | |
download | rockbox-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.c | 15 | ||||
-rw-r--r-- | firmware/logf.c | 10 | ||||
-rw-r--r-- | firmware/usb.c | 2 | ||||
-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 |
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) | ||
2361 | extern bool usb_core_serial_enabled; | ||
2362 | |||
2363 | static 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 *********/ |
2362 | struct the_menu_item { | 2374 | struct 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; | |||
286 | static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; | 286 | static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; |
287 | 287 | ||
288 | static bool usb_core_storage_enabled = false; | 288 | static bool usb_core_storage_enabled = false; |
289 | static bool usb_core_serial_enabled = false; | 289 | /* Next one is non-static, to enable setting it from the debug menu */ |
290 | bool usb_core_serial_enabled = false; | ||
290 | static bool usb_core_charging_enabled = false; | 291 | static bool usb_core_charging_enabled = false; |
291 | #if defined(USB_BENCHMARK) | 292 | #if defined(USB_BENCHMARK) |
292 | static bool usb_core_benchmark_enabled = false; | 293 | static bool usb_core_benchmark_enabled = false; |
@@ -405,6 +406,11 @@ void usb_core_init(void) | |||
405 | 406 | ||
406 | void usb_core_exit(void) | 407 | void 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 | |||
444 | void usb_core_enable_protocol(int driver,bool enabled) | 450 | void 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 | ||
28 | static unsigned char _transfer_buffer[16]; | 30 | #define BUFFER_SIZE 16384 /* No larger, because of controller limitations */ |
29 | static unsigned char* transfer_buffer; | 31 | static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32))); |
32 | static unsigned char* send_buffer; | ||
33 | |||
34 | static unsigned char _receive_buffer[512] __attribute__((aligned(32))); | ||
35 | static unsigned char* receive_buffer; | ||
36 | static bool busy_sending = false; | ||
37 | static int buffer_start; | ||
38 | static int buffer_length; | ||
39 | static bool active = false; | ||
40 | |||
41 | static struct mutex sendlock; | ||
30 | 42 | ||
31 | /* called by usb_code_init() */ | 43 | /* called by usb_code_init() */ |
32 | void usb_serial_init(void) | 44 | void 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 | |||
56 | void usb_serial_exit(void) | ||
57 | { | ||
58 | active = false; | ||
59 | } | ||
60 | |||
61 | static 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 | |||
76 | void 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() */ |
39 | void usb_serial_transfer_complete(bool in, int status, int length) | 116 | void 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 | ||
24 | void usb_serial_init(void); | 24 | void usb_serial_init(void); |
25 | void usb_serial_exit(void); | ||
25 | void usb_serial_transfer_complete(bool in, int status, int length); | 26 | void usb_serial_transfer_complete(bool in, int status, int length); |
26 | bool usb_serial_control_request(struct usb_ctrlrequest* req); | 27 | bool usb_serial_control_request(struct usb_ctrlrequest* req); |
27 | 28 | ||
29 | void usb_serial_send(unsigned char *data,int length); | ||
30 | |||
28 | #endif | 31 | #endif |
29 | 32 | ||