Skip to content

Commit f511c3b

Browse files
Added printf ability, so as to easily test code when switching between MCU flavours.
- enabled with #define or -DSTM32F103_USE_LEAN_PRINTF Signed-off-by: Don Prince <minimum-necessary-change@users.noreply.github.com>
1 parent c319794 commit f511c3b

File tree

2 files changed

+323
-0
lines changed

2 files changed

+323
-0
lines changed

STM32F1/cores/maple/Print.cpp

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,316 @@ size_t s=0;
316316
return s;
317317
}
318318

319+
#if defined(STM32F103_USE_LEAN_PRINTF)
320+
//------------------------------------------------
321+
// ref: https://www.stm32duino.com/viewtopic.php?f=18&t=1014&sid=b5b2a990c12312751dbde58f9e3802fb
322+
323+
#ifdef toupper
324+
#undef toupper
325+
#endif
326+
#ifdef tolower
327+
#undef tolower
328+
#endif
329+
#ifdef islower
330+
#undef islower
331+
#endif
332+
#ifdef isdigit
333+
#undef isdigit
334+
#endif
335+
336+
#define toupper(c) ((c)&=0xDF)
337+
#define tolower(c) ((c)|=0x20)
338+
#define islower(c) ((unsigned char)c >= (unsigned char)'a' && (unsigned char)c <= (unsigned char)'z')
339+
#define isdigit(c) ((unsigned char)c >= (unsigned char)'0' && (unsigned char)c <= (unsigned char)'9')
340+
341+
typedef union {
342+
unsigned char byte[5];
343+
long l;
344+
unsigned long ul;
345+
float f;
346+
const char *ptr;
347+
} value_t;
348+
349+
350+
size_t Print::printDigit(unsigned char n, bool lower_case)
351+
{
352+
register unsigned char c = n + (unsigned char)'0';
353+
354+
if (c > (unsigned char)'9') {
355+
c += (unsigned char)('A' - '0' - 10);
356+
if (lower_case)
357+
c += (unsigned char)('a' - 'A');
358+
}
359+
return write(c);
360+
}
361+
362+
static void calculateDigit (value_t* value, unsigned char radix)
363+
{
364+
unsigned long ul = value->ul;
365+
unsigned char* pb4 = &value->byte[4];
366+
unsigned char i = 32;
367+
368+
do {
369+
*pb4 = (*pb4 << 1) | ((ul >> 31) & 0x01);
370+
ul <<= 1;
371+
372+
if (radix <= *pb4 ) {
373+
*pb4 -= radix;
374+
ul |= 1;
375+
}
376+
} while (--i);
377+
value->ul = ul;
378+
}
379+
380+
size_t Print::printf(const char *format, ...)
381+
{
382+
va_list ap;
383+
bool left_justify;
384+
bool zero_padding;
385+
bool prefix_sign;
386+
bool prefix_space;
387+
bool signed_argument;
388+
bool char_argument;
389+
bool long_argument;
390+
bool lower_case;
391+
value_t value;
392+
int charsOutputted;
393+
bool lsd;
394+
395+
unsigned char radix;
396+
unsigned char width;
397+
signed char decimals;
398+
unsigned char length;
399+
char c;
400+
// reset output chars
401+
charsOutputted = 0;
402+
403+
va_start(ap, format);
404+
while( c=*format++ ) {
405+
if ( c=='%' ) {
406+
left_justify = 0;
407+
zero_padding = 0;
408+
prefix_sign = 0;
409+
prefix_space = 0;
410+
signed_argument = 0;
411+
char_argument = 0;
412+
long_argument = 0;
413+
radix = 0;
414+
width = 0;
415+
decimals = -1;
416+
417+
get_conversion_spec:
418+
c = *format++;
419+
420+
if (c=='%') {
421+
charsOutputted+=write(c);
422+
continue;
423+
}
424+
425+
if (isdigit(c)) {
426+
if (decimals==-1) {
427+
width = 10*width + c - '0';
428+
if (width == 0) {
429+
zero_padding = 1;
430+
}
431+
} else {
432+
decimals = 10*decimals + c - '0';
433+
}
434+
goto get_conversion_spec;
435+
}
436+
if (c=='.') {
437+
if (decimals==-1)
438+
decimals=0;
439+
else
440+
; // duplicate, ignore
441+
goto get_conversion_spec;
442+
}
443+
if (islower(c)) {
444+
c = toupper(c);
445+
lower_case = 1;
446+
} else
447+
lower_case = 0;
448+
449+
switch( c ) {
450+
case '-':
451+
left_justify = 1;
452+
goto get_conversion_spec;
453+
case '+':
454+
prefix_sign = 1;
455+
goto get_conversion_spec;
456+
case ' ':
457+
prefix_space = 1;
458+
goto get_conversion_spec;
459+
case 'B': /* byte */
460+
char_argument = 1;
461+
goto get_conversion_spec;
462+
// case '#': /* not supported */
463+
case 'H': /* short */
464+
case 'J': /* intmax_t */
465+
case 'T': /* ptrdiff_t */
466+
case 'Z': /* size_t */
467+
goto get_conversion_spec;
468+
case 'L': /* long */
469+
long_argument = 1;
470+
goto get_conversion_spec;
471+
472+
case 'C':
473+
if( char_argument )
474+
c = va_arg(ap,char);
475+
else
476+
c = va_arg(ap,int);
477+
charsOutputted+=write(c);
478+
break;
479+
480+
case 'S':
481+
value.ptr = va_arg(ap,const char *);
482+
483+
length = strlen(value.ptr);
484+
if ( decimals == -1 ) {
485+
decimals = length;
486+
}
487+
if ( ( !left_justify ) && (length < width) ) {
488+
width -= length;
489+
while( width-- != 0 ) {
490+
charsOutputted+=write(' ');
491+
}
492+
}
493+
494+
while ( (c = *value.ptr) && (decimals-- > 0)) {
495+
charsOutputted+=write(c);
496+
value.ptr++;
497+
}
498+
499+
if ( left_justify && (length < width)) {
500+
width -= length;
501+
while( width-- != 0 ) {
502+
charsOutputted+=write(' ');
503+
}
504+
}
505+
break;
506+
507+
case 'D':
508+
case 'I':
509+
signed_argument = 1;
510+
radix = 10;
511+
break;
512+
513+
case 'O':
514+
radix = 8;
515+
break;
516+
517+
case 'U':
518+
radix = 10;
519+
break;
520+
521+
case 'X':
522+
radix = 16;
523+
break;
524+
525+
default:
526+
// nothing special, just output the character
527+
charsOutputted+=write(c);
528+
break;
529+
}
530+
531+
if (radix != 0) {
532+
unsigned char store[6];
533+
unsigned char *pstore = &store[5];
534+
535+
if (char_argument) {
536+
value.l = va_arg(ap, char);
537+
if (!signed_argument) {
538+
value.l &= 0xFF;
539+
}
540+
} else if (long_argument) {
541+
value.l = va_arg(ap, long);
542+
} else { // must be int
543+
value.l = va_arg(ap, int);
544+
if (!signed_argument) {
545+
value.l &= 0xFFFF;
546+
}
547+
}
548+
549+
if ( signed_argument ) {
550+
if (value.l < 0)
551+
value.l = -value.l;
552+
else
553+
signed_argument = 0;
554+
}
555+
556+
length=0;
557+
lsd = 1;
558+
559+
do {
560+
value.byte[4] = 0;
561+
calculateDigit(&value, radix);
562+
if (!lsd) {
563+
*pstore = (value.byte[4] << 4) | (value.byte[4] >> 4) | *pstore;
564+
pstore--;
565+
} else {
566+
*pstore = value.byte[4];
567+
}
568+
length++;
569+
lsd = !lsd;
570+
} while( value.ul );
571+
if (width == 0) {
572+
// default width. We set it to 1 to output
573+
// at least one character in case the value itself
574+
// is zero (i.e. length==0)
575+
width = 1;
576+
}
577+
/* prepend spaces if needed */
578+
if (!zero_padding && !left_justify) {
579+
while ( width > (unsigned char) (length+1) ) {
580+
charsOutputted+=write(' ');
581+
width--;
582+
}
583+
}
584+
if (signed_argument) { // this now means the original value was negative
585+
charsOutputted+=write('-');
586+
// adjust width to compensate for this character
587+
width--;
588+
} else if (length != 0) {
589+
// value > 0
590+
if (prefix_sign) {
591+
charsOutputted+=write('+');
592+
// adjust width to compensate for this character
593+
width--;
594+
} else if (prefix_space) {
595+
charsOutputted+=write(' ');
596+
// adjust width to compensate for this character
597+
width--;
598+
}
599+
}
600+
/* prepend zeroes/spaces if needed */
601+
if (!left_justify) {
602+
while ( width-- > length ) {
603+
charsOutputted+=write( zero_padding ? '0' : ' ');
604+
}
605+
} else {
606+
/* spaces are appended after the digits */
607+
if (width > length)
608+
width -= length;
609+
else
610+
width = 0;
611+
}
612+
/* output the digits */
613+
while( length-- ) {
614+
lsd = !lsd;
615+
if (!lsd) {
616+
pstore++;
617+
value.byte[4] = *pstore >> 4;
618+
} else {
619+
value.byte[4] = *pstore & 0x0F;
620+
}
621+
charsOutputted+=printDigit(value.byte[4], lower_case);
622+
}
623+
}
624+
} else {
625+
charsOutputted+=write(c);
626+
}
627+
}
628+
va_end(ap);
629+
return (size_t)charsOutputted;
630+
}
631+
#endif

STM32F1/cores/maple/Print.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#include "WString.h"
2828
#include "Printable.h"
2929

30+
#if defined(STM32F103_USE_LEAN_PRINTF)
31+
#include <stdarg.h>
32+
#endif
33+
3034
enum {
3135
BIN = 2,
3236
OCT = 8,
@@ -70,6 +74,9 @@ class Print {
7074
#ifdef SUPPORTS_PRINTF
7175
// Roger Clark. Work in progress to add printf support
7276
int printf(const char * format, ...);
77+
#endif
78+
#if defined(STM32F103_USE_LEAN_PRINTF)
79+
size_t printf(const char * format, ...);
7380
#endif
7481
Print() : write_error(0) {}
7582

@@ -83,6 +90,9 @@ class Print {
8390
int write_error;
8491
size_t printNumber(unsigned long long, uint8);
8592
size_t printFloat(double, uint8);
93+
#if defined(STM32F103_USE_LEAN_PRINTF)
94+
size_t printDigit(unsigned char n, bool lower_case);
95+
#endif
8696
};
8797

8898
#endif

0 commit comments

Comments
 (0)