[BSP]update the serial driver.
Signed-off-by: pangwei <271372443@qq.com>
This commit is contained in:
parent
0ac07f9ffb
commit
77707e32b1
|
@ -3,15 +3,22 @@ Import('rtconfig')
|
|||
from building import *
|
||||
|
||||
cwd = os.path.join(str(Dir('#')), 'drivers')
|
||||
src = Glob('*.c')
|
||||
|
||||
# remove no need file.
|
||||
if GetDepend('RT_USING_LWIP') == False:
|
||||
SrcRemove(src, 'stm32_eth.c')
|
||||
# add the general drivers.
|
||||
src = Split("""
|
||||
board.c
|
||||
stm32f10x_it.c
|
||||
usart.c
|
||||
platform.c
|
||||
""")
|
||||
|
||||
if GetDepend('RT_USING_SPI') == False:
|
||||
SrcRemove(src, 'rt_stm32f10x_spi.c')
|
||||
SrcRemove(src, 'msd.c')
|
||||
# add Ethernet drivers.
|
||||
if GetDepend('RT_USING_LWIP'):
|
||||
src += ['stm32_eth.c']
|
||||
|
||||
if GetDepend('RT_USING_SPI'):
|
||||
src += ['rt_stm32f10x_spi.c']
|
||||
src += ['msd.c']
|
||||
|
||||
CPPPATH = [cwd]
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include "board.h"
|
||||
#include "usart.h"
|
||||
|
||||
/**
|
||||
* @addtogroup STM32
|
||||
|
|
|
@ -1,418 +0,0 @@
|
|||
/*
|
||||
* File : serial.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2009, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rt-thread.org/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2009-02-05 Bernard first version
|
||||
* 2009-10-25 Bernard fix rt_serial_read bug when there is no data
|
||||
* in the buffer.
|
||||
* 2010-03-29 Bernard cleanup code.
|
||||
*/
|
||||
|
||||
#include "serial.h"
|
||||
#include <stm32f10x_dma.h>
|
||||
#include <stm32f10x_usart.h>
|
||||
|
||||
static void rt_serial_enable_dma(DMA_Channel_TypeDef* dma_channel,
|
||||
rt_uint32_t address, rt_uint32_t size);
|
||||
|
||||
/**
|
||||
* @addtogroup STM32
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/* RT-Thread Device Interface */
|
||||
static rt_err_t rt_serial_init (rt_device_t dev)
|
||||
{
|
||||
struct stm32_serial_device* uart = (struct stm32_serial_device*) dev->user_data;
|
||||
|
||||
if (!(dev->flag & RT_DEVICE_FLAG_ACTIVATED))
|
||||
{
|
||||
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
rt_memset(uart->int_rx->rx_buffer, 0,
|
||||
sizeof(uart->int_rx->rx_buffer));
|
||||
uart->int_rx->read_index = 0;
|
||||
uart->int_rx->save_index = 0;
|
||||
}
|
||||
|
||||
if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
|
||||
{
|
||||
RT_ASSERT(uart->dma_tx->dma_channel != RT_NULL);
|
||||
uart->dma_tx->list_head = uart->dma_tx->list_tail = RT_NULL;
|
||||
|
||||
/* init data node memory pool */
|
||||
rt_mp_init(&(uart->dma_tx->data_node_mp), "dn",
|
||||
uart->dma_tx->data_node_mem_pool,
|
||||
sizeof(uart->dma_tx->data_node_mem_pool),
|
||||
sizeof(struct stm32_serial_data_node));
|
||||
}
|
||||
|
||||
/* Enable USART */
|
||||
USART_Cmd(uart->uart_device, ENABLE);
|
||||
|
||||
dev->flag |= RT_DEVICE_FLAG_ACTIVATED;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_serial_close(rt_device_t dev)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||
{
|
||||
rt_uint8_t* ptr;
|
||||
rt_err_t err_code;
|
||||
struct stm32_serial_device* uart;
|
||||
|
||||
ptr = buffer;
|
||||
err_code = RT_EOK;
|
||||
uart = (struct stm32_serial_device*)dev->user_data;
|
||||
|
||||
if (dev->flag & RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
/* interrupt mode Rx */
|
||||
while (size)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
if (uart->int_rx->read_index != uart->int_rx->save_index)
|
||||
{
|
||||
/* read a character */
|
||||
*ptr++ = uart->int_rx->rx_buffer[uart->int_rx->read_index];
|
||||
size--;
|
||||
|
||||
/* move to next position */
|
||||
uart->int_rx->read_index ++;
|
||||
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
|
||||
uart->int_rx->read_index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set error code */
|
||||
err_code = -RT_EEMPTY;
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
break;
|
||||
}
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* polling mode */
|
||||
while ((rt_uint32_t)ptr - (rt_uint32_t)buffer < size)
|
||||
{
|
||||
while (uart->uart_device->SR & USART_FLAG_RXNE)
|
||||
{
|
||||
*ptr = uart->uart_device->DR & 0xff;
|
||||
ptr ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set error code */
|
||||
rt_set_errno(err_code);
|
||||
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
||||
}
|
||||
|
||||
static void rt_serial_enable_dma(DMA_Channel_TypeDef* dma_channel,
|
||||
rt_uint32_t address, rt_uint32_t size)
|
||||
{
|
||||
RT_ASSERT(dma_channel != RT_NULL);
|
||||
|
||||
/* disable DMA */
|
||||
DMA_Cmd(dma_channel, DISABLE);
|
||||
|
||||
/* set buffer address */
|
||||
dma_channel->CMAR = address;
|
||||
/* set size */
|
||||
dma_channel->CNDTR = size;
|
||||
|
||||
/* enable DMA */
|
||||
DMA_Cmd(dma_channel, ENABLE);
|
||||
}
|
||||
|
||||
static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||
{
|
||||
rt_uint8_t* ptr;
|
||||
rt_err_t err_code;
|
||||
struct stm32_serial_device* uart;
|
||||
|
||||
err_code = RT_EOK;
|
||||
ptr = (rt_uint8_t*)buffer;
|
||||
uart = (struct stm32_serial_device*)dev->user_data;
|
||||
|
||||
if (dev->flag & RT_DEVICE_FLAG_INT_TX)
|
||||
{
|
||||
/* interrupt mode Tx, does not support */
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
else if (dev->flag & RT_DEVICE_FLAG_DMA_TX)
|
||||
{
|
||||
/* DMA mode Tx */
|
||||
|
||||
/* allocate a data node */
|
||||
struct stm32_serial_data_node* data_node = (struct stm32_serial_data_node*)
|
||||
rt_mp_alloc (&(uart->dma_tx->data_node_mp), RT_WAITING_FOREVER);
|
||||
if (data_node == RT_NULL)
|
||||
{
|
||||
/* set error code */
|
||||
err_code = -RT_ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_uint32_t level;
|
||||
|
||||
/* fill data node */
|
||||
data_node->data_ptr = ptr;
|
||||
data_node->data_size = size;
|
||||
|
||||
/* insert to data link */
|
||||
data_node->next = RT_NULL;
|
||||
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
data_node->prev = uart->dma_tx->list_tail;
|
||||
if (uart->dma_tx->list_tail != RT_NULL)
|
||||
uart->dma_tx->list_tail->next = data_node;
|
||||
uart->dma_tx->list_tail = data_node;
|
||||
|
||||
if (uart->dma_tx->list_head == RT_NULL)
|
||||
{
|
||||
/* start DMA to transmit data */
|
||||
uart->dma_tx->list_head = data_node;
|
||||
|
||||
/* Enable DMA Channel */
|
||||
rt_serial_enable_dma(uart->dma_tx->dma_channel,
|
||||
(rt_uint32_t)uart->dma_tx->list_head->data_ptr,
|
||||
uart->dma_tx->list_head->data_size);
|
||||
}
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* polling mode */
|
||||
if (dev->flag & RT_DEVICE_FLAG_STREAM)
|
||||
{
|
||||
/* stream mode */
|
||||
while (size)
|
||||
{
|
||||
if (*ptr == '\n')
|
||||
{
|
||||
while (!(uart->uart_device->SR & USART_FLAG_TXE));
|
||||
uart->uart_device->DR = '\r';
|
||||
}
|
||||
|
||||
while (!(uart->uart_device->SR & USART_FLAG_TXE));
|
||||
uart->uart_device->DR = (*ptr & 0x1FF);
|
||||
|
||||
++ptr; --size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* write data directly */
|
||||
while (size)
|
||||
{
|
||||
while (!(uart->uart_device->SR & USART_FLAG_TXE));
|
||||
uart->uart_device->DR = (*ptr & 0x1FF);
|
||||
|
||||
++ptr; --size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set error code */
|
||||
rt_set_errno(err_code);
|
||||
|
||||
return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
|
||||
}
|
||||
|
||||
static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||
{
|
||||
struct stm32_serial_device* uart;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
uart = (struct stm32_serial_device*)dev->user_data;
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_SUSPEND:
|
||||
/* suspend device */
|
||||
dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
|
||||
USART_Cmd(uart->uart_device, DISABLE);
|
||||
break;
|
||||
|
||||
case RT_DEVICE_CTRL_RESUME:
|
||||
/* resume device */
|
||||
dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
|
||||
USART_Cmd(uart->uart_device, ENABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* serial register for STM32
|
||||
* support STM32F103VB and STM32F103ZE
|
||||
*/
|
||||
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct stm32_serial_device *serial)
|
||||
{
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
if ((flag & RT_DEVICE_FLAG_DMA_RX) ||
|
||||
(flag & RT_DEVICE_FLAG_INT_TX))
|
||||
{
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
|
||||
device->type = RT_Device_Class_Char;
|
||||
device->rx_indicate = RT_NULL;
|
||||
device->tx_complete = RT_NULL;
|
||||
device->init = rt_serial_init;
|
||||
device->open = rt_serial_open;
|
||||
device->close = rt_serial_close;
|
||||
device->read = rt_serial_read;
|
||||
device->write = rt_serial_write;
|
||||
device->control = rt_serial_control;
|
||||
device->user_data = serial;
|
||||
|
||||
/* register a character device */
|
||||
return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
|
||||
}
|
||||
|
||||
/* ISR for serial interrupt */
|
||||
void rt_hw_serial_isr(rt_device_t device)
|
||||
{
|
||||
struct stm32_serial_device* uart = (struct stm32_serial_device*) device->user_data;
|
||||
|
||||
if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
/* interrupt mode receive */
|
||||
RT_ASSERT(device->flag & RT_DEVICE_FLAG_INT_RX);
|
||||
|
||||
/* save on rx buffer */
|
||||
while (uart->uart_device->SR & USART_FLAG_RXNE)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
/* save character */
|
||||
uart->int_rx->rx_buffer[uart->int_rx->save_index] = uart->uart_device->DR & 0xff;
|
||||
uart->int_rx->save_index ++;
|
||||
if (uart->int_rx->save_index >= UART_RX_BUFFER_SIZE)
|
||||
uart->int_rx->save_index = 0;
|
||||
|
||||
/* if the next position is read index, discard this 'read char' */
|
||||
if (uart->int_rx->save_index == uart->int_rx->read_index)
|
||||
{
|
||||
uart->int_rx->read_index ++;
|
||||
if (uart->int_rx->read_index >= UART_RX_BUFFER_SIZE)
|
||||
uart->int_rx->read_index = 0;
|
||||
}
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/* clear interrupt */
|
||||
USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
|
||||
|
||||
/* invoke callback */
|
||||
if (device->rx_indicate != RT_NULL)
|
||||
{
|
||||
rt_size_t rx_length;
|
||||
|
||||
/* get rx length */
|
||||
rx_length = uart->int_rx->read_index > uart->int_rx->save_index ?
|
||||
UART_RX_BUFFER_SIZE - uart->int_rx->read_index + uart->int_rx->save_index :
|
||||
uart->int_rx->save_index - uart->int_rx->read_index;
|
||||
|
||||
device->rx_indicate(device, rx_length);
|
||||
}
|
||||
}
|
||||
|
||||
if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
|
||||
{
|
||||
/* clear interrupt */
|
||||
USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ISR for DMA mode Tx
|
||||
*/
|
||||
void rt_hw_serial_dma_tx_isr(rt_device_t device)
|
||||
{
|
||||
rt_uint32_t level;
|
||||
struct stm32_serial_data_node* data_node;
|
||||
struct stm32_serial_device* uart = (struct stm32_serial_device*) device->user_data;
|
||||
|
||||
/* DMA mode receive */
|
||||
RT_ASSERT(device->flag & RT_DEVICE_FLAG_DMA_TX);
|
||||
|
||||
/* get the first data node */
|
||||
data_node = uart->dma_tx->list_head;
|
||||
RT_ASSERT(data_node != RT_NULL);
|
||||
|
||||
/* invoke call to notify tx complete */
|
||||
if (device->tx_complete != RT_NULL)
|
||||
device->tx_complete(device, data_node->data_ptr);
|
||||
|
||||
/* disable interrupt */
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
/* remove list head */
|
||||
uart->dma_tx->list_head = data_node->next;
|
||||
if (uart->dma_tx->list_head == RT_NULL) /* data link empty */
|
||||
uart->dma_tx->list_tail = RT_NULL;
|
||||
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
/* release data node memory */
|
||||
rt_mp_free(data_node);
|
||||
|
||||
if (uart->dma_tx->list_head != RT_NULL)
|
||||
{
|
||||
/* transmit next data node */
|
||||
rt_serial_enable_dma(uart->dma_tx->dma_channel,
|
||||
(rt_uint32_t)uart->dma_tx->list_head->data_ptr,
|
||||
uart->dma_tx->list_head->data_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no data to be transmitted, disable DMA */
|
||||
DMA_Cmd(uart->dma_tx->dma_channel, DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/*@}*/
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* File : serial.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2009 - 2010, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rt-thread.org/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2009-01-05 Bernard first version
|
||||
* 2010-03-29 Bernard remove interrupt tx and DMA rx mode.
|
||||
*/
|
||||
#ifndef __RT_HW_SERIAL_H__
|
||||
#define __RT_HW_SERIAL_H__
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
/* STM32F10x library definitions */
|
||||
#include <stm32f10x.h>
|
||||
|
||||
#define UART_RX_BUFFER_SIZE 128
|
||||
#define UART_TX_DMA_NODE_SIZE 4
|
||||
|
||||
/* data node for Tx Mode */
|
||||
struct stm32_serial_data_node
|
||||
{
|
||||
rt_uint8_t *data_ptr;
|
||||
rt_size_t data_size;
|
||||
struct stm32_serial_data_node *next, *prev;
|
||||
};
|
||||
struct stm32_serial_dma_tx
|
||||
{
|
||||
/* DMA Channel */
|
||||
DMA_Channel_TypeDef* dma_channel;
|
||||
|
||||
/* data list head and tail */
|
||||
struct stm32_serial_data_node *list_head, *list_tail;
|
||||
|
||||
/* data node memory pool */
|
||||
struct rt_mempool data_node_mp;
|
||||
rt_uint8_t data_node_mem_pool[UART_TX_DMA_NODE_SIZE *
|
||||
(sizeof(struct stm32_serial_data_node) + sizeof(void*))];
|
||||
};
|
||||
|
||||
struct stm32_serial_int_rx
|
||||
{
|
||||
rt_uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
|
||||
rt_uint32_t read_index, save_index;
|
||||
};
|
||||
|
||||
struct stm32_serial_device
|
||||
{
|
||||
USART_TypeDef* uart_device;
|
||||
|
||||
/* rx structure */
|
||||
struct stm32_serial_int_rx* int_rx;
|
||||
|
||||
/* tx structure */
|
||||
struct stm32_serial_dma_tx* dma_tx;
|
||||
};
|
||||
|
||||
rt_err_t rt_hw_serial_register(rt_device_t device, const char* name, rt_uint32_t flag, struct stm32_serial_device *serial);
|
||||
|
||||
void rt_hw_serial_isr(rt_device_t device);
|
||||
void rt_hw_serial_dma_tx_isr(rt_device_t device);
|
||||
|
||||
#endif
|
|
@ -107,85 +107,4 @@ void DebugMon_Handler(void)
|
|||
{
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F10x Peripherals Interrupt Handlers */
|
||||
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
|
||||
/* available peripheral interrupt handler's name please refer to the startup */
|
||||
/* file (startup_stm32f10x_xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : USART1_IRQHandler
|
||||
* Description : This function handles USART1 global interrupt request.
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
#ifdef RT_USING_UART1
|
||||
extern struct rt_device uart1_device;
|
||||
extern void rt_hw_serial_isr(struct rt_device *device);
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
rt_hw_serial_isr(&uart1_device);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : USART2_IRQHandler
|
||||
* Description : This function handles USART2 global interrupt request.
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
#ifdef RT_USING_UART2
|
||||
extern struct rt_device uart2_device;
|
||||
extern void rt_hw_serial_isr(struct rt_device *device);
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
rt_hw_serial_isr(&uart2_device);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : USART3_IRQHandler
|
||||
* Description : This function handles USART3 global interrupt request.
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
#ifdef RT_USING_UART3
|
||||
extern struct rt_device uart3_device;
|
||||
extern void rt_hw_serial_isr(struct rt_device *device);
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
rt_hw_serial_isr(&uart3_device);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* File : usart.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2009, RT-Thread Development Team
|
||||
* COPYRIGHT (C) 2006-2013, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
|
@ -11,109 +11,234 @@
|
|||
* Date Author Notes
|
||||
* 2009-01-05 Bernard the first version
|
||||
* 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode
|
||||
* 2013-05-13 aozima update for kehong-lingtai.
|
||||
* 2015-01-31 armink make sure the serial transmit complete in putc()
|
||||
*/
|
||||
|
||||
#include <board.h>
|
||||
#include "stm32f10x.h"
|
||||
#include "usart.h"
|
||||
#include <serial.h>
|
||||
#include <stm32f10x_dma.h>
|
||||
#include "board.h"
|
||||
#include <rtdevice.h>
|
||||
|
||||
/*
|
||||
* Use UART1 as console output and finsh input
|
||||
* interrupt Rx and poll Tx (stream mode)
|
||||
*
|
||||
* Use UART2 with interrupt Rx and poll Tx
|
||||
* Use UART3 with DMA Tx and interrupt Rx -- DMA channel 2
|
||||
*
|
||||
* USART DMA setting on STM32
|
||||
* USART1 Tx --> DMA Channel 4
|
||||
* USART1 Rx --> DMA Channel 5
|
||||
* USART2 Tx --> DMA Channel 7
|
||||
* USART2 Rx --> DMA Channel 6
|
||||
* USART3 Tx --> DMA Channel 2
|
||||
* USART3 Rx --> DMA Channel 3
|
||||
*/
|
||||
|
||||
#ifdef RT_USING_UART1
|
||||
struct stm32_serial_int_rx uart1_int_rx;
|
||||
struct stm32_serial_device uart1 =
|
||||
{
|
||||
USART1,
|
||||
&uart1_int_rx,
|
||||
RT_NULL
|
||||
};
|
||||
struct rt_device uart1_device;
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART2
|
||||
struct stm32_serial_int_rx uart2_int_rx;
|
||||
struct stm32_serial_device uart2 =
|
||||
{
|
||||
USART2,
|
||||
&uart2_int_rx,
|
||||
RT_NULL
|
||||
};
|
||||
struct rt_device uart2_device;
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART3
|
||||
struct stm32_serial_int_rx uart3_int_rx;
|
||||
struct stm32_serial_dma_tx uart3_dma_tx;
|
||||
struct stm32_serial_device uart3 =
|
||||
{
|
||||
USART3,
|
||||
&uart3_int_rx,
|
||||
&uart3_dma_tx
|
||||
};
|
||||
struct rt_device uart3_device;
|
||||
#endif
|
||||
|
||||
#define USART1_DR_Base 0x40013804
|
||||
#define USART2_DR_Base 0x40004404
|
||||
#define USART3_DR_Base 0x40004804
|
||||
|
||||
/* USART1_REMAP = 0 */
|
||||
#define UART1_GPIO_TX GPIO_Pin_9
|
||||
#define UART1_GPIO_RX GPIO_Pin_10
|
||||
#define UART1_GPIO GPIOA
|
||||
#define RCC_APBPeriph_UART1 RCC_APB2Periph_USART1
|
||||
#define UART1_TX_DMA DMA1_Channel4
|
||||
#define UART1_RX_DMA DMA1_Channel5
|
||||
/* USART1 */
|
||||
#define UART1_GPIO_TX GPIO_Pin_9
|
||||
#define UART1_GPIO_RX GPIO_Pin_10
|
||||
#define UART1_GPIO GPIOA
|
||||
|
||||
/* USART2 */
|
||||
#if defined(STM32F10X_LD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
|
||||
#define UART2_GPIO_TX GPIO_Pin_5
|
||||
#define UART2_GPIO_RX GPIO_Pin_6
|
||||
#define UART2_GPIO GPIOD
|
||||
#define RCC_APBPeriph_UART2 RCC_APB1Periph_USART2
|
||||
#define UART2_GPIO GPIOD
|
||||
|
||||
#else /* for STM32F10X_HD */
|
||||
/* USART2_REMAP = 0 */
|
||||
#define UART2_GPIO_TX GPIO_Pin_2
|
||||
#define UART2_GPIO_RX GPIO_Pin_3
|
||||
#define UART2_GPIO GPIOA
|
||||
#define RCC_APBPeriph_UART2 RCC_APB1Periph_USART2
|
||||
#define UART2_TX_DMA DMA1_Channel7
|
||||
#define UART2_RX_DMA DMA1_Channel6
|
||||
#define UART2_GPIO_TX GPIO_Pin_2
|
||||
#define UART2_GPIO_RX GPIO_Pin_3
|
||||
#define UART2_GPIO GPIOA
|
||||
#endif
|
||||
|
||||
/* USART3_REMAP[1:0] = 00 */
|
||||
#define UART3_GPIO_RX GPIO_Pin_11
|
||||
#define UART3_GPIO_TX GPIO_Pin_10
|
||||
#define UART3_GPIO GPIOB
|
||||
#define RCC_APBPeriph_UART3 RCC_APB1Periph_USART3
|
||||
#define UART3_TX_DMA DMA1_Channel2
|
||||
#define UART3_RX_DMA DMA1_Channel3
|
||||
/* STM32 uart driver */
|
||||
struct stm32_uart
|
||||
{
|
||||
USART_TypeDef* uart_device;
|
||||
IRQn_Type irq;
|
||||
};
|
||||
|
||||
static rt_err_t stm32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
||||
{
|
||||
struct stm32_uart* uart;
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
|
||||
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;
|
||||
|
||||
if (cfg->data_bits == DATA_BITS_8){
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
} else if (cfg->data_bits == DATA_BITS_9) {
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
|
||||
}
|
||||
|
||||
if (cfg->stop_bits == STOP_BITS_1){
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
} else if (cfg->stop_bits == STOP_BITS_2){
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_2;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct stm32_uart* uart;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
uart = (struct stm32_uart *)serial->parent.user_data;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
/* disable interrupt */
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* disable rx irq */
|
||||
UART_DISABLE_IRQ(uart->irq);
|
||||
/* disable interrupt */
|
||||
USART_ITConfig(uart->uart_device, USART_IT_RXNE, DISABLE);
|
||||
break;
|
||||
/* enable interrupt */
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* enable rx irq */
|
||||
UART_ENABLE_IRQ(uart->irq);
|
||||
/* enable interrupt */
|
||||
USART_ITConfig(uart->uart_device, USART_IT_RXNE, ENABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static int stm32_putc(struct rt_serial_device *serial, char c)
|
||||
{
|
||||
struct stm32_uart* uart;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
uart = (struct stm32_uart *)serial->parent.user_data;
|
||||
|
||||
uart->uart_device->DR = c;
|
||||
while (!(uart->uart_device->SR & USART_FLAG_TC));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int stm32_getc(struct rt_serial_device *serial)
|
||||
{
|
||||
int ch;
|
||||
struct stm32_uart* uart;
|
||||
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
uart = (struct stm32_uart *)serial->parent.user_data;
|
||||
|
||||
ch = -1;
|
||||
if (uart->uart_device->SR & USART_FLAG_RXNE)
|
||||
{
|
||||
ch = uart->uart_device->DR & 0xff;
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
static const struct rt_uart_ops stm32_uart_ops =
|
||||
{
|
||||
stm32_configure,
|
||||
stm32_control,
|
||||
stm32_putc,
|
||||
stm32_getc,
|
||||
};
|
||||
|
||||
#if defined(RT_USING_UART1)
|
||||
/* UART1 device driver structure */
|
||||
struct stm32_uart uart1 =
|
||||
{
|
||||
USART1,
|
||||
USART1_IRQn,
|
||||
};
|
||||
struct rt_serial_device serial1;
|
||||
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
struct stm32_uart* uart;
|
||||
|
||||
uart = &uart1;
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
rt_hw_serial_isr(&serial1, RT_SERIAL_EVENT_RX_IND);
|
||||
/* clear interrupt */
|
||||
USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
|
||||
}
|
||||
|
||||
if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
|
||||
{
|
||||
/* clear interrupt */
|
||||
USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
|
||||
}
|
||||
if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
|
||||
{
|
||||
stm32_getc(&serial1);
|
||||
}
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* RT_USING_UART1 */
|
||||
|
||||
#if defined(RT_USING_UART2)
|
||||
/* UART1 device driver structure */
|
||||
struct stm32_uart uart2 =
|
||||
{
|
||||
USART2,
|
||||
USART2_IRQn,
|
||||
};
|
||||
struct rt_serial_device serial2;
|
||||
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
struct stm32_uart* uart;
|
||||
|
||||
uart = &uart2;
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);
|
||||
/* clear interrupt */
|
||||
USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);
|
||||
}
|
||||
if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)
|
||||
{
|
||||
/* clear interrupt */
|
||||
USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);
|
||||
}
|
||||
if (USART_GetFlagStatus(uart->uart_device, USART_FLAG_ORE) == SET)
|
||||
{
|
||||
stm32_getc(&serial2);
|
||||
}
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* RT_USING_UART2 */
|
||||
|
||||
static void RCC_Configuration(void)
|
||||
{
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
|
||||
|
||||
#ifdef RT_USING_UART1
|
||||
/* Enable USART1 and GPIOA clocks */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART2
|
||||
#if defined(RT_USING_UART1)
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
#endif /* RT_USING_UART1 */
|
||||
|
||||
#if defined(RT_USING_UART2)
|
||||
#if (defined(STM32F10X_LD) || defined(STM32F10X_MD) || defined(STM32F10X_CL))
|
||||
/* Enable AFIO and GPIOD clock */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD, ENABLE);
|
||||
|
@ -125,218 +250,86 @@ static void RCC_Configuration(void)
|
|||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
|
||||
#endif
|
||||
|
||||
/* Enable USART2 clock */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART3
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
/* Enable USART3 clock */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
|
||||
/* DMA clock enable */
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
#endif
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
#endif /* RT_USING_UART2 */
|
||||
}
|
||||
|
||||
static void GPIO_Configuration(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
#ifdef RT_USING_UART1
|
||||
/* Configure USART1 Rx (PA.10) as input floating */
|
||||
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
|
||||
#if defined(RT_USING_UART1)
|
||||
/* Configure USART1 Rx (PA.10) as input floating */
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_RX;
|
||||
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
|
||||
|
||||
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
|
||||
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_TX;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
|
||||
#endif
|
||||
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 */
|
||||
|
||||
#ifdef RT_USING_UART2
|
||||
/* Configure USART2 Rx as input floating */
|
||||
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_RX;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
|
||||
#if defined(RT_USING_UART2)
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_RX;
|
||||
GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
|
||||
|
||||
/* Configure USART2 Tx as alternate function push-pull */
|
||||
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_TX;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART3
|
||||
/* Configure USART3 Rx as input floating */
|
||||
GPIO_InitStructure.GPIO_Pin = UART3_GPIO_RX;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
|
||||
|
||||
/* Configure USART3 Tx as alternate function push-pull */
|
||||
GPIO_InitStructure.GPIO_Pin = UART3_GPIO_TX;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
|
||||
#endif
|
||||
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 */
|
||||
}
|
||||
|
||||
static void NVIC_Configuration(void)
|
||||
static void NVIC_Configuration(struct stm32_uart* uart)
|
||||
{
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
#ifdef RT_USING_UART1
|
||||
/* Enable the USART1 Interrupt */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART2
|
||||
/* Enable the USART2 Interrupt */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART3
|
||||
/* Enable the USART3 Interrupt */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
|
||||
/* Enable the DMA1 Channel2 Interrupt */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
/* Enable the USART1 Interrupt */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = uart->irq;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
}
|
||||
|
||||
static void DMA_Configuration(void)
|
||||
void rt_hw_usart_init(void)
|
||||
{
|
||||
#if defined (RT_USING_UART3)
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
struct stm32_uart* uart;
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
|
||||
/* fill init structure */
|
||||
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;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||
RCC_Configuration();
|
||||
GPIO_Configuration();
|
||||
|
||||
/* DMA1 Channel5 (triggered by USART3 Tx event) Config */
|
||||
DMA_DeInit(UART3_TX_DMA);
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)0;
|
||||
DMA_InitStructure.DMA_BufferSize = 0;
|
||||
DMA_Init(UART3_TX_DMA, &DMA_InitStructure);
|
||||
DMA_ITConfig(UART3_TX_DMA, DMA_IT_TC | DMA_IT_TE, ENABLE);
|
||||
DMA_ClearFlag(DMA1_FLAG_TC5);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Init all related hardware in here
|
||||
* rt_hw_serial_init() will register all supported USART device
|
||||
*/
|
||||
void rt_hw_usart_init()
|
||||
{
|
||||
USART_InitTypeDef USART_InitStructure;
|
||||
USART_ClockInitTypeDef USART_ClockInitStructure;
|
||||
|
||||
RCC_Configuration();
|
||||
|
||||
GPIO_Configuration();
|
||||
|
||||
NVIC_Configuration();
|
||||
|
||||
DMA_Configuration();
|
||||
|
||||
/* uart init */
|
||||
#ifdef RT_USING_UART1
|
||||
USART_InitStructure.USART_BaudRate = 115200;
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
|
||||
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
|
||||
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
|
||||
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
|
||||
USART_Init(USART1, &USART_InitStructure);
|
||||
USART_ClockInit(USART1, &USART_ClockInitStructure);
|
||||
|
||||
/* register uart1 */
|
||||
rt_hw_serial_register(&uart1_device, "uart1",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
|
||||
&uart1);
|
||||
|
||||
/* enable interrupt */
|
||||
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART2
|
||||
USART_InitStructure.USART_BaudRate = 115200;
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
|
||||
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
|
||||
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
|
||||
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
|
||||
USART_Init(USART2, &USART_InitStructure);
|
||||
USART_ClockInit(USART2, &USART_ClockInitStructure);
|
||||
|
||||
/* register uart2 */
|
||||
rt_hw_serial_register(&uart2_device, "uart2",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
|
||||
&uart2);
|
||||
|
||||
/* Enable USART2 DMA Rx request */
|
||||
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_UART3
|
||||
USART_InitStructure.USART_BaudRate = 115200;
|
||||
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
||||
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
||||
USART_InitStructure.USART_Parity = USART_Parity_No;
|
||||
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
||||
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
||||
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
|
||||
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
|
||||
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
|
||||
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
|
||||
USART_Init(USART3, &USART_InitStructure);
|
||||
USART_ClockInit(USART3, &USART_ClockInitStructure);
|
||||
|
||||
uart3_dma_tx.dma_channel= UART3_TX_DMA;
|
||||
|
||||
/* register uart3 */
|
||||
rt_hw_serial_register(&uart3_device, "uart3",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_DMA_TX,
|
||||
&uart3);
|
||||
|
||||
/* Enable USART3 DMA Tx request */
|
||||
USART_DMACmd(USART3, USART_DMAReq_Tx , ENABLE);
|
||||
|
||||
/* enable interrupt */
|
||||
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
|
||||
#endif
|
||||
#if defined(RT_USING_UART1)
|
||||
uart = &uart1;
|
||||
config.baud_rate = BAUD_RATE_115200;
|
||||
|
||||
serial1.ops = &stm32_uart_ops;
|
||||
serial1.config = config;
|
||||
|
||||
NVIC_Configuration(&uart1);
|
||||
|
||||
/* register UART1 device */
|
||||
rt_hw_serial_register(&serial1, "uart1",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX ,
|
||||
uart);
|
||||
#endif /* RT_USING_UART1 */
|
||||
|
||||
#if defined(RT_USING_UART2)
|
||||
uart = &uart2;
|
||||
|
||||
config.baud_rate = BAUD_RATE_115200;
|
||||
serial2.ops = &stm32_uart_ops;
|
||||
serial2.config = config;
|
||||
|
||||
NVIC_Configuration(&uart2);
|
||||
|
||||
/* register UART1 device */
|
||||
rt_hw_serial_register(&serial2, "uart2",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
#endif /* RT_USING_UART2 */
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n))
|
||||
#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n))
|
||||
|
||||
void rt_hw_usart_init(void);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -58,6 +58,11 @@
|
|||
/* SECTION: Device System */
|
||||
/* Using Device System */
|
||||
#define RT_USING_DEVICE
|
||||
// <bool name="RT_USING_DEVICE_IPC" description="Using device communication" default="true" />
|
||||
#define RT_USING_DEVICE_IPC
|
||||
// <bool name="RT_USING_SERIAL" description="Using Serial" default="true" />
|
||||
#define RT_USING_SERIAL
|
||||
|
||||
#define RT_USING_SPI
|
||||
|
||||
/* SECTION: Console options */
|
||||
|
|
Loading…
Reference in New Issue