-Cosmetic change in a comparison
[kugel-rb.git] / firmware / debug.c
blob94404586de5aae1402dd4c097e5bf62c1f474cb6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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 ****************************************************************************/
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdarg.h>
25 #include "config.h"
26 #include "cpu.h"
27 #ifdef HAVE_GDB_API
28 #include "gdb_api.h"
29 #endif
31 #ifdef DEBUG
32 static char debugmembuf[200];
33 #if CONFIG_CPU == SH7034
34 static char debugbuf[400];
35 #endif
36 #endif
38 #ifndef SIMULATOR /* allow non archos platforms to display output */
39 #include "kernel.h"
40 #include "system.h"
41 #include "debug.h"
43 #ifdef DEBUG
44 #if CONFIG_CPU == SH7034 /* these are still very SH-oriented */
45 void debug_init(void)
47 /* Clear it all! */
48 SSR1 &= ~(SCI_RDRF | SCI_ORER | SCI_PER | SCI_FER);
50 /* This enables the serial Rx interrupt, to be able to exit into the
51 debugger when you hit CTRL-C */
52 SCR1 |= 0x40;
53 SCR1 &= ~0x80;
54 IPRE |= 0xf000; /* Set to highest priority */
57 static int debug_tx_ready(void)
59 return (SSR1 & SCI_TDRE);
62 static void debug_tx_char(char ch)
64 while (!debug_tx_ready())
70 * Write data into TDR and clear TDRE
72 TDR1 = ch;
73 SSR1 &= ~SCI_TDRE;
76 static void debug_handle_error(char ssr)
78 (void)ssr;
79 SSR1 &= ~(SCI_ORER | SCI_PER | SCI_FER);
82 static int debug_rx_ready(void)
84 char ssr;
86 ssr = SSR1 & ( SCI_PER | SCI_FER | SCI_ORER );
87 if ( ssr )
88 debug_handle_error ( ssr );
89 return SSR1 & SCI_RDRF;
92 static char debug_rx_char(void)
94 char ch;
95 char ssr;
97 while (!debug_rx_ready())
102 ch = RDR1;
103 SSR1 &= ~SCI_RDRF;
105 ssr = SSR1 & (SCI_PER | SCI_FER | SCI_ORER);
107 if (ssr)
108 debug_handle_error (ssr);
110 return ch;
113 static const char hexchars[] = "0123456789abcdef";
115 static char highhex(int x)
117 return hexchars[(x >> 4) & 0xf];
120 static char lowhex(int x)
122 return hexchars[x & 0xf];
125 static void putpacket (const char *buffer)
127 register int checksum;
129 const char *src = buffer;
131 /* Special debug hack. Shut off the Rx IRQ during I/O to prevent the debug
132 stub from interrupting the message */
133 SCR1 &= ~0x40;
135 debug_tx_char ('$');
136 checksum = 0;
138 while (*src)
140 int runlen;
142 /* Do run length encoding */
143 for (runlen = 0; runlen < 100; runlen ++)
145 if (src[0] != src[runlen] || runlen == 99)
147 if (runlen > 3)
149 int encode;
150 /* Got a useful amount */
151 debug_tx_char (*src);
152 checksum += *src;
153 debug_tx_char ('*');
154 checksum += '*';
155 checksum += (encode = runlen + ' ' - 4);
156 debug_tx_char (encode);
157 src += runlen;
159 else
161 debug_tx_char (*src);
162 checksum += *src;
163 src++;
165 break;
171 debug_tx_char ('#');
172 debug_tx_char (highhex(checksum));
173 debug_tx_char (lowhex(checksum));
175 /* Wait for the '+' */
176 debug_rx_char();
178 /* Special debug hack. Enable the IRQ again */
179 SCR1 |= 0x40;
183 /* convert the memory, pointed to by mem into hex, placing result in buf */
184 /* return a pointer to the last char put in buf (null) */
185 static char *mem2hex (const char *mem, char *buf, int count)
187 int i;
188 int ch;
189 for (i = 0; i < count; i++)
191 ch = *mem++;
192 *buf++ = highhex (ch);
193 *buf++ = lowhex (ch);
195 *buf = 0;
196 return (buf);
199 static void debug(const char *msg)
201 debugbuf[0] = 'O';
203 mem2hex(msg, &debugbuf[1], strlen(msg));
204 putpacket(debugbuf);
206 #elif defined(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)
231 #else /* !SH7034 && !HAVE_GDB_API */
232 void debug_init(void)
236 static inline void debug(char *msg)
238 (void)msg;
240 #endif
242 #endif /* end of DEBUG section */
244 #ifdef __GNUC__
245 void debugf(const char *fmt, ...)
246 #endif
248 #ifdef DEBUG
249 va_list ap;
251 va_start(ap, fmt);
252 vsnprintf(debugmembuf, sizeof(debugmembuf), fmt, ap);
253 va_end(ap);
254 debug(debugmembuf);
255 #else
256 (void)fmt;
257 #endif
260 #endif