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 #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 }