1 /*
2  * Copyright (c) 2021-2024 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef __ICCRISCV__
9 #include <sys/stat.h>
10 #endif
11 #include "hpm_debug_console.h"
12 #include "hpm_uart_drv.h"
13 
14 static UART_Type* g_console_uart = NULL;
15 
console_init(console_config_t * cfg)16 hpm_stat_t console_init(console_config_t *cfg)
17 {
18     hpm_stat_t stat = status_fail;
19 
20     if (cfg->type == CONSOLE_TYPE_UART) {
21         uart_config_t config = {0};
22         uart_default_config((UART_Type *)cfg->base, &config);
23         config.src_freq_in_hz = cfg->src_freq_in_hz;
24         config.baudrate = cfg->baudrate;
25         stat = uart_init((UART_Type *)cfg->base, &config);
26         if (status_success == stat) {
27             g_console_uart = (UART_Type *)cfg->base;
28         }
29     }
30 
31     return stat;
32 }
33 
console_receive_byte(void)34 uint8_t console_receive_byte(void)
35 {
36     uint8_t c;
37     while (status_success != uart_receive_byte(g_console_uart, &c)) {
38     };
39     return c;
40 }
41 
console_try_receive_byte(void)42 uint8_t console_try_receive_byte(void)
43 {
44     uint8_t c = 0;
45 
46     uart_try_receive_byte(g_console_uart, &c);
47 
48     return c;
49 }
50 
console_send_byte(uint8_t c)51 void console_send_byte(uint8_t c)
52 {
53     while (status_success != uart_send_byte(g_console_uart, c)) {
54     }
55 }
56 
57 #ifdef __SEGGER_RTL_VERSION
58 #include <stdio.h>
59 #include "__SEGGER_RTL_Int.h"
60 static int _stdin_ungot  = EOF;
61 struct __SEGGER_RTL_FILE_impl { /* NOTE: Provides implementation for FILE */
62     int stub; /* only needed so impl has size != 0. */
63 };
64 
65 static FILE __SEGGER_RTL_stdin_file  = { 0 };  /* stdin reads from UART */
66 static FILE __SEGGER_RTL_stdout_file = { 0 };  /* stdout writes to UART */
67 static FILE __SEGGER_RTL_stderr_file = { 0 };  /* stderr writes to UART */
68 
69 FILE *stdin  = &__SEGGER_RTL_stdin_file;  /* NOTE: Provide implementation of stdin for RTL. */
70 FILE *stdout = &__SEGGER_RTL_stdout_file; /* NOTE: Provide implementation of stdout for RTL. */
71 FILE *stderr = &__SEGGER_RTL_stderr_file; /* NOTE: Provide implementation of stderr for RTL. */
72 
__SEGGER_RTL_X_file_write(__SEGGER_RTL_FILE * file,const char * data,unsigned int size)73 int __SEGGER_RTL_X_file_write(__SEGGER_RTL_FILE *file, const char *data, unsigned int size)
74 {
75     unsigned int count;
76     (void)file;
77     for (count = 0; count < size; count++) {
78         if (data[count] == '\n') {
79             while (status_success != uart_send_byte(g_console_uart, '\r')) {
80             }
81         }
82         while (status_success != uart_send_byte(g_console_uart, data[count])) {
83         }
84     }
85     while (status_success != uart_flush(g_console_uart)) {
86     }
87     return count;
88 
89 }
90 
__SEGGER_RTL_X_file_read(__SEGGER_RTL_FILE * file,char * s,unsigned int size)91 int __SEGGER_RTL_X_file_read(__SEGGER_RTL_FILE *file, char *s, unsigned int size)
92 {
93     (void)file;
94     (void) size;
95     while (status_success != uart_receive_byte(g_console_uart, (uint8_t *)s)) {
96     }
97     return 1;
98 }
99 
__SEGGER_RTL_X_file_stat(__SEGGER_RTL_FILE * stream)100 int __SEGGER_RTL_X_file_stat(__SEGGER_RTL_FILE *stream)
101 {
102     (void) stream;
103     return 0;
104 }
105 
__SEGGER_RTL_X_file_bufsize(__SEGGER_RTL_FILE * stream)106 int __SEGGER_RTL_X_file_bufsize(__SEGGER_RTL_FILE *stream)
107 {
108     (void) stream;
109     return 1;
110 }
111 
__SEGGER_RTL_X_file_unget(__SEGGER_RTL_FILE * stream,int c)112 int __SEGGER_RTL_X_file_unget(__SEGGER_RTL_FILE *stream, int c)
113 {
114     if (stream == stdin) {
115         if (c != EOF && _stdin_ungot == EOF) {
116             _stdin_ungot = c;
117         } else {
118             c = EOF;
119         }
120     } else {
121         c = EOF;
122     }
123     return c;
124 }
125 
__SEGGER_RTL_X_file_flush(__SEGGER_RTL_FILE * __stream)126 int  __SEGGER_RTL_X_file_flush(__SEGGER_RTL_FILE *__stream)
127 {
128     (void) __stream;
129     return 1;
130 }
131 
132 #endif
133 
_write(int file,char * data,int size)134 int _write(int file, char *data, int size)
135 {
136     int count;
137     (void)file;
138     for (count = 0; count < size; count++) {
139         if (data[count] == '\n') {
140             while (status_success != uart_send_byte(g_console_uart, '\r')) {
141             }
142         }
143         while (status_success != uart_send_byte(g_console_uart, data[count])) {
144         }
145     }
146     while (status_success != uart_flush(g_console_uart)) {
147     }
148     return count;
149 }
150 
_read(int file,char * s,int size)151 int _read(int file, char *s, int size)
152 {
153     (void)file;
154     (void) size;
155     while (status_success != uart_receive_byte(g_console_uart, (uint8_t *)s)) {
156     }
157     return 1;
158 }
159 
160 #ifndef __ICCRISCV__
_fstat(int file,struct stat * s)161 int _fstat(int file, struct stat *s)
162 {
163     (void) file;
164     s->st_mode = S_IFCHR;
165     return 0;
166 }
167 #else
168 
169 #ifndef _DLIB_FILE_DESCRIPTOR
170 #define _DLIB_FILE_DESCRIPTOR 0
171 #endif
172 
__write(int file,char * data,int size)173 int __write(int file, char *data, int size)
174 {
175     return _write(file, data, size);
176 }
177 
__read(int file,char * s,int size)178 int __read(int file, char *s, int size)
179 {
180     return _read(file, s, size);
181 }
182 #endif
183