Fix FS#12824 : Malfunctioning FFT plugin in Sansa Clip Zip
[maemo-rb.git] / firmware / logf.c
blobe135b0b27f18d035a96a6ebee1a59e6b5609b50c
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Daniel Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 * logf() logs entries in a circular buffer. Each logged string is null-terminated.
25 * When the length of log exceeds MAX_LOGF_SIZE bytes, the buffer wraps.
29 #include <string.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include "config.h"
33 #include "system.h"
34 #include "font.h"
35 #ifdef HAVE_REMOTE_LCD
36 #include "lcd-remote.h"
37 #endif
38 #include "logf.h"
39 #include "serial.h"
40 #include "format.h"
42 #ifdef HAVE_USBSTACK
43 #include "usb_core.h"
44 #include "usbstack/usb_serial.h"
45 #endif
47 #ifdef ROCKBOX_HAS_LOGDISKF
48 #include "logdiskf.h"
49 #include "file.h"
50 #include "rbpaths.h"
51 #include "ata_idle_notify.h"
53 unsigned char logdiskfbuffer[MAX_LOGDISKF_SIZE];
54 int logdiskfindex;
55 #endif
57 /* Only provide all this if asked to */
58 #ifdef ROCKBOX_HAS_LOGF
60 #ifndef __PCTOOL__
61 unsigned char logfbuffer[MAX_LOGF_SIZE];
62 int logfindex;
63 bool logfwrap;
64 #endif
66 #ifdef HAVE_REMOTE_LCD
67 static void displayremote(void)
69 /* TODO: we should have a debug option that enables/disables this! */
70 int w, h, i;
71 int fontnr;
72 int cur_x, cur_y, delta_y, delta_x;
73 struct font* font;
74 int nb_lines;
75 char buf[2];
76 /* Memorize the pointer to the beginning of the last ... lines
77 I assume delta_y >= 6 to avoid wasting memory and allocating memory dynamically
78 I hope there is no font with height < 6 ! */
79 const int NB_ENTRIES=LCD_REMOTE_HEIGHT / 6;
80 int line_start_ptr[NB_ENTRIES];
82 fontnr = lcd_getfont();
83 font = font_get(fontnr);
85 /* get the horizontal size of each line */
86 font_getstringsize("A", NULL, &delta_y, fontnr);
88 /* font too small ? */
89 if(delta_y < 6)
90 return;
91 /* nothing to print ? */
92 if(logfindex == 0 && !logfwrap)
93 return;
95 w = LCD_REMOTE_WIDTH;
96 h = LCD_REMOTE_HEIGHT;
97 nb_lines = 0;
99 if(logfwrap)
100 i = logfindex;
101 else
102 i = 0;
104 cur_x = 0;
106 line_start_ptr[0] = i;
110 if(logfbuffer[i] == '\0')
112 line_start_ptr[++nb_lines % NB_ENTRIES] = i+1;
113 cur_x = 0;
115 else
117 /* does character fit on this line ? */
118 delta_x = font_get_width(font, logfbuffer[i]);
120 if(cur_x + delta_x > w)
122 cur_x = 0;
123 line_start_ptr[++nb_lines % NB_ENTRIES] = i;
125 /* update pointer */
126 cur_x += delta_x;
128 i++;
129 if(i >= MAX_LOGF_SIZE)
130 i = 0;
131 } while(i != logfindex);
133 lcd_remote_clear_display();
135 i = line_start_ptr[ MAX(nb_lines - h / delta_y, 0) % NB_ENTRIES];
136 cur_x = 0;
137 cur_y = 0;
138 buf[1] = '\0';
140 do {
141 if(logfbuffer[i] == '\0')
143 cur_y += delta_y;
144 cur_x = 0;
146 else
148 /* does character fit on this line ? */
149 delta_x = font_get_width(font, logfbuffer[i]);
151 if(cur_x + delta_x > w)
153 cur_y += delta_y;
154 cur_x = 0;
157 buf[0] = logfbuffer[i];
158 lcd_remote_putsxy(cur_x, cur_y, buf);
159 cur_x += delta_x;
162 i++;
163 if(i >= MAX_LOGF_SIZE)
164 i = 0;
165 } while(i != logfindex);
167 lcd_remote_update();
169 #else
170 #define displayremote()
171 #endif
173 #ifdef __PCTOOL__
174 void _logf(const char *format, ...)
176 char buf[1024];
177 va_list ap;
178 va_start(ap, format);
180 vsnprintf(buf, sizeof buf, format, ap);
181 printf("DEBUG: %s\n", buf);
183 #else
184 static void check_logfindex(void)
186 if(logfindex >= MAX_LOGF_SIZE)
188 /* wrap */
189 logfwrap = true;
190 logfindex = 0;
194 static int logf_push(void *userp, unsigned char c)
196 (void)userp;
198 logfbuffer[logfindex++] = c;
199 check_logfindex();
201 #if defined(HAVE_SERIAL) && !defined(SIMULATOR) && defined(LOGF_SERIAL)
202 if(c != '\0')
204 char buf[2];
205 buf[0] = c;
206 buf[1] = '\0';
207 serial_tx(buf);
209 #endif
211 return true;
214 void _logf(const char *fmt, ...)
216 #ifdef USB_ENABLE_SERIAL
217 int old_logfindex = logfindex;
218 #endif
219 va_list ap;
221 va_start(ap, fmt);
223 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
224 char buf[1024];
225 vsnprintf(buf, sizeof buf, fmt, ap);
226 DEBUGF("%s\n", buf);
227 /* restart va_list otherwise the result if undefined when vuprintf is called */
228 va_end(ap);
229 va_start(ap, fmt);
230 #endif
232 vuprintf(logf_push, NULL, fmt, ap);
233 va_end(ap);
235 /* add trailing zero */
236 logf_push(NULL, '\0');
238 #if defined(HAVE_SERIAL) && !defined(SIMULATOR) && defined(LOGF_SERIAL)
239 serial_tx("\r\n");
240 #endif
241 #ifdef USB_ENABLE_SERIAL
243 if(logfindex < old_logfindex)
245 usb_serial_send(logfbuffer + old_logfindex, MAX_LOGF_SIZE - old_logfindex);
246 usb_serial_send(logfbuffer, logfindex - 1);
248 else
249 usb_serial_send(logfbuffer + old_logfindex, logfindex - old_logfindex - 1);
250 usb_serial_send("\r\n", 2);
251 #endif
253 displayremote();
255 #endif
257 #endif
259 #ifdef ROCKBOX_HAS_LOGDISKF
260 static int logdiskf_push(void *userp, unsigned char c)
262 (void)userp;
264 /*just stop logging if out of space*/
265 if(logdiskfindex>=MAX_LOGDISKF_SIZE-1)
267 strcpy(&logdiskfbuffer[logdiskfindex-8], "LOGFULL");
268 logdiskfindex=MAX_LOGDISKF_SIZE;
269 return false;
271 logdiskfbuffer[logdiskfindex++] = c;
273 return true;
276 void _logdiskf(const char* file, const char level, const char *fmt, ...)
279 va_list ap;
281 va_start(ap, fmt);
282 int len =strlen(file);
283 if(logdiskfindex +len + 4 > MAX_LOGDISKF_SIZE-1)
285 strcpy(&logdiskfbuffer[logdiskfindex-8], "LOGFULL");
286 logdiskfindex=MAX_LOGDISKF_SIZE;
287 return;
290 logdiskf_push(NULL, level);
291 logdiskf_push(NULL, ' ');
292 logdiskf_push(NULL, '[');
293 strcpy(&logdiskfbuffer[logdiskfindex], file);
294 logdiskfindex += len;
295 logdiskf_push(NULL, ']');
297 vuprintf(logdiskf_push, NULL, fmt, ap);
298 va_end(ap);
302 static void flush_buffer(void* data)
304 (void)data;
305 int fd;
306 if(logdiskfindex < 1)
307 return;
309 fd = open(HOME_DIR"/rockbox_log.txt", O_RDWR | O_CREAT | O_APPEND, 0666);
310 if (fd < 0)
311 return;
313 write(fd, logdiskfbuffer, logdiskfindex);
314 close(fd);
316 logdiskfindex = 0;
319 void init_logdiskf()
321 register_storage_idle_func(flush_buffer);
323 #endif