usart.c 18.2 KB
Newer Older
M
Ming, Bai 已提交
1
/*
2
 * Copyright (c) 2006-2018, RT-Thread Development Team
M
Ming, Bai 已提交
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
M
Ming, Bai 已提交
5 6 7 8 9
 *
 * Change Logs:
 * Date           Author       Notes
 * 2009-01-05     Bernard      the first version
 * 2010-03-29     Bernard      remove interrupt Tx and DMA Rx mode
10
 * 2013-05-13     aozima       update for kehong-lingtai.
11
 * 2015-01-31     armink       make sure the serial transmit complete in putc()
12
 * 2016-05-13     armink       add DMA Rx mode
13
 * 2017-01-19     aubr.cool    add interrupt Tx mode
14
 * 2017-04-13     aubr.cool    correct Rx parity err
M
Ming, Bai 已提交
15 16
 */

17
#include "stm32f10x.h"
M
Ming, Bai 已提交
18
#include "usart.h"
19 20
#include "board.h"
#include <rtdevice.h>
M
Ming, Bai 已提交
21

22
/* USART1 */
23 24 25
#define UART1_GPIO_TX        GPIO_Pin_9
#define UART1_GPIO_RX        GPIO_Pin_10
#define UART1_GPIO           GPIOA
26 27

/* USART2 */
28 29 30
#define UART2_GPIO_TX        GPIO_Pin_2
#define UART2_GPIO_RX        GPIO_Pin_3
#define UART2_GPIO           GPIOA
31 32

/* USART3_REMAP[1:0] = 00 */
33 34 35
#define UART3_GPIO_TX        GPIO_Pin_10
#define UART3_GPIO_RX        GPIO_Pin_11
#define UART3_GPIO           GPIOB
36

U
unknown 已提交
37 38 39 40 41 42
/* USART4 */
#define UART4_GPIO_TX        GPIO_Pin_10
#define UART4_GPIO_RX        GPIO_Pin_11
#define UART4_GPIO           GPIOC


43 44
/* STM32 uart driver */
struct stm32_uart
M
Ming, Bai 已提交
45
{
46
    USART_TypeDef *uart_device;
47
    IRQn_Type irq;
48
#ifdef RT_SERIAL_USING_DMA    
49 50
    struct stm32_uart_dma
    {
51 52 53 54 55 56
        /* dma channel */
        DMA_Channel_TypeDef *rx_ch;
        /* dma global flag */
        uint32_t rx_gl_flag;
        /* dma irq channel */
        uint8_t rx_irq_ch;
57 58
        /* setting receive len */
        rt_size_t setting_recv_len;
59
        /* last receive index */
60
        rt_size_t last_recv_index;
61
    } dma;
62
#endif /* RT_SERIAL_USING_DMA */    
M
Ming, Bai 已提交
63 64
};

65
#ifdef RT_SERIAL_USING_DMA
66
static void DMA_Configuration(struct rt_serial_device *serial);
67
#endif /* RT_SERIAL_USING_DMA */ 
68

69
static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
M
Ming, Bai 已提交
70
{
71 72
    struct stm32_uart* uart;
    USART_InitTypeDef USART_InitStructure;
M
Ming, Bai 已提交
73

74 75 76 77 78 79 80
    RT_ASSERT(serial != RT_NULL);
    RT_ASSERT(cfg != RT_NULL);

    uart = (struct stm32_uart *)serial->parent.user_data;

    USART_InitStructure.USART_BaudRate = cfg->baud_rate;

81
    if (cfg->data_bits == DATA_BITS_8){
82
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
83 84 85
    } else if (cfg->data_bits == DATA_BITS_9) {
        USART_InitStructure.USART_WordLength = USART_WordLength_9b;
    }
86

87
    if (cfg->stop_bits == STOP_BITS_1){
88
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
89
    } else if (cfg->stop_bits == STOP_BITS_2){
90
        USART_InitStructure.USART_StopBits = USART_StopBits_2;
91 92 93 94 95 96 97 98 99
    }

    if (cfg->parity == PARITY_NONE){
        USART_InitStructure.USART_Parity = USART_Parity_No;
    } else if (cfg->parity == PARITY_ODD) {
        USART_InitStructure.USART_Parity = USART_Parity_Odd;
    } else if (cfg->parity == PARITY_EVEN) {
        USART_InitStructure.USART_Parity = USART_Parity_Even;
    }
100 101 102 103 104 105 106 107 108 109 110 111

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(uart->uart_device, &USART_InitStructure);

    /* Enable USART */
    USART_Cmd(uart->uart_device, ENABLE);

    return RT_EOK;
}

