BeRTOS
|
00001 00044 #include <hw/hw_cpufreq.h> /* for CPU_FREQ */ 00045 #include "hw/hw_ser.h" /* Required for bus macros overrides */ 00046 00047 #include "cfg/cfg_debug.h" /* for debugging configuration settings */ 00048 #include <cfg/macros.h> /* for BV(), DIV_ROUND */ 00049 00050 #include <cpu/types.h> 00051 #include <cpu/attr.h> 00052 00053 #include <avr/io.h> 00054 00055 /* Set KDBG_USART, KDBG_USART_PORT and KDBG_USART_TX_PIN_bm 00056 * according to the CONFIG_KDEBUG_PORT setting 00057 * The Xmega A and D families support at least 2 UARTS 00058 */ 00059 #if CONFIG_KDEBUG_PORT == 0 00060 #define KDBG_USART USARTC0 00061 #define KDBG_USART_PORT PORTC 00062 #define KDBG_USART_TX_PIN_bm PIN3_bm 00063 #elif CONFIG_KDEBUG_PORT == 1 00064 #define KDBG_USART USARTD0 00065 #define KDBG_USART_PORT PORTD 00066 #define KDBG_USART_TX_PIN_bm PIN3_bm 00067 #endif 00068 /* Allow the configuration of the extra 3 UARTS for the 00069 * Xmega A family 00070 */ 00071 #ifdef CPU_AVR_XMEGA_A 00072 #if CONFIG_KDEBUG_PORT == 2 00073 #define KDBG_USART USARTC1 00074 #define KDBG_USART_PORT PORTC 00075 #define KDBG_USART_TX_PIN_bm PIN7_bm 00076 #elif CONFIG_KDEBUG_PORT == 3 00077 #define KDBG_USART USARTD1 00078 #define KDBG_USART_PORT PORTD 00079 #define KDBG_USART_TX_PIN_bm PIN7_bm 00080 #elif CONFIG_KDEBUG_PORT == 4 00081 #define KDBG_USART USARTE0 00082 #define KDBG_USART_PORT PORTE 00083 #define KDBG_USART_TX_PIN_bm PIN3_bm 00084 #endif 00085 #endif 00086 /* Check if all required KDBG_ macros are defined 00087 */ 00088 #ifndef KDBG_USART 00089 #if CPU_AVR_XMEGA_D 00090 #error CONFIG_KDEBUG_PORT should be either 0 or 1 00091 #elif CPU_AVR_XMEGA_A 00092 #error CONFIG_KDEBUG_PORT should be either 0, 1, 2, 3 or 4 00093 #endif 00094 #endif 00095 00096 /* 00097 * Scalefactor to use for computing the baudrate 00098 * this scalefactor should be an integer value between -7 00099 * and 7 00100 */ 00101 #ifndef KDBG_USART_SCALE_FACTOR 00102 #define KDBG_USART_SCALE_FACTOR (-7) 00103 #else 00104 #if KDBG_USART_SCALE_FACTOR > 7 || KDBG_USART_SCALE_FACTOR < -7 00105 #error KDBG_USART_SCALE_FACTOR should be an integer between -7 and 7 00106 #endif 00107 #endif 00108 00109 /* 00110 * \name KDBG macros 00111 * 00112 * Used to set or alter the KDB_USART operation, 00113 * enable the usart or send a byte. 00114 * Some of these methods are called/included from kdbg_hw_init() 00115 * others are called/included from the cpu independ kdebug implementation 00116 * These macros are heavily imspired by the examples provided by atmel 00117 * 00118 * \{ 00119 */ 00120 #define KDBG_SET_FORMAT(_charSize, _parityMode, _twoStopBits) \ 00121 (KDBG_USART).CTRLC = (uint8_t) _charSize | _parityMode | \ 00122 (_twoStopBits ? USART_SBMODE_bm : 0) 00123 00124 #define KDBG_SET_BAUDRATE(_bselValue, _bScaleFactor) \ 00125 (KDBG_USART).BAUDCTRLA =(uint8_t)_bselValue; \ 00126 (KDBG_USART).BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8) 00127 00128 #define KDBG_TX_ENABLE() ((KDBG_USART).CTRLB |= USART_TXEN_bm) 00129 00130 #define KDBG_SET_MODE(_usartMode) \ 00131 ((KDBG_USART).CTRLC = ((KDBG_USART).CTRLC & (~USART_CMODE_gm)) | _usartMode) 00132 00133 #define KDBG_WAIT_READY() do{ loop_until_bit_is_set((KDBG_USART).STATUS, USART_DREIF_bp); } while(0) 00134 #define KDBG_WAIT_TXDONE() do { loop_until_bit_is_set((KDBG_USART).STATUS, USART_TXCIF_bp); } while(0) 00135 #define KDBG_WRITE_CHAR(c) do { (KDBG_USART).DATA = (c); } while(0) 00136 00137 #define KDBG_SET_TX_INTERRUPTLEVEL(_txdIntLevel) \ 00138 (KDBG_USART).CTRLA = ((KDBG_USART).CTRLA & ~USART_TXCINTLVL_gm) | _txdIntLevel 00139 00140 #define KDBG_SET_DRE_INTERRUPTLEVEL(_dreIntLevel) \ 00141 (KDBG_USART).CTRLA = ((KDBG_USART).CTRLA & ~USART_DREINTLVL_gm) | _dreIntLevel 00142 00143 /*\}*/ 00144 00145 /* 00146 * To restore the USART state, to registers need to be restored 00147 * These registers (CTRLA and CTRLB) can be saved to the 00148 * kdbg_avr_xmaga_irqsave structure 00149 */ 00150 struct kdbg_avr_xmega_irqsave 00151 { 00152 uint8_t ctrlb; 00153 uint8_t ctrla; 00154 }; 00155 typedef struct kdbg_avr_xmega_irqsave kdbg_irqsave_t; 00156 00157 /* 00158 * param is the kdbg_irqsave_t structure 00159 * 00160 * * Stores the current state of the USART.CTRLA and 00161 * the USART.CTRLB registers 00162 * * Disables Transmit Complete and Date Register Empty interrupts 00163 * * Enabled the transmitter 00164 */ 00165 #define KDBG_MASK_IRQ(old) do { \ 00166 (old).ctrlb = KDBG_USART.CTRLB; \ 00167 (old).ctrla = KDBG_USART.CTRLA; \ 00168 KDBG_SET_TX_INTERRUPTLEVEL(USART_TXCINTLVL_OFF_gc); \ 00169 KDBG_SET_DRE_INTERRUPTLEVEL(USART_DREINTLVL_OFF_gc); \ 00170 KDBG_TX_ENABLE(); \ 00171 } while(0) 00172 00173 /* 00174 * param is the kdbg_irqsave_t structure 00175 * 00176 * * waits until all data has been transmitted 00177 * * restores the USART.CTRLA and USART.CTRLB registers 00178 */ 00179 #define KDBG_RESTORE_IRQ(old) do { \ 00180 KDBG_WAIT_TXDONE(); \ 00181 KDBG_USART.CTRLB = (old).ctrlb; \ 00182 KDBG_USART.CTRLA = (old).ctrla; \ 00183 } while(0) 00184 00185 00186 /* 00187 * method included from the cpu independent kdebug.c file. 00188 * it initializes KDBG_USART by: 00189 * * Setting the KDBG_USART_TX_PIN_bm as an outputpin 00190 * * Setting KDBG_USART to use 8 bits, No parity, 1 stopbit 00191 * * Setting the baudrate to 115200 00192 * * Enabeling the transmitter 00193 */ 00194 INLINE void kdbg_hw_init(void) 00195 { 00196 //set transmit pin as output 00197 KDBG_USART_PORT.OUT = KDBG_USART_PORT.OUT & ~KDBG_USART_TX_PIN_bm; 00198 KDBG_USART_PORT.DIRSET = KDBG_USART_TX_PIN_bm; 00199 //set 8 bits, no parity, 1 stop bit 00200 KDBG_SET_FORMAT(USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false); 00201 //compute and set the baud rate 00202 /* Compute baud-rate period, this requires a valid USART_SCALE_FACTOR */ 00203 #if KDBG_USART_SCALE_FACTOR < 0 00204 uint16_t bsel = DIV_ROUND((1 << (-(KDBG_USART_SCALE_FACTOR))) * (CPU_FREQ - (16 * CONFIG_KDEBUG_BAUDRATE)), 16 * CONFIG_KDEBUG_BAUDRATE); 00205 #else 00206 uint16_t bsel = DIV_ROUND(CPU_FREQ, (1 << (KDBG_USART_SCALE_FACTOR)) * 16 * CONFIG_KDEBUG_BAUDRATE) - 1; 00207 #endif 00208 KDBG_SET_BAUDRATE(bsel, KDBG_USART_SCALE_FACTOR); 00209 //enable the Transmitter 00210 KDBG_TX_ENABLE(); 00211 }