aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonny Svärd <jonny.svaerd@arm.com>2020-12-15 16:02:41 +0100
committerKristofer Jonsson <kristofer.jonsson@arm.com>2020-12-17 12:30:53 +0000
commitff265f9ad6505878a1b55d560ee697531fa33044 (patch)
tree4bdacd81701f3045c0a253525d756045a23607ef
parent7cfa570a4a25d8ab2a05c856a8b1bfa0855b9bee (diff)
downloadethos-u-core-software-ff265f9ad6505878a1b55d560ee697531fa33044.tar.gz
Add basic UART drivers
Add basic drivers for: - PL011 UART - CMSDK APB UART - dummy/stub UART Change-Id: I2f89874fba59044e6c7c084f8e1dc6faa9eb8d1b
-rw-r--r--drivers/CMakeLists.txt13
-rw-r--r--drivers/uart/CMakeLists.txt41
-rw-r--r--drivers/uart/include/uart_stdout.h35
-rw-r--r--drivers/uart/src/uart_cmsdk_apb.c135
-rw-r--r--drivers/uart/src/uart_dummy.c36
-rw-r--r--drivers/uart/src/uart_pl011.c220
-rw-r--r--drivers/uart/uart_config.h.in23
7 files changed, 503 insertions, 0 deletions
diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt
index c130a26..9feeeae 100644
--- a/drivers/CMakeLists.txt
+++ b/drivers/CMakeLists.txt
@@ -18,11 +18,18 @@
add_library(ethosu_drivers INTERFACE)
+#############################################################################
# Mailbox driver
+#############################################################################
add_subdirectory(mailbox)
target_link_libraries(ethosu_drivers INTERFACE ethosu_mailbox)
+#############################################################################
# MHU drivers
+#############################################################################
+# NOTE: These are all built and linked from a CMake perspective. However the
+# application code can instantiate one or more of the drivers. The
+# one(s) not used will later be removed by the linker.
add_subdirectory(mhu_v2)
add_subdirectory(mhu_juno)
add_subdirectory(mhu_dummy)
@@ -30,3 +37,9 @@ target_link_libraries(ethosu_drivers INTERFACE ethosu_mhu_v2)
target_link_libraries(ethosu_drivers INTERFACE ethosu_mhu_juno)
target_link_libraries(ethosu_drivers INTERFACE ethosu_mhu_dummy)
+#############################################################################
+# UART drivers
+#############################################################################
+# NOTE: All UART drivers are built, however a platform application should
+# link the appropriate driver target (see drivers/uart/CMakeLists.txt).
+add_subdirectory(uart)
diff --git a/drivers/uart/CMakeLists.txt b/drivers/uart/CMakeLists.txt
new file mode 100644
index 0000000..1293bdc
--- /dev/null
+++ b/drivers/uart/CMakeLists.txt
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+add_library(ethosu_uart_common INTERFACE)
+
+target_include_directories(ethosu_uart_common INTERFACE
+ include
+ ${CMAKE_CURRENT_BINARY_DIR})
+
+# UART configuration (can be overriden from user project)
+set(UART0_BASE "0xFFFFFFFF" CACHE STRING "UART base address")
+set(UART0_BAUDRATE "115200" CACHE STRING "UART baudrate")
+set(SYSTEM_CORE_CLOCK "25000000" CACHE STRING "System core clock (Hz)")
+
+# Generate UART configuration file
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/uart_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/uart_config.h")
+
+# Drivers
+add_library(ethosu_uart_cmsdk_apb STATIC src/uart_cmsdk_apb.c)
+target_link_libraries(ethosu_uart_cmsdk_apb PUBLIC ethosu_uart_common)
+
+add_library(ethosu_uart_pl011 STATIC src/uart_pl011.c)
+target_link_libraries(ethosu_uart_pl011 PUBLIC ethosu_uart_common)
+
+add_library(ethosu_uart_dummy STATIC src/uart_dummy.c)
+target_link_libraries(ethosu_uart_dummy PUBLIC ethosu_uart_common)
diff --git a/drivers/uart/include/uart_stdout.h b/drivers/uart/include/uart_stdout.h
new file mode 100644
index 0000000..02f8e49
--- /dev/null
+++ b/drivers/uart/include/uart_stdout.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#ifndef _UART_STDOUT_H_
+#define _UART_STDOUT_H_
+
+#if __cplusplus
+extern "C" {
+#endif
+
+void UartStdOutInit(void);
+unsigned char UartPutc(unsigned char my_ch);
+unsigned char UartGetc(void);
+unsigned int GetLine(char *lp, unsigned int len);
+
+#if __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/uart/src/uart_cmsdk_apb.c b/drivers/uart/src/uart_cmsdk_apb.c
new file mode 100644
index 0000000..2639ef5
--- /dev/null
+++ b/drivers/uart/src/uart_cmsdk_apb.c
@@ -0,0 +1,135 @@
+/*
+ * 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.
+ */
+
+/* Basic CMSDK APB UART driver */
+
+#include "uart_config.h"
+#include "uart_stdout.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
+
+#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 UartStdOutInit(void) {
+ 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 UartPutc(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 UartGetc(void) {
+ unsigned char my_ch;
+ // unsigned int cnt;
+
+ while ((CMSDK_UART0->STATE & 2) == 0) // Wait if Receive Holding register is empty
+ ;
+
+ 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 GetLine(char *lp, unsigned int len) {
+ unsigned int cnt = 0;
+ char c;
+
+ do {
+ c = UartGetc();
+ 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 */
+ UartPutc(0x08); /* echo backspace */
+ UartPutc(' ');
+ UartPutc(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:
+ UartPutc(*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;
+}
diff --git a/drivers/uart/src/uart_dummy.c b/drivers/uart/src/uart_dummy.c
new file mode 100644
index 0000000..ebe384b
--- /dev/null
+++ b/drivers/uart/src/uart_dummy.c
@@ -0,0 +1,36 @@
+/*
+ * 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_stdout.h"
+
+void UartStdOutInit(void) {}
+
+unsigned char UartPutc(unsigned char c) {
+ (void)c;
+ return 0;
+}
+
+unsigned char UartGetc(void) {
+ return 0;
+}
+
+unsigned int GetLine(char *lp, unsigned int len) {
+ (void)lp;
+ (void)len;
+ return 0;
+}
diff --git a/drivers/uart/src/uart_pl011.c b/drivers/uart/src/uart_pl011.c
new file mode 100644
index 0000000..617ce5f
--- /dev/null
+++ b/drivers/uart/src/uart_pl011.c
@@ -0,0 +1,220 @@
+/*
+ * 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.
+ */
+
+/* Basic PL011 UART driver */
+
+#include "uart_config.h"
+#include "uart_stdout.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
+
+/*****************************************************************************/
+/* UART Control Register Locations */
+/*****************************************************************************/
+#define UART0_DR *((volatile uint32_t *)UART0_BASE)
+#define UART0_RSR *((volatile uint32_t *)(UART0_BASE + 0x04))
+#define UART0_ECR *((volatile uint32_t *)(UART0_BASE + 0x04))
+#define UART0_LCRH *((volatile uint32_t *)(UART0_BASE + 0x2C))
+#define UART0_LCRM *((volatile uint32_t *)(UART0_BASE + 0x28))
+#define UART0_LCRL *((volatile uint32_t *)(UART0_BASE + 0x24))
+#define UART0_CR *((volatile uint32_t *)(UART0_BASE + 0x30))
+#define UART0_FR *((volatile uint32_t *)(UART0_BASE + 0x18))
+#define UART0_IIR *((volatile uint32_t *)(UART0_BASE + 0x1C))
+#define UART0_ICR *((volatile uint32_t *)(UART0_BASE + 0x44))
+
+/*****************************************************************************/
+/* Received Status Register - RSR */
+/*****************************************************************************/
+#define RSR_OVERRUN_ERROR 0x08
+#define RSR_BREAK_ERROR 0x04
+#define RSR_PARITY_ERROR 0x02
+#define RSR_FRAMING_ERROR 0x01
+
+/*****************************************************************************/
+/* Line Control High Byte Register - LCRH */
+/*****************************************************************************/
+#define LCRH_WORD_LENGTH_8 0x60
+#define LCRH_WORD_LENGTH_7 0x40
+#define LCRH_WORD_LENGTH_6 0x20
+#define LCRH_WORD_LENGTH_5 0x00
+#define LCRH_FIFO_ENABLED 0x10
+#define LCRH_2_STOP_BITS 0x08
+#define LCRH_EVEN_PARITY 0x04
+#define LCRH_PARITY_ENABLE 0x02
+#define LCRH_SEND_BREAK 0x01
+
+/*****************************************************************************/
+/* Line Control Medium Byte Register - LCRM */
+/* This register specifies the high byte of the Baud rate divisor */
+/*****************************************************************************/
+#define LCRM_BAUD_460800 0x00
+#define LCRM_BAUD_230400 0x00
+#define LCRM_BAUD_115200 0x00
+#define LCRM_BAUD_76800 0x00
+#define LCRM_BAUD_57600 0x00
+#define LCRM_BAUD_38400 0x00
+#define LCRM_BAUD_19200 0x00
+#define LCRM_BAUD_14400 0x00
+#define LCRM_BAUD_9600 0x00
+#define LCRM_BAUD_2400 0x01
+#define LCRM_BAUD_1200 0x02
+
+/*****************************************************************************/
+/* Line Control Low Byte Register - LCRL */
+/* This register specifies the low byte of the Baud rate divisor */
+/*****************************************************************************/
+#define LCRL_BAUD_460800 0x01
+#define LCRL_BAUD_230400 0x03
+#define LCRL_BAUD_115200 0x07
+#define LCRL_BAUD_76800 0x0B
+#define LCRL_BAUD_57600 0x0F
+#define LCRL_BAUD_38400 0xC
+#define LCRL_BAUD_19200 0x2F
+#define LCRL_BAUD_14400 0x3F
+#define LCRL_BAUD_9600 0x5F
+#define LCRL_BAUD_2400 0x7F
+#define LCRL_BAUD_1200 0xFF
+
+/*****************************************************************************/
+/* Control Register - CR */
+/*****************************************************************************/
+#define CR_LOOP_BACK_EN 0x80
+#define CR_TIMEOUT_INT_EN 0x40
+#define CR_TX_INT_ENABLE 0x100
+#define CR_RX_INT_ENABLE 0x200
+#define CR_MODSTAT_INT_EN 0x08
+#define CR_UART_ENABLE 0x01
+
+/*****************************************************************************/
+/* Flag Register - FR */
+/*****************************************************************************/
+#define FR_TX_FIFO_EMPTY 0x80
+#define FR_RX_FIFO_FULL 0x40
+#define FR_TX_FIFO_FULL 0x20
+#define FR_RX_FIFO_EMPTY 0x10
+#define FR_BUSY 0x08
+#define FR_CARRIER_DETECT 0x04
+#define FR_SET_READY 0x02
+#define FR_CLEAR_TO_SEND 0x01
+
+/*****************************************************************************/
+/* Interrupt Identification Register - IIR */
+/*****************************************************************************/
+#define IIR_RX_TIME_OUT 0x08
+#define IIR_TX 0x04
+#define IIR_RX 0x02
+#define IIR_MODEM 0x01
+
+void UartStdOutInit(void) {
+ // Disable the serial port while setting the baud rate and word length
+ UART0_CR = 0;
+
+ // Clear the receive status register
+ UART0_ECR = 0;
+
+ // Set the correct baud rate and word length
+ UART0_LCRL = LCRL_BAUD_115200;
+ UART0_LCRM = LCRM_BAUD_115200;
+ UART0_LCRH = LCRH_WORD_LENGTH_8;
+
+ // Explicitly disable FIFO's for char mode
+ UART0_LCRH &= ~LCRH_FIFO_ENABLED;
+
+ // Enable UART0 (and RX/TX) without interrupts
+ UART0_CR = CR_UART_ENABLE | CR_TX_INT_ENABLE | CR_RX_INT_ENABLE;
+}
+
+unsigned char UartPutc(unsigned char ch) {
+ if (ch == '\n') {
+ (void)UartPutc('\r');
+ }
+ while (UART0_FR & FR_TX_FIFO_FULL)
+ ;
+ UART0_DR = ch;
+
+ return ch;
+}
+
+unsigned char UartGetc(void) {
+ unsigned char c;
+ while (UART0_FR & FR_RX_FIFO_EMPTY)
+ ;
+ c = UART0_DR;
+ if (c == '\r') {
+ c = '\n';
+ }
+
+ return c;
+}
+
+// Get line from terminal
+unsigned int GetLine(char *lp, unsigned int len) {
+ unsigned int cnt = 0;
+ char c;
+
+ do {
+ c = UartGetc();
+ 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 */
+ UartPutc(0x08); /* echo backspace */
+ UartPutc(' ');
+ UartPutc(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;
+ UartPutc(*lp = c); /* echo and store character */
+ fflush(stdout);
+ lp++; /* increment line pointer */
+ cnt++; /* and count */
+ break;
+ default:
+ UartPutc(*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;
+}
diff --git a/drivers/uart/uart_config.h.in b/drivers/uart/uart_config.h.in
new file mode 100644
index 0000000..eb858fa
--- /dev/null
+++ b/drivers/uart/uart_config.h.in
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#define UART0_BASE (@UART0_BASE@)
+#define UART0_BAUDRATE (@UART0_BAUDRATE@)
+#define SYSTEM_CORE_CLOCK (@SYSTEM_CORE_CLOCK@)