aboutsummaryrefslogtreecommitdiff
path: root/targets/corstone-300/uart.c
diff options
context:
space:
mode:
authorKristofer Jonsson <kristofer.jonsson@arm.com>2020-11-20 09:42:53 +0100
committerKristofer Jonsson <kristofer.jonsson@arm.com>2020-11-26 15:17:39 +0100
commit43ce491cdf7a94e0f227502217f574d95fc4c68a (patch)
treee6040562696f610d262539a5430de12739fa684f /targets/corstone-300/uart.c
parent5e84a8425c3d93f9c441823c894f744e7c9c831f (diff)
downloadethos-u-core-platform-43ce491cdf7a94e0f227502217f574d95fc4c68a.tar.gz
Add Corstone-300 target20.11
Change-Id: I34e9845abdccb3363953bd70fad7c6420865291e
Diffstat (limited to 'targets/corstone-300/uart.c')
-rw-r--r--targets/corstone-300/uart.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/targets/corstone-300/uart.c b/targets/corstone-300/uart.c
new file mode 100644
index 0000000..cba54d8
--- /dev/null
+++ b/targets/corstone-300/uart.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "uart.h"
+#include "uart_config.h"
+#include <stdint.h>
+#include <stdio.h>
+
+#define CNTLQ 0x11
+#define CNTLS 0x13
+#define DEL 0x7F
+#define BACKSPACE 0x08
+#define CR 0x0D
+#define LF 0x0A
+#define ESC 0x1B
+
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
+
+#define __IO volatile
+#define __I volatile const
+#define __O volatile
+
+typedef struct {
+ __IO uint32_t DATA; /* Offset: 0x000 (R/W) Data Register */
+ __IO uint32_t STATE; /* Offset: 0x004 (R/W) Status Register */
+ __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Control Register */
+ union {
+ __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */
+ __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */
+ };
+ __IO uint32_t BAUDDIV; /* Offset: 0x010 (R/W) Baudrate Divider Register */
+} CMSDK_UART_TypeDef;
+
+#define CMSDK_UART0_BASE UART0_BASE
+#define CMSDK_UART0 ((CMSDK_UART_TypeDef *)CMSDK_UART0_BASE)
+#define CMSDK_UART0_BAUDRATE UART0_BAUDRATE
+
+void uart_init(void) {
+ // SystemCoreClock / 9600
+ CMSDK_UART0->BAUDDIV = SYSTEM_CORE_CLOCK / CMSDK_UART0_BAUDRATE;
+
+ CMSDK_UART0->CTRL = ((1ul << 0) | /* TX enable */
+ (1ul << 1)); /* RX enable */
+}
+
+// Output a character
+unsigned char uart_putc(unsigned char my_ch) {
+ while ((CMSDK_UART0->STATE & 1))
+ ; // Wait if Transmit Holding register is full
+
+ if (my_ch == '\n') {
+ CMSDK_UART0->DATA = '\r';
+ while ((CMSDK_UART0->STATE & 1))
+ ; // Wait if Transmit Holding register is full
+ }
+
+ CMSDK_UART0->DATA = my_ch; // write to transmit holding register
+
+ return (my_ch);
+}
+
+// Get a character
+unsigned char uart_getc(void) {
+ unsigned char my_ch;
+ // unsigned int cnt;
+
+ while ((CMSDK_UART0->STATE & 2) == 0) // Wait if Receive Holding register is empty
+ {
+#if 0
+ cnt = MPS3_FPGAIO->CLK100HZ / 50;
+ if (cnt & 0x8)
+ MPS3_FPGAIO->LED = 0x01 << (cnt & 0x7);
+ else
+ MPS3_FPGAIO->LED = 0x80 >> (cnt & 0x7);
+#endif
+ }
+
+ my_ch = CMSDK_UART0->DATA;
+
+ // Convert CR to LF
+ if (my_ch == '\r')
+ my_ch = '\n';
+
+ return (my_ch);
+}
+
+// Get line from terminal
+unsigned int uart_getline(char *lp, unsigned int len) {
+ unsigned int cnt = 0;
+ char c;
+
+ do {
+ c = uart_getc();
+ switch (c) {
+ case CNTLQ: /* ignore Control S/Q */
+ case CNTLS:
+ break;
+ case BACKSPACE:
+ case DEL:
+ if (cnt == 0) {
+ break;
+ }
+ cnt--; /* decrement count */
+ lp--; /* and line pointer */
+ uart_putc(0x08); /* echo backspace */
+ uart_putc(' ');
+ uart_putc(0x08);
+ fflush(stdout);
+ break;
+ case ESC:
+ case 0:
+ *lp = 0; /* ESC - stop editing line */
+ return 0;
+ case CR: /* CR - done, stop editing line */
+ *lp = c;
+ lp++; /* increment line pointer */
+ cnt++; /* and count */
+ c = LF;
+ default:
+ uart_putc(*lp = c); /* echo and store character */
+ fflush(stdout);
+ lp++; /* increment line pointer */
+ cnt++; /* and count */
+ break;
+ }
+ } while (cnt < len - 2 && c != LF); /* check limit and CR */
+ *lp = 0; /* mark end of string */
+ return 1;
+}