kdebug_avr.c
Go to the documentation of this file.00001
00042 #include "hw/hw_cpu.h"
00043 #include "hw/hw_ser.h"
00044
00045 #include "cfg/cfg_debug.h"
00046 #include <cfg/macros.h>
00047
00048 #include <cpu/types.h>
00049 #include <cpu/attr.h>
00050
00051 #include <avr/io.h>
00052
00053 #if CONFIG_KDEBUG_PORT == 0
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifndef KDBG_UART0_BUS_INIT
00065 #define KDBG_UART0_BUS_INIT do { \
00066 UCR = BV(TXEN0); \
00067 } while (0)
00068 #endif
00069 #ifndef KDBG_UART0_BUS_RX
00070 #define KDBG_UART0_BUS_RX do {} while (0)
00071 #endif
00072 #ifndef KDBG_UART0_BUS_TX
00073 #define KDBG_UART0_BUS_TX do {} while (0)
00074 #endif
00075
00076 #if CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168
00077 #define UCR UCSR0B
00078 #define UDR UDR0
00079 #define USR UCSR0A
00080 #elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32
00081 #define UCR UCSRB
00082 #define USR UCSRA
00083 #define TXEN0 TXEN
00084 #define UDRE0 UDRE
00085 #define TXC0 TXC
00086 #define TXCIE0 TXCIE
00087 #define UDRIE0 UDRIE
00088 #else
00089 #error Unknown CPU
00090 #endif
00091
00092 #define KDBG_WAIT_READY() do { loop_until_bit_is_set(USR, UDRE0); } while(0)
00093 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(USR, TXC0); } while(0)
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #define KDBG_WRITE_CHAR(c) do { USR |= BV(TXC0); UDR = (c); } while(0)
00105
00106 #define KDBG_MASK_IRQ(old) do { \
00107 (old) = UCR; \
00108 UCR |= BV(TXEN0); \
00109 UCR &= ~(BV(TXCIE0) | BV(UDRIE0)); \
00110 KDBG_UART0_BUS_TX; \
00111 } while(0)
00112
00113 #define KDBG_RESTORE_IRQ(old) do { \
00114 KDBG_WAIT_TXDONE(); \
00115 KDBG_UART0_BUS_RX; \
00116 UCR = (old); \
00117 } while(0)
00118
00119 typedef uint8_t kdbg_irqsave_t;
00120
00121 #elif CONFIG_KDEBUG_PORT == 1
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 #ifndef KDBG_UART1_BUS_INIT
00133 #define KDBG_UART1_BUS_INIT do { \
00134 UCSR1B = BV(TXEN1); \
00135 } while (0)
00136 #endif
00137 #ifndef KDBG_UART1_BUS_RX
00138 #define KDBG_UART1_BUS_RX do {} while (0)
00139 #endif
00140 #ifndef KDBG_UART1_BUS_TX
00141 #define KDBG_UART1_BUS_TX do {} while (0)
00142 #endif
00143
00144 #define KDBG_WAIT_READY() do { loop_until_bit_is_set(UCSR1A, UDRE1); } while(0)
00145 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set(UCSR1A, TXC1); } while(0)
00146 #define KDBG_WRITE_CHAR(c) do { UCSR1A |= BV(TXC1); UDR1 = (c); } while(0)
00147
00148 #define KDBG_MASK_IRQ(old) do { \
00149 (old) = UCSR1B; \
00150 UCSR1B |= BV(TXEN1); \
00151 UCSR1B &= ~(BV(TXCIE1) | BV(UDRIE1)); \
00152 KDBG_UART1_BUS_TX; \
00153 } while(0)
00154
00155 #define KDBG_RESTORE_IRQ(old) do { \
00156 KDBG_WAIT_TXDONE(); \
00157 KDBG_UART1_BUS_RX; \
00158 UCSR1B = (old); \
00159 } while(0)
00160
00161 typedef uint8_t kdbg_irqsave_t;
00162
00163
00164
00165
00166 #elif CONFIG_KDEBUG_PORT == 666
00167 #include "hw/hw_ser.h"
00168 #define KDBG_WAIT_READY() do { } while(0)
00169 #define KDBG_WRITE_CHAR(c) _kdebug_bitbang_putchar((c))
00170 #define KDBG_MASK_IRQ(old) do { IRQ_SAVE_DISABLE((old)); } while(0)
00171 #define KDBG_RESTORE_IRQ(old) do { IRQ_RESTORE((old)); } while(0)
00172 typedef cpu_flags_t kdbg_irqsave_t;
00173
00174 #define KDBG_DELAY (((CLOCK_FREQ + CONFIG_KDEBUG_BAUDRATE / 2) / CONFIG_KDEBUG_BAUDRATE) + 7) / 14
00175
00176 static void _kdebug_bitbang_delay(void)
00177 {
00178 unsigned long i;
00179
00180 for (i = 0; i < KDBG_DELAY; i++)
00181 {
00182 NOP;
00183 NOP;
00184 NOP;
00185 NOP;
00186 NOP;
00187 }
00188 }
00189
00199 static void _kdebug_bitbang_putchar(char c)
00200 {
00201 int i;
00202 uint16_t data = c;
00203
00204
00205 data |= 0x0100;
00206
00207
00208 data <<= 1;
00209
00210
00211 uint16_t shift = 1;
00212 for (i = 0; i < 10; i++)
00213 {
00214 if (data & shift)
00215 SER_BITBANG_HIGH;
00216 else
00217 SER_BITBANG_LOW;
00218 _kdebug_bitbang_delay();
00219 shift <<= 1;
00220 }
00221 }
00222 #else
00223 #error CONFIG_KDEBUG_PORT should be either 0, 1 or 666
00224 #endif
00225
00226
00227 INLINE void kdbg_hw_init(void)
00228 {
00229 #if CONFIG_KDEBUG_PORT == 666
00230 SER_BITBANG_INIT;
00231 #else
00232
00233 uint16_t period = DIV_ROUND(CLOCK_FREQ / 16UL, CONFIG_KDEBUG_BAUDRATE) - 1;
00234
00235 #if (CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281)
00236 #if CONFIG_KDEBUG_PORT == 0
00237 UBRR0H = (uint8_t)(period>>8);
00238 UBRR0L = (uint8_t)period;
00239 KDBG_UART0_BUS_INIT;
00240 #elif CONFIG_KDEBUG_PORT == 1
00241 UBRR1H = (uint8_t)(period>>8);
00242 UBRR1L = (uint8_t)period;
00243 KDBG_UART1_BUS_INIT;
00244 #else
00245 #error CONFIG_KDEBUG_PORT must be either 0 or 1
00246 #endif
00247
00248 #elif CPU_AVR_ATMEGA168
00249 UBRR0H = (uint8_t)(period>>8);
00250 UBRR0L = (uint8_t)period;
00251 KDBG_UART0_BUS_INIT;
00252 #elif CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA32
00253 UBRRH = (uint8_t)(period>>8);
00254 UBRRL = (uint8_t)period;
00255 KDBG_UART0_BUS_INIT;
00256 #elif CPU_AVR_ATMEGA103
00257 UBRR = (uint8_t)period;
00258 KDBG_UART0_BUS_INIT;
00259 #else
00260 #error Unknown CPU
00261 #endif
00262 #endif
00263 }
00264