blob: 6bdda3f424f806124e7c85848660cdef2e10fc45 [file] [log] [blame]
Daniel Stenbergb033f6c2005-05-23 22:47:42 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Daniel Stenberg
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Daniel Stenbergb033f6c2005-05-23 22:47:42 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/*
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +000023 * logf() logs entries in a circular buffer. Each logged string is null-terminated.
Maurus Cuelenaere4c793fe2008-12-31 17:01:00 +000024 *
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +000025 * When the length of log exceeds MAX_LOGF_SIZE bytes, the buffer wraps.
Maurus Cuelenaere4c793fe2008-12-31 17:01:00 +000026 *
Daniel Stenbergb033f6c2005-05-23 22:47:42 +000027 */
28
29#include <string.h>
30#include <stdio.h>
31#include <stdarg.h>
Daniel Stenbergb033f6c2005-05-23 22:47:42 +000032#include "config.h"
Thomas Martitz6ac64202010-05-06 22:17:34 +000033#include "system.h"
34#include "font.h"
Daniel Stenberg9e9f58f2005-05-24 14:28:48 +000035#include "lcd-remote.h"
Daniel Stenberg11bf87f2005-05-24 14:26:54 +000036#include "logf.h"
Linus Nielsen Feltzing00d21822006-10-12 20:22:16 +000037#include "serial.h"
Jeffrey Goodeb8a51ad2010-05-15 03:47:06 +000038#include "format.h"
Daniel Stenbergb033f6c2005-05-23 22:47:42 +000039
Frank Gevaerts776d0152008-03-02 20:45:33 +000040#ifdef HAVE_USBSTACK
41#include "usb_core.h"
42#include "usbstack/usb_serial.h"
43#endif
44
Daniel Stenbergedc07922005-05-30 13:00:43 +000045/* Only provide all this if asked to */
46#ifdef ROCKBOX_HAS_LOGF
47
Miika Pekkarinen0dd7ea22006-11-10 08:03:33 +000048#ifndef __PCTOOL__
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +000049unsigned char logfbuffer[MAX_LOGF_SIZE];
Linus Nielsen Feltzing056effc2005-05-24 14:01:16 +000050int logfindex;
Daniel Stenbergb033f6c2005-05-23 22:47:42 +000051bool logfwrap;
Miika Pekkarinen0dd7ea22006-11-10 08:03:33 +000052#endif
Daniel Stenbergb033f6c2005-05-23 22:47:42 +000053
Daniel Stenberg11bf87f2005-05-24 14:26:54 +000054#ifdef HAVE_REMOTE_LCD
55static void displayremote(void)
56{
57 /* TODO: we should have a debug option that enables/disables this! */
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +000058 int w, h, i;
59 int fontnr;
60 int cur_x, cur_y, delta_y, delta_x;
61 struct font* font;
62 int nb_lines;
63 char buf[2];
64 /* Memorize the pointer to the beginning of the last ... lines
65 I assume delta_y >= 6 to avoid wasting memory and allocating memory dynamically
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
Daniel Stenberg11bf87f2005-05-24 14:26:54 +0000121 lcd_remote_clear_display();
122
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000123 i = line_start_ptr[ MAX(nb_lines - h / delta_y, 0) % NB_ENTRIES];
124 cur_x = 0;
125 cur_y = 0;
126 buf[1] = '\0';
127
128 do {
129 if(logfbuffer[i] == '\0')
130 {
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;
Daniel Stenberg11bf87f2005-05-24 14:26:54 +0000148 }
149
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000150 i++;
151 if(i >= MAX_LOGF_SIZE)
152 i = 0;
153 } while(i != logfindex);
154
Daniel Stenberg11bf87f2005-05-24 14:26:54 +0000155 lcd_remote_update();
156}
157#else
158#define displayremote()
159#endif
160
Miika Pekkarinen0dd7ea22006-11-10 08:03:33 +0000161#ifdef __PCTOOL__
162void _logf(const char *format, ...)
163{
164 char buf[1024];
165 va_list ap;
166 va_start(ap, format);
167
168 vsnprintf(buf, sizeof buf, format, ap);
169 printf("DEBUG: %s\n", buf);
170}
171#else
Frank Gevaerts7ae9c8d2009-02-07 19:59:51 +0000172static void check_logfindex(void)
173{
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000174 if(logfindex >= MAX_LOGF_SIZE)
175 {
Frank Gevaerts7ae9c8d2009-02-07 19:59:51 +0000176 /* wrap */
177 logfwrap = true;
178 logfindex = 0;
179 }
180}
181
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000182static int logf_push(void *userp, unsigned char c)
Daniel Stenbergb033f6c2005-05-23 22:47:42 +0000183{
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000184 (void)userp;
185
186 logfbuffer[logfindex++] = c;
187 check_logfindex();
188
Maurus Cuelenaeredd9a9e42009-03-11 16:42:25 +0000189#if defined(HAVE_SERIAL) && !defined(SIMULATOR)
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000190 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
207 va_list ap;
208
209 va_start(ap, fmt);
Jeffrey Goodefade88a2009-11-02 15:30:06 +0000210
211#ifdef SIMULATOR
212 char buf[1024];
213 vsnprintf(buf, sizeof buf, fmt, ap);
214 DEBUGF("%s\n", buf);
215#endif
216
Thomas Martitz1ddb91a2009-11-03 21:20:09 +0000217 vuprintf(logf_push, NULL, fmt, ap);
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000218 va_end(ap);
219
220 /* add trailing zero */
221 logf_push(NULL, '\0');
222
223#if defined(HAVE_SERIAL) && !defined(SIMULATOR)
Linus Nielsen Feltzing00d21822006-10-12 20:22:16 +0000224 serial_tx("\r\n");
225#endif
Frank Gevaertsc61a7512009-05-23 14:30:20 +0000226#ifdef USB_ENABLE_SERIAL
Frank Gevaerts776d0152008-03-02 20:45:33 +0000227
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000228 if(logfindex < old_logfindex)
Maurus Cuelenaere4c793fe2008-12-31 17:01:00 +0000229 {
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000230 usb_serial_send(logfbuffer + old_logfindex, MAX_LOGF_SIZE - old_logfindex);
231 usb_serial_send(logfbuffer, logfindex - 1);
Maurus Cuelenaere4c793fe2008-12-31 17:01:00 +0000232 }
Maurus Cuelenaere20b0dd22009-08-21 22:54:23 +0000233 else
234 usb_serial_send(logfbuffer + old_logfindex, logfindex - old_logfindex - 1);
235 usb_serial_send("\r\n", 2);
236#endif
Daniel Stenberg11bf87f2005-05-24 14:26:54 +0000237
238 displayremote();
Daniel Stenbergb033f6c2005-05-23 22:47:42 +0000239}
Miika Pekkarinen0dd7ea22006-11-10 08:03:33 +0000240#endif
Daniel Stenbergedc07922005-05-30 13:00:43 +0000241
242#endif