LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Retarget.c
Go to the documentation of this file.
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 "sys_config.h"
46 #include "board.h"
47 
48 /* Keil (Realview) support */
49 #if defined(__CC_ARM)
50 
51 #include <stdio.h>
52 #include <rt_misc.h>
53 
54 #if defined(DEBUG)
55 #if defined(DEBUG_SEMIHOSTING)
56 #define ITM_Port8(n) (*((volatile unsigned char *) (0xE0000000 + 4 * n)))
57 #define ITM_Port16(n) (*((volatile unsigned short *) (0xE0000000 + 4 * n)))
58 #define ITM_Port32(n) (*((volatile unsigned long *) (0xE0000000 + 4 * n)))
59 
60 #define DEMCR (*((volatile unsigned long *) (0xE000EDFC)))
61 #define TRCENA 0x01000000
62 
63 /* Write to SWO */
64 void _ttywrch(int ch)
65 {
66  if (DEMCR & TRCENA) {
67  while (ITM_Port32(0) == 0) {}
68  ITM_Port8(0) = ch;
69  }
70 }
71 
72 #else
73 static INLINE void BoardOutChar(char ch)
74 {
76 }
77 
78 #endif /* defined(DEBUG_SEMIHOSTING) */
79 #endif /* defined(DEBUG) */
80 
81 struct __FILE {
82  int handle;
83 };
84 
85 FILE __stdout;
86 FILE __stdin;
87 FILE __stderr;
88 
89 void *_sys_open(const char *name, int openmode)
90 {
91  return 0;
92 }
93 
94 int fputc(int c, FILE *f)
95 {
96 #if defined(DEBUG)
97 #if defined(DEBUG_SEMIHOSTING)
98  _ttywrch(c);
99 #else
100  BoardOutChar((char) c);
101 #endif
102 #endif
103  return 0;
104 }
105 
106 int fgetc(FILE *f)
107 {
108 #if defined(DEBUG) && !defined(DEBUG_SEMIHOSTING)
109  return Board_UARTGetChar();
110 #else
111  return 0;
112 #endif
113 }
114 
115 int ferror(FILE *f)
116 {
117  return EOF;
118 }
119 
120 void _sys_exit(int return_code)
121 {
122 label: goto label; /* endless loop */
123 }
124 
125 #endif /* defined (__CC_ARM) */
126 
127 /* IAR support */
128 #if defined(__ICCARM__)
129 /*******************
130  *
131  * Copyright 1998-2003 IAR Systems. All rights reserved.
132  *
133  * $Revision: 30870 $
134  *
135  * This is a template implementation of the "__write" function used by
136  * the standard library. Replace it with a system-specific
137  * implementation.
138  *
139  * The "__write" function should output "size" number of bytes from
140  * "buffer" in some application-specific way. It should return the
141  * number of characters written, or _LLIO_ERROR on failure.
142  *
143  * If "buffer" is zero then __write should perform flushing of
144  * internal buffers, if any. In this case "handle" can be -1 to
145  * indicate that all handles should be flushed.
146  *
147  * The template implementation below assumes that the application
148  * provides the function "MyLowLevelPutchar". It should return the
149  * character written, or -1 on failure.
150  *
151  ********************/
152 
153 #include <yfuns.h>
154 
155 _STD_BEGIN
156 
157 #pragma module_name = "?__write"
158 
159 #if defined(DEBUG)
160 #if defined(DEBUG_SEMIHOSTING)
161 #error Semihosting support not yet working on IAR
162 #endif /* defined(DEBUG_SEMIHOSTING) */
163 #endif /* defined(DEBUG) */
164 
165 /*
166  If the __write implementation uses internal buffering, uncomment
167  the following line to ensure that we are called with "buffer" as 0
168  (i.e. flush) when the application terminates. */
169 size_t __write(int handle, const unsigned char *buffer, size_t size)
170 {
171 #if defined(DEBUG)
172  size_t nChars = 0;
173 
174  if (buffer == 0) {
175  /*
176  This means that we should flush internal buffers. Since we
177  don't we just return. (Remember, "handle" == -1 means that all
178  handles should be flushed.)
179  */
180  return 0;
181  }
182 
183  /* This template only writes to "standard out" and "standard err",
184  for all other file handles it returns failure. */
185  if (( handle != _LLIO_STDOUT) && ( handle != _LLIO_STDERR) ) {
186  return _LLIO_ERROR;
187  }
188 
189  for ( /* Empty */; size != 0; --size) {
190  Board_UARTPutChar(*buffer++);
191  ++nChars;
192  }
193 
194  return nChars;
195 #else
196  return size;
197 #endif /* defined(DEBUG) */
198 }
199 
200 _STD_END
201 
202 #endif /* defined (__ICCARM__) */
203 
204 #if defined( __GNUC__ )
205 /* Include stdio.h to pull in __REDLIB_INTERFACE_VERSION__ */
206 #include <stdio.h>
207 
208 #if (__REDLIB_INTERFACE_VERSION__ >= 20000)
209 /* We are using new Redlib_v2 semihosting interface */
210  #define WRITEFUNC __sys_write
211  #define READFUNC __sys_readc
212 #else
213 /* We are using original Redlib semihosting interface */
214  #define WRITEFUNC __write
215  #define READFUNC __readc
216 #endif
217 
218 #if defined(DEBUG)
219 #if defined(DEBUG_SEMIHOSTING)
220 /* Do nothing, semihosting is enabled by default in LPCXpresso */
221 #endif /* defined(DEBUG_SEMIHOSTING) */
222 #endif /* defined(DEBUG) */
223 
224 #if !defined(DEBUG_SEMIHOSTING)
225 int WRITEFUNC(int iFileHandle, char *pcBuffer, int iLength)
226 {
227 #if defined(DEBUG)
228  unsigned int i;
229  for (i = 0; i < iLength; i++) {
230  Board_UARTPutChar(pcBuffer[i]);
231  }
232 #endif
233 
234  return iLength;
235 }
236 
237 /* Called by bottom level of scanf routine within RedLib C library to read
238  a character. With the default semihosting stub, this would read the character
239  from the debugger console window (which acts as stdin). But this version reads
240  the character from the LPC1768/RDB1768 UART. */
241 int READFUNC(void)
242 {
243 #if defined(DEBUG)
244  char c = Board_UARTGetChar();
245  return (int) c;
246 
247 #else
248  return (int) -1;
249 #endif
250 }
251 
252 #endif /* !defined(DEBUG_SEMIHOSTING) */
253 #endif /* defined ( __GNUC__ ) */