1 /*
2 * @brief IO redirection support
3 *
4 * This file adds re-direction support to the library for various
5 * projects. It can be configured in one of 3 ways - no redirection,
6 * redirection via a UART, or redirection via semihosting. If DEBUG
7 * is not defined, all printf statements will do nothing with the
8 * output being throw away. If DEBUG is defined, then the choice of
9 * output is selected by the DEBUG_SEMIHOSTING define. If the
10 * DEBUG_SEMIHOSTING is not defined, then output is redirected via
11 * the UART. If DEBUG_SEMIHOSTING is defined, then output will be
12 * attempted to be redirected via semihosting. If the UART method
13 * is used, then the Board_UARTPutChar and Board_UARTGetChar
14 * functions must be defined to be used by this driver and the UART
15 * must already be initialized to the correct settings.
16 *
17 * @note
18 * Copyright(C) NXP Semiconductors, 2012
19 * All rights reserved.
20 *
21 * @par
22 * Software that is described herein is for illustrative purposes only
23 * which provides customers with programming information regarding the
24 * LPC products. This software is supplied "AS IS" without any warranties of
25 * any kind, and NXP Semiconductors and its licensor disclaim any and
26 * all warranties, express or implied, including all implied warranties of
27 * merchantability, fitness for a particular purpose and non-infringement of
28 * intellectual property rights. NXP Semiconductors assumes no responsibility
29 * or liability for the use of the software, conveys no license or rights under any
30 * patent, copyright, mask work right, or any other intellectual property rights in
31 * or to any products. NXP Semiconductors reserves the right to make changes
32 * in the software without notification. NXP Semiconductors also makes no
33 * representation or warranty that such application will be suitable for the
34 * specified use without further testing or modification.
35 *
36 * @par
37 * Permission to use, copy, modify, and distribute this software and its
38 * documentation is hereby granted, under NXP Semiconductors' and its
39 * licensor's relevant copyrights in the software, without fee, provided that it
40 * is used in conjunction with NXP Semiconductors microcontrollers. This
41 * copyright, permission, and disclaimer notice must appear in all copies of
42 * this code.
43 */
44
45 #include "board.h"
46
47 /* Keil (Realview) support */
48 #if defined(__CC_ARM)
49
50 #include <stdio.h>
51 #include <rt_misc.h>
52
53 #if defined(DEBUG_ENABLE)
54 #if defined(DEBUG_SEMIHOSTING)
55 #define ITM_Port8(n) (*((volatile unsigned char *) (0xE0000000 + 4 * n)))
56 #define ITM_Port16(n) (*((volatile unsigned short *) (0xE0000000 + 4 * n)))
57 #define ITM_Port32(n) (*((volatile unsigned long *) (0xE0000000 + 4 * n)))
58
59 #define DEMCR (*((volatile unsigned long *) (0xE000EDFC)))
60 #define TRCENA 0x01000000
61
62 /* Write to SWO */
_ttywrch(int ch)63 void _ttywrch(int ch)
64 {
65 if (DEMCR & TRCENA) {
66 while (ITM_Port32(0) == 0) {}
67 ITM_Port8(0) = ch;
68 }
69 }
70
71 #else
BoardOutChar(char ch)72 static INLINE void BoardOutChar(char ch)
73 {
74 Board_UARTPutChar(ch);
75 }
76
77 #endif /* defined(DEBUG_SEMIHOSTING) */
78 #endif /* defined(DEBUG_ENABLE) */
79
80 struct __FILE {
81 int handle;
82 };
83
84 FILE __stdout;
85 FILE __stdin;
86 FILE __stderr;
87
_sys_open(const char * name,int openmode)88 void *_sys_open(const char *name, int openmode)
89 {
90 return 0;
91 }
92
fputc(int c,FILE * f)93 int fputc(int c, FILE *f)
94 {
95 #if defined(DEBUG_ENABLE)
96 #if defined(DEBUG_SEMIHOSTING)
97 _ttywrch(c);
98 #else
99 BoardOutChar((char) c);
100 #endif
101 #endif
102 return 0;
103 }
104
fgetc(FILE * f)105 int fgetc(FILE *f)
106 {
107 #if defined(DEBUG_ENABLE) && !defined(DEBUG_SEMIHOSTING)
108 return Board_UARTGetChar();
109 #else
110 return 0;
111 #endif
112 }
113
ferror(FILE * f)114 int ferror(FILE *f)
115 {
116 return EOF;
117 }
118
_sys_exit(int return_code)119 void _sys_exit(int return_code)
120 {
121 label:
122 __WFI();
123 goto label; /* endless loop */
124 }
125
126 #endif /* defined (__CC_ARM) */
127
128 /* IAR support */
129 #if defined(__ICCARM__)
130 /*******************
131 *
132 * Copyright 1998-2003 IAR Systems. All rights reserved.
133 *
134 * $Revision: 30870 $
135 *
136 * This is a template implementation of the "__write" function used by
137 * the standard library. Replace it with a system-specific
138 * implementation.
139 *
140 * The "__write" function should output "size" number of bytes from
141 * "buffer" in some application-specific way. It should return the
142 * number of characters written, or _LLIO_ERROR on failure.
143 *
144 * If "buffer" is zero then __write should perform flushing of
145 * internal buffers, if any. In this case "handle" can be -1 to
146 * indicate that all handles should be flushed.
147 *
148 * The template implementation below assumes that the application
149 * provides the function "MyLowLevelPutchar". It should return the
150 * character written, or -1 on failure.
151 *
152 ********************/
153
154 #include <yfuns.h>
155
156 #if defined(DEBUG_ENABLE) && !defined(DEBUG_SEMIHOSTING)
157
158 _STD_BEGIN
159
160 #pragma module_name = "?__write"
161
162 /*
163 If the __write implementation uses internal buffering, uncomment
164 the following line to ensure that we are called with "buffer" as 0
165 (i.e. flush) when the application terminates. */
__write(int handle,const unsigned char * buffer,size_t size)166 size_t __write(int handle, const unsigned char *buffer, size_t size)
167 {
168 #if defined(DEBUG_ENABLE)
169 size_t nChars = 0;
170
171 if (buffer == 0) {
172 /*
173 This means that we should flush internal buffers. Since we
174 don't we just return. (Remember, "handle" == -1 means that all
175 handles should be flushed.)
176 */
177 return 0;
178 }
179
180 /* This template only writes to "standard out" and "standard err",
181 for all other file handles it returns failure. */
182 if (( handle != _LLIO_STDOUT) && ( handle != _LLIO_STDERR) ) {
183 return _LLIO_ERROR;
184 }
185
186 for ( /* Empty */; size != 0; --size) {
187 Board_UARTPutChar(*buffer++);
188 ++nChars;
189 }
190
191 return nChars;
192 #else
193 return size;
194 #endif /* defined(DEBUG_ENABLE) */
195 }
196
197 _STD_END
198 #endif
199
200 #endif /* defined (__ICCARM__) */
201
202 #if defined( __GNUC__ )
203 /* Include stdio.h to pull in __REDLIB_INTERFACE_VERSION__ */
204 #include <stdio.h>
205
206 #if (__REDLIB_INTERFACE_VERSION__ >= 20000)
207 /* We are using new Redlib_v2 semihosting interface */
208 #define WRITEFUNC __sys_write
209 #define READFUNC __sys_readc
210 #else
211 /* We are using original Redlib semihosting interface */
212 #define WRITEFUNC __write
213 #define READFUNC __readc
214 #endif
215
216 #if defined(DEBUG_ENABLE)
217 #if defined(DEBUG_SEMIHOSTING)
218 /* Do nothing, semihosting is enabled by default in LPCXpresso */
219 #endif /* defined(DEBUG_SEMIHOSTING) */
220 #endif /* defined(DEBUG_ENABLE) */
221
222 #if !defined(DEBUG_SEMIHOSTING)
WRITEFUNC(int iFileHandle,char * pcBuffer,int iLength)223 int WRITEFUNC(int iFileHandle, char *pcBuffer, int iLength)
224 {
225 #if defined(DEBUG_ENABLE)
226 unsigned int i;
227 for (i = 0; i < iLength; i++) {
228 Board_UARTPutChar(pcBuffer[i]);
229 }
230 #endif
231
232 return iLength;
233 }
234
235 /* Called by bottom level of scanf routine within RedLib C library to read
236 a character. With the default semihosting stub, this would read the character
237 from the debugger console window (which acts as stdin). But this version reads
238 the character from the LPC1768/RDB1768 UART. */
READFUNC(void)239 int READFUNC(void)
240 {
241 #if defined(DEBUG_ENABLE)
242 char c = Board_UARTGetChar();
243 return (int) c;
244
245 #else
246 return (int) -1;
247 #endif
248 }
249
250 #endif /* !defined(DEBUG_SEMIHOSTING) */
251 #endif /* defined ( __GNUC__ ) */
252