summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2009-08-21 22:54:23 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2009-08-21 22:54:23 +0000
commit20b0dd2788794521ac7f3eec1065b7de99e4a5aa (patch)
treeef44f6d28e4674e6a4dda8e36187e9723186cb2e /firmware
parent249392c2d33130b86e39ad36d99cc2673842e37d (diff)
downloadrockbox-20b0dd2788794521ac7f3eec1065b7de99e4a5aa.tar.gz
rockbox-20b0dd2788794521ac7f3eec1065b7de99e4a5aa.zip
A new implementation of logf, logfdisplay and logfdump.
Flyspray: FS#10528 Author: Amaury Pouly git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22462 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/common/sprintf.c5
-rw-r--r--firmware/export/logf.h9
-rw-r--r--firmware/include/sprintf.h2
-rw-r--r--firmware/logf.c212
4 files changed, 147 insertions, 81 deletions
diff --git a/firmware/common/sprintf.c b/firmware/common/sprintf.c
index 0f012f7340..6c1855e06b 100644
--- a/firmware/common/sprintf.c
+++ b/firmware/common/sprintf.c
@@ -292,3 +292,8 @@ int fdprintf(int fd, const char *fmt, ...)
292 return fpr.bytes; /* return 0 on error */ 292 return fpr.bytes; /* return 0 on error */
293} 293}
294 294
295int vfnprintf(int (*push)(void *userp, unsigned char data), void *userp, const char *fmt, va_list ap)
296{
297 return format(push, userp, fmt, ap);
298}
299
diff --git a/firmware/export/logf.h b/firmware/export/logf.h
index 4926fe5ef2..16666449d4 100644
--- a/firmware/export/logf.h
+++ b/firmware/export/logf.h
@@ -28,15 +28,10 @@
28#ifdef ROCKBOX_HAS_LOGF 28#ifdef ROCKBOX_HAS_LOGF
29 29
30#ifndef __PCTOOL__ 30#ifndef __PCTOOL__
31#define MAX_LOGF_LINES 1000
32#define MAX_LOGF_ENTRY 29
33#define MAX_LOGF_ONE_LINE_SIZE 200
34 31
35#define LOGF_TERMINATE_ONE_LINE 0x00 32#define MAX_LOGF_SIZE 16384
36#define LOGF_TERMINATE_CONTINUE_LINE 0x01
37#define LOGF_TERMINATE_MULTI_LINE 0x02
38 33
39extern unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1]; 34extern unsigned char logfbuffer[MAX_LOGF_SIZE];
40extern int logfindex; 35extern int logfindex;
41extern bool logfwrap; 36extern bool logfwrap;
42#endif /* __PCTOOL__ */ 37#endif /* __PCTOOL__ */
diff --git a/firmware/include/sprintf.h b/firmware/include/sprintf.h
index ff9cf54d3a..b07ac9dfb6 100644
--- a/firmware/include/sprintf.h
+++ b/firmware/include/sprintf.h
@@ -32,4 +32,6 @@ int snprintf (char *buf, size_t size, const char *fmt, ...)
32int vsnprintf (char *buf, int size, const char *fmt, va_list ap); 32int vsnprintf (char *buf, int size, const char *fmt, va_list ap);
33int fdprintf (int fd, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3); 33int fdprintf (int fd, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
34 34
35int vfnprintf(int (*push)(void *userp, unsigned char data), void *userp, const char *fmt, va_list ap);
36
35#endif /* __SPRINTF_H__ */ 37#endif /* __SPRINTF_H__ */
diff --git a/firmware/logf.c b/firmware/logf.c
index 00fbfdc4b7..8817d4df45 100644
--- a/firmware/logf.c
+++ b/firmware/logf.c
@@ -20,28 +20,18 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22/* 22/*
23 * logf() logs MAX_LOGF_ENTRY (29) bytes per entry in a circular buffer. Each 23 * logf() logs entries in a circular buffer. Each logged string is null-terminated.
24 * logged string is space- padded for easier and faster output on screen. Just
25 * output MAX_LOGF_ENTRY characters on each line. MAX_LOGF_ENTRY bytes fit
26 * nicely on the iRiver remote LCD (128 pixels with an 8x6 pixels font).
27 * 24 *
28 * When the length of log exceeds MAX_LOGF_ENTRY bytes, dividing into the 25 * When the length of log exceeds MAX_LOGF_SIZE bytes, the buffer wraps.
29 * string of length is MAX_LOGF_ENTRY-1 bytes.
30 * 26 *
31 * logfbuffer[*]:
32 *
33 * |<- MAX_LOGF_ENTRY bytes ->|1|
34 * | log data area |T|
35 *
36 * T : log terminate flag
37 * == LOGF_TERMINATE_ONE_LINE(0x00) : log data end (one line)
38 * == LOGF_TERMINATE_CONTINUE_LINE(0x01) : log data continues
39 * == LOGF_TERMINATE_MULTI_LINE(0x02) : log data end (multi line)
40 */ 27 */
41 28
42#include <string.h> 29#include <string.h>
43#include <stdio.h> 30#include <stdio.h>
44#include <stdarg.h> 31#include <stdarg.h>
32#include <sprintf.h>
33#include <system.h>
34#include <font.h>
45#include "config.h" 35#include "config.h"
46#include "lcd-remote.h" 36#include "lcd-remote.h"
47#include "logf.h" 37#include "logf.h"
@@ -56,7 +46,7 @@
56#ifdef ROCKBOX_HAS_LOGF 46#ifdef ROCKBOX_HAS_LOGF
57 47
58#ifndef __PCTOOL__ 48#ifndef __PCTOOL__
59unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1]; 49unsigned char logfbuffer[MAX_LOGF_SIZE];
60int logfindex; 50int logfindex;
61bool logfwrap; 51bool logfwrap;
62#endif 52#endif
@@ -65,32 +55,103 @@ bool logfwrap;
65static void displayremote(void) 55static void displayremote(void)
66{ 56{
67 /* TODO: we should have a debug option that enables/disables this! */ 57 /* TODO: we should have a debug option that enables/disables this! */
68 int w, h; 58 int w, h, i;
69 int lines; 59 int fontnr;
70 int columns; 60 int cur_x, cur_y, delta_y, delta_x;
71 int i; 61 struct font* font;
72 int index; 62 int nb_lines;
73 63 char buf[2];
74 lcd_remote_getstringsize("A", &w, &h); 64 /* Memorize the pointer to the beginning of the last ... lines
75 lines = LCD_REMOTE_HEIGHT/h; 65 I assume delta_y >= 6 to avoid wasting memory and allocating memory dynamically
76 columns = LCD_REMOTE_WIDTH/w; 66 I hope there is no font with height < 6 ! */
67 const int NB_ENTRIES=LCD_REMOTE_HEIGHT / 6;
68 int line_start_ptr[NB_ENTRIES];
69
70 fontnr = lcd_getfont();
71 font = font_get(fontnr);
72
73 /* get the horizontal size of each line */
74 font_getstringsize("A", NULL, &delta_y, fontnr);
75
76 /* font too small ? */
77 if(delta_y < 6)
78 return;
79 /* nothing to print ? */
80 if(logfindex == 0 && !logfwrap)
81 return;
82
83 w = LCD_REMOTE_WIDTH;
84 h = LCD_REMOTE_HEIGHT;
85 nb_lines = 0;
86
87 if(logfwrap)
88 i = logfindex;
89 else
90 i = 0;
91
92 cur_x = 0;
93
94 line_start_ptr[0] = i;
95
96 do
97 {
98 if(logfbuffer[i] == '\0')
99 {
100 line_start_ptr[++nb_lines % NB_ENTRIES] = i+1;
101 cur_x = 0;
102 }
103 else
104 {
105 /* does character fit on this line ? */
106 delta_x = font_get_width(font, logfbuffer[i]);
107
108 if(cur_x + delta_x > w)
109 {
110 cur_x = 0;
111 line_start_ptr[++nb_lines % NB_ENTRIES] = i;
112 }
113 /* update pointer */
114 cur_x += delta_x;
115 }
116 i++;
117 if(i >= MAX_LOGF_SIZE)
118 i = 0;
119 } while(i != logfindex);
120
77 lcd_remote_clear_display(); 121 lcd_remote_clear_display();
78 122
79 index = logfindex; 123 i = line_start_ptr[ MAX(nb_lines - h / delta_y, 0) % NB_ENTRIES];
80 for(i = lines-1; i>=0; i--) { 124 cur_x = 0;
81 unsigned char buffer[columns+1]; 125 cur_y = 0;
82 126 buf[1] = '\0';
83 if(--index < 0) { 127
84 if(logfwrap) 128 do {
85 index = MAX_LOGF_LINES-1; 129 if(logfbuffer[i] == '\0')
86 else 130 {
87 break; /* done */ 131 cur_y += delta_y;
132 cur_x = 0;
133 }
134 else
135 {
136 /* does character fit on this line ? */
137 delta_x = font_get_width(font, logfbuffer[i]);
138
139 if(cur_x + delta_x > w)
140 {
141 cur_y += delta_y;
142 cur_x = 0;
143 }
144
145 buf[0] = logfbuffer[i];
146 lcd_remote_putsxy(cur_x, cur_y, buf);
147 cur_x += delta_x;
88 } 148 }
89 149
90 memcpy(buffer, logfbuffer[index], columns); 150 i++;
91 buffer[columns]=0; 151 if(i >= MAX_LOGF_SIZE)
92 lcd_remote_puts(0, i, buffer); 152 i = 0;
93 } 153 } while(i != logfindex);
154
94 lcd_remote_update(); 155 lcd_remote_update();
95} 156}
96#else 157#else
@@ -110,59 +171,62 @@ void _logf(const char *format, ...)
110#else 171#else
111static void check_logfindex(void) 172static void check_logfindex(void)
112{ 173{
113 if(logfindex >= MAX_LOGF_LINES) { 174 if(logfindex >= MAX_LOGF_SIZE)
175 {
114 /* wrap */ 176 /* wrap */
115 logfwrap = true; 177 logfwrap = true;
116 logfindex = 0; 178 logfindex = 0;
117 } 179 }
118} 180}
119 181
120void _logf(const char *format, ...) 182static int logf_push(void *userp, unsigned char c)
121{ 183{
122 int len; 184 (void)userp;
123 int tlen; 185
124 unsigned char buf[MAX_LOGF_ONE_LINE_SIZE]; 186 logfbuffer[logfindex++] = c;
125 unsigned char *ptr; 187 check_logfindex();
188
189#if defined(HAVE_SERIAL) && !defined(SIMULATOR)
190 if(c != '\0')
191 {
192 char buf[2];
193 buf[0] = c;
194 buf[1] = '\0';
195 serial_tx(buf);
196 }
197#endif
198
199 return true;
200}
201
202void _logf(const char *fmt, ...)
203{
204 #ifdef USB_ENABLE_SERIAL
205 int old_logfindex = logfindex;
206 #endif
126 va_list ap; 207 va_list ap;
127 bool multiline = false;
128 208
129 va_start(ap, format); 209 va_start(ap, fmt);
130 vsnprintf(buf, MAX_LOGF_ONE_LINE_SIZE, format, ap); 210 vfnprintf(logf_push, NULL, fmt, ap);
131 va_end(ap); 211 va_end(ap);
132 212
133 len = strlen(buf); 213 /* add trailing zero */
214 logf_push(NULL, '\0');
215
134#if defined(HAVE_SERIAL) && !defined(SIMULATOR) 216#if defined(HAVE_SERIAL) && !defined(SIMULATOR)
135 serial_tx(buf);
136 serial_tx("\r\n"); 217 serial_tx("\r\n");
137#endif 218#endif
138#ifdef USB_ENABLE_SERIAL 219#ifdef USB_ENABLE_SERIAL
139 usb_serial_send(buf, len);
140 usb_serial_send("\r\n", 2);
141#endif
142 220
143 tlen = 0; 221 if(logfindex < old_logfindex)
144 check_logfindex();
145 while(len > MAX_LOGF_ENTRY)
146 { 222 {
147 ptr = logfbuffer[logfindex]; 223 usb_serial_send(logfbuffer + old_logfindex, MAX_LOGF_SIZE - old_logfindex);
148 memcpy(ptr, buf + tlen, MAX_LOGF_ENTRY); 224 usb_serial_send(logfbuffer, logfindex - 1);
149 ptr[MAX_LOGF_ENTRY] = LOGF_TERMINATE_CONTINUE_LINE;
150 logfindex++;
151 check_logfindex();
152 len -= MAX_LOGF_ENTRY;
153 tlen += MAX_LOGF_ENTRY;
154 multiline = true;
155 } 225 }
156 226 else
157 ptr = logfbuffer[logfindex]; 227 usb_serial_send(logfbuffer + old_logfindex, logfindex - old_logfindex - 1);
158 memcpy(ptr, buf + tlen,len); 228 usb_serial_send("\r\n", 2);
159 229#endif
160 if(len < MAX_LOGF_ENTRY)
161 /* pad with spaces up to the MAX_LOGF_ENTRY byte border */
162 memset(ptr+len, ' ', MAX_LOGF_ENTRY-len);
163 ptr[MAX_LOGF_ENTRY] = (multiline)?LOGF_TERMINATE_MULTI_LINE:LOGF_TERMINATE_ONE_LINE;
164
165 logfindex++; /* leave it where we write the next time */
166 230
167 displayremote(); 231 displayremote();
168} 232}