Skip to content

Commit

Permalink
fix #19, improve support multi device (#21)
Browse files Browse the repository at this point in the history
- add ESP32 HSPI / VSPI support (Kudo's to Alex Uta, PR #22)
  - add **performance_0.2.4.md** for ESP32
- add example **MCP23S17_two_SELECT.ino** (#19)
- add example **MCP23S17_two_ADDRESS.ino** (#19)
- add **void enableHardwareAddress()** (#19)
- add **void disableHardwareAddress()** (#19)
- add keywords.txt (#20)
- update readme.md
- minor edits
  • Loading branch information
RobTillaart authored Aug 14, 2023
1 parent bba8f62 commit 228b1bd
Show file tree
Hide file tree
Showing 15 changed files with 489 additions and 71 deletions.
23 changes: 22 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,63 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.2.5] - 2023-07-31

- add ESP32 HSPI / VSPI support (Kudo's to Alex Uta, PR #22)
- add **performance_0.2.4.md** for ESP32
- add example **MCP23S17_two_SELECT.ino** (#19)
- add example **MCP23S17_two_ADDRESS.ino** (#19)
- add **void enableHardwareAddress()** (#19)
- add **void disableHardwareAddress()** (#19)
- add keywords.txt (#20)
- update readme.md
- minor edits


## [0.2.4] - 2023-02-04

- update readme.md
- update GitHub actions
- update license 2023


## [0.2.3] - 2022-10-20

- add CHANGELOG.md
- add **enableControlRegister(uint8_t mask)**
- add **disableControlRegister(uint8_t mask)**
- add mcp23S17_registers.h )moved register defines in one place.

## [0.2.2] - 2022-09-28

- optimize digitalWrite - most used one only.

## [0.2.1] - 2022-06-29

- add SPIClass as parameter for constructor (See #10)
- redo constructors.
- add getAddress() + optimized (_address << 1)
- update readme.md

## [0.2.0] - 2022-06-28

- fix #10 incorrect mask

----

## [0.1.3] - 2022-04-13

- fix compiling for NANO33 BLE

## [0.1.2] - 2022-01-12

- change the URL for library manager

## [0.1.1] - 2022-01-10

- add 16 bit interface

## [0.1.0] - 2021-12-30

- initial version (a 2019 version did not make it)


Expand Down
58 changes: 57 additions & 1 deletion MCP23S17.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: MCP23S17.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.4
// VERSION: 0.2.5
// PURPOSE: Arduino library for SPI MCP23S17 16 channel port expander
// DATE: 2021-12-30
// URL: https://github.com/RobTillaart/MCP23S17
Expand Down Expand Up @@ -595,6 +595,62 @@ void MCP23S17::disableControlRegister(uint8_t mask)
}


void MCP23S17::enableHardwareAddress()
{
enableControlRegister(MCP23S17_IOCR_HAEN);
}


void MCP23S17::disableHardwareAddress()
{
disableControlRegister(MCP23S17_IOCR_HAEN);
}


#if defined(ESP32)

void MCP23S17::selectHSPI()
{
_useHSPI = true;
}


void MCP23S17::selectVSPI()
{
_useHSPI = false;
}


bool MCP23S17::usesHSPI()
{
return _useHSPI;
}


bool MCP23S17::usesVSPI()
{
return !_useHSPI;
}


void MCP23S17::setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select)
{
_clock = clk;
_dataOut = mosi;
_dataIn = miso;
_select = select;
pinMode(_select, OUTPUT);
digitalWrite(_select, HIGH);

_mySPI->end(); // disable old SPI

_mySPI->begin(clk, miso, mosi, select); // enable new pins
}

#endif



////////////////////////////////////////////////////
//
// PRIVATE
Expand Down
28 changes: 17 additions & 11 deletions MCP23S17.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// FILE: MCP23S17.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.4
// VERSION: 0.2.5
// PURPOSE: Arduino library for SPI MCP23S17 16 channel port expander
// DATE: 2021-12-30
// URL: https://github.com/RobTillaart/MCP23S17
Expand All @@ -12,7 +12,8 @@
#include "SPI.h"
#include "MCP23S17_registers.h"

#define MCP23S17_LIB_VERSION (F("0.2.4"))

#define MCP23S17_LIB_VERSION (F("0.2.5"))

// ERROR CODES
#define MCP23S17_OK 0x00
Expand Down Expand Up @@ -40,11 +41,11 @@ class MCP23S17

bool begin();
bool isConnected();
uint8_t getAddress(); // typically returns 0x00
uint8_t getAddress(); // default returns 0x00


// single pin interface
// mode = INPUT, OUTPUT or INPUT_PULLUP (==INPUT)
// mode: 0 = OUTPUT, 1 = INPUT, 1 = INPUT_PULLUP (==INPUT)
bool pinMode(uint8_t pin, uint8_t mode);
bool digitalWrite(uint8_t pin, uint8_t value);
uint8_t digitalRead(uint8_t pin);
Expand Down Expand Up @@ -91,17 +92,22 @@ class MCP23S17
// set/clear IOCR bit fields (0.2.3 experimental)
void enableControlRegister(uint8_t mask);
void disableControlRegister(uint8_t mask);
// 0.2.5 experimental
void enableHardwareAddress();
void disableHardwareAddress();

// ESP32 specific
#if defined(ESP32)
void selectHSPI() { _useHSPI = true; };
void selectVSPI() { _useHSPI = false; };
bool usesHSPI() { return _useHSPI; };
bool usesVSPI() { return !_useHSPI; };
#if defined(ESP32)

void selectHSPI();
void selectVSPI();
bool usesHSPI();
bool usesVSPI();

// to overrule ESP32 default hardware pins
// to overrule the ESP32s default hardware pins
void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select);
#endif

#endif


private:
Expand Down
85 changes: 73 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,28 @@ The two hardware constructors allow to call 4 different constructors.
```


#### sharing select lines
#### Sharing SELECT lines

(not tested)
Technically two chips could use the same select pin and a different address.
The constructors would allow to setup such a configuration.
I assume that this is less used and IMHO not recommended.
(verified in #19)
Technically two chips could use the same SELECT pin and a different address.
Since 0.2.5 the constructors allow to setup such a configuration.
The added value is that one can use up to 8 devices (= 128 IO lines) with only
four lines (MISO, MOSI, CLOCK, SELECT).

I assume that this configuration is less used and IMHO not recommended.
NB it is more difficult to detect which device is selected when debugging.

To use the hardware addresses the Hardware Address ENable register must be set.
See datasheet 3.3.2 ADDRESSING SPI DEVICES, need to set IOCON.HAEN.

The library supports two ways:
```cpp
MCP.enableControlRegister(MCP23S17_IOCR_HAEN); // or 0x08
or
MCP.enableHardwareAddress(); // 0.2.5 version and up
```

See also **IO Control Register** section below.


### Single pin interface
Expand Down Expand Up @@ -112,7 +128,7 @@ Returns true if successful.
Returns true if successful.


### IO Control Register
### IO Control Register

Since 0.2.3 the library supports setting bit fields in the IO control register.
Read the datasheet carefully!
Expand All @@ -133,6 +149,44 @@ Read the datasheet carefully!
| MCP23S17_IOCR_NI | 0x01 | Not implemented.


Two dedicated functions are added since 0.2.5.

- **void enableHardwareAddress()** set IOCR_HAEN bit.
- **void disableHardwareAddress()** clear IOCR_HAEN bit.


### ESP32 HW SPI port selection

This functionality is new in 0.2.5.

- **void selectHSPI()** in case hardware SPI, the ESP32 has two options HSPI and VSPI.
- **void selectVSPI()** see above.
- **bool usesHSPI()** returns true if HSPI is used.
- **bool usesVSPI()** returns true if VSPI is used.

The **selectVSPI()** or the **selectHSPI()** needs to be called
BEFORE the **begin()** function.


#### Experimental

- **void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select)**
overrule GPIO pins of ESP32 for hardware SPI.
Needs to be called AFTER the **begin()** function.

```cpp
void setup()
{
MCP.selectVSPI();
MCP.begin(15);
MCP.setGPIOpins(CLK, MISO, MOSI, SELECT); // SELECT should match the param of begin()
}
```

This interface can change in the future as the **select** pin is known
in the code.


### Error codes

If one of the above functions return false, there might be an error.
Expand Down Expand Up @@ -163,20 +217,27 @@ See examples.

#### Should

- buy additional hardware
- keep functional in sync with MCP23017_RT
- test with multiple devices.
- multi SELECT lines
- add example with interrupts
- test
- IOCON.HAEN, Hardware Address ENable.
- should this be enabled in **begin()** by default? 0.3.0
- check address range in constructor.

#### Could

- check need for writing in all functions (Polarity / pullup)
- check need for writing in all functions (Polarity / Pull-up)
- check if bit mask changes.
- what is performance gain vs footprint?
- implement ESP32 specific support in begin()
- see MCP_ADC.begin()
- SW_SPI is roughly equal in performance as HW SPI on ESP32.
- investigate and reimplement the INPUT_PULLUP for pinMode() ?
- RP2040 support for SPI, setGPIOpins() etc
- See MCP_DAC
- AVR software SPI optimize 0.3.0
- dao and clock - see fastShiftOut.

#### Wont

- check address range in constructor.


8 changes: 4 additions & 4 deletions examples/MCP23S17_digitalRead/MCP23S17_digitalRead.ino
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//
// FILE: MCP23S17_digitalRead.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-12-30
// PUPROSE: test MCP23017 library
// PURPOSE: test MCP23S17 library
// URL: https://github.com/RobTillaart/MCP23S17


#include "MCP23S17.h"
Expand All @@ -25,7 +25,7 @@ void setup()
rv = MCP.begin();
Serial.println(rv ? "true" : "false");

rv = MCP.pinMode8(0, 0xFF); // CHECK
rv = MCP.pinMode8(0, 0xFF);
Serial.println(rv);
rv = MCP.pinMode8(1, 0xFF);
Serial.println(rv);
Expand Down Expand Up @@ -62,5 +62,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

14 changes: 7 additions & 7 deletions examples/MCP23S17_digitalWrite/MCP23S17_digitalWrite.ino
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//
// FILE: MCP23S17_digitalWrite.ino
// AUTHOR: Rob Tillaart
// DATE: 2021-12-30
// PUPROSE: test MCP23017 library
// PURPOSE: test MCP23S17 library
// URL: https://github.com/RobTillaart/MCP23S17


#include "MCP23S17.h"
#include "SPI.h"

MCP23S17 MCP(10, 5, 6, 7); // SW SPI address 0x00
MCP23S17 MCP(10, 5, 6, 7); // SW SPI address 0x00


void setup()
Expand All @@ -24,14 +24,14 @@ void setup()
Serial.println(b ? "true" : "false");
delay(100);

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

Serial.println("TEST digitalWrite(0)");
delay(100);
for (int i = 0; i < 16; i++)
{
MCP.digitalWrite(0, i % 2); // alternating HIGH/LOW
MCP.digitalWrite(0, i % 2); // alternating HIGH/LOW
Serial.print(i % 2);
Serial.print(' ');
delay(100);
Expand All @@ -43,7 +43,7 @@ void setup()
delay(100);
for (int pin = 0; pin < 16; pin++)
{
MCP.digitalWrite(pin, 1 - pin % 2); // alternating HIGH/LOW
MCP.digitalWrite(pin, 1 - pin % 2); // alternating HIGH/LOW
Serial.print(1 - pin % 2);
Serial.print(' ');
delay(100);
Expand All @@ -70,5 +70,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

Loading

0 comments on commit 228b1bd

Please sign in to comment.