kdebug_mega.c
Go to the documentation of this file.
00001 00041 #include <hw/hw_cpufreq.h> /* for CPU_FREQ */ 00042 #include "hw/hw_ser.h" /* Required for bus macros overrides */ 00043 00044 #include "cfg/cfg_debug.h" 00045 #include <cfg/macros.h> /* for BV(), DIV_ROUND */ 00046 00047 #include <cpu/types.h> 00048 #include <cpu/attr.h> 00049 00050 #include <avr/io.h> 00051 00052 #if CONFIG_KDEBUG_PORT == 0 00053 00054 /* 00055 * Support for special bus policies or external transceivers 00056 * on UART0 (to be overridden in "hw/hw_ser.h"). 00057 * 00058 * HACK: if we don't set TXEN, kdbg disables the transmitter 00059 * after each output statement until the serial driver 00060 * is initialized. These glitches confuse the debug 00061 * terminal that ends up printing some trash. 00062 */ 00063 #ifndef KDBG_UART0_BUS_INIT 00064 #define KDBG_UART0_BUS_INIT do { \ 00065 UCR = BV(TXEN0); \ 00066 } while (0) 00067 #endif 00068 #ifndef KDBG_UART0_BUS_RX 00069 #define KDBG_UART0_BUS_RX do {} while (0) 00070 #endif 00071 #ifndef KDBG_UART0_BUS_TX 00072 #define KDBG_UART0_BUS_TX do {} while (0) 00073 #endif 00074 00075 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA1280 \ 00076 || CPU_AVR_ATMEGA324P || CPU_AVR_ATMEGA644P || CPU_AVR_ATMEGA88P || CPU_AVR_ATMEGA168 \ 00077 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA2560 00078 #define UCR UCSR0B 00079 #define UDR UDR0 00080 #define USR UCSR0A 00081 #elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32 00082 #define UCR UCSRB 00083 #define USR UCSRA 00084 #define TXEN0 TXEN 00085 #define UDRE0 UDRE 00086 #define TXC0 TXC 00087 #define TXCIE0 TXCIE 00088 #define UDRIE0 UDRIE 00089 #else 00090 #error Unknown CPU 00091 #endif 00092 00093 #define KDBG_WAIT_READY() do { loop_until_bit_is_set(USR, UDRE0); } while(0) 00094 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(USR, TXC0); } while(0) 00095 00096 /* 00097 * We must clear the TXC flag before sending a new character to allow 00098 * KDBG_WAIT_TXDONE() to work properly. 00099 * 00100 * BUG: if KDBG_WRITE_CHAR() is called after the TXC flag is set by hardware, 00101 * a new TXC could be generated after we've cleared it and before the new 00102 * character is written to UDR. On a 485 bus, the transceiver will be put 00103 * in RX mode while still transmitting the last char. 00104 */ 00105 #define KDBG_WRITE_CHAR(c) do { USR |= BV(TXC0); UDR = (c); } while(0) 00106 00107 #define KDBG_MASK_IRQ(old) do { \ 00108 (old) = UCR; \ 00109 UCR |= BV(TXEN0); \ 00110 UCR &= ~(BV(TXCIE0) | BV(UDRIE0)); \ 00111 KDBG_UART0_BUS_TX; \ 00112 } while(0) 00113 00114 #define KDBG_RESTORE_IRQ(old) do { \ 00115 KDBG_WAIT_TXDONE(); \ 00116 KDBG_UART0_BUS_RX; \ 00117 UCR = (old); \ 00118 } while(0) 00119 00120 typedef uint8_t kdbg_irqsave_t; 00121 00122 #elif CONFIG_KDEBUG_PORT == 1 00123 00124 /* 00125 * Support for special bus policies or external transceivers 00126 * on UART1 (to be overridden in "hw/hw_ser.h"). 00127 * 00128 * HACK: if we don't set TXEN, kdbg disables the transmitter 00129 * after each output statement until the serial driver 00130 * is initialized. These glitches confuse the debug 00131 * terminal that ends up printing some trash. 00132 */ 00133 #ifndef KDBG_UART1_BUS_INIT 00134 #define KDBG_UART1_BUS_INIT do { \ 00135 UCSR1B = BV(TXEN1); \ 00136 } while (0) 00137 #endif 00138 #ifndef KDBG_UART1_BUS_RX 00139 #define KDBG_UART1_BUS_RX do {} while (0) 00140 #endif 00141 #ifndef KDBG_UART1_BUS_TX 00142 #define KDBG_UART1_BUS_TX do {} while (0) 00143 #endif 00144 00145 #define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR1A, UDRE1); } while(0) 00146 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR1A, TXC1); } while(0) 00147 #define KDBG_WRITE_CHAR(c) do { UCSR1A |= BV(TXC1); UDR1 = (c); } while(0) 00148 00149 #define KDBG_MASK_IRQ(old) do { \ 00150 (old) = UCSR1B; \ 00151 UCSR1B |= BV(TXEN1); \ 00152 UCSR1B &= ~(BV(TXCIE1) | BV(UDRIE1)); \ 00153 KDBG_UART1_BUS_TX; \ 00154 } while(0) 00155 00156 #define KDBG_RESTORE_IRQ(old) do { \ 00157 KDBG_WAIT_TXDONE(); \ 00158 KDBG_UART1_BUS_RX; \ 00159 UCSR1B = (old); \ 00160 } while(0) 00161 00162 typedef uint8_t kdbg_irqsave_t; 00163 00164 #elif CONFIG_KDEBUG_PORT == 2 00165 00166 /* 00167 * Support for special bus policies or external transceivers 00168 * on UART2 (to be overridden in "hw/hw_ser.h"). 00169 * 00170 * HACK: if we don't set TXEN, kdbg disables the transmitter 00171 * after each output statement until the serial driver 00172 * is initialized. These glitches confuse the debug 00173 * terminal that ends up printing some trash. 00174 */ 00175 #ifndef KDBG_UART2_BUS_INIT 00176 #define KDBG_UART2_BUS_INIT do { \ 00177 UCSR2B = BV(TXEN2); \ 00178 } while (0) 00179 #endif 00180 #ifndef KDBG_UART2_BUS_RX 00181 #define KDBG_UART2_BUS_RX do {} while (0) 00182 #endif 00183 #ifndef KDBG_UART2_BUS_TX 00184 #define KDBG_UART2_BUS_TX do {} while (0) 00185 #endif 00186 00187 #define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR2A, UDRE2); } while(0) 00188 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR2A, TXC2); } while(0) 00189 #define KDBG_WRITE_CHAR(c) do { UCSR2A |= BV(TXC2); UDR2 = (c); } while(0) 00190 00191 #define KDBG_MASK_IRQ(old) do { \ 00192 (old) = UCSR2B; \ 00193 UCSR2B |= BV(TXEN2); \ 00194 UCSR2B &= ~(BV(TXCIE2) | BV(UDRIE2)); \ 00195 KDBG_UART2_BUS_TX; \ 00196 } while(0) 00197 00198 #define KDBG_RESTORE_IRQ(old) do { \ 00199 KDBG_WAIT_TXDONE(); \ 00200 KDBG_UART2_BUS_RX; \ 00201 UCSR2B = (old); \ 00202 } while(0) 00203 00204 typedef uint8_t kdbg_irqsave_t; 00205 00206 #elif CONFIG_KDEBUG_PORT == 3 00207 00208 /* 00209 * Support for special bus policies or external transceivers 00210 * on UART3 (to be overridden in "hw/hw_ser.h"). 00211 * 00212 * HACK: if we don't set TXEN, kdbg disables the transmitter 00213 * after each output statement until the serial driver 00214 * is initialized. These glitches confuse the debug 00215 * terminal that ends up printing some trash. 00216 */ 00217 #ifndef KDBG_UART3_BUS_INIT 00218 #define KDBG_UART3_BUS_INIT do { \ 00219 UCSR3B = BV(TXEN3); \ 00220 } while (0) 00221 #endif 00222 #ifndef KDBG_UART3_BUS_RX 00223 #define KDBG_UART3_BUS_RX do {} while (0) 00224 #endif 00225 #ifndef KDBG_UART3_BUS_TX 00226 #define KDBG_UART3_BUS_TX do {} while (0) 00227 #endif 00228 00229 #define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR3A, UDRE3); } while(0) 00230 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR3A, TXC3); } while(0) 00231 #define KDBG_WRITE_CHAR(c) do { UCSR3A |= BV(TXC3); UDR3 = (c); } while(0) 00232 00233 #define KDBG_MASK_IRQ(old) do { \ 00234 (old) = UCSR3B; \ 00235 UCSR3B |= BV(TXEN3); \ 00236 UCSR3B &= ~(BV(TXCIE3) | BV(UDRIE3)); \ 00237 KDBG_UART3_BUS_TX; \ 00238 } while(0) 00239 00240 #define KDBG_RESTORE_IRQ(old) do { \ 00241 KDBG_WAIT_TXDONE(); \ 00242 KDBG_UART3_BUS_RX; \ 00243 UCSR3B = (old); \ 00244 } while(0) 00245 00246 typedef uint8_t kdbg_irqsave_t; 00247 00248 00249 /* 00250 * Special debug port for BitBanged Serial see below for details... 00251 */ 00252 #elif CONFIG_KDEBUG_PORT == 666 00253 #include "hw/hw_ser.h" 00254 #define KDBG_WAIT_READY() do { /*nop*/ } while(0) 00255 #define KDBG_WRITE_CHAR(c) _kdebug_bitbang_putchar((c)) 00256 #define KDBG_MASK_IRQ(old) do { IRQ_SAVE_DISABLE((old)); } while(0) 00257 #define KDBG_RESTORE_IRQ(old) do { IRQ_RESTORE((old)); } while(0) 00258 typedef cpu_flags_t kdbg_irqsave_t; 00259 00260 #define KDBG_DELAY (((CPU_FREQ + CONFIG_KDEBUG_BAUDRATE / 2) / CONFIG_KDEBUG_BAUDRATE) + 7) / 14 00261 00262 static void _kdebug_bitbang_delay(void) 00263 { 00264 unsigned long i; 00265 00266 for (i = 0; i < KDBG_DELAY; i++) 00267 { 00268 NOP; 00269 NOP; 00270 NOP; 00271 NOP; 00272 NOP; 00273 } 00274 } 00275 00285 static void _kdebug_bitbang_putchar(char c) 00286 { 00287 int i; 00288 uint16_t data = c; 00289 00290 /* Add stop bit */ 00291 data |= 0x0100; 00292 00293 /* Add start bit*/ 00294 data <<= 1; 00295 00296 /* Shift out data */ 00297 uint16_t shift = 1; 00298 for (i = 0; i < 10; i++) 00299 { 00300 if (data & shift) 00301 SER_BITBANG_HIGH; 00302 else 00303 SER_BITBANG_LOW; 00304 _kdebug_bitbang_delay(); 00305 shift <<= 1; 00306 } 00307 } 00308 #else 00309 #error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3 or 666 00310 #endif 00311 00312 00313 INLINE void kdbg_hw_init(void) 00314 { 00315 #if CONFIG_KDEBUG_PORT == 666 00316 SER_BITBANG_INIT; 00317 #else /* CONFIG_KDEBUG_PORT != 666 */ 00318 /* Compute the baud rate */ 00319 uint16_t period = DIV_ROUND(CPU_FREQ / 16UL, CONFIG_KDEBUG_BAUDRATE) - 1; 00320 00321 #if (CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 \ 00322 || CPU_AVR_ATMEGA324P || CPU_AVR_ATMEGA644P) 00323 #if CONFIG_KDEBUG_PORT == 0 00324 UBRR0H = (uint8_t)(period>>8); 00325 UBRR0L = (uint8_t)period; 00326 KDBG_UART0_BUS_INIT; 00327 #elif CONFIG_KDEBUG_PORT == 1 00328 UBRR1H = (uint8_t)(period>>8); 00329 UBRR1L = (uint8_t)period; 00330 KDBG_UART1_BUS_INIT; 00331 #else 00332 #error CONFIG_KDEBUG_PORT must be either 0 or 1 00333 #endif 00334 00335 #elif CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560 00336 #if CONFIG_KDEBUG_PORT == 0 00337 UBRR0H = (uint8_t)(period>>8); 00338 UBRR0L = (uint8_t)period; 00339 KDBG_UART0_BUS_INIT; 00340 #elif CONFIG_KDEBUG_PORT == 1 00341 UBRR1H = (uint8_t)(period>>8); 00342 UBRR1L = (uint8_t)period; 00343 KDBG_UART1_BUS_INIT; 00344 #elif CONFIG_KDEBUG_PORT == 2 00345 UBRR2H = (uint8_t)(period>>8); 00346 UBRR2L = (uint8_t)period; 00347 KDBG_UART2_BUS_INIT; 00348 #elif CONFIG_KDEBUG_PORT == 3 00349 UBRR3H = (uint8_t)(period>>8); 00350 UBRR3L = (uint8_t)period; 00351 KDBG_UART3_BUS_INIT; 00352 #else 00353 #error CONFIG_KDEBUG_PORT must be either 0 or 1 or 2 or 3 00354 #endif 00355 00356 #elif CPU_AVR_ATMEGA88P || CPU_AVR_ATMEGA168 || CPU_AVR_ATMEGA328P 00357 #if CONFIG_KDEBUG_PORT == 0 00358 UBRR0H = (uint8_t)(period>>8); 00359 UBRR0L = (uint8_t)period; 00360 UCSR0A = 0; /* The Arduino Uno bootloader turns on U2X0 */ 00361 KDBG_UART0_BUS_INIT; 00362 #else 00363 #error Only CONFIG_KDEBUG_PORT 0 is supported for this cpu 00364 #endif 00365 00366 #elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32 00367 #if CONFIG_KDEBUG_PORT == 0 00368 UBRRH = (uint8_t)(period>>8); 00369 UBRRL = (uint8_t)period; 00370 KDBG_UART0_BUS_INIT; 00371 #else 00372 #error Only CONFIG_KDEBUG_PORT 0 is supported for this cpu 00373 #endif 00374 #elif CPU_AVR_ATMEGA103 00375 #if CONFIG_KDEBUG_PORT == 0 00376 UBRR = (uint8_t)period; 00377 KDBG_UART0_BUS_INIT; 00378 #else 00379 #error Only CONFIG_KDEBUG_PORT 0 is supported for this cpu 00380 #endif 00381 #else 00382 #error Unknown CPU 00383 #endif 00384 #endif /* CONFIG_KDEBUG_PORT == 666 */ 00385 } 00386
![(please configure the [header_logo] section in trac.ini)](/chrome/site/bertos_logo.png)