static rt_err_t stm32_control(struct rt_serial_device *serial, int cmd, void *arg)
M
Ming, Bai 已提交
112
{
113 114 115 116 117 118 119
    struct stm32_uart* uart;

    RT_ASSERT(serial != RT_NULL);
    uart = (struct stm32_uart *)serial->parent.user_data;

    switch (cmd)
    {
armink_ztl's avatar
armink_ztl 已提交
120
        /* disable interrupt */
121 122 123
    case RT_DEVICE_CTRL_CLR_INT:
        /* disable rx irq */
        UART_DISABLE_IRQ(uart->irq);
armink_ztl's avatar
armink_ztl 已提交
124 125
        /* disable interrupt */
        USART_ITConfig(uart->uart_device, USART_IT_RXNE, DISABLE);
126
        break;
armink_ztl's avatar
armink_ztl 已提交
127
        /* enable interrupt */
128 129 130
    case RT_DEVICE_CTRL_SET_INT:
        /* enable rx irq */
        UART_ENABLE_IRQ(uart->irq);
armink_ztl's avatar
armink_ztl 已提交
131 132
        /* enable interrupt */
        USART_ITConfig(uart->uart_device, USART_IT_RXNE, ENABLE);
133
        break;
134
#ifdef RT_SERIAL_USING_DMA
135 136
        /* USART config */
    case RT_DEVICE_CTRL_CONFIG :
137
        if ((rt_uint32_t)(arg) == RT_DEVICE_FLAG_DMA_RX) {
138 139 140
            DMA_Configuration(serial);
        }
        break;
141
#endif /* RT_SERIAL_USING_DMA */    
142 143 144
    }
    return RT_EOK;
}
M
Ming, Bai 已提交
145

146 147 148
static int stm32_putc(struct rt_serial_device *serial, char c)
{
    struct stm32_uart* uart;
M
Ming, Bai 已提交
149

150 151
    RT_ASSERT(serial != RT_NULL);
    uart = (struct stm32_uart *)serial->parent.user_data;
M
Ming, Bai 已提交
152

153
    if (serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX)
154
    {
155 156 157 158 159 160 161
        if (!(uart->uart_device->SR & USART_FLAG_TXE))
        {
            USART_ITConfig(uart->uart_device, USART_IT_TC, ENABLE);
            return -1;
        }
        uart->uart_device->DR = c;
        USART_ITConfig(uart->uart_device, USART_IT_TC, ENABLE);
162 163 164
    }
    else
    {
165
        USART_ClearFlag(uart->uart_device,USART_FLAG_TC);
166 167 168
        uart->uart_device->DR = c;
        while (!(uart->uart_device->SR & USART_FLAG_TC));
    }
M
Ming, Bai 已提交
169

170 171 172 173
    return 1;
}

static int stm32_getc(struct rt_serial_device *serial)
M
Ming, Bai 已提交
174
{
175 176
    int ch;
    struct stm32_uart* uart;
M
Ming, Bai 已提交
177

178 179
    RT_ASSERT(serial != RT_NULL);
    uart = (struct stm32_uart *)serial->parent.user_data;
M
Ming, Bai 已提交
180

181 182 183 184 185
    ch = -1;
    if (uart->uart_device->SR & USART_FLAG_RXNE)
    {
        ch = uart->uart_device->DR & 0xff;
    }
M
Ming, Bai 已提交
186

187 188
    return ch;
}
M
Ming, Bai 已提交
189

