/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2009-01-05 Bernard the first version * 2010-03-29 Bernard remove interrupt Tx and DMA Rx mode */ #include "usart.h" #include #include #include /* * 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_UART6 struct stm32_serial_int_rx uart6_int_rx; struct stm32_serial_device uart6 = { USART6, &uart6_int_rx, RT_NULL }; struct rt_device uart6_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 #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 /* 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 /* USART6_REMAP = 0 */ #define UART6_GPIO_TX GPIO_Pin_6 #define UART6_GPIO_RX GPIO_Pin_7 #define UART6_GPIO GPIOC #define RCC_APBPeriph_UART6 RCC_APB2Periph_USART6 //#define UART1_TX_DMA DMA1_Channel? //#define UART1_RX_DMA DMA1_Channel? static void RCC_Configuration(void) { #ifdef RT_USING_UART1 /* Enable USART1 and GPIOA clocks */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); #endif #ifdef RT_USING_UART6 /* Enable USART6 and GPIOC clocks */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); #endif } static void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStruct; #ifdef RT_USING_UART1 GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); #endif #ifdef RT_USING_UART6 GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP; GPIO_InitStruct.GPIO_Pin=UART6_GPIO_TX|UART6_GPIO_RX; GPIO_Init(UART6_GPIO,&GPIO_InitStruct); GPIO_PinAFConfig(UART6_GPIO, GPIO_PinSource6, GPIO_AF_USART6); GPIO_PinAFConfig(UART6_GPIO, GPIO_PinSource7, GPIO_AF_USART6); #endif } static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; #ifdef RT_USING_UART1 /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif #ifdef RT_USING_UART6 /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #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; RCC_Configuration(); GPIO_Configuration(); NVIC_Configuration(); /* uart init */ #ifdef RT_USING_UART1 USART_DeInit(USART1); 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_Init(USART1, &USART_InitStructure); /* 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); /* Enable USART1 */ USART_Cmd(USART1, ENABLE); USART_ClearFlag(USART1,USART_FLAG_TXE); #endif /* uart init */ #ifdef RT_USING_UART6 USART_DeInit(USART6); 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_Init(USART6, &USART_InitStructure); /* register uart1 */ rt_hw_serial_register(&uart6_device, "uart6", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM, &uart6); /* enable interrupt */ USART_ITConfig(USART6, USART_IT_RXNE, ENABLE); /* Enable USART6 */ USART_Cmd(USART6, ENABLE); USART_ClearFlag(USART6,USART_FLAG_TXE); #endif } #ifdef RT_USING_UART1 void USART1_IRQHandler() { /* enter interrupt */ rt_interrupt_enter(); rt_hw_serial_isr(&uart1_device); /* leave interrupt */ rt_interrupt_leave(); } #endif #ifdef RT_USING_UART6 void USART6_IRQHandler() { /* enter interrupt */ rt_interrupt_enter(); rt_hw_serial_isr(&uart6_device); /* leave interrupt */ rt_interrupt_leave(); } #endif