Skip to content

Commit 362cb37

Browse files
committed
0.1.1 MCP23S08
1 parent 19572c2 commit 362cb37

File tree

8 files changed

+121
-57
lines changed

8 files changed

+121
-57
lines changed

libraries/MCP23S08/MCP23S08.cpp

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
//
22
// FILE: MCP23S08.cpp
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.1.0
4+
// VERSION: 0.1.1
55
// PURPOSE: Arduino library for SPI MCP23S08 8 channel port expander
66
// DATE: 2022-01-10
77
// URL: https://github.com/RobTillaart/MCP23S08
88

99
//
1010
// HISTORY:
1111
// 0.1.0 2022-01-10 initial version
12+
// 0.1.1 2022-09-28 optimize digitalWrite - most used one only.
13+
// add MCP23S08_REGISTER_ERROR
1214

1315

1416
#include "Arduino.h"
@@ -70,7 +72,7 @@ bool MCP23S08::begin()
7072

7173
if (_hwSPI)
7274
{
73-
// TODO - ESP32 specific support - see MCP_ADC.
75+
// TODO - ESP32 specific support - see MCP_ADC.
7476
mySPI = &SPI;
7577
mySPI->end();
7678
mySPI->begin();
@@ -84,12 +86,12 @@ bool MCP23S08::begin()
8486
::digitalWrite(_clock, LOW);
8587
}
8688

87-
// check connected
89+
// check connected
8890
if (! isConnected()) return false;
8991

90-
// disable address increment (datasheet)
92+
// disable address increment (datasheet)
9193
if (! writeReg(MCP23S08_IOCR, 0b00100000)) return false; // TODO MAGIC NR
92-
// Force INPUT_PULLUP
94+
// Force INPUT_PULLUP
9395
if (! writeReg(MCP23S08_PUR_A, 0xFF)) return false;
9496
return true;
9597
}
@@ -102,9 +104,9 @@ bool MCP23S08::isConnected()
102104
}
103105

104106

105-
// single pin interface
106-
// pin = 0..7
107-
// mode = INPUT, OUTPUT, INPUT_PULLUP (= same as INPUT)
107+
// single pin interface
108+
// pin = 0..7
109+
// mode = INPUT, OUTPUT, INPUT_PULLUP (= same as INPUT)
108110
bool MCP23S08::pinMode(uint8_t pin, uint8_t mode)
109111
{
110112
if (pin > 7)
@@ -125,7 +127,7 @@ bool MCP23S08::pinMode(uint8_t pin, uint8_t mode)
125127
return false;
126128
}
127129
uint8_t mask = 1 << pin;
128-
// only work with valid
130+
// only work with valid
129131
if ((mode == INPUT) || (mode == INPUT_PULLUP))
130132
{
131133
val |= mask;
@@ -134,7 +136,7 @@ bool MCP23S08::pinMode(uint8_t pin, uint8_t mode)
134136
{
135137
val &= ~mask;
136138
}
137-
// other values won't change val ....
139+
// other values won't change val ....
138140
writeReg(dataDirectionRegister, val);
139141
if (_error != MCP23S08_OK)
140142
{
@@ -144,8 +146,8 @@ bool MCP23S08::pinMode(uint8_t pin, uint8_t mode)
144146
}
145147

146148

147-
// pin = 0..7
148-
// value = LOW, HIGH
149+
// pin = 0..7
150+
// value = LOW, HIGH
149151
bool MCP23S08::digitalWrite(uint8_t pin, uint8_t value)
150152
{
151153
if (pin > 7)
@@ -155,6 +157,7 @@ bool MCP23S08::digitalWrite(uint8_t pin, uint8_t value)
155157
}
156158
uint8_t IOR = MCP23S08_GPIO_A;
157159
uint8_t val = readReg(IOR);
160+
uint8_t pre = val;
158161
if (_error != MCP23S08_OK)
159162
{
160163
return false;
@@ -168,10 +171,13 @@ bool MCP23S08::digitalWrite(uint8_t pin, uint8_t value)
168171
{
169172
val &= ~mask;
170173
}
171-
writeReg(IOR, val);
172-
if (_error != MCP23S08_OK)
174+
if (pre != val)
173175
{
174-
return false;
176+
writeReg(IOR, val);
177+
if (_error != MCP23S08_OK)
178+
{
179+
return false;
180+
}
175181
}
176182
return true;
177183
}
@@ -196,8 +202,8 @@ uint8_t MCP23S08::digitalRead(uint8_t pin)
196202
}
197203

