Skip to content

Commit 416b696

Browse files
committed
activate float support with Print
1 parent 84ad83b commit 416b696

7 files changed

Lines changed: 178 additions & 85 deletions

File tree

docs/index.md

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ Arduino libraries porting parts of the Arduino environment was the logical
2222
first step. After doing that porting the firmware was finished in a
2323
couple of days.
2424

25-
This whole thing is far from being a finished product. It is in alpha stage,
26-
but still already useful. It solved its purpose for me, it might me useful
27-
for others as well. The documentation is incomplete and written in a wild
28-
mix of English and German, but hopefully you can still figure it out.
29-
3025
All you need to get stated is a simple STM8S103F breakout board and a
3126
ST-Link V2 compatible flash programmer. Three boards and one flash
3227
programmer together are available for well under five dollars on
@@ -181,23 +176,23 @@ protocol for the STM32 CPUs.
181176

182177
Pinout of Chinese ST-Link V2-clone with green plasic housing:
183178

184-
+-----+
185-
T_JRST | 1 2| 3V3
186-
5V | 3 4| T_JTCK/T_SWCLK
187-
SWIM 5 6| T_JTMS/T_SWDIO
188-
GND | 7 8| T_JTDO
189-
SWIM RST| 9 10| T_JTDI
190-
+-----+
179+
+-----+
180+
T_JRST | 1 2| 3V3
181+
5V | 3 4| T_JTCK/T_SWCLK
182+
SWIM 5 6| T_JTMS/T_SWDIO
183+
GND | 7 8| T_JTDO
184+
SWIM RST| 9 10| T_JTDI
185+
+-----+
191186

192187
Pinout of Chinese ST-Link V2-clone with metal housing:
193188

194-
+-----+
195-
RST | 1 2| SWDIO
196-
GND | 3 4| GND
197-
SWIM 5 6| SWCLK
198-
3V3 | 7 8| 3V3
199-
5V | 9 10| 5V
200-
+-----+
189+
+-----+
190+
RST | 1 2| SWDIO
191+
GND | 3 4| GND
192+
SWIM 5 6| SWCLK
193+
3V3 | 7 8| 3V3
194+
5V | 9 10| 5V
195+
+-----+
201196

202197
For Linux: required lines in /etc/udev/rules.d/99-stlink.rules:
203198

@@ -215,7 +210,7 @@ For Linux: required lines in /etc/udev/rules.d/99-stlink.rules:
215210
The pinout of the SWIM connector P3 on my board fits the pinout of the flash
216211
tool in the metal housing perfectly:
217212

218-
| STM8-Board | SWIM-Verbinder P3
213+
| STM8 board | SWIM connector P3
219214
| ---------- | -----------------
220215
| 1 | 3V3
221216
| 2 | SWIM (PD1)
@@ -331,6 +326,30 @@ of timers: the library can control 12 servos using only 1 timer.
331326

332327

333328

329+
## Float arithmetics
330+
331+
Floating point arithmetics is supported by the SDCC standard library, but it
332+
comes at a pretty high cost in terms of code space and CPU load. This is how
333+
much the generated code grows by add one single float operation instead of
334+
using a long int:
335+
336+
Floating point operation |approx. code size
337+
-------------------- |---------
338+
addition | 736 Bytes
339+
subtraction | 754 Bytes
340+
division | 673 Bytes
341+
multiplication | 907 Bytes
342+
sinf() or cosf() | 3346 Bytes
343+
log10f() | 3437 Bytes
344+
345+
The Arduino standard example '01. Basics/ReadAnalogVoltage' does not much,
346+
it already occupies 7336 bytes. A similar sketch using integer arithmetics
347+
result in only 3791 bytes.
348+
349+
Float does work, but better try to avoid it and use fixed point arithmetics
350+
whenever possible.
351+
352+
334353

335354
## Current status and to-do list
336355