190
#ifdef RT_SERIAL_USING_DMA
191 192 193 194 195 196 197
/**
 * Serial port receive idle process. This need add to uart idle ISR.
 *
 * @param serial serial device
 */
static void dma_uart_rx_idle_isr(struct rt_serial_device *serial) {
    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;
198 199 200 201 202 203 204
    rt_size_t recv_total_index, recv_len;
    rt_base_t level;

    /* disable interrupt */
    level = rt_hw_interrupt_disable();

    recv_total_index = uart->dma.setting_recv_len - DMA_GetCurrDataCounter(uart->dma.rx_ch);
205
    recv_len = recv_total_index - uart->dma.last_recv_index;
206 207 208 209 210
    uart->dma.last_recv_index = recv_total_index;
    /* enable interrupt */
    rt_hw_interrupt_enable(level);

    if (recv_len) rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
211 212 213 214 215 216 217 218 219 220 221 222 223

    /* read a data for clear receive idle interrupt flag */
    USART_ReceiveData(uart->uart_device);
    DMA_ClearFlag(uart->dma.rx_gl_flag);
}

/**
 * DMA receive done process. This need add to DMA receive done ISR.
 *
 * @param serial serial device
 */
static void dma_rx_done_isr(struct rt_serial_device *serial) {
    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;
224
    rt_size_t recv_len;
225 226 227 228 229
    rt_base_t level;

    /* disable interrupt */
    level = rt_hw_interrupt_disable();

230 231 232
    recv_len = uart->dma.setting_recv_len - uart->dma.last_recv_index;
    /* reset last recv index */
    uart->dma.last_recv_index = 0;
233 234 235 236
    /* enable interrupt */
    rt_hw_interrupt_enable(level);

    if (recv_len) rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
237 238 239

    DMA_ClearFlag(uart->dma.rx_gl_flag);
}
240
#endif /* RT_SERIAL_USING_DMA */ 
241 242 243 244 245 246 247 248 249 250 251 252 253

/**
 * Uart common interrupt process. This need add to uart ISR.
 *
 * @param serial serial device
 */
static void uart_isr(struct rt_serial_device *serial) {
    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;

    RT_ASSERT(uart != RT_NULL);

    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
    {
254 255 256 257
        if(USART_GetFlagStatus(uart->uart_device, USART_FLAG_PE) == RESET)
        {
            rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
        }
258 259 260
        /* clear interrupt */
        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
    }
261
#ifdef RT_SERIAL_USING_DMA    
262 263 264 265
    if(USART_GetITStatus(uart->uart_device, USART_IT_IDLE) != RESET)
    {
        dma_uart_rx_idle_isr(serial);
    }
266
#endif /* RT_SERIAL_USING_DMA */     
267 268 269
    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
    {
        /* clear interrupt */
270 271 272 273
        if(serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX)
        {
            rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
        }
A
Aubr.Cool 已提交
274
        USART_ITConfig(uart->uart_device, USART_IT_TC, DISABLE);
275 276 277 278
        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
    }
    if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
    {
279
        USART_ReceiveData(uart->uart_device);
280 281 282
    }
}

283 284 285 286 287 288 289
static const struct rt_uart_ops stm32_uart_ops =
{
    stm32_configure,
    stm32_control,
    stm32_putc,
    stm32_getc,
};
M
Ming, Bai 已提交
290

291 292 293 294 295
#if defined(RT_USING_UART1)
/* UART1 device driver structure */
struct stm32_uart uart1 =
{
    USART1,
296
#ifdef RT_SERIAL_USING_DMA
297
    USART1_IRQn,
298 299 300 301 302 303
    {
        DMA1_Channel5,
        DMA1_FLAG_GL5,
        DMA1_Channel5_IRQn,
        0,
    },
304
#endif /* RT_SERIAL_USING_DMA */       
305 306
};
struct rt_serial_device serial1;
M
Ming, Bai 已提交
307

