2 * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright notice, this list
10 * of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice, this
13 * list of conditions and the following disclaimer in the documentation and/or other
14 * materials provided with the distribution.
16 * Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
17 * contributors may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
26 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
39 #include "build/build_config.h"
41 #include "common/utils.h"
43 #include "drivers/serial.h"
44 #include "io/serial.h"
48 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
49 #include "typeconversion.h"
52 static serialPort_t
*printfSerialPort
;
54 #ifdef REQUIRE_CC_ARM_PRINTF_SUPPORT
56 typedef void (*putcf
) (void *, char);
57 static putcf stdout_putf
;
58 static void *stdout_putp
;
60 // print bf, padded from left to at least n characters.
61 // padding is zero ('0') if z!=0, space (' ') otherwise
62 static int putchw(void *putp
, putcf putf
, int n
, char z
, char *bf
)
65 char fc
= z
? '0' : ' ';
71 putf(putp
, fc
); written
++;
73 while ((ch
= *bf
++)) {
74 putf(putp
, ch
); written
++;
79 // retrun number of bytes written
80 int tfp_format(void *putp
, putcf putf
, const char *fmt
, va_list va
)
86 while ((ch
= *(fmt
++))) {
88 putf(putp
, ch
); written
++;
91 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
100 if (ch
>= '0' && ch
<= '9') {
101 ch
= a2i(ch
, &fmt
, 10, &w
);
103 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
113 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
115 uli2a(va_arg(va
, unsigned long int), 10, 0, bf
);
118 ui2a(va_arg(va
, unsigned int), 10, 0, bf
);
119 written
+= putchw(putp
, putf
, w
, lz
, bf
);
123 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
125 li2a(va_arg(va
, unsigned long int), bf
);
128 i2a(va_arg(va
, int), bf
);
129 written
+= putchw(putp
, putf
, w
, lz
, bf
);
134 #ifdef REQUIRE_PRINTF_LONG_SUPPORT
136 uli2a(va_arg(va
, unsigned long int), 16, (ch
== 'X'), bf
);
139 ui2a(va_arg(va
, unsigned int), 16, (ch
== 'X'), bf
);
140 written
+= putchw(putp
, putf
, w
, lz
, bf
);
143 putf(putp
, (char) (va_arg(va
, int))); written
++;
146 written
+= putchw(putp
, putf
, w
, 0, va_arg(va
, char *));
149 putf(putp
, ch
); written
++;
152 *va_arg(va
, int*) = written
;
163 void init_printf(void *putp
, void (*putf
) (void *, char))
169 int tfp_printf(const char *fmt
, ...)
173 int written
= tfp_format(stdout_putp
, stdout_putf
, fmt
, va
);
175 while (!isSerialTransmitBufferEmpty(printfSerialPort
));
179 static void putcp(void *p
, char c
)
181 *(*((char **) p
))++ = c
;
184 int tfp_sprintf(char *s
, const char *fmt
, ...)
189 int written
= tfp_format(&s
, putcp
, fmt
, va
);
196 static void _putc(void *p
, char c
)
199 serialWrite(printfSerialPort
, c
);
202 void printfSupportInit(void)
204 init_printf(NULL
, _putc
);
209 // keil/armcc version
210 int fputc(int c
, FILE *f
)
212 // let DMA catch up a bit when using set or dump, we're too fast.
213 while (!isSerialTransmitBufferEmpty(printfSerialPort
));
214 serialWrite(printfSerialPort
, c
);
218 void printfSupportInit(void)
224 void setPrintfSerialPort(serialPort_t
*serialPort
)
226 printfSerialPort
= serialPort
;