sduino/hardware/sduino/stm8/cores/sduino/HardwareSerial.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,16 @@ void HardwareSerial_end(void);
9494
#define Serial_print_ib(I,B) Print_print_ib(HardwareSerial_write,I,B)
9595
#define Serial_print_ub(U,B) Print_print_ub(HardwareSerial_write,U,B)
9696

97+
// print float value
98+
#define Serial_print_f(F) Print_printFloat(HardwareSerial_write,F,2)
99+
#define Serial_printFloat(F,D) Print_printFloat(HardwareSerial_write,F,D)
97100

98101
#define Serial_println() Print_println(HardwareSerial_write)
99102
#define Serial_println_s(S) Print_println_s(HardwareSerial_write,S)
100103
#define Serial_println_u(U) Print_println_u(HardwareSerial_write,U)
101104
#define Serial_println_i(I) Print_println_i(HardwareSerial_write,I)
102-
103-
// float (not implemented yet)
104-
#define Serial_print_f(F,D) Print_print_f(HardwareSerial_write,F,D)
105+
#define Serial_println_f(F) Print_printlnFloat(HardwareSerial_write,F,2)
106+
#define Serial_printlnFloat(F,D) Print_printlnFloat(HardwareSerial_write,F,D)
105107

106108

107109
#endif
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
Print.c - Base class that provides print() and println()
3+
Copyright (c) 2008 David A. Mellis. All right reserved.
4+
5+
The float functions are moved to a separate file Print-float.c. This way
6+
we can keep the linker from pulling in all the float functions even when no
7+
floats are used in the sketch.
8+
9+
This library is free software; you can redistribute it and/or
10+
modify it under the terms of the GNU Lesser General Public
11+
License as published by the Free Software Foundation; either
12+
version 2.1 of the License, or (at your option) any later version.
13+
14+
This library is distributed in the hope that it will be useful,
15+
but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+
Lesser General Public License for more details.
18+
19+
You should have received a copy of the GNU Lesser General Public
20+
License along with this library; if not, write to the Free Software
21+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22+
23+
Modified 23 November 2006 by David A. Mellis
24+
Modified 03 August 2015 by Chuck Todd
25+
Modified 30 December 2016 by Michael Mayer
26+
*/
27+
28+
#ifdef _GCC_
29+
#include <stdint.h>
30+
#include <stdio.h>
31+
#define PROGMEM
32+
#endif
33+
34+
//#include <stdlib.h>
35+
//#include <stdio.h>
36+
//#include <string.h>
37+
#include <math.h>
38+
#include "Arduino.h"
39+
40+
#include "Print.h"
41+
42+
#ifdef _GCC_
43+
#undef printChr
44+
#define printChr(C) putchar(C)
45+
#endif
46+
47+
48+
// Public Methods //////////////////////////////////////////////////////////////
49+
50+
51+
size_t Print_printFloat(writefunc_p writefunc, double number, uint8_t digits)
52+
{
53+
size_t n = 0;
54+
uint8_t i;
55+
unsigned long int_part;
56+
double remainder, rounding;
57+
unsigned int toPrint;
58+
59+
if (isnan(number)) return printStr(writefunc,"nan");
60+
if (isinf(number)) return printStr(writefunc,"inf");
61+
if (number > 4294967040.0) return printStr (writefunc,"ovf"); // constant determined empirically
62+
if (number <-4294967040.0) return printStr (writefunc,"ovf"); // constant determined empirically
63+
64+
// Handle negative numbers
65+
if (number < 0.0)
66+
{
67+
n += writefunc('-');
68+
number = -number;
69+
}
70+
71+
// Round correctly so that print(1.999, 2) prints as "2.00"
72+
rounding = 0.5;
73+
for (i=0; i<digits; ++i)
74+
rounding /= 10.0;
75+
76+
number += rounding;
77+
78+
// Extract the integer part of the number and print it
79+
int_part = (unsigned long)number;
80+
remainder = number - (double)int_part;
81+
n += printNumber(writefunc,int_part,10);
82+
83+
// Print the decimal point, but only if there are digits beyond
84+
if (digits > 0) {
85+
n += writefunc('.');
86+
}
87+
88+
// Extract digits from the remainder one at a time
89+
while (digits-- > 0)
90+
{
91+
remainder *= 10.0;
92+
toPrint = (unsigned int)(remainder);
93+
n += printNumber(writefunc,toPrint,10);
94+
remainder -= toPrint;
95+
}
96+
97+
return n;
98+
}
99+
100+
101+
size_t Print_printlnFloat(writefunc_p writefunc, double number, uint8_t digits)
102+
{
103+
size_t r;
104+
105+
r = Print_printFloat(writefunc, number, digits);
106+
return r + Print_println(writefunc);
107+
}
108+

