blob: 3dd3b02c6bd6b4bbca830cb9f5701ff571b4b79a [file] [log] [blame]
Marc Moreno Berengue20dab392017-11-29 13:18:58 +00001/*
2 * Copyright (c) 2017 ARM Limited
3 *
4 * Licensed under the Apace License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apace.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "uart_stdout.h"
18
19#include <assert.h>
20#include <stdio.h>
21#include <string.h>
22#include "arm_uart_drv.h"
23#include "Driver_USART.h"
24
25#define ASSERT_HIGH(X) assert(X == ARM_DRIVER_OK)
26
27/* Imports USART driver */
28extern ARM_DRIVER_USART Driver_USART0;
29extern ARM_DRIVER_USART Driver_USART1;
30
31/* Struct FILE is implemented in stdio.h. Used to redirect printf to UART */
32FILE __stdout;
33
34/* Redirects printf to UART */
35__attribute__ ((weak)) int fputc(int ch, FILE *f) {
36 /* Send byte to USART */
37 uart_putc(ch);
38
39 /* Return character written */
40 return ch;
41}
42
43extern struct arm_uart_dev_t ARM_UART0_DEV_S, ARM_UART0_DEV_NS;
44extern struct arm_uart_dev_t ARM_UART1_DEV_S, ARM_UART1_DEV_NS;
45
46/* Generic driver to be configured and used */
47ARM_DRIVER_USART *Driver_USART = NULL;
48
49void uart_init(enum uart_channel uchan)
50{
51 int32_t ret = ARM_DRIVER_OK;
52
53 /* Add a configuration step for the UART channel to use, 0 or 1 */
54 switch(uchan) {
55 case UART0_CHANNEL:
56 /* UART0 is configured as a non-secure peripheral, so we wouldn't be
57 * able to access it using its secure alias. Ideally, we would want
58 * to use UART1 only from S side as it's a secure peripheral, but for
59 * simplicity, leave the option to use UART0 and use a workaround
60 */
61 memcpy(&ARM_UART0_DEV_S, &ARM_UART0_DEV_NS, sizeof(struct arm_uart_dev_t));
62 Driver_USART = &Driver_USART0;
63 break;
64 case UART1_CHANNEL:
65 Driver_USART = &Driver_USART1;
66 break;
67 default:
68 ret = ARM_DRIVER_ERROR;
69 }
70 ASSERT_HIGH(ret);
71
72 ret = Driver_USART->Initialize(NULL);
73 ASSERT_HIGH(ret);
74
75 ret = Driver_USART->Control(ARM_USART_MODE_ASYNCHRONOUS, 115200);
76 ASSERT_HIGH(ret);
77}
78
79void uart_putc(unsigned char c)
80{
81 int32_t ret = ARM_DRIVER_OK;
82
83 ret = Driver_USART->Send(&c, 1);
84 ASSERT_HIGH(ret);
85}
86
87unsigned char uart_getc(void)
88{
89 unsigned char c = 0;
90 int32_t ret = ARM_DRIVER_OK;
91
92 ret = Driver_USART->Receive(&c, 1);
93 ASSERT_HIGH(ret);
94
95 return c;
96}