blob: 40bb425513218fbe4dbaf459372e5b2d45504c83 [file] [log] [blame]
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001/*
2 * Copyright (c) 2011-2012, 2014-2015 Wind River Systems, Inc.
3 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005 */
6
Anas Nashif275ca602015-12-04 10:09:39 -05007/**
8 * @file
9 * @brief UART-driven console
10 *
Dan Kalowskyda67b292015-10-20 09:42:33 -070011 *
12 * Serial console driver.
13 * Hooks into the printk and fputc (for printf) modules. Poll driven.
Anas Nashifea0d0b22015-07-01 17:22:39 -040014 */
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070015
Baohong Liufa2d38e2016-11-30 14:58:45 -080016#include <kernel.h>
Dan Kalowskyc02dd342015-05-28 10:56:47 -070017#include <arch/cpu.h>
Andrei Emeltchenko139c8562015-04-20 11:04:22 +030018
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070019#include <stdio.h>
20#include <stdint.h>
Andrei Emeltchenko139c8562015-04-20 11:04:22 +030021#include <errno.h>
Johan Hedbergf88cccd2015-12-08 10:35:04 +020022#include <ctype.h>
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070023
Daniel Leungad2d2962015-08-12 10:17:35 -070024#include <device.h>
25#include <init.h>
26
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070027#include <board.h>
Tomasz Bursztyka17e06fb2015-10-15 09:48:03 +030028#include <uart.h>
Tomasz Bursztykaae09a482015-04-23 13:12:51 +030029#include <console/uart_console.h>
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070030#include <toolchain.h>
31#include <sections.h>
Johan Hedberg8683dc42015-12-09 11:36:25 +020032#include <atomic.h>
Johan Hedberga9f6f892015-12-08 22:45:12 +020033#include <misc/printk.h>
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070034
Daniel Leung08b4fd42015-12-01 08:42:20 -080035static struct device *uart_console_dev;
36
Benjamin Walsh0ff5d372016-04-11 17:11:28 -040037#ifdef CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS
Marcus Shawcroft1bc999c2016-10-23 08:53:21 +010038
39static uart_console_in_debug_hook_t debug_hook_in;
40void uart_console_in_debug_hook_install(uart_console_in_debug_hook_t hook)
41{
42 debug_hook_in = hook;
43}
44
Benjamin Walsh0ff5d372016-04-11 17:11:28 -040045static UART_CONSOLE_OUT_DEBUG_HOOK_SIG(debug_hook_out_nop)
46{
47 ARG_UNUSED(c);
48 return !UART_CONSOLE_DEBUG_HOOK_HANDLED;
49}
50
51static uart_console_out_debug_hook_t *debug_hook_out = debug_hook_out_nop;
52void uart_console_out_debug_hook_install(uart_console_out_debug_hook_t *hook)
53{
54 debug_hook_out = hook;
55}
56#define HANDLE_DEBUG_HOOK_OUT(c) \
57 (debug_hook_out(c) == UART_CONSOLE_DEBUG_HOOK_HANDLED)
Vincenzo Frascinof3a92412016-11-16 12:01:48 +000058
Benjamin Walsh0ff5d372016-04-11 17:11:28 -040059#endif /* CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS */
60
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070061#if 0 /* NOTUSED */
Anas Nashifea0d0b22015-07-01 17:22:39 -040062/**
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070063 *
Anas Nashiff367f072015-07-01 17:51:40 -040064 * @brief Get a character from UART
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070065 *
Anas Nashif1362e3c2015-07-01 17:29:04 -040066 * @return the character or EOF if nothing present
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070067 */
68
Daniel Leung08b4fd42015-12-01 08:42:20 -080069static int console_in(void)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070070{
71 unsigned char c;
Dan Kalowskyda67b292015-10-20 09:42:33 -070072
Daniel Leung08b4fd42015-12-01 08:42:20 -080073 if (uart_poll_in(uart_console_dev, &c) < 0)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070074 return EOF;
75 else
76 return (int)c;
77}
78#endif
79
80#if defined(CONFIG_PRINTK) || defined(CONFIG_STDOUT_CONSOLE)
Anas Nashifea0d0b22015-07-01 17:22:39 -040081/**
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070082 *
Anas Nashiff367f072015-07-01 17:51:40 -040083 * @brief Output one character to UART
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070084 *
85 * Outputs both line feed and carriage return in the case of a '\n'.
86 *
Daniel Leung08b4fd42015-12-01 08:42:20 -080087 * @param c Character to output
88 *
Anas Nashif1362e3c2015-07-01 17:29:04 -040089 * @return The character passed as input.
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070090 */
91
Daniel Leung08b4fd42015-12-01 08:42:20 -080092static int console_out(int c)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070093{
Vincenzo Frascinof3a92412016-11-16 12:01:48 +000094#ifdef CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS
95
Benjamin Walsh0ff5d372016-04-11 17:11:28 -040096 int handled_by_debug_server = HANDLE_DEBUG_HOOK_OUT(c);
97
98 if (handled_by_debug_server) {
99 return c;
100 }
101
Vincenzo Frascinof3a92412016-11-16 12:01:48 +0000102#endif /* CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS */
103
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700104 if ('\n' == c) {
Andy Ross425145d2016-09-01 08:49:10 -0700105 uart_poll_out(uart_console_dev, '\r');
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700106 }
Andy Ross425145d2016-09-01 08:49:10 -0700107 uart_poll_out(uart_console_dev, c);
108
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700109 return c;
110}
Daniel Leung08b4fd42015-12-01 08:42:20 -0800111
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700112#endif
113
114#if defined(CONFIG_STDOUT_CONSOLE)
115extern void __stdout_hook_install(int (*hook)(int));
116#else
117#define __stdout_hook_install(x) \
118 do {/* nothing */ \
119 } while ((0))
120#endif
121
122#if defined(CONFIG_PRINTK)
123extern void __printk_hook_install(int (*fn)(int));
124#else
125#define __printk_hook_install(x) \
126 do {/* nothing */ \
127 } while ((0))
128#endif
129
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300130#if defined(CONFIG_CONSOLE_HANDLER)
Luiz Augusto von Dentz6b2443e2016-11-11 14:11:44 +0200131static struct k_fifo *avail_queue;
132static struct k_fifo *lines_queue;
Szymon Jancd7e8fd02016-05-25 16:23:42 +0200133static uint8_t (*completion_cb)(char *line, uint8_t len);
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300134
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200135/* Control characters */
136#define ESC 0x1b
137#define DEL 0x7f
138
139/* ANSI escape sequences */
140#define ANSI_ESC '['
141#define ANSI_UP 'A'
142#define ANSI_DOWN 'B'
143#define ANSI_FORWARD 'C'
144#define ANSI_BACKWARD 'D'
Szymon Janc6b0cf542016-10-26 18:10:50 +0200145#define ANSI_END 'F'
146#define ANSI_HOME 'H'
Szymon Janca0373162016-10-26 18:15:02 +0200147#define ANSI_DEL '~'
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200148
Daniel Leung1ad2a562015-08-05 12:13:36 -0700149static int read_uart(struct device *uart, uint8_t *buf, unsigned int size)
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300150{
151 int rx;
152
153 rx = uart_fifo_read(uart, buf, size);
154 if (rx < 0) {
155 /* Overrun issue. Stop the UART */
156 uart_irq_rx_disable(uart);
157
158 return -EIO;
159 }
160
161 return rx;
162}
163
Johan Hedberga9f6f892015-12-08 22:45:12 +0200164static inline void cursor_forward(unsigned int count)
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200165{
Johan Hedberga9f6f892015-12-08 22:45:12 +0200166 printk("\x1b[%uC", count);
167}
168
169static inline void cursor_backward(unsigned int count)
170{
171 printk("\x1b[%uD", count);
172}
173
Johan Hedbergceba31a2015-12-09 12:40:29 +0200174static inline void cursor_save(void)
175{
176 printk("\x1b[s");
177}
178
179static inline void cursor_restore(void)
180{
181 printk("\x1b[u");
182}
183
Johan Hedberga9f6f892015-12-08 22:45:12 +0200184static void insert_char(char *pos, char c, uint8_t end)
185{
Johan Hedberga9f6f892015-12-08 22:45:12 +0200186 char tmp;
187
188 /* Echo back to console */
189 uart_poll_out(uart_console_dev, c);
190
191 if (end == 0) {
192 *pos = c;
193 return;
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200194 }
Johan Hedberga9f6f892015-12-08 22:45:12 +0200195
196 tmp = *pos;
197 *(pos++) = c;
198
Johan Hedbergceba31a2015-12-09 12:40:29 +0200199 cursor_save();
200
201 while (end-- > 0) {
Johan Hedberga9f6f892015-12-08 22:45:12 +0200202 uart_poll_out(uart_console_dev, tmp);
Johan Hedbergceba31a2015-12-09 12:40:29 +0200203 c = *pos;
204 *(pos++) = tmp;
Johan Hedberga9f6f892015-12-08 22:45:12 +0200205 tmp = c;
206 }
207
208 /* Move cursor back to right place */
Johan Hedbergceba31a2015-12-09 12:40:29 +0200209 cursor_restore();
Johan Hedberga9f6f892015-12-08 22:45:12 +0200210}
211
212static void del_char(char *pos, uint8_t end)
213{
Johan Hedberga9f6f892015-12-08 22:45:12 +0200214 uart_poll_out(uart_console_dev, '\b');
215
216 if (end == 0) {
217 uart_poll_out(uart_console_dev, ' ');
218 uart_poll_out(uart_console_dev, '\b');
219 return;
220 }
221
Johan Hedbergceba31a2015-12-09 12:40:29 +0200222 cursor_save();
223
224 while (end-- > 0) {
225 *pos = *(pos + 1);
226 uart_poll_out(uart_console_dev, *(pos++));
Johan Hedberga9f6f892015-12-08 22:45:12 +0200227 }
228
229 uart_poll_out(uart_console_dev, ' ');
230
231 /* Move cursor back to right place */
Johan Hedbergceba31a2015-12-09 12:40:29 +0200232 cursor_restore();
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200233}
234
Johan Hedberg8683dc42015-12-09 11:36:25 +0200235enum {
236 ESC_ESC,
237 ESC_ANSI,
238 ESC_ANSI_FIRST,
239 ESC_ANSI_VAL,
240 ESC_ANSI_VAL_2
241};
242
243static atomic_t esc_state;
244static unsigned int ansi_val, ansi_val_2;
245static uint8_t cur, end;
246
Szymon Janca0373162016-10-26 18:15:02 +0200247static void handle_ansi(uint8_t byte, char *line)
Johan Hedberg8683dc42015-12-09 11:36:25 +0200248{
249 if (atomic_test_and_clear_bit(&esc_state, ESC_ANSI_FIRST)) {
250 if (!isdigit(byte)) {
251 ansi_val = 1;
252 goto ansi_cmd;
253 }
254
255 atomic_set_bit(&esc_state, ESC_ANSI_VAL);
256 ansi_val = byte - '0';
257 ansi_val_2 = 0;
258 return;
259 }
260
261 if (atomic_test_bit(&esc_state, ESC_ANSI_VAL)) {
262 if (isdigit(byte)) {
263 if (atomic_test_bit(&esc_state, ESC_ANSI_VAL_2)) {
264 ansi_val_2 *= 10;
265 ansi_val_2 += byte - '0';
266 } else {
267 ansi_val *= 10;
268 ansi_val += byte - '0';
269 }
270 return;
271 }
272
273 /* Multi value sequence, e.g. Esc[Line;ColumnH */
274 if (byte == ';' &&
275 !atomic_test_and_set_bit(&esc_state, ESC_ANSI_VAL_2)) {
276 return;
277 }
278
279 atomic_clear_bit(&esc_state, ESC_ANSI_VAL);
280 atomic_clear_bit(&esc_state, ESC_ANSI_VAL_2);
281 }
282
283ansi_cmd:
284 switch (byte) {
285 case ANSI_BACKWARD:
286 if (ansi_val > cur) {
287 break;
288 }
289
290 end += ansi_val;
291 cur -= ansi_val;
292 cursor_backward(ansi_val);
293 break;
294 case ANSI_FORWARD:
295 if (ansi_val > end) {
296 break;
297 }
298
299 end -= ansi_val;
300 cur += ansi_val;
301 cursor_forward(ansi_val);
302 break;
Szymon Janc6b0cf542016-10-26 18:10:50 +0200303 case ANSI_HOME:
304 if (!cur) {
305 break;
306 }
307
308 cursor_backward(cur);
309 end += cur;
310 cur = 0;
311 break;
312 case ANSI_END:
313 if (!end) {
314 break;
315 }
316
317 cursor_forward(end);
318 cur += end;
319 end = 0;
320 break;
Szymon Janca0373162016-10-26 18:15:02 +0200321 case ANSI_DEL:
322 if (!end) {
323 break;
324 }
325
326 cursor_forward(1);
327 del_char(&line[cur], --end);
328 break;
Johan Hedberg8683dc42015-12-09 11:36:25 +0200329 default:
330 break;
331 }
332
333 atomic_clear_bit(&esc_state, ESC_ANSI);
334}
335
Daniel Leunge643ced2016-03-03 10:14:50 -0800336void uart_console_isr(struct device *unused)
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300337{
338 ARG_UNUSED(unused);
339
Johan Hedberg5ad78032015-12-07 15:03:20 +0200340 while (uart_irq_update(uart_console_dev) &&
341 uart_irq_is_pending(uart_console_dev)) {
342 static struct uart_console_input *cmd;
343 uint8_t byte;
344 int rx;
345
346 if (!uart_irq_rx_ready(uart_console_dev)) {
347 continue;
348 }
349
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300350 /* Character(s) have been received */
Andrei Emeltchenko879541a2015-05-04 14:43:36 +0300351
Johan Hedberg5ad78032015-12-07 15:03:20 +0200352 rx = read_uart(uart_console_dev, &byte, 1);
353 if (rx < 0) {
354 return;
355 }
356
Marcus Shawcroft1bc999c2016-10-23 08:53:21 +0100357#ifdef CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS
358 if (debug_hook_in != NULL && debug_hook_in(byte) != 0) {
Johan Hedberg5ad78032015-12-07 15:03:20 +0200359 /*
360 * The input hook indicates that no further processing
361 * should be done by this handler.
362 */
363 return;
364 }
Marcus Shawcroft1bc999c2016-10-23 08:53:21 +0100365#endif
Johan Hedberg5ad78032015-12-07 15:03:20 +0200366
367 if (!cmd) {
Luiz Augusto von Dentz6b2443e2016-11-11 14:11:44 +0200368 cmd = k_fifo_get(avail_queue, K_NO_WAIT);
Johan Hedberg5ad78032015-12-07 15:03:20 +0200369 if (!cmd)
Peter Mitsisb1c10202015-09-17 13:22:00 -0400370 return;
Johan Hedberg5ad78032015-12-07 15:03:20 +0200371 }
Peter Mitsisb1c10202015-09-17 13:22:00 -0400372
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200373 /* Handle ANSI escape mode */
Johan Hedberg8683dc42015-12-09 11:36:25 +0200374 if (atomic_test_bit(&esc_state, ESC_ANSI)) {
Szymon Janca0373162016-10-26 18:15:02 +0200375 handle_ansi(byte, cmd->line);
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200376 continue;
377 }
378
379 /* Handle escape mode */
Johan Hedberg8683dc42015-12-09 11:36:25 +0200380 if (atomic_test_and_clear_bit(&esc_state, ESC_ESC)) {
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200381 switch (byte) {
382 case ANSI_ESC:
Johan Hedberg8683dc42015-12-09 11:36:25 +0200383 atomic_set_bit(&esc_state, ESC_ANSI);
384 atomic_set_bit(&esc_state, ESC_ANSI_FIRST);
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200385 break;
386 default:
387 break;
388 }
389
390 continue;
391 }
392
393 /* Handle special control characters */
394 if (!isprint(byte)) {
395 switch (byte) {
396 case DEL:
Johan Hedberga9f6f892015-12-08 22:45:12 +0200397 if (cur > 0) {
398 del_char(&cmd->line[--cur], end);
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200399 }
400 break;
401 case ESC:
Johan Hedberg8683dc42015-12-09 11:36:25 +0200402 atomic_set_bit(&esc_state, ESC_ESC);
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200403 break;
404 case '\r':
Johan Hedberga9f6f892015-12-08 22:45:12 +0200405 cmd->line[cur + end] = '\0';
Johan Hedberg65433182016-02-05 13:45:48 +0200406 uart_poll_out(uart_console_dev, '\r');
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200407 uart_poll_out(uart_console_dev, '\n');
Johan Hedberga9f6f892015-12-08 22:45:12 +0200408 cur = 0;
409 end = 0;
Luiz Augusto von Dentz6b2443e2016-11-11 14:11:44 +0200410 k_fifo_put(lines_queue, cmd);
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200411 cmd = NULL;
412 break;
Szymon Jancd7e8fd02016-05-25 16:23:42 +0200413 case '\t':
414 if (completion_cb && !end) {
415 cur += completion_cb(cmd->line, cur);
416 }
417 break;
Johan Hedbergf88cccd2015-12-08 10:35:04 +0200418 default:
419 break;
420 }
421
422 continue;
423 }
424
Johan Hedberg6147fc62015-12-08 09:26:31 +0200425 /* Ignore characters if there's no more buffer space */
Johan Hedberga9f6f892015-12-08 22:45:12 +0200426 if (cur + end < sizeof(cmd->line) - 1) {
427 insert_char(&cmd->line[cur++], byte, end);
Johan Hedberg6147fc62015-12-08 09:26:31 +0200428 }
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300429 }
430}
431
Andrei Emeltchenko879541a2015-05-04 14:43:36 +0300432static void console_input_init(void)
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300433{
434 uint8_t c;
435
Daniel Leung08b4fd42015-12-01 08:42:20 -0800436 uart_irq_rx_disable(uart_console_dev);
437 uart_irq_tx_disable(uart_console_dev);
Daniel Leunge643ced2016-03-03 10:14:50 -0800438
439 uart_irq_callback_set(uart_console_dev, uart_console_isr);
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300440
441 /* Drain the fifo */
Daniel Leung08b4fd42015-12-01 08:42:20 -0800442 while (uart_irq_rx_ready(uart_console_dev)) {
443 uart_fifo_read(uart_console_dev, &c, 1);
Daniel Leung1ad2a562015-08-05 12:13:36 -0700444 }
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300445
Daniel Leung08b4fd42015-12-01 08:42:20 -0800446 uart_irq_rx_enable(uart_console_dev);
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300447}
448
Luiz Augusto von Dentz6b2443e2016-11-11 14:11:44 +0200449void uart_register_input(struct k_fifo *avail, struct k_fifo *lines,
Szymon Jancd7e8fd02016-05-25 16:23:42 +0200450 uint8_t (*completion)(char *str, uint8_t len))
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300451{
Andrei Emeltchenko879541a2015-05-04 14:43:36 +0300452 avail_queue = avail;
453 lines_queue = lines;
Szymon Jancd7e8fd02016-05-25 16:23:42 +0200454 completion_cb = completion;
Andrei Emeltchenko879541a2015-05-04 14:43:36 +0300455
456 console_input_init();
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300457}
Szymon Jancd7e8fd02016-05-25 16:23:42 +0200458
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300459#else
Andrei Emeltchenko879541a2015-05-04 14:43:36 +0300460#define console_input_init(x) \
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300461 do {/* nothing */ \
462 } while ((0))
Andrei Emeltchenko879541a2015-05-04 14:43:36 +0300463#define uart_register_input(x) \
Andrei Emeltchenko139c8562015-04-20 11:04:22 +0300464 do {/* nothing */ \
465 } while ((0))
466#endif
467
Anas Nashifea0d0b22015-07-01 17:22:39 -0400468/**
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700469 *
Daniel Leungad2d2962015-08-12 10:17:35 -0700470 * @brief Install printk/stdout hook for UART console output
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700471 *
Anas Nashif1362e3c2015-07-01 17:29:04 -0400472 * @return N/A
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700473 */
474
Daniel Leungad2d2962015-08-12 10:17:35 -0700475void uart_console_hook_install(void)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700476{
Daniel Leung08b4fd42015-12-01 08:42:20 -0800477 __stdout_hook_install(console_out);
478 __printk_hook_install(console_out);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700479}
Daniel Leungad2d2962015-08-12 10:17:35 -0700480
481/**
482 *
483 * @brief Initialize one UART as the console/debug port
484 *
Andre Guedes024cfe72016-03-09 14:01:20 -0300485 * @return 0 if successful, otherwise failed.
Daniel Leungad2d2962015-08-12 10:17:35 -0700486 */
487static int uart_console_init(struct device *arg)
488{
Jithu Josephfca0add2016-11-06 16:58:14 -0800489
Daniel Leungad2d2962015-08-12 10:17:35 -0700490 ARG_UNUSED(arg);
491
Daniel Leung08b4fd42015-12-01 08:42:20 -0800492 uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);
493
Jithu Josephfca0add2016-11-06 16:58:14 -0800494#ifdef CONFIG_USB_UART_CONSOLE
495 while (1) {
Johan Hedberg488f72d2016-11-12 11:32:32 +0200496 uint32_t dtr = 0;
497
Jithu Josephfca0add2016-11-06 16:58:14 -0800498 uart_line_ctrl_get(uart_console_dev, LINE_CTRL_DTR, &dtr);
499 if (dtr) {
500 break;
501 }
502 }
Baohong Liufa2d38e2016-11-30 14:58:45 -0800503 k_busy_wait(1000000);
Jithu Josephfca0add2016-11-06 16:58:14 -0800504#endif
505
Daniel Leungad2d2962015-08-12 10:17:35 -0700506 uart_console_hook_install();
507
Andre Guedes024cfe72016-03-09 14:01:20 -0300508 return 0;
Daniel Leungad2d2962015-08-12 10:17:35 -0700509}
Dmitriy Korovkin57f27412015-10-26 15:56:02 -0400510
Chuck Jordan12e29fe2016-05-06 12:43:56 -0700511/* UART console initializes after the UART device itself */
Benjamin Walsha4ec9632016-01-28 15:16:31 -0500512SYS_INIT(uart_console_init,
Jithu Josephfca0add2016-11-06 16:58:14 -0800513#if defined(CONFIG_USB_UART_CONSOLE)
514 APPLICATION,
515#elif defined(CONFIG_EARLY_CONSOLE)
Andrew Boie0b474ee2016-11-08 11:06:55 -0800516 PRE_KERNEL_1,
Dmitriy Korovkin57f27412015-10-26 15:56:02 -0400517#else
Andrew Boie0b474ee2016-11-08 11:06:55 -0800518 POST_KERNEL,
Dmitriy Korovkin57f27412015-10-26 15:56:02 -0400519#endif
Daniel Leung546b8ad2016-03-28 14:05:33 -0700520 CONFIG_UART_CONSOLE_INIT_PRIORITY);