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