308 309
void USART1_IRQHandler(void)
{
310 311
    /* enter interrupt */
    rt_interrupt_enter();
312

313 314 315 316 317
    uart_isr(&serial1);

    /* leave interrupt */
    rt_interrupt_leave();
}
318

319
#ifdef RT_SERIAL_USING_DMA
320
void DMA1_Channel5_IRQHandler(void) {
321 322
    /* enter interrupt */
    rt_interrupt_enter();
323

324 325
    dma_rx_done_isr(&serial1);

326 327 328
    /* leave interrupt */
    rt_interrupt_leave();
}
329 330
#endif /* RT_SERIAL_USING_DMA */   

331 332 333
#endif /* RT_USING_UART1 */

#if defined(RT_USING_UART2)
334
/* UART2 device driver structure */
335 336 337
struct stm32_uart uart2 =
{
    USART2,
338
#ifdef RT_SERIAL_USING_DMA    
339
    USART2_IRQn,
340 341 342 343 344 345
    {
        DMA1_Channel6,
        DMA1_FLAG_GL6,
        DMA1_Channel6_IRQn,
        0,
    },
346
#endif /* RT_SERIAL_USING_DMA */       
347 348
};
struct rt_serial_device serial2;
M
Ming, Bai 已提交
349

350 351
void USART2_IRQHandler(void)
{
352 353
    /* enter interrupt */
    rt_interrupt_enter();
354

355
    uart_isr(&serial2);
356

357 358 359 360
    /* leave interrupt */
    rt_interrupt_leave();
}

361
#ifdef RT_SERIAL_USING_DMA    
362
void DMA1_Channel6_IRQHandler(void) {
363 364
    /* enter interrupt */
    rt_interrupt_enter();
365 366

    dma_rx_done_isr(&serial2);
367 368 369

    /* leave interrupt */
    rt_interrupt_leave();
M
Ming, Bai 已提交
370
}
371 372
#endif /* RT_SERIAL_USING_DMA */  

373
#endif /* RT_USING_UART2 */
M
Ming, Bai 已提交
374

375
#if defined(RT_USING_UART3)
376
/* UART3 device driver structure */
377 378 379
struct stm32_uart uart3 =
{
    USART3,
380
#ifdef RT_SERIAL_USING_DMA     
381
    USART3_IRQn,
382 383 384 385 386 387
    {
        DMA1_Channel3,
        DMA1_FLAG_GL3,
        DMA1_Channel3_IRQn,
        0,
    },
388
#endif /* RT_SERIAL_USING_DMA */   
389 390 391 392
};
struct rt_serial_device serial3;

void USART3_IRQHandler(void)
M
Ming, Bai 已提交
393
{
394 395
    /* enter interrupt */
    rt_interrupt_enter();
396

397
    uart_isr(&serial3);
398

399 400 401 402
    /* leave interrupt */
    rt_interrupt_leave();
}

403
#ifdef RT_SERIAL_USING_DMA  
404
void DMA1_Channel3_IRQHandler(void) {
405 406
    /* enter interrupt */
    rt_interrupt_enter();
407 408

    dma_rx_done_isr(&serial3);
409 410 411 412

    /* leave interrupt */
    rt_interrupt_leave();
}
413 414
#endif /* RT_SERIAL_USING_DMA */

415
#endif /* RT_USING_UART3 */
M
Ming, Bai 已提交
416

U
unknown 已提交
417 418 419 420 421
#if defined(RT_USING_UART4)
/* UART4 device driver structure */
struct stm32_uart uart4 =
{
    UART4,
422
#ifdef RT_SERIAL_USING_DMA  
U
unknown 已提交
423
    UART4_IRQn,
424 425 426 427 428 429
    {
        DMA2_Channel3,
        DMA2_FLAG_GL3,
        DMA2_Channel3_IRQn,
        0,
    },
430
#endif /* RT_SERIAL_USING_DMA */    
U
unknown 已提交
431 432 433 434 435
};
struct rt_serial_device serial4;

