Move C linkage binding for c++ to exporting header files instead of includes.
[Rockbox.git] / firmware / debug.c
blobf6d93a378dafaa3623d9f273e37e4eeecec086c5
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include "config.h"
24 #include "cpu.h"
25 #ifdef HAVE_GDB_API
26 #include "gdb_api.h"
27 #endif
29 #ifdef DEBUG
30 static char debugmembuf[200];
31 #if CONFIG_CPU == SH7034
32 static char debugbuf[400];
33 #endif
34 #endif
36 #ifndef SIMULATOR /* allow non archos platforms to display output */
37 #include "kernel.h"
38 #include "system.h"
39 #include "debug.h"
41 #ifdef DEBUG
42 #if CONFIG_CPU == SH7034 /* these are still very SH-oriented */
43 void debug_init(void)
45 /* Clear it all! */
46 SSR1 &= ~(SCI_RDRF | SCI_ORER | SCI_PER | SCI_FER);
48 /* This enables the serial Rx interrupt, to be able to exit into the
49 debugger when you hit CTRL-C */
50 SCR1 |= 0x40;
51 SCR1 &= ~0x80;
52 IPRE |= 0xf000; /* Set to highest priority */
55 static int debug_tx_ready(void)
57 return (SSR1 & SCI_TDRE);
60 static void debug_tx_char(char ch)
62 while (!debug_tx_ready())
68 * Write data into TDR and clear TDRE
70 TDR1 = ch;
71 SSR1 &= ~SCI_TDRE;
74 static void debug_handle_error(char ssr)
76 (void)ssr;
77 SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
80 static int debug_rx_ready(void)
82 char ssr;
84 ssr = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
85 if ( ssr )
86 debug_handle_error ( ssr );
87 return SSR1 & SCI_RDRF;
90 static char debug_rx_char(void)
92 char ch;
93 char ssr;
95 while (!debug_rx_ready())
100 ch = RDR1;
101 SSR1 &= ~SCI_RDRF;
103 ssr = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
105 if (ssr)
106 debug_handle_error (ssr);
108 return ch;
111 static const char hexchars[] = "0123456789abcdef";
113 static char highhex(int x)
115 return hexchars[(x >> 4) & 0xf];
118 static char lowhex(int x)
120 return hexchars[x & 0xf];
123 static void putpacket (const char *buffer)
125 register int checksum;
127 const char *src = buffer;
129 /* Special debug hack. Shut off the Rx IRQ during I/O to prevent the debug
130 stub from interrupting the message */
131 SCR1 &= ~0x40;
133 debug_tx_char ('$');
134 checksum = 0;
136 while (*src)
138 int runlen;
140 /* Do run length encoding */
141 for (runlen = 0; runlen < 100; runlen ++)
143 if (src[0] != src[runlen] || runlen == 99)
145 if (runlen > 3)
147 int encode;
148 /* Got a useful amount */
149 debug_tx_char (*src);
150 checksum += *src;
151 debug_tx_char ('*');
152 checksum += '*';
153 checksum += (encode = runlen + ' ' - 4);
154 debug_tx_char (encode);
155 src += runlen;
157 else
159 debug_tx_char (*src);
160 checksum += *src;
161 src++;
163 break;
169 debug_tx_char ('#');
170 debug_tx_char (highhex(checksum));
171 debug_tx_char (lowhex(checksum));
173 /* Wait for the '+' */
174 debug_rx_char();
176 /* Special debug hack. Enable the IRQ again */
177 SCR1 |= 0x40;
181 /* convert the memory, pointed to by mem into hex, placing result in buf */
182 /* return a pointer to the last char put in buf (null) */
183 static char *mem2hex (const char *mem, char *buf, int count)
185 int i;
186 int ch;
187 for (i = 0; i < count; i++)
189 ch = *mem++;
190 *buf++ = highhex (ch);
191 *buf++ = lowhex (ch);
193 *buf = 0;
194 return (buf);
197 static void debug(const char *msg)
199 debugbuf[0] = 'O';
201 mem2hex(msg, &debugbuf[1], strlen(msg));
202 putpacket(debugbuf);
204 #endif /* SH7034 */
206 #ifdef HAVE_GDB_API
207 static void *get_api_function(int n)
209 struct gdb_api *api = (struct gdb_api *)GDB_API_ADDRESS;
210 if (api->magic == GDB_API_MAGIC)
211 return api->func[n];
212 else
213 return NULL;
216 void breakpoint(void)
218 void (*f)(void) = get_api_function(0);
219 if (f) (*f)();
222 static void debug(char *msg)
224 void (*f)(char *) = get_api_function(1);
225 if (f) (*f)(msg);
228 void debug_init(void)
232 #endif /* HAVE_GDB_API */
233 #endif /* end of DEBUG section */
235 #ifdef __GNUC__
236 void debugf(const char *fmt, ...)
237 #endif
239 #ifdef DEBUG
240 va_list ap;
242 va_start(ap, fmt);
243 vsnprintf(debugmembuf, sizeof(debugmembuf), fmt, ap);
244 va_end(ap);
245 debug(debugmembuf);
246 #else
247 (void)fmt;
248 #endif
251 #endif