00001
00038 #include "ser_stm32.h"
00039
00040 #include "cfg/cfg_ser.h"
00041
00042 #include <cfg/macros.h>
00043 #include <cfg/debug.h>
00044
00045 #include <drv/gpio_stm32.h>
00046 #include <drv/irq_cm3.h>
00047 #include <drv/clock_stm32.h>
00048 #include <drv/ser_p.h>
00049 #include <drv/ser.h>
00050
00051
00052
00053 extern struct Serial *ser_handles[SER_CNT];
00054
00055 struct CM3Serial
00056 {
00057 struct SerialHardware hw;
00058 volatile bool sending;
00059 uint32_t base;
00060 sysirq_t irq;
00061 };
00062
00063
00064 static struct CM3Serial UARTDesc[SER_CNT];
00065
00066
00067 struct gpio_uart_info
00068 {
00069
00070 uint32_t base;
00071
00072 uint32_t rx_pin;
00073 uint32_t tx_pin;
00074
00075 uint32_t sysctl_gpio;
00076 uint32_t sysctl_usart;
00077
00078 };
00079
00080
00081 static const struct gpio_uart_info gpio_uart[SER_CNT] =
00082 {
00083
00084 {
00085 .base = GPIOA_BASE,
00086 .rx_pin = GPIO_USART1_RX_PIN,
00087 .tx_pin = GPIO_USART1_TX_PIN,
00088 .sysctl_gpio = RCC_APB2_GPIOA,
00089 .sysctl_usart = RCC_APB2_USART1,
00090 },
00091
00092 {
00093 .base = GPIOA_BASE,
00094 .rx_pin = GPIO_USART2_RX_PIN,
00095 .tx_pin = GPIO_USART2_TX_PIN,
00096 .sysctl_gpio = RCC_APB2_GPIOA,
00097 .sysctl_usart = RCC_APB1_USART2,
00098 },
00099 #if CPU_CM3_STM32F103RB || CPU_CM3_STM32F103RE
00100
00101 {
00102 .base = GPIOB_BASE,
00103 .rx_pin = GPIO_USART3_RX_PIN,
00104 .tx_pin = GPIO_USART3_TX_PIN,
00105 .sysctl_gpio = RCC_APB2_GPIOB,
00106 .sysctl_usart = RCC_APB1_USART3,
00107 },
00108 #endif
00109 };
00110
00111 #define USART1_PORT 0
00112 #define USART2_PORT 1
00113 #define USART3_PORT 2
00114
00115 void stm32_uartSetBaudRate(uint32_t base, unsigned long baud)
00116 {
00117 struct stm32_usart *_base = (struct stm32_usart *)base;
00118 _base->BRR = evaluate_brr(_base, CPU_FREQ, baud);
00119 }
00120
00121 void stm32_uartSetParity(uint32_t base, int parity)
00122 {
00123 struct stm32_usart *_base = (struct stm32_usart *)base;
00124
00125
00126 _base->CR1 &= ~BV(CR1_M);
00127
00128 switch(parity)
00129 {
00130 case SER_PARITY_NONE:
00131 _base->CR1 &= ~BV(CR1_PCE);
00132 break;
00133 case SER_PARITY_ODD:
00134 _base->CR1 |= (BV(CR1_PCE) | BV(CR1_PS));
00135 break;
00136 case SER_PARITY_EVEN:
00137 _base->CR1 |= BV(CR1_PCE);
00138 _base->CR1 &= ~BV(CR1_PS);
00139 break;
00140 default:
00141 ASSERT(0);
00142 return;
00143 }
00144 }
00145
00146 void stm32_uartInit(int port)
00147 {
00148 struct stm32_usart *base = (struct stm32_usart *)UARTDesc[port].base;
00149
00150 ASSERT(port >= 0 && port < SER_CNT);
00151
00152
00153 RCC->APB2ENR |= RCC_APB2_AFIO;
00154 RCC->APB2ENR |= gpio_uart[port].sysctl_gpio;
00155
00156
00157 if (port == USART1_PORT)
00158 {
00159 RCC->APB2ENR |= gpio_uart[port].sysctl_usart;
00160 }
00161 else
00162 {
00163 RCC->APB1ENR |= gpio_uart[port].sysctl_usart;
00164 }
00165
00166 stm32_gpioPinConfig((struct stm32_gpio *)gpio_uart[port].base, gpio_uart[port].tx_pin,
00167 GPIO_MODE_AF_PP, GPIO_SPEED_50MHZ);
00168
00169 stm32_gpioPinConfig((struct stm32_gpio *)gpio_uart[port].base, gpio_uart[port].rx_pin,
00170 GPIO_MODE_IN_FLOATING, GPIO_SPEED_50MHZ);
00171
00172
00173 base->CR2 = 0;
00174 base->CR1 = 0;
00175 base->CR3 = 0;
00176 base->SR = 0;
00177
00178
00179 stm32_uartSetBaudRate(UARTDesc[port].base, 115200);
00180 stm32_uartSetParity(UARTDesc[port].base, SER_PARITY_NONE);
00181
00182
00183
00184 base->CR1 |= (BV(CR1_TE) | BV(CR1_RE));
00185
00186 }
00187
00188 static bool tx_sending(struct SerialHardware *_hw)
00189 {
00190 struct CM3Serial *hw = (struct CM3Serial *)_hw;
00191 return hw->sending;
00192 }
00193
00194 static void uart_irq_rx(int port)
00195 {
00196 struct FIFOBuffer *rxfifo = &ser_handles[port]->rxfifo;
00197 struct stm32_usart *base = (struct stm32_usart *)UARTDesc[port].base;
00198 char c;
00199
00200 while (stm32_uartRxReady(UARTDesc[port].base))
00201 {
00202 c = base->DR;
00203 if (fifo_isfull(rxfifo))
00204 ser_handles[port]->status |= SERRF_RXFIFOOVERRUN;
00205 else
00206 fifo_push(rxfifo, c);
00207 }
00208 }
00209
00210 static void uart_irq_tx(int port)
00211 {
00212 struct FIFOBuffer *txfifo = &ser_handles[port]->txfifo;
00213 struct stm32_usart *base = (struct stm32_usart *)UARTDesc[port].base;
00214
00215 if (fifo_isempty(txfifo))
00216 {
00217
00218
00219
00220
00221 base->CR1 &= ~BV(CR1_TXEIE);
00222 UARTDesc[port].sending = false;
00223 }
00224 else
00225 {
00226 base->DR = fifo_pop(txfifo);
00227 }
00228 }
00229
00230 static void uart_common_irq_handler(int port)
00231 {
00232 struct stm32_usart *base = (struct stm32_usart *)UARTDesc[port].base;
00233 uint32_t status;
00234
00235
00236 status = base->SR;
00237
00238
00239 ser_handles[port]->status = status &
00240 (BV(SR_ORE) | BV(SR_FE) | BV(SR_PE) | BV(SR_NE));
00241
00242
00243 if (status & BV(CR1_RXNEIE))
00244 {
00245 uart_irq_rx(port);
00246 }
00247 if (status & (BV(CR1_TXEIE) | BV(CR1_TCIE)))
00248 {
00249 uart_irq_tx(port);
00250 }
00251 }
00252
00253 static void stm32_uartIRQEnable(int port, sysirq_handler_t handler)
00254 {
00255 struct stm32_usart *base = (struct stm32_usart *)UARTDesc[port].base;
00256
00257
00258 sysirq_setHandler(UARTDesc[port].irq, handler);
00259
00260 base->CR1 |= BV(CR1_RXNEIE);
00261 }
00262
00263 static void stm32_uartIRQDisable(int port)
00264 {
00265 struct stm32_usart *base = (struct stm32_usart *)UARTDesc[port].base;
00266
00267 base->CR1 &= ~(BV(CR1_RXNEIE) | USART_FLAG_TXE);
00268 }
00269
00270
00271
00272 #define UART_PORT(port) \
00273 \
00274 static unsigned char uart ## port ## _txbuffer[CONFIG_UART ## port ## _TXBUFSIZE]; \
00275 static unsigned char uart ## port ## _rxbuffer[CONFIG_UART ## port ## _RXBUFSIZE]; \
00276 \
00277 \
00278 static DECLARE_ISR(uart ## port ## _irq_handler) \
00279 { \
00280 uart_common_irq_handler(USART ## port ## _PORT); \
00281 } \
00282 \
00283 \
00284 static void uart ## port ## _txStart(struct SerialHardware *_hw) \
00285 { \
00286 struct FIFOBuffer *txfifo = &ser_handles[USART ## port ## _PORT]->txfifo; \
00287 struct CM3Serial *hw = (struct CM3Serial *)_hw; \
00288 struct stm32_usart *base = (struct stm32_usart *)USART## port ## _BASE; \
00289 if (hw->sending) \
00290 return; \
00291 stm32_uartPutChar(USART ## port ## _BASE, fifo_pop(txfifo)); \
00292 if (!fifo_isempty(txfifo)) \
00293 { \
00294 hw->sending = true; \
00295 base->CR1 |= BV(CR1_TXEIE); \
00296 } \
00297 } \
00298 \
00299 static void uart ## port ## _setbaudrate(UNUSED_ARG(struct SerialHardware *, hw), \
00300 unsigned long baud) \
00301 { \
00302 stm32_uartSetBaudRate(USART## port ## _BASE, baud); \
00303 } \
00304 \
00305 static void uart ## port ## _setparity(UNUSED_ARG(struct SerialHardware *, hw), \
00306 int parity) \
00307 { \
00308 stm32_uartSetParity(USART## port ## _BASE, parity); \
00309 } \
00310 \
00311 static void uart ## port ## _cleanup(struct SerialHardware *_hw) \
00312 { \
00313 struct CM3Serial *hw = (struct CM3Serial *)_hw; \
00314 hw->sending = false; \
00315 stm32_uartIRQDisable(USART ## port ## _PORT); \
00316 stm32_uartClear(USART## port ## _BASE); \
00317 stm32_uartDisable(USART## port ## _BASE); \
00318 } \
00319 \
00320 static void uart ## port ## _init(UNUSED_ARG(struct SerialHardware *, hw), \
00321 UNUSED_ARG(struct Serial *, ser)) \
00322 { \
00323 stm32_uartInit(USART ## port ## _PORT); \
00324 stm32_uartEnable(USART## port ## _BASE); \
00325 stm32_uartIRQEnable(USART ## port ## _PORT, uart ## port ## _irq_handler); \
00326 } \
00327 \
00328 \
00329 static const struct SerialHardwareVT USART ## port ## _VT = \
00330 { \
00331 .init = uart ## port ## _init, \
00332 .cleanup = uart ## port ## _cleanup, \
00333 .setBaudrate = uart ## port ## _setbaudrate, \
00334 .setParity = uart ## port ## _setparity, \
00335 .txStart = uart ## port ## _txStart, \
00336 .txSending = tx_sending, \
00337 };
00338
00339
00340 UART_PORT(1)
00341 UART_PORT(2)
00342 #if CPU_CM3_STM32F103RB || CPU_CM3_STM32F103RE
00343 UART_PORT(3)
00344 #endif
00345
00346 static struct CM3Serial UARTDesc[SER_CNT] =
00347 {
00348 {
00349 .hw = {
00350 .table = &USART1_VT,
00351 .txbuffer = uart1_txbuffer,
00352 .rxbuffer = uart1_rxbuffer,
00353 .txbuffer_size = sizeof(uart1_txbuffer),
00354 .rxbuffer_size = sizeof(uart1_rxbuffer),
00355 },
00356 .sending = false,
00357 .base = USART1_BASE,
00358 .irq = USART1_IRQHANDLER,
00359 },
00360 {
00361 .hw = {
00362 .table = &USART2_VT,
00363 .txbuffer = uart2_txbuffer,
00364 .rxbuffer = uart2_rxbuffer,
00365 .txbuffer_size = sizeof(uart2_txbuffer),
00366 .rxbuffer_size = sizeof(uart2_rxbuffer),
00367 },
00368 .sending = false,
00369 .base = USART2_BASE,
00370 .irq = USART2_IRQHANDLER,
00371 },
00372 #if CPU_CM3_STM32F103RB || CPU_CM3_STM32F103RE
00373 {
00374 .hw = {
00375 .table = &USART3_VT,
00376 .txbuffer = uart3_txbuffer,
00377 .rxbuffer = uart3_rxbuffer,
00378 .txbuffer_size = sizeof(uart3_txbuffer),
00379 .rxbuffer_size = sizeof(uart3_rxbuffer),
00380 },
00381 .sending = false,
00382 .base = USART3_BASE,
00383 .irq = USART3_IRQHANDLER,
00384 },
00385 #endif
00386 };
00387
00388 struct SerialHardware *ser_hw_getdesc(int port)
00389 {
00390 ASSERT(port >= 0 && port < SER_CNT);
00391 return &UARTDesc[port].hw;
00392 }