1 #include <debug-uart.h>
2 #include <sys-interrupt.h>
4 #include <AT91SAM7S64.h>
6 #include <interrupt-utils.h>
8 #ifndef DBG_XMIT_BUFFER_LEN
9 #define DBG_XMIT_BUFFER_LEN 3024
11 #ifndef DBG_RECV_BUFFER_LEN
12 #define DBG_RECV_BUFFER_LEN 256
15 static unsigned char dbg_xmit_buffer[DBG_XMIT_BUFFER_LEN];
16 static unsigned char dbg_recv_buffer[DBG_RECV_BUFFER_LEN];
17 static unsigned int dbg_recv_buffer_len = 0;
23 *AT91C_PIOA_OER = AT91C_PA10_DTXD;
24 *AT91C_PIOA_ODR = AT91C_PA9_DRXD;
25 *AT91C_PIOA_ASR = AT91C_PA10_DTXD | AT91C_PA9_DRXD;
26 *AT91C_PIOA_PDR = AT91C_PA10_DTXD | AT91C_PA9_DRXD;
28 *AT91C_DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL;
29 *AT91C_DBGU_IDR= 0xffffffff;
31 *AT91C_DBGU_BRGR = MCK / (115200 * 16);
32 *AT91C_DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;
34 *AT91C_DBGU_TPR = (
unsigned int)dbg_xmit_buffer;
35 *AT91C_DBGU_TNPR = (
unsigned int)dbg_xmit_buffer;
40 static void (*input_func)(
const char *inp,
unsigned int len) =
NULL;
42 static int dbg_recv_handler_func()
44 if (!(*AT91C_DBGU_CSR & AT91C_US_RXRDY))
return 0;
45 unsigned char c = *AT91C_DBGU_RHR;
47 if (dbg_recv_buffer_len < (DBG_RECV_BUFFER_LEN -1)) {
48 dbg_recv_buffer[dbg_recv_buffer_len++] = c;
51 dbg_recv_buffer[dbg_recv_buffer_len] =
'\0';
52 if (input_func) input_func((
char*)dbg_recv_buffer, dbg_recv_buffer_len);
53 dbg_recv_buffer_len = 0;
58 static SystemInterruptHandler dbg_recv_handler = {
NULL, dbg_recv_handler_func};
61 dbg_set_input_handler(
void (*handler)(
const char *inp,
unsigned int len))
64 sys_interrupt_append_handler(&dbg_recv_handler);
65 sys_interrupt_enable();
66 *AT91C_DBGU_IER = AT91C_US_RXRDY;
68 static volatile unsigned char mutex = 0;
71 dbg_send_bytes(
const unsigned char *seq,
unsigned int len)
73 unsigned short next_count;
74 unsigned short current_count;
76 unsigned int save = disableIRQ();
82 *AT91C_DBGU_PTCR =AT91C_PDC_TXTDIS;
83 while(*AT91C_DBGU_PTSR & AT91C_PDC_TXTEN);
84 next_count = *AT91C_DBGU_TNCR;
85 current_count = *AT91C_DBGU_TCR;
87 left = DBG_XMIT_BUFFER_LEN - next_count - current_count;
89 if (left < len) len = left;
92 memcpy(&dbg_xmit_buffer[next_count], seq, len);
93 *AT91C_DBGU_TNCR = next_count + len;
95 unsigned char *to = ((
unsigned char*)*AT91C_DBGU_TPR) + current_count;
96 left = &dbg_xmit_buffer[DBG_XMIT_BUFFER_LEN] - to;
98 unsigned int wrapped = len - left;
99 memcpy(to, seq, left);
100 memcpy(dbg_xmit_buffer, &seq[left], wrapped);
101 *AT91C_DBGU_TCR = current_count + left;
102 *AT91C_DBGU_TNCR = wrapped;
104 memcpy(to, seq, len);
105 *AT91C_DBGU_TCR = current_count + len;
112 *AT91C_DBGU_PTCR =AT91C_PDC_TXTEN;
117 static unsigned char dbg_write_overrun = 0;
120 dbg_putchar(
const char ch)
122 if (dbg_write_overrun) {
123 if (dbg_send_bytes((
const unsigned char*)
"^",1) != 1)
return;
125 dbg_write_overrun = 0;
126 if (dbg_send_bytes((
const unsigned char*)&ch,1) != 1) {
127 dbg_write_overrun = 1;
132 dbg_blocking_putchar(
const char ch)
134 if (dbg_write_overrun) {
135 while (dbg_send_bytes((
const unsigned char*)
"^",1) != 1);
137 dbg_write_overrun = 0;
138 while (dbg_send_bytes((
const unsigned char*)&ch,1) != 1);
142 static StrFormatResult
143 dbg_write_cb(
void *user_data,
const char *data,
unsigned int len)
145 if (dbg_send_bytes((
const unsigned char*)data, len) != len) {
146 dbg_write_overrun = 1;
147 return STRFORMAT_FAILED;
153 dbg_printf(
const char *format, ...)
155 static const StrFormatContext ctxt = {dbg_write_cb,
NULL};
157 if (dbg_write_overrun) {
158 if (dbg_send_bytes((
const unsigned char*)
"^",1) != 1)
return;
160 dbg_write_overrun = 0;
161 va_start(ap, format);
162 format_str_v(&ctxt, format, ap);
166 static StrFormatResult
167 dbg_write_blocking_cb(
void *user_data,
const char *data,
unsigned int len)
169 unsigned int left = len;
171 unsigned int sent = dbg_send_bytes((
const unsigned char*)data, left);
179 dbg_blocking_printf(
const char *format, ...)
181 static const StrFormatContext ctxt = {dbg_write_blocking_cb,
NULL};
183 if (dbg_write_overrun) {
184 while (dbg_send_bytes((
const unsigned char*)
"^",1) != 1);
186 dbg_write_overrun = 0;
187 va_start(ap, format);
188 format_str_v(&ctxt, format, ap);
195 while(!(*AT91C_DBGU_CSR & AT91C_US_TXBUFE));