Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file uart.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 8 *
Pawel Zarembski 0:01f31e923fe2 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 10 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 11 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 12 *
Pawel Zarembski 0:01f31e923fe2 13 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 18 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 19 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 20 */
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 #include "string.h"
Pawel Zarembski 0:01f31e923fe2 23 #include "uart.h"
Pawel Zarembski 0:01f31e923fe2 24 #include "gpio.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "circ_buf.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "NuMicro.h"
Pawel Zarembski 0:01f31e923fe2 28
Pawel Zarembski 0:01f31e923fe2 29 #define RX_OVRF_MSG "<DAPLink:Overflow>\n"
Pawel Zarembski 0:01f31e923fe2 30 #define RX_OVRF_MSG_SIZE (sizeof(RX_OVRF_MSG) - 1)
Pawel Zarembski 0:01f31e923fe2 31 #define BUFFER_SIZE (512)
Pawel Zarembski 0:01f31e923fe2 32
Pawel Zarembski 0:01f31e923fe2 33 #define TX_FIFO_SIZE 16 /* TX Hardware FIFO size */
Pawel Zarembski 0:01f31e923fe2 34
Pawel Zarembski 0:01f31e923fe2 35 circ_buf_t write_buffer;
Pawel Zarembski 0:01f31e923fe2 36 uint8_t write_buffer_data[BUFFER_SIZE];
Pawel Zarembski 0:01f31e923fe2 37 circ_buf_t read_buffer;
Pawel Zarembski 0:01f31e923fe2 38 uint8_t read_buffer_data[BUFFER_SIZE];
Pawel Zarembski 0:01f31e923fe2 39
Pawel Zarembski 0:01f31e923fe2 40 static UART_Configuration configuration = {
Pawel Zarembski 0:01f31e923fe2 41 .Baudrate = 9600,
Pawel Zarembski 0:01f31e923fe2 42 .DataBits = UART_DATA_BITS_8,
Pawel Zarembski 0:01f31e923fe2 43 .Parity = UART_PARITY_NONE,
Pawel Zarembski 0:01f31e923fe2 44 .StopBits = UART_STOP_BITS_1,
Pawel Zarembski 0:01f31e923fe2 45 .FlowControl = UART_FLOW_CONTROL_NONE,
Pawel Zarembski 0:01f31e923fe2 46 };
Pawel Zarembski 0:01f31e923fe2 47
Pawel Zarembski 0:01f31e923fe2 48 static void clear_buffers(void)
Pawel Zarembski 0:01f31e923fe2 49 {
Pawel Zarembski 0:01f31e923fe2 50 circ_buf_init(&write_buffer, write_buffer_data, sizeof(write_buffer_data));
Pawel Zarembski 0:01f31e923fe2 51 circ_buf_init(&read_buffer, read_buffer_data, sizeof(read_buffer_data));
Pawel Zarembski 0:01f31e923fe2 52 }
Pawel Zarembski 0:01f31e923fe2 53
Pawel Zarembski 0:01f31e923fe2 54 int32_t uart_initialize(void)
Pawel Zarembski 0:01f31e923fe2 55 {
Pawel Zarembski 0:01f31e923fe2 56 clear_buffers();
Pawel Zarembski 0:01f31e923fe2 57 UART_Open(UART0, 115200);
Pawel Zarembski 0:01f31e923fe2 58 UART_ENABLE_INT(UART0, (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk | UART_INTEN_RXTOIEN_Msk));
Pawel Zarembski 0:01f31e923fe2 59 NVIC_EnableIRQ(UART0_IRQn);
Pawel Zarembski 0:01f31e923fe2 60 return 1;
Pawel Zarembski 0:01f31e923fe2 61 }
Pawel Zarembski 0:01f31e923fe2 62
Pawel Zarembski 0:01f31e923fe2 63 int32_t uart_uninitialize(void)
Pawel Zarembski 0:01f31e923fe2 64 {
Pawel Zarembski 0:01f31e923fe2 65 NVIC_DisableIRQ(UART0_IRQn);
Pawel Zarembski 0:01f31e923fe2 66 UART_Close(UART0);
Pawel Zarembski 0:01f31e923fe2 67 clear_buffers();
Pawel Zarembski 0:01f31e923fe2 68 return 1;
Pawel Zarembski 0:01f31e923fe2 69 }
Pawel Zarembski 0:01f31e923fe2 70
Pawel Zarembski 0:01f31e923fe2 71 int32_t uart_reset(void)
Pawel Zarembski 0:01f31e923fe2 72 {
Pawel Zarembski 0:01f31e923fe2 73 UART_Configuration backup_configuration = configuration;
Pawel Zarembski 0:01f31e923fe2 74 uart_set_configuration(&backup_configuration);
Pawel Zarembski 0:01f31e923fe2 75 return 1;
Pawel Zarembski 0:01f31e923fe2 76 }
Pawel Zarembski 0:01f31e923fe2 77
Pawel Zarembski 0:01f31e923fe2 78 int32_t uart_set_configuration(UART_Configuration *config)
Pawel Zarembski 0:01f31e923fe2 79 {
Pawel Zarembski 0:01f31e923fe2 80 uint32_t u32Reg;
Pawel Zarembski 0:01f31e923fe2 81 uint32_t u32Baud_Div;
Pawel Zarembski 0:01f31e923fe2 82 NVIC_DisableIRQ(UART0_IRQn);
Pawel Zarembski 0:01f31e923fe2 83 /* Reset hardware fifo */
Pawel Zarembski 0:01f31e923fe2 84 UART0->FIFO |= (UART_FIFO_TXRST_Msk | UART_FIFO_RXRST_Msk);
Pawel Zarembski 0:01f31e923fe2 85 /* Reset software fifo */
Pawel Zarembski 0:01f31e923fe2 86 clear_buffers();
Pawel Zarembski 0:01f31e923fe2 87 /* Set parity */
Pawel Zarembski 0:01f31e923fe2 88 configuration.Parity = config->Parity;
Pawel Zarembski 0:01f31e923fe2 89
Pawel Zarembski 0:01f31e923fe2 90 if (config->Parity == UART_PARITY_ODD) {
Pawel Zarembski 0:01f31e923fe2 91 u32Reg = 0x08;
Pawel Zarembski 0:01f31e923fe2 92 } else if (config->Parity == UART_PARITY_EVEN) {
Pawel Zarembski 0:01f31e923fe2 93 u32Reg = 0x18;
Pawel Zarembski 0:01f31e923fe2 94 } else if (config->Parity == UART_PARITY_NONE) {
Pawel Zarembski 0:01f31e923fe2 95 u32Reg = 0;
Pawel Zarembski 0:01f31e923fe2 96 } else {
Pawel Zarembski 0:01f31e923fe2 97 u32Reg = 0;
Pawel Zarembski 0:01f31e923fe2 98 }
Pawel Zarembski 0:01f31e923fe2 99
Pawel Zarembski 0:01f31e923fe2 100 /* Stop bit */
Pawel Zarembski 0:01f31e923fe2 101 configuration.StopBits = config->StopBits;
Pawel Zarembski 0:01f31e923fe2 102
Pawel Zarembski 0:01f31e923fe2 103 if (config->StopBits == UART_STOP_BITS_2) {
Pawel Zarembski 0:01f31e923fe2 104 u32Reg |= 0x4;
Pawel Zarembski 0:01f31e923fe2 105 } else if (config->StopBits == UART_STOP_BITS_1_5) {
Pawel Zarembski 0:01f31e923fe2 106 u32Reg |= 0x4;
Pawel Zarembski 0:01f31e923fe2 107 } else if (config->StopBits == UART_STOP_BITS_1)
Pawel Zarembski 0:01f31e923fe2 108 ;
Pawel Zarembski 0:01f31e923fe2 109
Pawel Zarembski 0:01f31e923fe2 110 /* Bit width */
Pawel Zarembski 0:01f31e923fe2 111 configuration.DataBits = config->DataBits;
Pawel Zarembski 0:01f31e923fe2 112
Pawel Zarembski 0:01f31e923fe2 113 if (config->DataBits == UART_DATA_BITS_5) {
Pawel Zarembski 0:01f31e923fe2 114 u32Reg |= 0;
Pawel Zarembski 0:01f31e923fe2 115 } else if (config->DataBits == UART_DATA_BITS_6) {
Pawel Zarembski 0:01f31e923fe2 116 u32Reg |= 1;
Pawel Zarembski 0:01f31e923fe2 117 } else if (config->DataBits == UART_DATA_BITS_7) {
Pawel Zarembski 0:01f31e923fe2 118 u32Reg |= 2;
Pawel Zarembski 0:01f31e923fe2 119 } else if (config->DataBits == UART_DATA_BITS_8) {
Pawel Zarembski 0:01f31e923fe2 120 u32Reg |= 3;
Pawel Zarembski 0:01f31e923fe2 121 }
Pawel Zarembski 0:01f31e923fe2 122
Pawel Zarembski 0:01f31e923fe2 123 configuration.FlowControl = UART_FLOW_CONTROL_NONE;
Pawel Zarembski 0:01f31e923fe2 124 /* Set baudrate */
Pawel Zarembski 0:01f31e923fe2 125 configuration.Baudrate = config->Baudrate;
Pawel Zarembski 0:01f31e923fe2 126 u32Baud_Div = UART_BAUD_MODE2_DIVIDER(__HXT, configuration.Baudrate);
Pawel Zarembski 0:01f31e923fe2 127
Pawel Zarembski 0:01f31e923fe2 128 if (u32Baud_Div > 0xFFFF) {
Pawel Zarembski 0:01f31e923fe2 129 UART0->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER(__HXT, configuration.Baudrate));
Pawel Zarembski 0:01f31e923fe2 130 } else {
Pawel Zarembski 0:01f31e923fe2 131 UART0->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
Pawel Zarembski 0:01f31e923fe2 132 }
Pawel Zarembski 0:01f31e923fe2 133
Pawel Zarembski 0:01f31e923fe2 134 UART0->LINE = u32Reg;
Pawel Zarembski 0:01f31e923fe2 135 NVIC_EnableIRQ(UART0_IRQn);
Pawel Zarembski 0:01f31e923fe2 136 return 1;
Pawel Zarembski 0:01f31e923fe2 137 }
Pawel Zarembski 0:01f31e923fe2 138
Pawel Zarembski 0:01f31e923fe2 139 int32_t uart_get_configuration(UART_Configuration *config)
Pawel Zarembski 0:01f31e923fe2 140 {
Pawel Zarembski 0:01f31e923fe2 141 config->Baudrate = configuration.Baudrate;
Pawel Zarembski 0:01f31e923fe2 142 config->DataBits = configuration.DataBits;
Pawel Zarembski 0:01f31e923fe2 143 config->Parity = configuration.Parity;
Pawel Zarembski 0:01f31e923fe2 144 config->StopBits = configuration.StopBits;
Pawel Zarembski 0:01f31e923fe2 145 config->FlowControl = UART_FLOW_CONTROL_NONE;
Pawel Zarembski 0:01f31e923fe2 146 return 1;
Pawel Zarembski 0:01f31e923fe2 147 }
Pawel Zarembski 0:01f31e923fe2 148
Pawel Zarembski 0:01f31e923fe2 149 int32_t uart_write_free(void)
Pawel Zarembski 0:01f31e923fe2 150 {
Pawel Zarembski 0:01f31e923fe2 151 return circ_buf_count_free(&write_buffer);
Pawel Zarembski 0:01f31e923fe2 152 }
Pawel Zarembski 0:01f31e923fe2 153
Pawel Zarembski 0:01f31e923fe2 154 int32_t uart_write_data(uint8_t *data, uint16_t size)
Pawel Zarembski 0:01f31e923fe2 155 {
Pawel Zarembski 0:01f31e923fe2 156 uint8_t bInChar;
Pawel Zarembski 0:01f31e923fe2 157 uint32_t u32Size = circ_buf_write(&write_buffer, data, size);
Pawel Zarembski 0:01f31e923fe2 158
Pawel Zarembski 0:01f31e923fe2 159 if (circ_buf_count_used(&write_buffer) > 0) {
Pawel Zarembski 0:01f31e923fe2 160 if ((UART0->INTEN & UART_INTEN_THREIEN_Msk) == 0) {
Pawel Zarembski 0:01f31e923fe2 161 bInChar = circ_buf_pop(&write_buffer);
Pawel Zarembski 0:01f31e923fe2 162 /* Send one bytes out */
Pawel Zarembski 0:01f31e923fe2 163 UART_WRITE(UART0, bInChar);
Pawel Zarembski 0:01f31e923fe2 164 /* Enable Tx Empty Interrupt. (Trigger first one) */
Pawel Zarembski 0:01f31e923fe2 165 UART0->INTEN |= UART_INTEN_THREIEN_Msk;
Pawel Zarembski 0:01f31e923fe2 166 }
Pawel Zarembski 0:01f31e923fe2 167 }
Pawel Zarembski 0:01f31e923fe2 168
Pawel Zarembski 0:01f31e923fe2 169 return u32Size;
Pawel Zarembski 0:01f31e923fe2 170 }
Pawel Zarembski 0:01f31e923fe2 171
Pawel Zarembski 0:01f31e923fe2 172 int32_t uart_read_data(uint8_t *data, uint16_t size)
Pawel Zarembski 0:01f31e923fe2 173 {
Pawel Zarembski 0:01f31e923fe2 174 return circ_buf_read(&read_buffer, data, size);
Pawel Zarembski 0:01f31e923fe2 175 }
Pawel Zarembski 0:01f31e923fe2 176
Pawel Zarembski 0:01f31e923fe2 177 void UART0_IRQHandler(void)
Pawel Zarembski 0:01f31e923fe2 178 {
Pawel Zarembski 0:01f31e923fe2 179 uint8_t bInChar;
Pawel Zarembski 0:01f31e923fe2 180 int32_t u32Size;
Pawel Zarembski 0:01f31e923fe2 181 uint32_t u32IntStatus;
Pawel Zarembski 0:01f31e923fe2 182 u32IntStatus = UART0->INTSTS;
Pawel Zarembski 0:01f31e923fe2 183
Pawel Zarembski 0:01f31e923fe2 184 if ((u32IntStatus & UART_INTSTS_RDAINT_Msk) || (u32IntStatus & UART_INTSTS_RXTOINT_Msk)) {
Pawel Zarembski 0:01f31e923fe2 185 /* Receiver FIFO threshold level is reached or Rx time out */
Pawel Zarembski 0:01f31e923fe2 186 /* Get all the input characters */
Pawel Zarembski 0:01f31e923fe2 187 while ((!UART_GET_RX_EMPTY(UART0))) {
Pawel Zarembski 0:01f31e923fe2 188 /* Get the character from UART Buffer */
Pawel Zarembski 0:01f31e923fe2 189 bInChar = UART_READ(UART0); /* Rx trigger level is 1 byte*/
Pawel Zarembski 0:01f31e923fe2 190 /* Check if buffer full */
Pawel Zarembski 0:01f31e923fe2 191 uint32_t u32Free = circ_buf_count_free(&read_buffer);
Pawel Zarembski 0:01f31e923fe2 192
Pawel Zarembski 0:01f31e923fe2 193 if (u32Free > RX_OVRF_MSG_SIZE) {
Pawel Zarembski 0:01f31e923fe2 194 circ_buf_push(&read_buffer, bInChar);
Pawel Zarembski 0:01f31e923fe2 195 } else if (RX_OVRF_MSG_SIZE == u32Free) {
Pawel Zarembski 0:01f31e923fe2 196 circ_buf_write(&read_buffer, (uint8_t *)RX_OVRF_MSG, RX_OVRF_MSG_SIZE);
Pawel Zarembski 0:01f31e923fe2 197 } else {
Pawel Zarembski 0:01f31e923fe2 198 // Drop character
Pawel Zarembski 0:01f31e923fe2 199 }
Pawel Zarembski 0:01f31e923fe2 200 }
Pawel Zarembski 0:01f31e923fe2 201 }
Pawel Zarembski 0:01f31e923fe2 202
Pawel Zarembski 0:01f31e923fe2 203 if (u32IntStatus & UART_INTSTS_THREINT_Msk) {
Pawel Zarembski 0:01f31e923fe2 204 if (circ_buf_count_used(&write_buffer) > 0) {
Pawel Zarembski 0:01f31e923fe2 205 /* Fill the Tx FIFO */
Pawel Zarembski 0:01f31e923fe2 206 u32Size = circ_buf_count_used(&write_buffer);
Pawel Zarembski 0:01f31e923fe2 207
Pawel Zarembski 0:01f31e923fe2 208 if (u32Size >= TX_FIFO_SIZE) {
Pawel Zarembski 0:01f31e923fe2 209 u32Size = TX_FIFO_SIZE;
Pawel Zarembski 0:01f31e923fe2 210 }
Pawel Zarembski 0:01f31e923fe2 211
Pawel Zarembski 0:01f31e923fe2 212 while (u32Size) {
Pawel Zarembski 0:01f31e923fe2 213 bInChar = circ_buf_pop(&write_buffer);
Pawel Zarembski 0:01f31e923fe2 214 UART_WRITE(UART0, bInChar);
Pawel Zarembski 0:01f31e923fe2 215 u32Size--;
Pawel Zarembski 0:01f31e923fe2 216 }
Pawel Zarembski 0:01f31e923fe2 217 } else {
Pawel Zarembski 0:01f31e923fe2 218 /* No more data, just stop Tx (Stop work) */
Pawel Zarembski 0:01f31e923fe2 219 UART0->INTEN &= ~UART_INTEN_THREIEN_Msk;
Pawel Zarembski 0:01f31e923fe2 220 }
Pawel Zarembski 0:01f31e923fe2 221 }
Pawel Zarembski 0:01f31e923fe2 222 }