fuzev2: prevent button light flickering when accessing µSD
[kugel-rb.git] / firmware / logf.c
blobb68f8a1d266adf7164f7524c02d49fe2fcd3b68b
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 #include "lcd-remote.h"
36 #include "logf.h"
37 #include "serial.h"
39 #ifdef HAVE_USBSTACK
40 #include "usb_core.h"
41 #include "usbstack/usb_serial.h"
42 #endif
44 /* Only provide all this if asked to */
45 #ifdef ROCKBOX_HAS_LOGF
47 #ifndef __PCTOOL__
48 unsigned char logfbuffer[MAX_LOGF_SIZE];
49 int logfindex;
50 bool logfwrap;
51 #endif
53 #ifdef HAVE_REMOTE_LCD
54 static void displayremote(void)
56 /* TODO: we should have a debug option that enables/disables this! */
57 int w, h, i;
58 int fontnr;
59 int cur_x, cur_y, delta_y, delta_x;
60 struct font* font;
61 int nb_lines;
62 char buf[2];
63 /* Memorize the pointer to the beginning of the last ... lines
64 I assume delta_y >= 6 to avoid wasting memory and allocating memory dynamically
65 I hope there is no font with height < 6 ! */
66 const int NB_ENTRIES=LCD_REMOTE_HEIGHT / 6;
67 int line_start_ptr[NB_ENTRIES];
69 fontnr = lcd_getfont();
70 font = font_get(fontnr);
72 /* get the horizontal size of each line */
73 font_getstringsize("A", NULL, &delta_y, fontnr);
75 /* font too small ? */
76 if(delta_y < 6)
77 return;
78 /* nothing to print ? */
79 if(logfindex == 0 && !logfwrap)
80 return;
82 w = LCD_REMOTE_WIDTH;
83 h = LCD_REMOTE_HEIGHT;
84 nb_lines = 0;
86 if(logfwrap)
87 i = logfindex;
88 else
89 i = 0;
91 cur_x = 0;
93 line_start_ptr[0] = i;
97 if(logfbuffer[i] == '\0')
99 line_start_ptr[++nb_lines % NB_ENTRIES] = i+1;
100 cur_x = 0;
102 else
104 /* does character fit on this line ? */
105 delta_x = font_get_width(font, logfbuffer[i]);
107 if(cur_x + delta_x > w)
109 cur_x = 0;
110 line_start_ptr[++nb_lines % NB_ENTRIES] = i;
112 /* update pointer */
113 cur_x += delta_x;
115 i++;
116 if(i >= MAX_LOGF_SIZE)
117 i = 0;
118 } while(i != logfindex);
120 lcd_remote_clear_display();
122 i = line_start_ptr[ MAX(nb_lines - h / delta_y, 0) % NB_ENTRIES];
123 cur_x = 0;
124 cur_y = 0;
125 buf[1] = '\0';
127 do {
128 if(logfbuffer[i] == '\0')
130 cur_y += delta_y;
131 cur_x = 0;
133 else
135 /* does character fit on this line ? */
136 delta_x = font_get_width(font, logfbuffer[i]);
138 if(cur_x + delta_x > w)
140 cur_y += delta_y;
141 cur_x = 0;
144 buf[0] = logfbuffer[i];
145 lcd_remote_putsxy(cur_x, cur_y, buf);
146 cur_x += delta_x;
149 i++;
150 if(i >= MAX_LOGF_SIZE)
151 i = 0;
152 } while(i != logfindex);
154 lcd_remote_update();
156 #else
157 #define displayremote()
158 #endif
160 #ifdef __PCTOOL__
161 void _logf(const char *format, ...)
163 char buf[1024];
164 va_list ap;
165 va_start(ap, format);
167 vsnprintf(buf, sizeof buf, format, ap);
168 printf("DEBUG: %s\n", buf);
170 #else
171 static void check_logfindex(void)
173 if(logfindex >= MAX_LOGF_SIZE)
175 /* wrap */
176 logfwrap = true;
177 logfindex = 0;
181 static int logf_push(void *userp, unsigned char c)
183 (void)userp;
185 logfbuffer[logfindex++] = c;
186 check_logfindex();
188 #if defined(HAVE_SERIAL) && !defined(SIMULATOR)
189 if(c != '\0')
191 char buf[2];
192 buf[0] = c;
193 buf[1] = '\0';
194 serial_tx(buf);
196 #endif
198 return true;
201 void _logf(const char *fmt, ...)
203 #ifdef USB_ENABLE_SERIAL
204 int old_logfindex = logfindex;
205 #endif
206 va_list ap;
208 va_start(ap, fmt);
210 #ifdef SIMULATOR
211 char buf[1024];
212 vsnprintf(buf, sizeof buf, fmt, ap);
213 DEBUGF("%s\n", buf);
214 #endif
216 vuprintf(logf_push, NULL, fmt, ap);
217 va_end(ap);
219 /* add trailing zero */
220 logf_push(NULL, '\0');
222 #if defined(HAVE_SERIAL) && !defined(SIMULATOR)
223 serial_tx("\r\n");
224 #endif
225 #ifdef USB_ENABLE_SERIAL
227 if(logfindex < old_logfindex)
229 usb_serial_send(logfbuffer + old_logfindex, MAX_LOGF_SIZE - old_logfindex);
230 usb_serial_send(logfbuffer, logfindex - 1);
232 else
233 usb_serial_send(logfbuffer + old_logfindex, logfindex - old_logfindex - 1);
234 usb_serial_send("\r\n", 2);
235 #endif
237 displayremote();
239 #endif
241 #endif