sduino/hardware/sduino/stm8/cores/sduino/Print.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
/*
2-
Print.cpp - Base class that provides print() and println()
2+
Print.c - Base class that provides print() and println()
33
Copyright (c) 2008 David A. Mellis. All right reserved.
4-
4+
5+
The float functions are moved to a separate file Print-float.c. This way
6+
we can keep the linker from pulling in all the float functions even when no
7+
floats are used in the sketch.
8+
59
This library is free software; you can redistribute it and/or
610
modify it under the terms of the GNU Lesser General Public
711
License as published by the Free Software Foundation; either
@@ -18,6 +22,7 @@
1822
1923
Modified 23 November 2006 by David A. Mellis
2024
Modified 03 August 2015 by Chuck Todd
25+
Modified 30 December 2016 by Michael Mayer
2126
*/
2227

2328
#ifdef _GCC_

sduino/hardware/sduino/stm8/cores/sduino/Print.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,15 @@ size_t Print_print_ib(writefunc_p writefunc, long n, uint8_t base);
6161
size_t Print_print_ub(writefunc_p writefunc, unsigned long n, uint8_t base);
6262

6363
// print float values
64-
//size_t Print_print_f(writefunc_p writefunc, double number, uint8_t digits);
64+
size_t Print_printFloat(writefunc_p writefunc, double number, uint8_t digits);
6565

6666

6767
// Variants of the above with a newline added at the and:
6868
size_t Print_println(writefunc_p writefunc);
6969
size_t Print_println_s(writefunc_p writefunc, const char *str);
7070
size_t Print_println_u(writefunc_p writefunc, unsigned long n);
7171
size_t Print_println_i(writefunc_p writefunc, long n);
72+
size_t Print_printlnFloat(writefunc_p writefunc, double number, uint8_t digits);
7273

7374

7475
#endif

sduino/hardware/sduino/stm8/cores/sduino/Serial.h

Lines changed: 8 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -17,66 +17,16 @@
1717

1818
// Public Methods //////////////////////////////////////////////////////////////
1919

