Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uart.c Source File

uart.c

00001 /**
00002  * @file    uart.c
00003  * @brief
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include "string.h"
00023 
00024 #include "stm32f1xx.h"
00025 #include "uart.h"
00026 #include "gpio.h"
00027 #include "util.h"
00028 #include "circ_buf.h"
00029 #include "IO_Config.h"
00030 
00031 // For usart
00032 #define CDC_UART                     USART2
00033 #define CDC_UART_ENABLE()            __HAL_RCC_USART2_CLK_ENABLE()
00034 #define CDC_UART_DISABLE()           __HAL_RCC_USART2_CLK_DISABLE()
00035 #define CDC_UART_IRQn                USART2_IRQn
00036 #define CDC_UART_IRQn_Handler        USART2_IRQHandler
00037 
00038 #define UART_PINS_PORT_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
00039 #define UART_PINS_PORT_DISABLE()     __HAL_RCC_GPIOA_CLK_DISABLE()
00040 
00041 #define UART_TX_PORT                 GPIOA
00042 #define UART_TX_PIN                  GPIO_PIN_2
00043 
00044 #define UART_RX_PORT                 GPIOA
00045 #define UART_RX_PIN                  GPIO_PIN_3
00046 
00047 #define UART_CTS_PORT                GPIOA
00048 #define UART_CTS_PIN                 GPIO_PIN_0
00049 
00050 #define UART_RTS_PORT                GPIOA
00051 #define UART_RTS_PIN                 GPIO_PIN_1
00052 
00053 
00054 #define RX_OVRF_MSG         "<DAPLink:Overflow>\n"
00055 #define RX_OVRF_MSG_SIZE    (sizeof(RX_OVRF_MSG) - 1)
00056 #define BUFFER_SIZE         (512)
00057 
00058 circ_buf_t write_buffer;
00059 uint8_t write_buffer_data[BUFFER_SIZE];
00060 circ_buf_t read_buffer;
00061 uint8_t read_buffer_data[BUFFER_SIZE];
00062 
00063 static UART_Configuration configuration = {
00064     .Baudrate = 9600,
00065     .DataBits = UART_DATA_BITS_8,
00066     .Parity = UART_PARITY_NONE,
00067     .StopBits = UART_STOP_BITS_1,
00068     .FlowControl = UART_FLOW_CONTROL_NONE,
00069 };
00070 
00071 extern uint32_t SystemCoreClock;
00072 
00073 
00074 
00075 static void clear_buffers(void)
00076 {
00077     circ_buf_init(&write_buffer, write_buffer_data, sizeof(write_buffer_data));
00078     circ_buf_init(&read_buffer, read_buffer_data, sizeof(read_buffer_data));
00079 }
00080 
00081 int32_t uart_initialize(void)
00082 {
00083     GPIO_InitTypeDef GPIO_InitStructure;
00084 
00085     CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
00086     clear_buffers();
00087 
00088     CDC_UART_ENABLE();
00089     UART_PINS_PORT_ENABLE();
00090 
00091     //TX pin
00092     GPIO_InitStructure.Pin = UART_TX_PIN;
00093     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00094     GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
00095     HAL_GPIO_Init(UART_TX_PORT, &GPIO_InitStructure);
00096     //RX pin
00097     GPIO_InitStructure.Pin = UART_RX_PIN;
00098     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00099     GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
00100     GPIO_InitStructure.Pull = GPIO_PULLUP;
00101     HAL_GPIO_Init(UART_RX_PORT, &GPIO_InitStructure);
00102     //CTS pin, input
00103     GPIO_InitStructure.Pin = UART_CTS_PIN;
00104     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00105     GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
00106     GPIO_InitStructure.Pull = GPIO_PULLUP;
00107     HAL_GPIO_Init(UART_CTS_PORT, &GPIO_InitStructure);
00108     //RTS pin, output low
00109     HAL_GPIO_WritePin(UART_RTS_PORT, UART_RTS_PIN, GPIO_PIN_RESET);
00110     GPIO_InitStructure.Pin = UART_RTS_PIN;
00111     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00112     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
00113     HAL_GPIO_Init(UART_RTS_PORT, &GPIO_InitStructure);
00114 
00115     NVIC_EnableIRQ(CDC_UART_IRQn);
00116 
00117     return 1;
00118 }
00119 
00120 int32_t uart_uninitialize(void)
00121 {
00122     CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
00123     clear_buffers();
00124     return 1;
00125 }
00126 
00127 int32_t uart_reset(void)
00128 {
00129     const uint32_t cr1 = CDC_UART->CR1;
00130     CDC_UART->CR1 = cr1 & ~(USART_IT_TXE | USART_IT_RXNE);
00131     clear_buffers();
00132     CDC_UART->CR1 = cr1 & ~USART_IT_TXE;
00133     return 1;
00134 }
00135 
00136 int32_t uart_set_configuration(UART_Configuration *config)
00137 {
00138     UART_HandleTypeDef uart_handle;
00139     HAL_StatusTypeDef status;
00140 
00141     memset(&uart_handle, 0, sizeof(uart_handle));
00142     uart_handle.Instance = CDC_UART;
00143 
00144     // parity
00145     configuration.Parity = config->Parity;
00146     if(config->Parity == UART_PARITY_ODD) {
00147         uart_handle.Init.Parity = HAL_UART_PARITY_ODD;
00148     } else if(config->Parity == UART_PARITY_EVEN) {
00149         uart_handle.Init.Parity = HAL_UART_PARITY_EVEN;
00150     } else if(config->Parity == UART_PARITY_NONE) {
00151         uart_handle.Init.Parity = HAL_UART_PARITY_NONE;
00152     } else {   //Other not support
00153         uart_handle.Init.Parity = HAL_UART_PARITY_NONE;
00154         configuration.Parity = UART_PARITY_NONE;
00155     }
00156 
00157     // stop bits
00158     configuration.StopBits = config->StopBits;
00159     if(config->StopBits == UART_STOP_BITS_2) {
00160         uart_handle.Init.StopBits = UART_STOPBITS_2;
00161     } else if(config->StopBits == UART_STOP_BITS_1_5) {
00162         uart_handle.Init.StopBits = UART_STOPBITS_2;
00163         configuration.StopBits = UART_STOP_BITS_2;
00164     } else if(config->StopBits == UART_STOP_BITS_1) {
00165         uart_handle.Init.StopBits = UART_STOPBITS_1;
00166     } else {
00167         uart_handle.Init.StopBits = UART_STOPBITS_1;
00168         configuration.StopBits = UART_STOP_BITS_1;
00169     }
00170 
00171     //Only 8 bit support
00172     configuration.DataBits = UART_DATA_BITS_8;
00173     uart_handle.Init.WordLength = UART_WORDLENGTH_8B;
00174 
00175     // No flow control
00176     configuration.FlowControl = UART_FLOW_CONTROL_NONE;
00177     uart_handle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
00178     
00179     // Specified baudrate
00180     configuration.Baudrate = config->Baudrate;
00181     uart_handle.Init.BaudRate = config->Baudrate;
00182 
00183     // TX and RX
00184     uart_handle.Init.Mode = UART_MODE_TX_RX;
00185     
00186     // Disable uart and tx/rx interrupt
00187     CDC_UART->CR1 &= ~(USART_IT_TXE | USART_IT_RXNE);
00188 
00189     clear_buffers();
00190 
00191     status = HAL_UART_DeInit(&uart_handle);
00192     util_assert(HAL_OK == status);
00193     status = HAL_UART_Init(&uart_handle);
00194     util_assert(HAL_OK == status);
00195     (void)status;
00196 
00197     CDC_UART->CR1 |= USART_IT_RXNE;
00198 
00199     return 1;
00200 }
00201 
00202 int32_t uart_get_configuration(UART_Configuration *config)
00203 {
00204     config->Baudrate = configuration.Baudrate;
00205     config->DataBits = configuration.DataBits;
00206     config->Parity   = configuration.Parity;
00207     config->StopBits = configuration.StopBits;
00208     config->FlowControl = UART_FLOW_CONTROL_NONE;
00209 
00210     return 1;
00211 }
00212 
00213 int32_t uart_write_free(void)
00214 {
00215     return circ_buf_count_free(&write_buffer);
00216 }
00217 
00218 int32_t uart_write_data(uint8_t *data, uint16_t size)
00219 {
00220     uint32_t cnt = circ_buf_write(&write_buffer, data, size);
00221     CDC_UART->CR1 |= USART_IT_TXE;
00222 
00223     return cnt;
00224 }
00225 
00226 int32_t uart_read_data(uint8_t *data, uint16_t size)
00227 {
00228     return circ_buf_read(&read_buffer, data, size);
00229 }
00230 
00231 void CDC_UART_IRQn_Handler(void)
00232 {
00233     const uint32_t sr = CDC_UART->SR;
00234 
00235     if (sr & USART_SR_RXNE) {
00236         uint8_t dat = CDC_UART->DR;
00237         uint32_t free = circ_buf_count_free(&read_buffer);
00238         if (free > RX_OVRF_MSG_SIZE) {
00239             circ_buf_push(&read_buffer, dat);
00240         } else if (RX_OVRF_MSG_SIZE == free) {
00241             circ_buf_write(&read_buffer, (uint8_t*)RX_OVRF_MSG, RX_OVRF_MSG_SIZE);
00242         } else {
00243             // Drop character
00244         }
00245     }
00246 
00247     if (sr & USART_SR_TXE) {
00248         if (circ_buf_count_used(&write_buffer) > 0) {
00249             CDC_UART->DR = circ_buf_pop(&write_buffer);
00250         } else {
00251             CDC_UART->CR1 &= ~USART_IT_TXE;
00252         }
00253     }
00254 }