void UART4_IRQHandler(void)
{
436 437
    /* enter interrupt */
    rt_interrupt_enter();
U
unknown 已提交
438

439
    uart_isr(&serial4);
U
unknown 已提交
440

441 442 443 444
    /* leave interrupt */
    rt_interrupt_leave();
}

445
#ifdef RT_SERIAL_USING_DMA  
446
void DMA2_Channel3_IRQHandler(void) {
U
unknown 已提交
447 448
    /* enter interrupt */
    rt_interrupt_enter();
449 450

    dma_rx_done_isr(&serial4);
U
unknown 已提交
451 452 453 454

    /* leave interrupt */
    rt_interrupt_leave();
}
455 456
#endif /* RT_SERIAL_USING_DMA */

457
#endif /* RT_USING_UART4 */
U
unknown 已提交
458

459 460
static void RCC_Configuration(void)
{
461
#if defined(RT_USING_UART1)
462
    /* Enable UART GPIO clocks */
463
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
464 465 466
    /* Enable UART clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
#endif /* RT_USING_UART1 */
M
Ming, Bai 已提交
467

468
#if defined(RT_USING_UART2)
469
    /* Enable UART GPIO clocks */
470
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
471 472 473
    /* Enable UART clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
#endif /* RT_USING_UART2 */
M
Ming, Bai 已提交
474

475
#if defined(RT_USING_UART3)
476
    /* Enable UART GPIO clocks */
477
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
478 479 480
    /* Enable UART clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
#endif /* RT_USING_UART3 */
U
unknown 已提交
481 482 483

#if defined(RT_USING_UART4)
    /* Enable UART GPIO clocks */
484
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
U
unknown 已提交
485 486 487
    /* Enable UART clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
#endif /* RT_USING_UART4 */
M
Ming, Bai 已提交
488 489
}