20-
/*
21-
#define Serial_begin(B) HardwareSerial_begin(B)
22-
#define Serial_begin_config(B,C) HardwareSerial_begin_config((B),(C))
23-
24-
#define Serial_available(X) HardwareSerial_available(X)
25-
#define Serial_read(X) HardwareSerial_read(X)
26-
#define Serial_write(X) HardwareSerial_write(X)
27-
#define Serial_flush(X) HardwareSerial_flush(X)
28-
29-
#define Serial_end(X) HardwareSerial_end(X)
30-
31-
// the more sophisticated Arduino-Style functions:
32-
33-
// variants of the standard Serial.print() function: Separate impementations
34-
// for string, char, unsigned, signed int
35-
#define Serial_print_s(S) printStr(HardwareSerial_write,S)
36-
#define Serial_print_c(C) HardwareSerial_write(C)
37-
#define Serial_print_u(X) Print_print_u(HardwareSerial_write,X)
38-
#define Serial_print_i(X) Print_print_i(HardwareSerial_write,X)
39-
#define Serial_print_ub(U,B) Print_print_ub(HardwareSerial_write,U,B)
40-
#define Serial_print_ib(I,B) Print_print_ib(HardwareSerial_write,I,B)
41-
42-
#define Serial_println() Print_println(HardwareSerial_write)
43-
#define Serial_println_s(S) Print_println_s(HardwareSerial_write,S)
44-
#define Serial_println_u(X) Print_println_u(X)
45-
#define Serial_println_i(X) Print_println_i(X)
46-
//#define Serial_println_ub(U,B) Print_println_ub(U,B)
47-
//#define Serial_println_ib(I,B) Print_println_ib(I,B)
48-
*/
49-
5020
// Alias Definitions for a more Arduino-like look ////////////////////////////
51-
#if 0
52-
#define Serial_begin HardwareSerial_begin
53-
#define Serial_begin_config HardwareSerial_begin_config
54-
#define Serial_available HardwareSerial_available
55-
#define Serial_read HardwareSerial_read
56-
#define Serial_write HardwareSerial_write
57-
#define Serial_flush HardwareSerial_flush
58-
#define Serial_end HardwareSerial_end
59-
60-
// variants of the standard Serial.print() function: Separate implementations
61-
// for string, char, unsigned, signed int
62-
#define Serial_print_s(S) printStr(HardwareSerial_write,S)
63-
#define Serial_print_c(C) HardwareSerial_write(C)
64-
65-
// print signed/unsigned integer values (char, short, int, long) as decimal values
66-
#define Serial_print_i(I) Print_print_i(HardwareSerial_write,I)
67-
#define Serial_print_u(U) Print_print_u(HardwareSerial_write,U)
68-
69-
// print signed/unsigned integer values (char, short, int, long) to base B
70-
#define Serial_print_ib(I,B) printInt(HardwareSerial_write,I,B)
71-
#define Serial_print_ub(U,B) printNumber(HardwareSerial_write,U,B)
7221

22+
/*
23+
* all empty.
24+
*
25+
* so far, the alias definitions are done in HardwareSerial and not here.
26+
* This file is supposed to be a kind of intermediate switch to choose the
27+
* serial module depending on the configured CPU.
28+
*
29+
*/
7330

74-
#define Serial_println() Print_println(HardwareSerial_write)
75-
#define Serial_println_s(S) Print_println_s(HardwareSerial_write,S)
76-
#define Serial_println_u(U) Print_println_u(HardwareSerial_write,U)
77-
#define Serial_println_i(I) Print_println_i(HardwareSerial_write,I)
7831

79-
// float (not implemented yet)
80-
#define Serial_print_f(F,D) Print_printFloat(HardwareSerial_write,F,D)
81-
#endif
8232
#endif

sduino/hardware/sduino/stm8/cores/sduino/xmacro.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@
7373
// case 2: single instance, using a constructor
7474
//
7575
// No instance identifier required, only function name alias are needed.
76+
//
77+
// name scheme: INSTANCE_NAME(...) -> CLASS_NAME(...)
78+
// example: Serial_begin(baud) -> HardwareSerial_begin(baud)
7679

7780
// simple method without arguments
7881
#define X2Method0(class,instance,name) inline \
@@ -204,10 +207,15 @@
204207
Xprinthelper1 (class,instance,print_u,unsigned long) \
205208
Xprinthelper2 (class,instance,print_ib,long,uint8_t) \
206209
Xprinthelper2 (class,instance,print_ub,unsigned long,uint8_t) \
210+
Xprinthelper1 (class,instance,print_f,double) \
211+
Xprinthelper2 (class,instance,printFloat,double,uint8_t) \
207212
Xprinthelper0 (class,instance,println) \
208213
Xprinthelper1 (class,instance,println_s,const char*) \
209214
Xprinthelper1 (class,instance,println_i,long) \
210-
Xprinthelper1 (class,instance,println_u,unsigned long)
215+
Xprinthelper1 (class,instance,println_u,unsigned long) \
216+
Xprinthelper1 (class,instance,println_f,double)
217+
Xprinthelper2 (class,instance,printFloatln,double,uint8_t)
218+
211219

212220

213221

0 commit comments

Comments
 (0)