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 00024 #include "uart.h" 00025 #include "util.h" 00026 #include "cortex_m.h" 00027 #include "IO_Config.h" 00028 #include "circ_buf.h" 00029 #include "settings.h" // for config_get_overflow_detect 00030 00031 #define RX_OVRF_MSG "<DAPLink:Overflow>\n" 00032 #define RX_OVRF_MSG_SIZE (sizeof(RX_OVRF_MSG) - 1) 00033 #define BUFFER_SIZE (512) 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 void clear_buffers(void) 00041 { 00042 util_assert(!(UART->C2 & UART_C2_TIE_MASK)); 00043 circ_buf_init(&write_buffer, write_buffer_data, sizeof(write_buffer_data)); 00044 circ_buf_init(&read_buffer, read_buffer_data, sizeof(read_buffer_data)); 00045 } 00046 00047 int32_t uart_initialize(void) 00048 { 00049 NVIC_DisableIRQ(UART_RX_TX_IRQn); 00050 00051 // enable clk port 00052 if (UART_PORT == PORTA) { 00053 SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK; 00054 } 00055 00056 if (UART_PORT == PORTC) { 00057 SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; 00058 } 00059 00060 if (UART_PORT == PORTD) { 00061 SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; 00062 } 00063 00064 if (UART_PORT == PORTE) { 00065 SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; 00066 } 00067 00068 // enable clk uart 00069 if (1 == UART_NUM) { 00070 SIM->SCGC4 |= SIM_SCGC4_UART1_MASK; 00071 } 00072 00073 if (2 == UART_NUM) { 00074 SIM->SCGC4 |= SIM_SCGC4_UART2_MASK; 00075 } 00076 00077 // transmitter and receiver disabled 00078 UART->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK); 00079 // disable interrupt 00080 UART->C2 &= ~(UART_C2_RIE_MASK | UART_C2_TIE_MASK); 00081 00082 clear_buffers(); 00083 00084 // alternate setting 00085 UART_PORT->PCR[PIN_UART_RX_BIT] = PORT_PCR_MUX(PIN_UART_RX_MUX_ALT) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK; 00086 UART_PORT->PCR[PIN_UART_TX_BIT] = PORT_PCR_MUX(PIN_UART_TX_MUX_ALT); 00087 // transmitter and receiver enabled 00088 UART->C2 |= UART_C2_RE_MASK | UART_C2_TE_MASK; 00089 // Enable receive interrupt 00090 UART->C2 |= UART_C2_RIE_MASK; 00091 NVIC_ClearPendingIRQ(UART_RX_TX_IRQn); 00092 NVIC_EnableIRQ(UART_RX_TX_IRQn); 00093 return 1; 00094 } 00095 00096 int32_t uart_uninitialize(void) 00097 { 00098 // transmitter and receiver disabled 00099 UART->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK); 00100 // disable interrupt 00101 UART->C2 &= ~(UART_C2_RIE_MASK | UART_C2_TIE_MASK); 00102 clear_buffers(); 00103 return 1; 00104 } 00105 00106 int32_t uart_reset(void) 00107 { 00108 // disable interrupt 00109 NVIC_DisableIRQ(UART_RX_TX_IRQn); 00110 // disable TIE interrupt 00111 UART->C2 &= ~(UART_C2_TIE_MASK); 00112 clear_buffers(); 00113 // enable interrupt 00114 NVIC_EnableIRQ(UART_RX_TX_IRQn); 00115 return 1; 00116 } 00117 00118 int32_t uart_set_configuration(UART_Configuration *config) 00119 { 00120 uint8_t data_bits = 8; 00121 uint8_t parity_enable = 0; 00122 uint8_t parity_type = 0; 00123 uint32_t dll; 00124 // disable interrupt 00125 NVIC_DisableIRQ(UART_RX_TX_IRQn); 00126 UART->C2 &= ~(UART_C2_RIE_MASK | UART_C2_TIE_MASK); 00127 // Disable receiver and transmitter while updating 00128 UART->C2 &= ~(UART_C2_RE_MASK | UART_C2_TE_MASK); 00129 clear_buffers(); 00130 00131 // set data bits, stop bits, parity 00132 if ((config->DataBits < 8) || (config->DataBits > 9)) { 00133 data_bits = 8; 00134 } 00135 00136 data_bits -= 8; 00137 00138 if (config->Parity == 1) { 00139 parity_enable = 1; 00140 parity_type = 1; 00141 data_bits++; 00142 } else if (config->Parity == 2) { 00143 parity_enable = 1; 00144 parity_type = 0; 00145 data_bits++; 00146 } 00147 00148 // does not support 10 bit data comm 00149 if (data_bits == 2) { 00150 data_bits = 0; 00151 parity_enable = 0; 00152 parity_type = 0; 00153 } 00154 00155 // data bits, parity and parity mode 00156 UART->C1 = data_bits << UART_C1_M_SHIFT | 00157 parity_enable << UART_C1_PE_SHIFT | 00158 parity_type << UART_C1_PT_SHIFT; 00159 dll = SystemCoreClock / (16 * config->Baudrate); 00160 00161 if (1 == UART_NUM || 2 == UART_NUM) { 00162 dll /= 2; //TODO <<= 1 00163 } 00164 00165 // set baudrate 00166 UART->BDH = (UART->BDH & ~(UART_BDH_SBR_MASK)) | ((dll >> 8) & UART_BDH_SBR_MASK); 00167 UART->BDL = (UART->BDL & ~(UART_BDL_SBR_MASK)) | (dll & UART_BDL_SBR_MASK); 00168 // Enable transmitter and receiver 00169 UART->C2 |= UART_C2_RE_MASK | UART_C2_TE_MASK; 00170 // Enable UART interrupt 00171 NVIC_ClearPendingIRQ(UART_RX_TX_IRQn); 00172 NVIC_EnableIRQ(UART_RX_TX_IRQn); 00173 UART->C2 |= UART_C2_RIE_MASK; 00174 return 1; 00175 } 00176 00177 int32_t uart_get_configuration(UART_Configuration *config) 00178 { 00179 return 1; 00180 } 00181 00182 int32_t uart_write_free(void) 00183 { 00184 return circ_buf_count_free(&write_buffer); 00185 } 00186 00187 int32_t uart_write_data(uint8_t *data, uint16_t size) 00188 { 00189 cortex_int_state_t state; 00190 uint32_t cnt; 00191 00192 cnt = circ_buf_write(&write_buffer, data, size); 00193 00194 // Atomically enable TX 00195 state = cortex_int_get_and_disable(); 00196 if (circ_buf_count_used(&write_buffer)) { 00197 UART->C2 |= UART_C2_TIE_MASK; 00198 } 00199 cortex_int_restore(state); 00200 00201 return cnt; 00202 } 00203 00204 int32_t uart_read_data(uint8_t *data, uint16_t size) 00205 { 00206 return circ_buf_read(&read_buffer, data, size); 00207 } 00208 00209 void uart_enable_flow_control(bool enabled) 00210 { 00211 // Flow control not implemented for this platform 00212 } 00213 00214 void UART_RX_TX_IRQHandler(void) 00215 { 00216 uint32_t s1; 00217 volatile uint8_t errorData; 00218 // read interrupt status 00219 s1 = UART->S1; 00220 // mask off interrupts that are not enabled 00221 if (!(UART->C2 & UART_C2_RIE_MASK)) { 00222 s1 &= ~UART_S1_RDRF_MASK; 00223 } 00224 if (!(UART->C2 & UART_C2_TIE_MASK)) { 00225 s1 &= ~UART_S1_TDRE_MASK; 00226 } 00227 00228 // handle character to transmit 00229 if (s1 & UART_S1_TDRE_MASK) { 00230 // Assert that there is data in the buffer 00231 util_assert(circ_buf_count_used(&write_buffer) > 0); 00232 // Send out data 00233 UART1->D = circ_buf_pop(&write_buffer); 00234 // Turn off the transmitter if that was the last byte 00235 if (circ_buf_count_used(&write_buffer) == 0) { 00236 // disable TIE interrupt 00237 UART->C2 &= ~(UART_C2_TIE_MASK); 00238 } 00239 } 00240 00241 // handle received character 00242 if (s1 & UART_S1_RDRF_MASK) { 00243 if ((s1 & UART_S1_NF_MASK) || (s1 & UART_S1_FE_MASK)) { 00244 errorData = UART->D; 00245 } else { 00246 uint32_t free; 00247 uint8_t data; 00248 00249 data = UART1->D; 00250 free = circ_buf_count_free(&read_buffer); 00251 if (free > RX_OVRF_MSG_SIZE) { 00252 circ_buf_push(&read_buffer, data); 00253 } else if (config_get_overflow_detect()) { 00254 if (RX_OVRF_MSG_SIZE == free) { 00255 circ_buf_write(&read_buffer, (uint8_t*)RX_OVRF_MSG, RX_OVRF_MSG_SIZE); 00256 } else { 00257 // Drop newest 00258 } 00259 } else { 00260 // Drop oldest 00261 circ_buf_pop(&read_buffer); 00262 circ_buf_push(&read_buffer, data); 00263 } 00264 } 00265 } 00266 }
Generated on Tue Jul 12 2022 15:37:25 by
1.7.2