Bright Pan 9691c659c8 It is a big patch for stm32f0x, see the fellow :
1. fix heap management for stm32f0xx(SRAM=8k)
    2. add USART1, USART2 driver for stm32f051R8
    3. fix finsh support for stm32f0x
    4. fix board components initial for stm32f0x and open debug msg
    5. add led driver(pc9) and test thread for stm32f0discovery board
    6. add init thread for stm32f0x do components initial
    7. add rcc initial for stm32f0x in rt_hw_board_init()
    8. add print rcc freq information function

the console output example is:
    SYSCLK_Frequency is 48000000HZ
    PCLK_Frequency is 48000000HZ
    HCLK_Frequency is 48000000HZ
    CECCLK_Frequency is 32786HZ
    ADCCLK_Frequency is 14000000HZ
    USART1CLK_Frequency is 48000000HZ
    I2C1CLK_Frequency is 8000000HZ
    SystemCoreClock is 48000000HZ
    initialize rti_start:0 done

    \ | /
    - RT -     Thread Operating System
    / | \     1.2.0 build Nov 15 2013
    2006 - 2013 Copyright by rt-thread team
    do components intialization.
    initialize rti_board_end:0 done
    initialize rt_hw_led_init:32768 done
    initialize finsh_system_init:0 done
    finsh>>
2013-11-15 14:05:30 +08:00

311 lines
8.0 KiB
C

/*
* File : usart.c
* This file is part of RT-Thread RTOS
* 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
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2013-11-15 bright the first version
*/
#include <stm32f0xx.h>
#include <rtdevice.h>
#include "usart.h"
/* USART1 */
#define UART1_GPIO_TX GPIO_Pin_9
#define UART1_GPIO_TX_SOURCE GPIO_PinSource9
#define UART1_GPIO_RX GPIO_Pin_10
#define UART1_GPIO_RX_SOURCE GPIO_PinSource10
#define UART1_GPIO_AF GPIO_AF_1
#define UART1_GPIO GPIOA
/* USART2 */
#define UART2_GPIO_TX GPIO_Pin_2
#define UART2_GPIO_TX_SOURCE GPIO_PinSource2
#define UART2_GPIO_RX GPIO_Pin_3
#define UART2_GPIO_RX_SOURCE GPIO_PinSource3
#define UART2_GPIO_AF GPIO_AF_1
#define UART2_GPIO GPIOA
/* 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->ISR & USART_FLAG_TXE));
uart->uart_device->TDR = 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->ISR & USART_FLAG_RXNE)
{
ch = uart->uart_device->RDR & 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)
/* UART2 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 */
static void RCC_Configuration(void)
{
#ifdef RT_USING_UART1
/* Enable GPIO clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* Enable USART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
#endif /* RT_USING_UART1 */
#ifdef RT_USING_UART2
/* Enable GPIO clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* Enable USART clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
#endif /* RT_USING_UART2 */
}
static void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
#ifdef RT_USING_UART1
/* Connect PXx to USARTx_Tx */
GPIO_PinAFConfig(UART1_GPIO, UART1_GPIO_TX_SOURCE, UART1_GPIO_AF);
/* Connect PXx to USARTx_Rx */
GPIO_PinAFConfig(UART1_GPIO, UART1_GPIO_RX_SOURCE, UART1_GPIO_AF);
/* Configure USART Tx, Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = UART1_GPIO_TX | UART1_GPIO_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(UART1_GPIO, &GPIO_InitStructure);
#endif /* RT_USING_UART1 */
#ifdef RT_USING_UART2
/* Connect PXx to USARTx_Tx */
GPIO_PinAFConfig(UART2_GPIO, UART2_GPIO_TX_SOURCE, UART2_GPIO_AF);
/* Connect PXx to USARTx_Rx */
GPIO_PinAFConfig(UART2_GPIO, UART2_GPIO_RX_SOURCE, UART2_GPIO_AF);
/* Configure USART Tx, Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = UART2_GPIO_TX | UART2_GPIO_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(UART2_GPIO, &GPIO_InitStructure);
#endif /* RT_USING_UART2 */
}
static void NVIC_Configuration(struct stm32_uart* uart)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the USART Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = uart->irq;
NVIC_InitStructure.NVIC_IRQChannelPriority = 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
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
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 */
}