blob: 8075873d82f7888910df666e347653fbd80c1fed [file] [log] [blame]
Marc Moreno Berengue20dab392017-11-29 13:18:58 +00001/*
Avinash Mehta788036c2018-03-15 12:38:43 +00002 * Copyright (c) 2017-2018 ARM Limited
Marc Moreno Berengue20dab392017-11-29 13:18:58 +00003 *
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>
Avinash Mehta788036c2018-03-15 12:38:43 +000022#ifdef TARGET_MUSCA_A
23#include "uart_pl011_drv.h"
24#else
Marc Moreno Berengue20dab392017-11-29 13:18:58 +000025#include "arm_uart_drv.h"
Avinash Mehta788036c2018-03-15 12:38:43 +000026#endif
Marc Moreno Berengue20dab392017-11-29 13:18:58 +000027#include "Driver_USART.h"
28
29#define ASSERT_HIGH(X) assert(X == ARM_DRIVER_OK)
30
31/* Imports USART driver */
32extern ARM_DRIVER_USART Driver_USART0;
33extern ARM_DRIVER_USART Driver_USART1;
34
35/* Struct FILE is implemented in stdio.h. Used to redirect printf to UART */
36FILE __stdout;
37
38/* Redirects printf to UART */
39__attribute__ ((weak)) int fputc(int ch, FILE *f) {
40 /* Send byte to USART */
41 uart_putc(ch);
42
43 /* Return character written */
44 return ch;
45}
46
Mate Toth-Pal31a2d962018-03-09 13:14:44 +010047int _write(int fd, char * str, int len)
48{
49 for (int i = 0; i < len; i++)
50 {
51 uart_putc(str[i]);
52 }
53 return len;
54}
55
Avinash Mehta788036c2018-03-15 12:38:43 +000056#ifdef TARGET_MUSCA_A
57extern struct uart_pl011_dev_t UART0_DEV_S, UART0_DEV_NS;
58extern struct uart_pl011_dev_t UART1_DEV_S, UART1_DEV_NS;
59#else
Marc Moreno Berengue20dab392017-11-29 13:18:58 +000060extern struct arm_uart_dev_t ARM_UART0_DEV_S, ARM_UART0_DEV_NS;
61extern struct arm_uart_dev_t ARM_UART1_DEV_S, ARM_UART1_DEV_NS;
Avinash Mehta788036c2018-03-15 12:38:43 +000062#endif
Marc Moreno Berengue20dab392017-11-29 13:18:58 +000063
64/* Generic driver to be configured and used */
65ARM_DRIVER_USART *Driver_USART = NULL;
66
67void uart_init(enum uart_channel uchan)
68{
69 int32_t ret = ARM_DRIVER_OK;
70
71 /* Add a configuration step for the UART channel to use, 0 or 1 */
72 switch(uchan) {
73 case UART0_CHANNEL:
Miklos Balint6cbeba62018-04-12 17:31:34 +020074 /* UART0 is configured as a non-secure peripheral, so it cannot be
75 * accessed using its secure alias. Ideally the driver would
76 * be configured with the right properties, but for simplicity,
77 * use a workaround for now
Marc Moreno Berengue20dab392017-11-29 13:18:58 +000078 */
Avinash Mehta788036c2018-03-15 12:38:43 +000079#ifdef TARGET_MUSCA_A
80 memcpy(&UART0_DEV_S, &UART0_DEV_NS, sizeof(struct uart_pl011_dev_t));
81#else
Miklos Balint6cbeba62018-04-12 17:31:34 +020082 memcpy(&ARM_UART0_DEV_S, &ARM_UART0_DEV_NS,
83 sizeof(struct arm_uart_dev_t));
Avinash Mehta788036c2018-03-15 12:38:43 +000084#endif
Marc Moreno Berengue20dab392017-11-29 13:18:58 +000085 Driver_USART = &Driver_USART0;
86 break;
87 case UART1_CHANNEL:
Miklos Balint6cbeba62018-04-12 17:31:34 +020088#ifndef SECURE_UART1
89 /* If UART1 is configured as a non-secure peripheral, it cannot be
90 * accessed using its secure alias. Ideally the driver would
91 * be configured with the right properties, but for simplicity,
92 * use a workaround for now
93 */
94#ifdef TARGET_MUSCA_A
95 memcpy(&UART1_DEV_S, &UART1_DEV_NS, sizeof(struct uart_pl011_dev_t));
96#else
97 memcpy(&ARM_UART1_DEV_S, &ARM_UART1_DEV_NS,
98 sizeof(struct arm_uart_dev_t));
99#endif
100#endif
Marc Moreno Berengue20dab392017-11-29 13:18:58 +0000101 Driver_USART = &Driver_USART1;
102 break;
103 default:
104 ret = ARM_DRIVER_ERROR;
105 }
106 ASSERT_HIGH(ret);
107
108 ret = Driver_USART->Initialize(NULL);
109 ASSERT_HIGH(ret);
110
111 ret = Driver_USART->Control(ARM_USART_MODE_ASYNCHRONOUS, 115200);
112 ASSERT_HIGH(ret);
113}
114
115void uart_putc(unsigned char c)
116{
117 int32_t ret = ARM_DRIVER_OK;
118
119 ret = Driver_USART->Send(&c, 1);
120 ASSERT_HIGH(ret);
121}
122
123unsigned char uart_getc(void)
124{
125 unsigned char c = 0;
126 int32_t ret = ARM_DRIVER_OK;
127
128 ret = Driver_USART->Receive(&c, 1);
129 ASSERT_HIGH(ret);
130
131 return c;
132}