kdebug_xmega.c
Go to the documentation of this file.00001
00045 #include <hw/hw_cpufreq.h>
00046 #include "hw/hw_ser.h"
00047
00048 #include "cfg/cfg_debug.h"
00049 #include <cfg/macros.h>
00050
00051 #include <cpu/types.h>
00052 #include <cpu/attr.h>
00053
00054 #include <avr/io.h>
00055
00056
00057
00058
00059
00060 #if CONFIG_KDEBUG_PORT == 0
00061 #define KDBG_USART USARTC0
00062 #define KDBG_USART_PORT PORTC
00063 #define KDBG_USART_TX_PIN_bm PIN3_bm
00064 #elif CONFIG_KDEBUG_PORT == 1
00065 #define KDBG_USART USARTD0
00066 #define KDBG_USART_PORT PORTD
00067 #define KDBG_USART_TX_PIN_bm PIN3_bm
00068 #endif
00069
00070
00071
00072 #ifdef CPU_AVR_XMEGA_A
00073 #if CONFIG_KDEBUG_PORT == 2
00074 #define KDBG_USART USARTC1
00075 #define KDBG_USART_PORT PORTC
00076 #define KDBG_USART_TX_PIN_bm PIN7_bm
00077 #elif CONFIG_KDEBUG_PORT == 3
00078 #define KDBG_USART USARTD1
00079 #define KDBG_USART_PORT PORTD
00080 #define KDBG_USART_TX_PIN_bm PIN7_bm
00081 #elif CONFIG_KDEBUG_PORT == 4
00082 #define KDBG_USART USARTE0
00083 #define KDBG_USART_PORT PORTE
00084 #define KDBG_USART_TX_PIN_bm PIN3_bm
00085 #endif
00086 #endif
00087
00088
00089 #ifndef KDBG_USART
00090 #if CPU_AVR_XMEGA_D
00091 #error CONFIG_KDEBUG_PORT should be either 0 or 1
00092 #elif CPU_AVR_XMEGA_A
00093 #error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3 or 4
00094 #endif
00095 #endif
00096
00097
00098
00099
00100
00101
00102 #ifndef KDBG_USART_SCALE_FACTOR
00103 #define KDBG_USART_SCALE_FACTOR (-7)
00104 #else
00105 #if KDBG_USART_SCALE_FACTOR > 7 || KDBG_USART_SCALE_FACTOR < -7
00106 #error KDBG_USART_SCALE_FACTOR should be an integer between -7 and 7
00107 #endif
00108 #endif
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 #define KDBG_SET_FORMAT(_charSize, _parityMode, _twoStopBits) \
00122 (KDBG_USART).CTRLC = (uint8_t) _charSize | _parityMode | \
00123 (_twoStopBits ? USART_SBMODE_bm : 0)
00124
00125 #define KDBG_SET_BAUDRATE(_bselValue, _bScaleFactor) \
00126 (KDBG_USART).BAUDCTRLA =(uint8_t)_bselValue; \
00127 (KDBG_USART).BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)
00128
00129 #define KDBG_TX_ENABLE() ((KDBG_USART).CTRLB |= USART_TXEN_bm)
00130
00131 #define KDBG_SET_MODE(_usartMode) \
00132 ((KDBG_USART).CTRLC = ((KDBG_USART).CTRLC & (~USART_CMODE_gm)) | _usartMode)
00133
00134 #define KDBG_WAIT_READY() do{ loop_until_bit_is_set((KDBG_USART).STATUS, USART_DREIF_bp); } while(0)
00135 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set((KDBG_USART).STATUS, USART_TXCIF_bp); } while(0)
00136 #define KDBG_WRITE_CHAR(c) do { (KDBG_USART).DATA = (c); } while(0)
00137
00138 #define KDBG_SET_TX_INTERRUPTLEVEL(_txdIntLevel) \
00139 (KDBG_USART).CTRLA = ((KDBG_USART).CTRLA & ~USART_TXCINTLVL_gm) | _txdIntLevel
00140
00141 #define KDBG_SET_DRE_INTERRUPTLEVEL(_dreIntLevel) \
00142 (KDBG_USART).CTRLA = ((KDBG_USART).CTRLA & ~USART_DREINTLVL_gm) | _dreIntLevel
00143
00144
00145
00146
00147
00148
00149
00150
00151 struct kdbg_avr_xmega_irqsave
00152 {
00153 uint8_t ctrlb;
00154 uint8_t ctrla;
00155 };
00156 typedef struct kdbg_avr_xmega_irqsave kdbg_irqsave_t;
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 #define KDBG_MASK_IRQ(old) do { \
00167 (old).ctrlb = KDBG_USART.CTRLB; \
00168 (old).ctrla = KDBG_USART.CTRLA; \
00169 KDBG_SET_TX_INTERRUPTLEVEL(USART_TXCINTLVL_OFF_gc); \
00170 KDBG_SET_DRE_INTERRUPTLEVEL(USART_DREINTLVL_OFF_gc); \
00171 KDBG_TX_ENABLE(); \
00172 } while(0)
00173
00174
00175
00176
00177
00178
00179
00180 #define KDBG_RESTORE_IRQ(old) do { \
00181 KDBG_WAIT_TXDONE(); \
00182 KDBG_USART.CTRLB = (old).ctrlb; \
00183 KDBG_USART.CTRLA = (old).ctrla; \
00184 } while(0)
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 INLINE void kdbg_hw_init(void)
00196 {
00197
00198 KDBG_USART_PORT.OUT = KDBG_USART_PORT.OUT & ~KDBG_USART_TX_PIN_bm;
00199 KDBG_USART_PORT.DIRSET = KDBG_USART_TX_PIN_bm;
00200
00201 KDBG_SET_FORMAT(USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);
00202
00203
00204 #if KDBG_USART_SCALE_FACTOR < 0
00205 uint16_t bsel = DIV_ROUND((1 << (-(KDBG_USART_SCALE_FACTOR))) * (CPU_FREQ - (16 * CONFIG_KDEBUG_BAUDRATE)), 16 * CONFIG_KDEBUG_BAUDRATE);
00206 #else
00207 uint16_t bsel = DIV_ROUND(CPU_FREQ, (1 << (KDBG_USART_SCALE_FACTOR)) * 16 * CONFIG_KDEBUG_BAUDRATE) - 1;
00208 #endif
00209 KDBG_SET_BAUDRATE(bsel, KDBG_USART_SCALE_FACTOR);
00210
00211 KDBG_TX_ENABLE();
00212 }