kdebug_stm32.c

Go to the documentation of this file.
00001 
00038 #include <cfg/macros.h> /* for BV() */
00039 #include <cfg/cfg_debug.h>
00040 #include <drv/gpio_stm32.h>
00041 #include <drv/clock_stm32.h> /* RCC */
00042 #include <io/stm32.h>
00043 #include "kdebug_stm32.h"
00044 
00045 #define CR1_RUN_SET               ((uint16_t)0x2000)  /* USART Enable MASK */
00046 #define CR1_RUN_RESET             ((uint16_t)0xDFFF)  /* USART Disable MASK */
00047 #define CR1_RWU_SET               ((uint16_t)0x0002)  /* USART mute mode Enable MASK */
00048 #define CR1_RWU_RESET             ((uint16_t)0xFFFD)  /* USART mute mode Enable MASK */
00049 #define CR1_SBK_SET               ((uint16_t)0x0001)  /* USART Break Character send MASK */
00050 #define CR1_CLEAR_MASK            ((uint16_t)0xE9F3)  /* USART CR1 MASK */
00051 
00052 #define CR2_MASK                  ((uint16_t)0xFFF0)  /* USART address MASK */
00053 #define CR2_LINE_SET              ((uint16_t)0x4000)  /* USART LIN Enable MASK */
00054 #define CR2_LINE_RESET            ((uint16_t)0xBFFF)  /* USART LIN Disable MASK */
00055 #define CR2_CLEAR_MASK            ((uint16_t)0xC0FF)  /* USART CR2 MASK */
00056 
00057 #define CR3_SCEN_SET              ((uint16_t)0x0020)  /* USART SC Enable MASK */
00058 #define CR3_SCEN_RESET            ((uint16_t)0xFFDF)  /* USART SC Disable MASK */
00059 #define CR3_NACK_SET              ((uint16_t)0x0010)  /* USART SC NACK Enable MASK */
00060 #define CR3_NACK_RESET            ((uint16_t)0xFFEF)  /* USART SC NACK Disable MASK */
00061 #define CR3_HDSEL_SET             ((uint16_t)0x0008)  /* USART Half-Duplex Enable MASK */
00062 #define CR3_HDSEL_RESET           ((uint16_t)0xFFF7)  /* USART Half-Duplex Disable MASK */
00063 #define CR3_IRLP_MASK             ((uint16_t)0xFFFB)  /* USART IrDA LowPower mode MASK */
00064 #define CR3_LBDL_MASK             ((uint16_t)0xFFDF)  /* USART LIN Break detection MASK */
00065 #define CR3_WAKE_MASK             ((uint16_t)0xF7FF)  /* USART WakeUp Method MASK */
00066 #define CR3_IREN_SET              ((uint16_t)0x0002)  /* USART IrDA Enable MASK */
00067 #define CR3_IREN_RESET            ((uint16_t)0xFFFD)  /* USART IrDA Disable MASK */
00068 #define CR3_CLEAR_MASK            ((uint16_t)0xFCFF)  /* USART CR3 MASK */
00069 
00070 #define GTPR_LSB_MASK             ((uint16_t)0x00FF)  /* Guard Time Register LSB MASK */
00071 #define GTPR_MSB_MASK             ((uint16_t)0xFF00)  /* Guard Time Register MSB MASK */
00072 
00073 #define USART_IT_MASK             ((uint16_t)0x001F)  /* USART Interrupt MASK */
00074 
00075 /* USART flags */
00076 #define USART_FLAG_CTS            ((uint16_t)0x0200)
00077 #define USART_FLAG_LBD            ((uint16_t)0x0100)
00078 #define USART_FLAG_TXE            ((uint16_t)0x0080)
00079 #define USART_FLAG_TC             ((uint16_t)0x0040)
00080 #define USART_FLAG_RXNE           ((uint16_t)0x0020)
00081 #define USART_FLAG_IDLE           ((uint16_t)0x0010)
00082 #define USART_FLAG_ORE            ((uint16_t)0x0008)
00083 #define USART_FLAG_NE             ((uint16_t)0x0004)
00084 #define USART_FLAG_FE             ((uint16_t)0x0002)
00085 #define USART_FLAG_PE             ((uint16_t)0x0001)
00086 
00087 /* USART registers */
00088 struct stm32_usart
00089 {
00090     reg16_t SR;
00091     uint16_t _RESERVED0;
00092     reg16_t DR;
00093     uint16_t _RESERVED1;
00094     reg16_t BRR;
00095     uint16_t _RESERVED2;
00096     reg16_t CR1;
00097     uint16_t _RESERVED3;
00098     reg16_t CR2;
00099     uint16_t _RESERVED4;
00100     reg16_t CR3;
00101     uint16_t _RESERVED5;
00102     reg16_t GTPR;
00103     uint16_t _RESERVED6;
00104 };
00105 
00106 /* USART mode */
00107 #define USART_MODE_RX             ((uint16_t)0x0004)
00108 #define USART_MODE_TX             ((uint16_t)0x0008)
00109 
00110 /* USART last bit */
00111 #define USART_LASTBIT_DISABLE     ((uint16_t)0x0000)
00112 #define USART_LASTBIT_ENABLE      ((uint16_t)0x0100)
00113 
00114 #if CONFIG_KDEBUG_PORT == 0
00115     #define UART_BASE ((struct stm32_usart *)USART1_BASE)
00116 #elif CONFIG_KDEBUG_PORT == 1
00117     #define UART_BASE ((struct stm32_usart *)USART2_BASE)
00118 #elif CONFIG_KDEBUG_PORT == 2
00119     #define UART_BASE ((struct stm32_usart *)USART3_BASE)
00120 #else
00121     #error "UART port not supported in this board"
00122 #endif
00123 
00124 #define KDBG_WAIT_READY()   while (!(UART_BASE->SR & USART_FLAG_TXE))
00125 #define KDBG_WAIT_TXDONE()  while (!(UART_BASE->SR & USART_FLAG_TC))
00126 
00127 #define KDBG_WRITE_CHAR(c)  do { UART_BASE->DR = (c) & 0x1ff; } while(0)
00128 
00129 /* Debug unit is used only for debug purposes so does not generate interrupts. */
00130 #define KDBG_MASK_IRQ(old)  do { (void)old; } while(0)
00131 
00132 /* Debug unit is used only for debug purposes so does not generate interrupts. */
00133 #define KDBG_RESTORE_IRQ(old)   do { (void)old; } while(0)
00134 
00135 typedef uint32_t kdbg_irqsave_t;
00136 
00137 #define GPIO_USART1_TX_PIN  (1 << 9)
00138 #define GPIO_USART1_RX_PIN  (1 << 10)
00139 
00140 #define GPIO_USART2_TX_PIN  (1 << 2)
00141 #define GPIO_USART2_RX_PIN  (1 << 3)
00142 
00143 #define GPIO_USART3_TX_PIN  (1 << 13)
00144 #define GPIO_USART3_RX_PIN  (1 << 14)
00145 
00146 INLINE uint16_t evaluate_brr(void)
00147 {
00148     uint32_t freq, reg, div, frac;
00149 
00150     /* NOTE: PCLK1 has been configured as CPU_FREQ / 2 */
00151     freq = (CONFIG_KDEBUG_PORT == 0) ? CPU_FREQ : CPU_FREQ / 2;
00152     div = (0x19 * freq) / (0x04 * CONFIG_KDEBUG_BAUDRATE);
00153     reg = (div / 0x64) << 0x04;
00154     frac = div - (0x64 * (reg >> 0x04));
00155     reg |= ((frac * 0x10 + 0x32) / 0x64) & 0x0f;
00156 
00157     return (uint16_t)reg;
00158 }
00159 
00160 /* Initialize UART debug port */
00161 INLINE void kdbg_hw_init(void)
00162 {
00163     /* Enable clocking on AFIO */
00164     RCC->APB2ENR |= RCC_APB2_AFIO;
00165     /* Configure USART pins */
00166 #if CONFIG_KDEBUG_PORT == 0
00167     RCC->APB2ENR |= RCC_APB2_GPIOA;
00168     RCC->APB2ENR |= RCC_APB2_USART1;
00169     stm32_gpioPinConfig((struct stm32_gpio *)GPIOA_BASE, GPIO_USART1_TX_PIN,
00170                 GPIO_MODE_AF_PP, GPIO_SPEED_50MHZ);
00171 #elif CONFIG_KDEBUG_PORT == 1
00172     RCC->APB2ENR |= RCC_APB2_GPIOA;
00173     RCC->APB1ENR |= RCC_APB1_USART2;
00174     stm32_gpioPinConfig((struct stm32_gpio *)GPIOA_BASE, GPIO_USART2_TX_PIN,
00175                 GPIO_MODE_AF_PP, GPIO_SPEED_50MHZ);
00176 #elif  CONFIG_KDEBUG_PORT == 2
00177     RCC->APB2ENR |= RCC_APB2_GPIOB;
00178     RCC->APB2ENR |= RCC_APB1_USART3;
00179     stm32_gpioPinConfig((struct stm32_gpio *)GPIOB_BASE, GPIO_USART3_TX_PIN,
00180                 GPIO_MODE_AF_PP, GPIO_SPEED_50MHZ);
00181 #else
00182     #error "UART port not supported in this board"
00183 #endif
00184     /* Enable the USART by writing the UE bit */
00185     UART_BASE->CR1 |= CR1_RUN_SET;
00186     /* Configure the desired baud rate */
00187     UART_BASE->BRR = evaluate_brr();
00188     /* Set the Transmitter Enable bit in CR1 */
00189     UART_BASE->CR1 |= USART_MODE_TX;
00190 }