198204

199-
// pin = 0..7
200-
// reversed = true or false
205+
// pin = 0..7
206+
// reversed = true or false
201207
bool MCP23S08::setPolarity(uint8_t pin, bool reversed)
202208
{
203209
if (pin > 7)
@@ -248,8 +254,8 @@ bool MCP23S08::getPolarity(uint8_t pin, bool &reversed)
248254
}
249255

250256

251-
// pin = 0..7
252-
// pullup = true or false
257+
// pin = 0..7
258+
// pullup = true or false
253259
bool MCP23S08::setPullup(uint8_t pin, bool pullup)
254260
{
255261
if (pin > 7)
@@ -309,9 +315,10 @@ void MCP23S08::setSPIspeed(uint32_t speed)
309315

310316

311317
///////////////////////////////////////////////////////////////////////
312-
// 8 pins interface
313-
// whole register at once
314-
// value = 0..0xFF bit pattern
318+
//
319+
// 8 pins interface
320+
// whole register at once
321+
// value = 0..0xFF bit pattern
315322
bool MCP23S08::pinMode8(uint8_t value)
316323
{
317324
writeReg(MCP23S08_DDR_A, value);
@@ -335,7 +342,7 @@ int MCP23S08::read8()
335342
}
336343

337344

338-
// mask = 0..0xFF bit pattern
345+
// mask = 0..0xFF bit pattern
339346
bool MCP23S08::setPolarity8(uint8_t mask)
340347
{
341348
writeReg(MCP23S08_POL_A, mask);
@@ -358,7 +365,7 @@ bool MCP23S08::getPolarity8(uint8_t &mask)
358365
}
359366

360367

361-
// mask = 0..0xFF bit pattern
368+
// mask = 0..0xFF bit pattern
362369
bool MCP23S08::setPullup8(uint8_t mask)
363370
{
364371
writeReg(MCP23S08_PUR_A, mask);
@@ -391,7 +398,7 @@ int MCP23S08::lastError()
391398

392399
////////////////////////////////////////////////////
393400
//
394-
// PRIVATE
401+
// PRIVATE
395402
//
396403

397404
bool MCP23S08::writeReg(uint8_t reg, uint8_t value)
@@ -400,7 +407,7 @@ bool MCP23S08::writeReg(uint8_t reg, uint8_t value)
400407

401408
if (reg > MCP23S08_OLAT_A)
402409
{
403-
_error = 0xFF; // TODO MAGIC NR
410+
_error = MCP23S08_REGISTER_ERROR;
404411
return false;
405412
}
406413
::digitalWrite(_select, LOW);
@@ -431,7 +438,7 @@ uint8_t MCP23S08::readReg(uint8_t reg)
431438

432439
if (reg > MCP23S08_OLAT_A)
433440
{
434-
_error = 0xFF; // TODO MAGIC NR
441+
_error = MCP23S08_REGISTER_ERROR;
435442
return false;
436443
}
437444

libraries/MCP23S08/MCP23S08.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// FILE: MCP23S08.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.1.0
5+
// VERSION: 0.1.1
66
// PURPOSE: Arduino library for SPI MCP23S08 8 channel port expander
77
// DATE: 2022-01-10
88
// URL: https://github.com/RobTillaart/MCP23S08
@@ -19,7 +19,7 @@
1919
#define MCP23S08_SPI_ERROR 0x82
2020
#define MCP23S08_VALUE_ERROR 0x83
2121
#define MCP23S08_PORT_ERROR 0x84
22-
22+
#define MCP23S08_REGISTER_ERROR 0xFF
2323

2424
#define MCP23S08_INVALID_READ -100
2525

@@ -34,8 +34,8 @@ class MCP23S08
3434
bool isConnected(); // needed ?
3535

3636

37-
// single pin interface
38-
// mode = INPUT, OUTPUT or INPUT_PULLUP (==INPUT)
37+
// single pin interface
38+
// mode = INPUT, OUTPUT or INPUT_PULLUP (==INPUT)
3939
bool pinMode(uint8_t pin, uint8_t mode);
4040
bool digitalWrite(uint8_t pin, uint8_t value);
4141
uint8_t digitalRead(uint8_t pin);
@@ -46,9 +46,9 @@ class MCP23S08
4646
bool getPullup(uint8_t pin, bool &pullup);
4747

4848

49-
// 8 pins interface
50-
// port = 0..1
51-
// value = bit pattern
49+
// 8 pins interface
50+
// port = 0..1
51+
// value = bit pattern
5252
bool pinMode8(uint8_t value);
5353
bool write8(uint8_t value);
5454
int read8();
@@ -63,7 +63,7 @@ class MCP23S08
6363
void setSPIspeed(uint32_t speed);
6464
uint32_t getSPIspeed() { return _SPIspeed; };
6565

66-
// debugging
66+
// debugging
6767
bool usesHWSPI() { return _hwSPI; };
6868
int lastError();
6969

@@ -79,7 +79,8 @@ class MCP23S08
7979
uint8_t _error = MCP23S08_OK;
8080

8181
bool _hwSPI = false;
82-
uint32_t _SPIspeed = 8000000UL; // 1MHz is a safe value TODO CHECK datasheet
82+
// 1 MHz is a safe value TODO CHECK datasheet
83+
uint32_t _SPIspeed = 8000000UL;
8384
SPIClass * mySPI;
8485
SPISettings _spi_settings;
8586

libraries/MCP23S08/README.md

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ This experimental library gives easy control over the 8 pins of a (SPI) MCP23S08
1818
This IC is strongly related to the MCP23017 I2C port expander - https://github.com/RobTillaart/MCP23017_RT
1919
Programming Interface is kept the same as much as possible.
2020

21+
Since 0.1.1 the **digitalWrite(pin, value)** is optimized.
22+
If a pin is not changed it will not be written again to save time.
23+
2124

2225
## Interface
2326

@@ -31,38 +34,51 @@ Programming Interface is kept the same as much as possible.
3134

3235
### Single pin interface
3336

34-
- **bool pinMode(uint8_t pin, uint8_t mode)** pin = 0..7, mode = INPUT, OUTPUT, returns true if successful.
35-
- **bool digitalWrite(uint8_t pin, uint8_t value)** pin = 0..7, value = LOW(0) HIGH (!0), returns true if successful.
37+
- **bool pinMode(uint8_t pin, uint8_t mode)** pin = 0..7, mode = INPUT, OUTPUT.
38+
Returns true if successful.
39+
- **bool digitalWrite(uint8_t pin, uint8_t value)** pin = 0..7, value = LOW(0) HIGH (!0).
40+
Returns true if successful.
3641
- **uint8_t digitalRead(uint8_t pin)** pin = 0..7, returns LOW or HIGH, might set the lastError();
37-
- **bool setPolarity(uint8_t pin, bool reversed)** pin = 0..7, set reversed flag, returns true if successful.
38-
- **bool getPolarity(uint8_t pin, bool &reversed)** pin = 0..7, reads reversed flag, returns true if successful.
39-
- **bool setPullup(uint8_t pin, bool pullup)** pin = 0..7, set pull-up flag, returns true if successful.
40-
- **bool getPullup(uint8_t pin, bool &pullup)** pin = 0..7, reads pull-up flag, returns true if successful.
42+
- **bool setPolarity(uint8_t pin, bool reversed)** pin = 0..7, set reversed flag.
43+
Returns true if successful.
44+
- **bool getPolarity(uint8_t pin, bool &reversed)** pin = 0..7, reads reversed flag.
45+
Returns true if successful.
46+
- **bool setPullup(uint8_t pin, bool pullup)** pin = 0..7, set pull-up flag.
47+
Returns true if successful.
48+
- **bool getPullup(uint8_t pin, bool &pullup)** pin = 0..7, reads pull-up flag.
49+
Returns true if successful.
4150

4251

4352
### 8 pins interface
4453

45-
- **bool pinMode8(uint8_t value)** value = 0..255, returns true if successful.
46-
- **bool write8(uint8_t value)** value = 0..255, returns true if successful.
54+
- **bool pinMode8(uint8_t value)** value = 0..255. Returns true if successful.
55+
- **bool write8(uint8_t value)** value = 0..255. Returns true if successful.
4756
- **uint8_t read8()** reads 8 pins into one byte.
4857
- **bool setPolarity8(uint8_t mask)** sets polarity for 8 channels at once.
58+
Returns true if successful.
4959
- **bool getPolarity8(uint8_t &mask)** reads polarity of 8 channels at once.
60+
Returns true if successful.
5061
- **bool setPullup8(uint8_t mask)** sets pull-up for 8 channels at once.
62+
Returns true if successful.
5163
- **bool getPullup8(uint8_t &mask)** reads pull-up for 8 channels at once.
64+
Returns true if successful.
5265

5366

5467
### Error codes
5568

69+
If one of the above functions return false, there might be an error.
70+
5671
- **int lastError()** Above functions set an error flag that can be read with this function.
5772
Reading it will reset the flag to **MCP23S08_OK**.
5873

59-
| DESCRIPTION | VALUE |
60-
|:----------------------|:-----:|
61-
| MCP23S08_OK | 0x00 |
62-
| MCP23S08_PIN_ERROR | 0x81 |
63-
| MCP23S08_I2C_ERROR | 0x82 |
64-
| MCP23S08_VALUE_ERROR | 0x83 |
65-
| MCP23S08_PORT_ERROR | 0x84 |
74+
| NAME | VALUE | DESCRIPTION |
75+
|:------------------------|:------:|:------------|
76+
| MCP23S08_OK | 0x00 | No error |
77+
| MCP23S08_PIN_ERROR | 0x81 |
78+
| MCP23S08_SPI_ERROR | 0x82 |
79+
| MCP23S08_VALUE_ERROR | 0x83 |
80+
| MCP23S08_PORT_ERROR | 0x84 |
81+
| MCP23S08_REGISTER_ERROR | 0xFF | low level.
6682

6783

6884
## Operation
@@ -73,4 +89,4 @@ See examples.
7389
## Future
7490

7591
- keep functional in sync with MCP23017_RT
76-
- **isConnected()** is not really needed
92+

libraries/MCP23S08/examples/MCP23S08_digitalWrite/MCP23S08_digitalWrite.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ void setup()
2121

2222
SPI.begin();
2323
bool b = MCP.begin();
24-
// Serial.println(b ? "true" : "false");
24+
Serial.print("BEGIN: ");
25+
Serial.println(b ? "true" : "false");
2526
delay(100);
2627

2728
MCP.pinMode8(0x00); // 0 = output , 1 = input

libraries/MCP23S08/examples/MCP23S08_performance/MCP23S08_performance.ino

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ void setup()
2525

2626
SPI.begin();
2727
bool b = MCP.begin();
28+
Serial.print("BEGIN: ");
29+
Serial.println(b);
2830

2931
Serial.print("HWSPI: ");
3032
Serial.println(MCP.usesHWSPI());
@@ -51,21 +53,23 @@ void setup()
5153
start = micros();
5254
for (int pin = 0; pin < 8; pin++)
5355
{
54-
MCP.digitalWrite(pin, 1 - pin % 2); // alternating HIGH/LOW
56+
MCP.digitalWrite(pin, 1 - pin % 2); // alternating HIGH/LOW
5557
}
5658
stop = micros();
5759
Serial.println((stop - start) / 8.0);
5860

5961

6062
Serial.print("TEST digitalRead(pin):\t");
6163
delay(100);
64+
volatile int val = 0;
6265
start = micros();
6366
for (int pin = 0; pin < 8; pin++)
6467
{
65-
volatile int val = MCP.digitalRead(pin);
68+
val = MCP.digitalRead(pin);
6669
}
6770
stop = micros();
6871
Serial.println((stop - start) / 8.0);
72+
Serial.println(val); // keep build CI compiler happy
6973
Serial.println();
7074

7175

@@ -87,6 +91,7 @@ void setup()
8791
volatile int val8 = MCP.read8();
8892
stop = micros();
8993
Serial.println(stop - start);
94+
Serial.println(val8); // keep build CI compiler happy
9095
Serial.println();
9196

9297
Serial.println("\ndone...");

0 commit comments

Comments
 (0)