490
static void GPIO_Configuration(void)
M
Ming, Bai 已提交
491
{
492 493 494
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
M
Ming, Bai 已提交
495

496
#if defined(RT_USING_UART1)
497 498 499 500 501 502 503 504 505
    /* Configure USART Rx/tx PIN */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX;
    GPIO_Init(UART1_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = UART1_GPIO_TX;
    GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
#endif /* RT_USING_UART1 */
M
Ming, Bai 已提交
506

507
#if defined(RT_USING_UART2)
508 509 510
    /* Configure USART Rx/tx PIN */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = UART2_GPIO_RX;
511
    GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
512 513 514 515 516

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = UART2_GPIO_TX;
    GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
#endif /* RT_USING_UART2 */
M
Ming, Bai 已提交
517

518
#if defined(RT_USING_UART3)
519 520 521 522 523 524 525 526 527
    /* Configure USART Rx/tx PIN */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = UART3_GPIO_RX;
    GPIO_Init(UART3_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = UART3_GPIO_TX;
    GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
#endif /* RT_USING_UART3 */
U
unknown 已提交
528 529 530 531 532 533 534 535 536 537 538

#if defined(RT_USING_UART4)
    /* Configure USART Rx/tx PIN */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = UART4_GPIO_RX;
    GPIO_Init(UART4_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = UART4_GPIO_TX;
    GPIO_Init(UART4_GPIO, &GPIO_InitStructure);
#endif /* RT_USING_UART4 */
M
Ming, Bai 已提交
539 540
}

541
static void NVIC_Configuration(struct stm32_uart* uart)
M
Ming, Bai 已提交
542
{
543 544 545 546 547
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Enable the USART1 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = uart->irq;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
548
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
549 550
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
M
Ming, Bai 已提交
551 552
}

553
#ifdef RT_SERIAL_USING_DMA
554 555 556 557 558 559
static void DMA_Configuration(struct rt_serial_device *serial) {
    struct stm32_uart *uart = (struct stm32_uart *) serial->parent.user_data;
    struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

560 561
    uart->dma.setting_recv_len = serial->config.bufsz;
    
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
    /* enable transmit idle interrupt */
    USART_ITConfig(uart->uart_device, USART_IT_IDLE , ENABLE);

    /* DMA clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

    /* rx dma config */
    DMA_DeInit(uart->dma.rx_ch);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(uart->uart_device->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) rx_fifo->buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = serial->config.bufsz;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
579
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
580 581 582 583 584 585 586 587 588 589 590
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(uart->dma.rx_ch, &DMA_InitStructure);
    DMA_ClearFlag(uart->dma.rx_gl_flag);
    DMA_ITConfig(uart->dma.rx_ch, DMA_IT_TC, ENABLE);
    USART_DMACmd(uart->uart_device, USART_DMAReq_Rx, ENABLE);
    DMA_Cmd(uart->dma.rx_ch, ENABLE);

    /* rx dma interrupt config */
    NVIC_InitStructure.NVIC_IRQChannel = uart->dma.rx_irq_ch;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
591
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
592 593 594
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
595
#endif /* RT_SERIAL_USING_DMA */   
596

597
void rt_hw_usart_init(void)
M
Ming, Bai 已提交
598
{
599 600
    struct stm32_uart* uart;
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
M
Ming, Bai 已提交
601

602 603
    RCC_Configuration();
    GPIO_Configuration();
M
Ming, Bai 已提交
604

605
#if defined(RT_USING_UART1)
606 607
    uart = &uart1;
    config.baud_rate = BAUD_RATE_115200;
M
Ming, Bai 已提交
608

609 610
    serial1.ops    = &stm32_uart_ops;
    serial1.config = config;
M
Ming, Bai 已提交
611

612
    NVIC_Configuration(uart);
M
Ming, Bai 已提交
613

614 615
    /* register UART1 device */
    rt_hw_serial_register(&serial1, "uart1",
616 617
                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |
                          RT_DEVICE_FLAG_INT_TX |   RT_DEVICE_FLAG_DMA_RX,
618 619
                          uart);
#endif /* RT_USING_UART1 */
M
Ming, Bai 已提交
620

621
#if defined(RT_USING_UART2)
622 623 624 625 626 627
    uart = &uart2;

    config.baud_rate = BAUD_RATE_115200;
    serial2.ops    = &stm32_uart_ops;
    serial2.config = config;

628
    NVIC_Configuration(uart);
629

630
    /* register UART2 device */
631
    rt_hw_serial_register(&serial2, "uart2",
632 633
                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |
                          RT_DEVICE_FLAG_INT_TX |   RT_DEVICE_FLAG_DMA_RX,
634 635
                          uart);
#endif /* RT_USING_UART2 */
M
Ming, Bai 已提交
636

637
#if defined(RT_USING_UART3)
638 639 640 641 642 643 644
    uart = &uart3;

    config.baud_rate = BAUD_RATE_115200;

    serial3.ops    = &stm32_uart_ops;
    serial3.config = config;

645
    NVIC_Configuration(uart);
646

647
    /* register UART3 device */
648
    rt_hw_serial_register(&serial3, "uart3",
649 650
                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |
                          RT_DEVICE_FLAG_INT_TX |   RT_DEVICE_FLAG_DMA_RX,
651 652
                          uart);
#endif /* RT_USING_UART3 */
U
unknown 已提交
653 654 655 656 657 658 659 660 661

#if defined(RT_USING_UART4)
    uart = &uart4;

    config.baud_rate = BAUD_RATE_115200;

    serial4.ops    = &stm32_uart_ops;
    serial4.config = config;

662
    NVIC_Configuration(uart);
U
unknown 已提交
663 664 665

    /* register UART4 device */
    rt_hw_serial_register(&serial4, "uart4",
666 667
                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX |
                          RT_DEVICE_FLAG_INT_TX |   RT_DEVICE_FLAG_DMA_RX,
U
unknown 已提交
668 669
                          uart);
#endif /* RT_USING_UART4 */
M
Ming, Bai 已提交
670
}