Fix red
[kugel-rb.git] / firmware / logf.c
blob8821f4a658dcbc5ec0bb5c3b151d19ba380573d2
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 MAX_LOGF_ENTRY (29) bytes per entry in a circular buffer. Each
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).
28 * When the length of log exceeds MAX_LOGF_ENTRY bytes, dividing into the
29 * string of length is MAX_LOGF_ENTRY-1 bytes.
31 * logfbuffer[*]:
33 * |<- MAX_LOGF_ENTRY bytes ->|1|
34 * | log data area |T|
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)
42 #include <string.h>
43 #include <stdio.h>
44 #include <stdarg.h>
45 #include "config.h"
46 #include "lcd-remote.h"
47 #include "logf.h"
48 #include "serial.h"
50 #ifdef HAVE_USBSTACK
51 #include "usb_core.h"
52 #include "usbstack/usb_serial.h"
53 #endif
55 /* Only provide all this if asked to */
56 #ifdef ROCKBOX_HAS_LOGF
58 #ifndef __PCTOOL__
59 unsigned char logfbuffer[MAX_LOGF_LINES][MAX_LOGF_ENTRY+1];
60 int logfindex;
61 bool logfwrap;
62 #endif
64 #ifdef HAVE_REMOTE_LCD
65 static void displayremote(void)
67 /* TODO: we should have a debug option that enables/disables this! */
68 int w, h;
69 int lines;
70 int columns;
71 int i;
72 int index;
74 lcd_remote_getstringsize("A", &w, &h);
75 lines = LCD_REMOTE_HEIGHT/h;
76 columns = LCD_REMOTE_WIDTH/w;
77 lcd_remote_clear_display();
79 index = logfindex;
80 for(i = lines-1; i>=0; i--) {
81 unsigned char buffer[columns+1];
83 if(--index < 0) {
84 if(logfwrap)
85 index = MAX_LOGF_LINES-1;
86 else
87 break; /* done */
90 memcpy(buffer, logfbuffer[index], columns);
91 buffer[columns]=0;
92 lcd_remote_puts(0, i, buffer);
94 lcd_remote_update();
96 #else
97 #define displayremote()
98 #endif
100 #ifdef __PCTOOL__
101 void _logf(const char *format, ...)
103 char buf[1024];
104 va_list ap;
105 va_start(ap, format);
107 vsnprintf(buf, sizeof buf, format, ap);
108 printf("DEBUG: %s\n", buf);
110 #else
111 static void check_logfindex(void)
113 if(logfindex >= MAX_LOGF_LINES) {
114 /* wrap */
115 logfwrap = true;
116 logfindex = 0;
120 void _logf(const char *format, ...)
122 int len;
123 int tlen;
124 unsigned char buf[MAX_LOGF_ONE_LINE_SIZE];
125 unsigned char *ptr;
126 va_list ap;
127 bool multiline = false;
129 va_start(ap, format);
130 vsnprintf(buf, MAX_LOGF_ONE_LINE_SIZE, format, ap);
131 va_end(ap);
133 len = strlen(buf);
134 #ifdef HAVE_SERIAL
135 serial_tx(buf);
136 serial_tx("\r\n");
137 #endif
138 #ifdef USB_SERIAL
139 usb_serial_send(buf, len);
140 usb_serial_send("\r\n", 2);
141 #endif
143 tlen = 0;
144 check_logfindex();
145 while(len > MAX_LOGF_ENTRY)
147 ptr = logfbuffer[logfindex];
148 strncpy(ptr, buf + tlen, MAX_LOGF_ENTRY-1);
149 ptr[MAX_LOGF_ENTRY] = LOGF_TERMINATE_CONTINUE_LINE;
150 logfindex++;
151 check_logfindex();
152 len -= MAX_LOGF_ENTRY-1;
153 tlen += MAX_LOGF_ENTRY-1;
154 multiline = true;
156 ptr = logfbuffer[logfindex];
157 strcpy(ptr, buf + tlen);
159 if(len < MAX_LOGF_ENTRY)
160 /* pad with spaces up to the MAX_LOGF_ENTRY byte border */
161 memset(ptr+len, ' ', MAX_LOGF_ENTRY-len);
162 ptr[MAX_LOGF_ENTRY] = (multiline)?LOGF_TERMINATE_MULTI_LINE:LOGF_TERMINATE_ONE_LINE;
164 logfindex++; /* leave it where we write the next time */
166 displayremote();
168 #endif
170 #endif