update usart driver: use serial driver component.
This commit is contained in:
parent
b12f6bbdee
commit
13c30f9269
|
@ -9,7 +9,6 @@ src = Split("""
|
|||
board.c
|
||||
stm32f10x_it.c
|
||||
led.c
|
||||
serial.c
|
||||
usart.c
|
||||
""")
|
||||
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
#define STM32_SRAM_SIZE 64
|
||||
#define STM32_SRAM_END (0x20000000 + STM32_SRAM_SIZE * 1024)
|
||||
|
||||
/* USART driver select. */
|
||||
#define RT_USING_UART1
|
||||
#define RT_USING_UART2
|
||||
#define RT_USING_UART3
|
||||
|
||||
#endif /* __BOARD_H__ */
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
|
|
@ -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 64
|
||||
#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
|
|
@ -119,105 +119,6 @@ void DebugMon_Handler(void)
|
|||
/* file (startup_stm32f10x_xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Function Name : DMA1_Channel2_IRQHandler
|
||||
* Description : This function handles DMA1 Channel 2 interrupt request.
|
||||
* Input : None
|
||||
* Output : None
|
||||
* Return : None
|
||||
*******************************************************************************/
|
||||
void DMA1_Channel2_IRQHandler(void)
|
||||
{
|
||||
#ifdef RT_USING_UART3
|
||||
extern struct rt_device uart3_device;
|
||||
extern void rt_hw_serial_dma_tx_isr(struct rt_device *device);
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
if (DMA_GetITStatus(DMA1_IT_TC2))
|
||||
{
|
||||
/* transmission complete, invoke serial dma tx isr */
|
||||
rt_hw_serial_dma_tx_isr(&uart3_device);
|
||||
}
|
||||
|
||||
/* clear DMA flag */
|
||||
DMA_ClearFlag(DMA1_FLAG_TC2 | DMA1_FLAG_TE2);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
}
|
||||
|
||||
#ifdef RT_USING_LWIP
|
||||
/*******************************************************************************
|
||||
* Function Name : EXTI4_IRQHandler
|
||||
|
|
|
@ -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,335 +11,365 @@
|
|||
* 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.
|
||||
*/
|
||||
|
||||
#include "stm32f10x.h"
|
||||
#include "usart.h"
|
||||
#include <serial.h>
|
||||
#include <stm32f10x_dma.h>
|
||||
#include "board.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
|
||||
*/
|
||||
#include <rtdevice.h>
|
||||
|
||||
#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 */
|
||||
/* USART1 */
|
||||
#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
|
||||
|
||||
#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
|
||||
#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
|
||||
#endif
|
||||
/* USART2 */
|
||||
#define UART2_GPIO_TX GPIO_Pin_2
|
||||
#define UART2_GPIO_RX GPIO_Pin_3
|
||||
#define UART2_GPIO GPIOA
|
||||
|
||||
/* USART3_REMAP[1:0] = 00 */
|
||||
#define UART3_GPIO_RX GPIO_Pin_11
|
||||
#define UART3_GPIO_TX GPIO_Pin_10
|
||||
#define UART3_GPIO_RX GPIO_Pin_11
|
||||
#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;
|
||||
|
||||
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;
|
||||
|
||||
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_Init(uart->uart_device, &USART_InitStructure);
|
||||
|
||||
/* Enable USART */
|
||||
USART_Cmd(uart->uart_device, ENABLE);
|
||||
/* enable interrupt */
|
||||
USART_ITConfig(uart->uart_device, USART_IT_RXNE, 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)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
/* disable rx irq */
|
||||
UART_DISABLE_IRQ(uart->irq);
|
||||
break;
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
/* enable rx irq */
|
||||
UART_ENABLE_IRQ(uart->irq);
|
||||
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;
|
||||
|
||||
while (!(uart->uart_device->SR & USART_FLAG_TXE));
|
||||
uart->uart_device->DR = c;
|
||||
|
||||
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 serial_ringbuffer uart1_int_rx;
|
||||
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);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* RT_USING_UART1 */
|
||||
|
||||
#if defined(RT_USING_UART2)
|
||||
/* UART1 device driver structure */
|
||||
struct serial_ringbuffer uart2_int_rx;
|
||||
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);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* RT_USING_UART2 */
|
||||
|
||||
#if defined(RT_USING_UART3)
|
||||
/* UART1 device driver structure */
|
||||
struct serial_ringbuffer uart3_int_rx;
|
||||
struct stm32_uart uart3 =
|
||||
{
|
||||
USART3,
|
||||
USART3_IRQn,
|
||||
};
|
||||
struct rt_serial_device serial3;
|
||||
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
struct stm32_uart* uart;
|
||||
|
||||
uart = &uart3;
|
||||
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
rt_hw_serial_isr(&serial3);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif /* RT_USING_UART3 */
|
||||
|
||||
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
|
||||
/* Enable UART GPIO clocks */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
/* Enable UART clock */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
|
||||
#endif /* RT_USING_UART1 */
|
||||
|
||||
#ifdef 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);
|
||||
|
||||
/* Enable the USART2 Pins Software Remapping */
|
||||
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
|
||||
#else
|
||||
/* Enable AFIO and GPIOA clock */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
|
||||
#endif
|
||||
|
||||
/* Enable USART2 clock */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
#endif
|
||||
/* Enable UART GPIO clocks */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
||||
/* Enable UART clock */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
|
||||
#endif /* RT_USING_UART2 */
|
||||
|
||||
#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
|
||||
/* Enable UART GPIO clocks */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
||||
/* Enable UART clock */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
|
||||
#endif /* RT_USING_UART3 */
|
||||
}
|
||||
|
||||
static void GPIO_Configuration(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
|
||||
#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);
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
/* Configure USART Rx/tx PIN */
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_RX;
|
||||
GPIO_Init(UART1_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
|
||||
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 */
|
||||
|
||||
#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 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);
|
||||
|
||||
/* 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 = UART3_GPIO_TX;
|
||||
GPIO_Init(UART3_GPIO, &GPIO_InitStructure);
|
||||
#endif /* RT_USING_UART3 */
|
||||
}
|
||||
|
||||
static void NVIC_Configuration(void)
|
||||
static void NVIC_Configuration(struct stm32_uart* uart)
|
||||
{
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
void rt_hw_usart_init(void)
|
||||
{
|
||||
struct stm32_uart* uart;
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
|
||||
RCC_Configuration();
|
||||
GPIO_Configuration();
|
||||
|
||||
#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
|
||||
uart = &uart1;
|
||||
config.baud_rate = BAUD_RATE_115200;
|
||||
|
||||
serial1.ops = &stm32_uart_ops;
|
||||
serial1.int_rx = &uart1_int_rx;
|
||||
serial1.config = config;
|
||||
|
||||
NVIC_Configuration(&uart1);
|
||||
|
||||
/* register UART1 device */
|
||||
rt_hw_serial_register(&serial1, "uart1",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM,
|
||||
uart);
|
||||
#endif /* RT_USING_UART1 */
|
||||
|
||||
#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
|
||||
uart = &uart2;
|
||||
|
||||
config.baud_rate = BAUD_RATE_115200;
|
||||
serial2.ops = &stm32_uart_ops;
|
||||
serial2.int_rx = &uart2_int_rx;
|
||||
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 */
|
||||
|
||||
#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);
|
||||
uart = &uart3;
|
||||
|
||||
/* 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
|
||||
}
|
||||
|
||||
static void DMA_Configuration(void)
|
||||
{
|
||||
#if defined (RT_USING_UART3)
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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;
|
||||
/* As we will set them before DMA actually enabled, the DMA_MemoryBaseAddr
|
||||
* and DMA_BufferSize are meaningless. So just set them to proper values
|
||||
* which could make DMA_Init happy.
|
||||
*/
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)0;
|
||||
DMA_InitStructure.DMA_BufferSize = 1;
|
||||
DMA_Init(UART3_TX_DMA, &DMA_InitStructure);
|
||||
DMA_ITConfig(UART3_TX_DMA, DMA_IT_TC | DMA_IT_TE, ENABLE);
|
||||
DMA_ClearFlag(DMA1_FLAG_TC2);
|
||||
#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
|
||||
config.baud_rate = BAUD_RATE_115200;
|
||||
|
||||
serial3.ops = &stm32_uart_ops;
|
||||
serial3.int_rx = &uart3_int_rx;
|
||||
serial3.config = config;
|
||||
|
||||
NVIC_Configuration(&uart3);
|
||||
|
||||
/* register UART1 device */
|
||||
rt_hw_serial_register(&serial3, "uart3",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
|
||||
uart);
|
||||
#endif /* RT_USING_UART3 */
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,6 +8,7 @@ Group (Drivers)
|
|||
Group (STM32_StdPeriph)
|
||||
Group (Kernel)
|
||||
Group (CORTEX-M3)
|
||||
Group (DeviceDrivers)
|
||||
Group (finsh)
|
||||
Group (Components)
|
||||
|
||||
|
@ -16,7 +17,6 @@ File 1,1,<applications\startup.c><startup.c>
|
|||
File 2,1,<drivers\board.c><board.c>
|
||||
File 2,1,<drivers\stm32f10x_it.c><stm32f10x_it.c>
|
||||
File 2,1,<drivers\led.c><led.c>
|
||||
File 2,1,<drivers\serial.c><serial.c>
|
||||
File 2,1,<drivers\usart.c><usart.c>
|
||||
File 3,1,<Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\system_stm32f10x.c><system_stm32f10x.c>
|
||||
File 3,1,<Libraries\STM32F10x_StdPeriph_Driver\src\stm32f10x_crc.c><stm32f10x_crc.c>
|
||||
|
@ -60,22 +60,27 @@ File 5,2,<..\..\libcpu\arm\cortex-m3\context_rvds.S><context_rvds.S>
|
|||
File 5,1,<..\..\libcpu\arm\common\backtrace.c><backtrace.c>
|
||||
File 5,1,<..\..\libcpu\arm\common\div0.c><div0.c>
|
||||
File 5,1,<..\..\libcpu\arm\common\showmem.c><showmem.c>
|
||||
File 6,1,<..\..\components\finsh\cmd.c><cmd.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_compiler.c><finsh_compiler.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_error.c><finsh_error.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_heap.c><finsh_heap.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_init.c><finsh_init.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_node.c><finsh_node.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_ops.c><finsh_ops.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_parser.c><finsh_parser.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_token.c><finsh_token.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_var.c><finsh_var.c>
|
||||
File 6,1,<..\..\components\finsh\finsh_vm.c><finsh_vm.c>
|
||||
File 6,1,<..\..\components\finsh\msh.c><msh.c>
|
||||
File 6,1,<..\..\components\finsh\msh_cmd.c><msh_cmd.c>
|
||||
File 6,1,<..\..\components\finsh\shell.c><shell.c>
|
||||
File 6,1,<..\..\components\finsh\symbol.c><symbol.c>
|
||||
File 7,1,<..\..\components\init\components.c><components.c>
|
||||
File 6,1,<..\..\components\drivers\serial\serial.c><serial.c>
|
||||
File 6,1,<..\..\components\drivers\src\completion.c><completion.c>
|
||||
File 6,1,<..\..\components\drivers\src\dataqueue.c><dataqueue.c>
|
||||
File 6,1,<..\..\components\drivers\src\pipe.c><pipe.c>
|
||||
File 6,1,<..\..\components\drivers\src\ringbuffer.c><ringbuffer.c>
|
||||
File 7,1,<..\..\components\finsh\cmd.c><cmd.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_compiler.c><finsh_compiler.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_error.c><finsh_error.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_heap.c><finsh_heap.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_init.c><finsh_init.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_node.c><finsh_node.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_ops.c><finsh_ops.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_parser.c><finsh_parser.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_token.c><finsh_token.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_var.c><finsh_var.c>
|
||||
File 7,1,<..\..\components\finsh\finsh_vm.c><finsh_vm.c>
|
||||
File 7,1,<..\..\components\finsh\msh.c><msh.c>
|
||||
File 7,1,<..\..\components\finsh\msh_cmd.c><msh_cmd.c>
|
||||
File 7,1,<..\..\components\finsh\shell.c><shell.c>
|
||||
File 7,1,<..\..\components\finsh\symbol.c><symbol.c>
|
||||
File 8,1,<..\..\components\init\components.c><components.c>
|
||||
|
||||
|
||||
|
||||
|
@ -138,7 +143,7 @@ Options 1,0,0 // Target 'RT-Thread STM32'
|
|||
ADSCMISC ()
|
||||
ADSCDEFN (STM32F10X_HD, USE_STDPERIPH_DRIVER)
|
||||
ADSCUDEF ()
|
||||
ADSCINCD (Libraries\STM32F10x_StdPeriph_Driver\inc;..\..\include;drivers;..\..\components\CMSIS\Include;.;applications;..\..\libcpu\arm\cortex-m3;..\..\libcpu\arm\common;..\..\components\init;..\..\components\finsh;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x)
|
||||
ADSCINCD (Libraries\STM32F10x_StdPeriph_Driver\inc;..\..\include;drivers;..\..\components\CMSIS\Include;.;applications;..\..\libcpu\arm\cortex-m3;..\..\components\drivers\include;..\..\libcpu\arm\common;..\..\components\init;..\..\components\finsh;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x)
|
||||
ADSASFLG { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
|
||||
ADSAMISC ()
|
||||
ADSADEFN ()
|
||||
|
|
|
@ -307,6 +307,7 @@
|
|||
<state>$PROJ_DIR$\.</state>
|
||||
<state>$PROJ_DIR$\applications</state>
|
||||
<state>$PROJ_DIR$\..\..\libcpu\arm\cortex-m3</state>
|
||||
<state>$PROJ_DIR$\..\..\components\drivers\include</state>
|
||||
<state>$PROJ_DIR$\..\..\libcpu\arm\common</state>
|
||||
<state>$PROJ_DIR$\..\..\components\init</state>
|
||||
<state>$PROJ_DIR$\..\..\components\finsh</state>
|
||||
|
@ -1236,6 +1237,7 @@
|
|||
<state>$PROJ_DIR$\.</state>
|
||||
<state>$PROJ_DIR$\applications</state>
|
||||
<state>$PROJ_DIR$\..\..\libcpu\arm\cortex-m3</state>
|
||||
<state>$PROJ_DIR$\..\..\components\drivers\include</state>
|
||||
<state>$PROJ_DIR$\..\..\libcpu\arm\common</state>
|
||||
<state>$PROJ_DIR$\..\..\components\init</state>
|
||||
<state>$PROJ_DIR$\..\..\components\finsh</state>
|
||||
|
@ -1893,6 +1895,24 @@
|
|||
<name>$PROJ_DIR$\..\..\libcpu\arm\common\showmem.c</name>
|
||||
</file>
|
||||
</group>
|
||||
<group>
|
||||
<name>DeviceDrivers</name>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\components\drivers\src\completion.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\components\drivers\src\dataqueue.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\components\drivers\src\pipe.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\components\drivers\src\ringbuffer.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\..\components\drivers\serial\serial.c</name>
|
||||
</file>
|
||||
</group>
|
||||
<group>
|
||||
<name>Drivers</name>
|
||||
<file>
|
||||
|
@ -1901,9 +1921,6 @@
|
|||
<file>
|
||||
<name>$PROJ_DIR$\drivers\led.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\drivers\serial.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\drivers\stm32f10x_it.c</name>
|
||||
</file>
|
||||
|
|
|
@ -351,7 +351,7 @@
|
|||
<MiscControls></MiscControls>
|
||||
<Define>STM32F10X_HD, USE_STDPERIPH_DRIVER</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>.;..\..\components\CMSIS\Include;..\..\components\finsh;..\..\components\init;..\..\include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m3;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x;Libraries\STM32F10x_StdPeriph_Driver\inc;applications;drivers</IncludePath>
|
||||
<IncludePath>.;..\..\components\CMSIS\Include;..\..\components\drivers\include;..\..\components\finsh;..\..\components\init;..\..\include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m3;Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x;Libraries\STM32F10x_StdPeriph_Driver\inc;applications;drivers</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
|
@ -422,11 +422,6 @@
|
|||
<FileType>1</FileType>
|
||||
<FilePath>drivers\led.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>serial.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>drivers\serial.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usart.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
|
@ -659,6 +654,36 @@
|
|||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>DeviceDrivers</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>serial.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\components\drivers\serial\serial.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>completion.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\components\drivers\src\completion.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>dataqueue.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\components\drivers\src\dataqueue.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>pipe.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\components\drivers\src\pipe.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>ringbuffer.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\components\drivers\src\ringbuffer.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>finsh</GroupName>
|
||||
<Files>
|
||||
|
|
|
@ -62,7 +62,10 @@
|
|||
/* SECTION: Device System */
|
||||
/* Using Device System */
|
||||
#define RT_USING_DEVICE
|
||||
#define RT_USING_UART1
|
||||
// <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
|
||||
|
||||
/* SECTION: Console options */
|
||||
#define RT_USING_CONSOLE
|
||||
|
|
Loading…
Reference in New Issue