Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 #include "uart.h" 00024 #include "gpio.h" 00025 #include "util.h" 00026 #include "circ_buf.h" 00027 #include "NuMicro.h" 00028 00029 #define RX_OVRF_MSG "<DAPLink:Overflow>\n" 00030 #define RX_OVRF_MSG_SIZE (sizeof(RX_OVRF_MSG) - 1) 00031 #define BUFFER_SIZE (512) 00032 00033 #define TX_FIFO_SIZE 16 /* TX Hardware FIFO size */ 00034 00035 circ_buf_t write_buffer; 00036 uint8_t write_buffer_data[BUFFER_SIZE]; 00037 circ_buf_t read_buffer; 00038 uint8_t read_buffer_data[BUFFER_SIZE]; 00039 00040 static UART_Configuration configuration = { 00041 .Baudrate = 9600, 00042 .DataBits = UART_DATA_BITS_8, 00043 .Parity = UART_PARITY_NONE, 00044 .StopBits = UART_STOP_BITS_1, 00045 .FlowControl = UART_FLOW_CONTROL_NONE, 00046 }; 00047 00048 static void clear_buffers(void) 00049 { 00050 circ_buf_init(&write_buffer, write_buffer_data, sizeof(write_buffer_data)); 00051 circ_buf_init(&read_buffer, read_buffer_data, sizeof(read_buffer_data)); 00052 } 00053 00054 int32_t uart_initialize(void) 00055 { 00056 clear_buffers(); 00057 UART_Open(UART0, 115200); 00058 UART_ENABLE_INT(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk | UART_INTEN_RXTOIEN_Msk)); 00059 NVIC_EnableIRQ(UART0_IRQn); 00060 return 1; 00061 } 00062 00063 int32_t uart_uninitialize(void) 00064 { 00065 NVIC_DisableIRQ(UART0_IRQn); 00066 UART_Close(UART0); 00067 clear_buffers(); 00068 return 1; 00069 } 00070 00071 int32_t uart_reset(void) 00072 { 00073 UART_Configuration backup_configuration = configuration; 00074 uart_set_configuration(&backup_configuration); 00075 return 1; 00076 } 00077 00078 int32_t uart_set_configuration(UART_Configuration *config) 00079 { 00080 uint32_t u32Reg; 00081 uint32_t u32Baud_Div; 00082 NVIC_DisableIRQ(UART0_IRQn); 00083 /* Reset hardware fifo */ 00084 UART0->FIFO |= (UART_FIFO_TXRST_Msk | UART_FIFO_RXRST_Msk); 00085 /* Reset software fifo */ 00086 clear_buffers(); 00087 /* Set parity */ 00088 configuration.Parity = config->Parity; 00089 00090 if (config->Parity == UART_PARITY_ODD) { 00091 u32Reg = 0x08; 00092 } else if (config->Parity == UART_PARITY_EVEN) { 00093 u32Reg = 0x18; 00094 } else if (config->Parity == UART_PARITY_NONE) { 00095 u32Reg = 0; 00096 } else { 00097 u32Reg = 0; 00098 } 00099 00100 /* Stop bit */ 00101 configuration.StopBits = config->StopBits; 00102 00103 if (config->StopBits == UART_STOP_BITS_2) { 00104 u32Reg |= 0x4; 00105 } else if (config->StopBits == UART_STOP_BITS_1_5) { 00106 u32Reg |= 0x4; 00107 } else if (config->StopBits == UART_STOP_BITS_1) 00108 ; 00109 00110 /* Bit width */ 00111 configuration.DataBits = config->DataBits; 00112 00113 if (config->DataBits == UART_DATA_BITS_5) { 00114 u32Reg |= 0; 00115 } else if (config->DataBits == UART_DATA_BITS_6) { 00116 u32Reg |= 1; 00117 } else if (config->DataBits == UART_DATA_BITS_7) { 00118 u32Reg |= 2; 00119 } else if (config->DataBits == UART_DATA_BITS_8) { 00120 u32Reg |= 3; 00121 } 00122 00123 configuration.FlowControl = UART_FLOW_CONTROL_NONE; 00124 /* Set baudrate */ 00125 configuration.Baudrate = config->Baudrate; 00126 u32Baud_Div = UART_BAUD_MODE2_DIVIDER(__HXT, configuration.Baudrate); 00127 00128 if (u32Baud_Div > 0xFFFF) { 00129 UART0->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER(__HXT, configuration.Baudrate)); 00130 } else { 00131 UART0->BAUD = (UART_BAUD_MODE2 | u32Baud_Div); 00132 } 00133 00134 UART0->LINE = u32Reg; 00135 NVIC_EnableIRQ(UART0_IRQn); 00136 return 1; 00137 } 00138 00139 int32_t uart_get_configuration(UART_Configuration *config) 00140 { 00141 config->Baudrate = configuration.Baudrate; 00142 config->DataBits = configuration.DataBits; 00143 config->Parity = configuration.Parity; 00144 config->StopBits = configuration.StopBits; 00145 config->FlowControl = UART_FLOW_CONTROL_NONE; 00146 return 1; 00147 } 00148 00149 int32_t uart_write_free(void) 00150 { 00151 return circ_buf_count_free(&write_buffer); 00152 } 00153 00154 int32_t uart_write_data(uint8_t *data, uint16_t size) 00155 { 00156 uint8_t bInChar; 00157 uint32_t u32Size = circ_buf_write(&write_buffer, data, size); 00158 00159 if (circ_buf_count_used(&write_buffer) > 0) { 00160 if ((UART0->INTEN & UART_INTEN_THREIEN_Msk) == 0) { 00161 bInChar = circ_buf_pop(&write_buffer); 00162 /* Send one bytes out */ 00163 UART_WRITE(UART0, bInChar); 00164 /* Enable Tx Empty Interrupt. (Trigger first one) */ 00165 UART0->INTEN |= UART_INTEN_THREIEN_Msk; 00166 } 00167 } 00168 00169 return u32Size; 00170 } 00171 00172 int32_t uart_read_data(uint8_t *data, uint16_t size) 00173 { 00174 return circ_buf_read(&read_buffer, data, size); 00175 } 00176 00177 void UART0_IRQHandler(void) 00178 { 00179 uint8_t bInChar; 00180 int32_t u32Size; 00181 uint32_t u32IntStatus; 00182 u32IntStatus = UART0->INTSTS; 00183 00184 if ((u32IntStatus & UART_INTSTS_RDAINT_Msk) || (u32IntStatus & UART_INTSTS_RXTOINT_Msk)) { 00185 /* Receiver FIFO threshold level is reached or Rx time out */ 00186 /* Get all the input characters */ 00187 while ((!UART_GET_RX_EMPTY(UART0))) { 00188 /* Get the character from UART Buffer */ 00189 bInChar = UART_READ(UART0); /* Rx trigger level is 1 byte*/ 00190 /* Check if buffer full */ 00191 uint32_t u32Free = circ_buf_count_free(&read_buffer); 00192 00193 if (u32Free > RX_OVRF_MSG_SIZE) { 00194 circ_buf_push(&read_buffer, bInChar); 00195 } else if (RX_OVRF_MSG_SIZE == u32Free) { 00196 circ_buf_write(&read_buffer, (uint8_t *)RX_OVRF_MSG, RX_OVRF_MSG_SIZE); 00197 } else { 00198 // Drop character 00199 } 00200 } 00201 } 00202 00203 if (u32IntStatus & UART_INTSTS_THREINT_Msk) { 00204 if (circ_buf_count_used(&write_buffer) > 0) { 00205 /* Fill the Tx FIFO */ 00206 u32Size = circ_buf_count_used(&write_buffer); 00207 00208 if (u32Size >= TX_FIFO_SIZE) { 00209 u32Size = TX_FIFO_SIZE; 00210 } 00211 00212 while (u32Size) { 00213 bInChar = circ_buf_pop(&write_buffer); 00214 UART_WRITE(UART0, bInChar); 00215 u32Size--; 00216 } 00217 } else { 00218 /* No more data, just stop Tx (Stop work) */ 00219 UART0->INTEN &= ~UART_INTEN_THREIEN_Msk; 00220 } 00221 } 00222 }
Generated on Tue Jul 12 2022 15:37:26 by
