Skip to content

Commit c1e1fd5

Browse files
committed
add more functions to Wire library, add docs, add examples
- add Wire_end, Wire_setClock, Wire_setTimeout, Wire_requestFrom5, Wire_write_s, Wire_peek, Wire_flush - add all Print functions - polymorph definition for Wire_requestFrom
1 parent 24ff6a7 commit c1e1fd5

19 files changed

Lines changed: 382 additions & 82 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212
- Support for Sduino MB board (mb208)
1313
- Unlocking a MCU by using Tools->Burn Bootloader in the Arduino IDE
1414
- new library LiquidCrystal_pcf2119 for I2C text LCD based on the PCF2119
15+
- new library Wire for I2C communication
1516

1617
### Changed
1718
- completed I2C library, master transmit and master receive modes work

docs/api/I2C.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ mangeling was needed to distinguish the different variant of the `read()`
1919
and `write()` method. Apart from this replacing the dots in the method names
2020
for underscores is all it needs.
2121

22-
The pullup setting is missing because this function is supported by the STM8
23-
hardware.
22+
The pullup setting is missing because this function is not supported by the
23+
STM8 hardware.
2424

2525

2626
Arduino syntax |sduino syntax

docs/api/Wire.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Wire
2+
3+
This is an improved version of the stock Arduino Wire library for I2C
4+
communication. It shares most of the hardware related code with the re-write
5+
of the [Sduino I2C library](I2C.md), but holds on to the Arduino API.
6+
7+
The main difference between this STM8 version and the Arduino AVR version is
8+
the existance of a timeout function to prevent deadlocks due to failed
9+
communication. Polling mode is used for communication, interrupts are not
10+
supported (yet).
11+
12+
So far, only Master Transmit and Master Receive modes are supported, slave
13+
modes are not implemented yet.
14+
15+
16+
## API
17+
18+
This is a pre-instantiated singleton library. It is not possible to use more
19+
than one instance per sketch or to change the instance name.
20+
21+
The API syntax is very similar to the original C++ syntax. Some name
22+
mangeling was needed to distinguish the different variants of the `write()`
23+
method. Apart from this replacing the dots in the method names for
24+
underscores is all it needs.
25+
26+
27+
28+
Arduino syntax |sduino syntax |real function name
29+
-------------------- |--------------------- |-------------
30+
`Wire.begin()` |`Wire_begin()` |same
31+
`Wire.begin(ownaddress)` |slave mode not supported yet|-
32+
`Wire.end()` |`Wire_end()` |same
33+
`Wire.setClock(clock)` |`Wire_setClock(clock)` |same
34+
not implemented |`Wire_timeOut(millisec)` |same
35+
`Wire.beginTransmission(addr)` |`Wire_beginTransmission(addr)` |same
36+
n = `Wire.endTransmission()` |n = `Wire_endTransmission()` |same (inline)
37+
n = `Wire.endTransmission(stop)` |n = `Wire_endTransmission1(stop)`|same
38+
`Wire.write(val)` |`Wire_write(val)` |same
39+
`Wire.write(*str)` |`Wire_write_s(*str)` |same
40+
`Wire.write(*data, len)` |`Wire_write_sn(*data, len)` |same
41+
`n = Wire.available()` |`n = Wire_available()` |same
42+
`val = Wire.read()` |`val = Wire_read()` |same
43+
`Wire.flush()` |`Wire_flush()` |same
44+
`val = Wire.peek()` |`val = Wire_peek()` |same
45+
`Wire.requestFrom(addr, n)` |`Wire_requestFrom(addr, n)` |`Wire_requestFrom2`
46+
`Wire.requestFrom(addr, n, sendStop)` |`Wire_requestFrom(addr, n, sendStop)` |`Wire_requestFrom3`
47+
`Wire.requestFrom(addr, n, iaddr, isize, sendStop)`|`Wire_requestFrom(addr, n, iaddr, isize, sendStop)` |`Wire_requestFrom5`
48+
`Wire.print(*str)` |`Wire_print_s(*str)` |`Print_print_s(Write_write1,*str)`
49+
`Wire.print(*data,len)` |`Wire_print_sn(*data,len)` |`Print_print_sn(Write_write1,*data,len)`
50+
`Wire.print(long)` |`Wire_print_i(long)` |`Print_print_i(Write_write1,long)`
51+
`Wire.print(ulong)` |`Wire_print_u(ulong)` |`Print_print_u(Write_write1,ulong)`
52+
`Wire.print(long,base)` |`Wire_print_ib(long,base)` |`Print_print_ib(Write_write1,long,base)`
53+
`Wire.print(ulong,base)`|`Wire_print_ub(ulong,base)` |`Print_print_ub(Write_write1,ulong,base)`
54+
`Wire.print(double)` |`Wire_print_f(float)` |`Print_print_f(Write_write1,float)`
55+
`Wire.print(double,dig)`|`Wire_print_f(float,dig)` |`Print_print_fd(Write_write1,float,dig)`
56+
`Wire.println()` |`Wire_println()` |`Print_println(Write_write1)`
57+
`Wire.println(*str)` |`Wire_println_s(*str)` |`Print_println_s(Write_write1,*str)`
58+
`Wire.println(*data,len)`|`Wire_println_sn(*data,len)` |`Print_println_sn(Write_write1,*data,len)`
59+
`Wire.println(long)` |`Wire_println_i(long)` |`Print_println_i(Write_write1,long)`
60+
`Wire.println(ulong)` |`Wire_println_u(ulong)` |`Print_println_u(Write_write1,ulong)`
61+
`Wire.println(long,base)`|`Wire_println_ib(long,base)` |`Print_println_ib(Write_write1,long,base)`
62+
`Wire.println(ulong,base)`|`Wire_println_ub(ulong,base)`|`Print_println_ub(Write_write1,ulong,base)`
63+
`Wire.println(double)` |`Wire_println_f(float)` |`Print_println_f(Write_write1,float)`
64+
`Wire.println(double,dig)`|`Wire_println_f(float,dig)` |`Print_println_fd(Write_write1,float,dig)`
65+
66+
67+
Please note the polymorphism of the `Wire_requestFrom()` method. This is a
68+
special case and only possible for pre-instantiated singleton libraries.
69+
70+
Due to the way sdcc invokes the preprocessor sdcpp the same trick doesn't
71+
work for functions without arguments - so we still need
72+
`Wire_endTransmission()` and `Wire_endTransmission1(stop)`. Hopefully, this
73+
inconsistency does not spread more confusion than it is worth.
74+
75+
76+
## Timeout
77+
78+
The timeout functionality was added for the Sduino port and is not part of
79+
the original library. The maximum transmission length is limited by the size
80+
of the data buffer of 32 bytes. At 100kHz this would take aprox. 3ms (1
81+
address byte, 32 data bytes, 1 ACK bit after every byte).
82+
83+
The default timeout is set to 20ms, that should work for most cases. If
84+
using a very slow device, the timeout can be changed using the
85+
`Wire_setTimeout()` function any time after initialzing the library by
86+
calling `Wire_begin()`. The timeout is defined in ms, so the maximum value
87+
for this 16 bit value represents about 65s - more than a minute.
88+
89+
The value zero disables the timeout feature.
90+
91+
92+
## Further reading
93+
94+
Programming the I2C communication on the register level is quite complex for
95+
the STM8, especially in receive mode. The most detailed information on this
96+
topic is the
97+
98+
- application note AN3281 bundeled with
99+
- the related source code package [STSW-STM8004](https://www.st.com/en/embedded-software/stsw-stm8004.html)
100+
101+
Downloading from the ST website requires a (free) registration. Somebody
102+
uploaded the full package to a [github
103+
repository](https://github.com/jiaohaitao/stsw-stm8004)
104+
105+
There are some important notes on I2C implementation in the errata sheets:
106+
107+
- [STM8S001J3/003xx/103xx/903xx Errata sheet, rev. 5
108+
(CD00265449)](https://www.st.com/content/ccc/resource/technical/document/errata_sheet/c9/f9/ef/bf/63/91/4a/1f/CD00265449.pdf/files/CD00265449.pdf/jcr:content/translations/en.CD00265449.pdf)
109+
- [STM8S005xx STM8S105xx Errata sheet, rev. 7
110+
(CD00270741)](https://www.st.com/content/ccc/resource/technical/document/errata_sheet/e3/c3/4e/24/0c/ca/4b/e7/CD00270741.pdf/files/CD00270741.pdf/jcr:content/translations/en.CD00270741.pdf)
111+
- [STM8S007xx STM8S20xxx Errata sheet, rev. 6
112+
(CD00244749)](https://www.st.com/content/ccc/resource/technical/document/errata_sheet/7a/94/8f/fe/84/14/41/6d/CD00244749.pdf/files/CD00244749.pdf/jcr:content/translations/en.CD00244749.pdf)

docs/developer/macro.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,9 @@ function pointer to the write function, that should be used.
231231
* include a pointer to the output write function with the parameter list of
232232
every (aliased) print function call.
233233
234+
235+
## Further reading
236+
237+
Polymorphism relies on variadic macros. Daniel Hardman wrote a very
238+
understandable [step-by-step
239+
introduction](https://codecraft.co/2014/11/25/variadic-macros-tricks/).

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ nav:
1818
- Print: api/Print.md
1919
- HardwareSerial: api/HardwareSerial.md
2020
- SPI: api/SPI.md
21+
- Wire: api/Wire.md
2122
- I2C: api/I2C.md
2223
- LiquidCrystal character LCD library: api/LiquidCrystal.md
2324
- LiquidCrystal_I2C character LCD connected via I2C backpack boards: api/LiquidCrystal_I2C.md

sduino/hardware/sduino/stm8/cores/sduino/Arduino.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void yield(void);
128128
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
129129
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
130130

131+
#define byte(w) ((uint8_t)(w))
131132
#define lowByte(w) ((uint8_t) ((w) & 0xff))
132133
#define highByte(w) ((uint8_t) ((w) >> 8))
133134

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
BOARD_TAG = stm8sblue
2+
3+
include ../../../../../../../sduino.mk

sduino/hardware/sduino/stm8/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,48 @@
55
// Demonstrates use of the Wire library reading data from the
66
// Devantech Utrasonic Rangers SFR08 and SFR10
77

8+
// Adapted to plain C for SDunio by M. Mayer 29 November 2018
89
// Created 29 April 2006
910

1011
// This example code is in the public domain.
1112

12-
1313
#include <Wire.h>
1414

1515
void setup() {
16-
Wire.begin(); // join i2c bus (address optional for master)
17-
Serial.begin(9600); // start serial communication at 9600bps
16+
Wire_begin(); // join i2c bus (address optional for master)
17+
Serial_begin(9600); // start serial communication at 9600bps
1818
}
1919

2020
int reading = 0;
2121

2222
void loop() {
2323
// step 1: instruct sensor to read echoes
24-
Wire.beginTransmission(112); // transmit to device #112 (0x70)
24+
Wire_beginTransmission(112); // transmit to device #112 (0x70)
2525
// the address specified in the datasheet is 224 (0xE0)
2626
// but i2c adressing uses the high 7 bits so it's 112
27-
Wire.write(byte(0x00)); // sets register pointer to the command register (0x00)
28-
Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50)
27+
Wire_write(byte(0x00)); // sets register pointer to the command register (0x00)
28+
Wire_write(byte(0x50)); // command sensor to measure in "inches" (0x50)
2929
// use 0x51 for centimeters
3030
// use 0x52 for ping microseconds
31-
Wire.endTransmission(); // stop transmitting
31+
Wire_endTransmission(); // stop transmitting
3232

3333
// step 2: wait for readings to happen
3434
delay(70); // datasheet suggests at least 65 milliseconds
3535

3636
// step 3: instruct sensor to return a particular echo reading
37-
Wire.beginTransmission(112); // transmit to device #112
38-
Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02)
39-
Wire.endTransmission(); // stop transmitting
37+
Wire_beginTransmission(112); // transmit to device #112
38+
Wire_write(byte(0x02)); // sets register pointer to echo #1 register (0x02)
39+
Wire_endTransmission(); // stop transmitting
4040

4141
// step 4: request reading from sensor
42-
Wire.requestFrom(112, 2); // request 2 bytes from slave device #112
42+
Wire_requestFrom(112, 2); // request 2 bytes from slave device #112
4343

4444
// step 5: receive reading from sensor
45-
if (2 <= Wire.available()) { // if two bytes were received
46-
reading = Wire.read(); // receive high byte (overwrites previous reading)
45+
if (2 <= Wire_available()) { // if two bytes were received
46+
reading = Wire_read(); // receive high byte (overwrites previous reading)
4747
reading = reading << 8; // shift high byte to be high 8 bits
48-
reading |= Wire.read(); // receive low byte as lower 8 bits
49-
Serial.println(reading); // print the reading
48+
reading |= Wire_read(); // receive low byte as lower 8 bits
49+
Serial_println_u(reading); // print the reading
5050
}
5151

5252
delay(250); // wait a bit since people have to read the output :)
@@ -60,25 +60,25 @@ void loop() {
6060
6161
void changeAddress(byte oldAddress, byte newAddress)
6262
{
63-
Wire.beginTransmission(oldAddress);
64-
Wire.write(byte(0x00));
65-
Wire.write(byte(0xA0));
66-
Wire.endTransmission();
67-
68-
Wire.beginTransmission(oldAddress);
69-
Wire.write(byte(0x00));
70-
Wire.write(byte(0xAA));
71-
Wire.endTransmission();
72-
73-
Wire.beginTransmission(oldAddress);
74-
Wire.write(byte(0x00));
75-
Wire.write(byte(0xA5));
76-
Wire.endTransmission();
77-
78-
Wire.beginTransmission(oldAddress);
79-
Wire.write(byte(0x00));
80-
Wire.write(newAddress);
81-
Wire.endTransmission();
63+
Wire_beginTransmission(oldAddress);
64+
Wire_write(byte(0x00));
65+
Wire_write(byte(0xA0));
66+
Wire_endTransmission();
67+
68+
Wire_beginTransmission(oldAddress);
69+
Wire_write(byte(0x00));
70+
Wire_write(byte(0xAA));
71+
Wire_endTransmission();
72+
73+
Wire_beginTransmission(oldAddress);
74+
Wire_write(byte(0x00));
75+
Wire_write(byte(0xA5));
76+
Wire_endTransmission();
77+
78+
Wire_beginTransmission(oldAddress);
79+
Wire_write(byte(0x00));
80+
Wire_write(newAddress);
81+
Wire_endTransmission();
8282
}
8383
8484
*/

sduino/hardware/sduino/stm8/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@
55
// Demonstrates use of the Wire library
66
// Controls AD5171 digital potentiometer via I2C/TWI
77

8+
// Adapted to plain C for SDunio by M. Mayer 27 November 2018
89
// Created 31 March 2006
910

1011
// This example code is in the public domain.
1112

12-
// This example code is in the public domain.
13-
1413

1514
#include <Wire.h>
1615

@@ -33,4 +32,3 @@ void loop() {
3332
}
3433
delay(500);
3534
}
36-
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
BOARD_TAG = stm8sblue
2+
3+
include ../../../../../../../sduino.mk

0 commit comments

Comments
 (0)