Skip to content

Commit

Permalink
improve performance 16 bit interface
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Aug 15, 2023
1 parent 228b1bd commit dd17659
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 37 deletions.
19 changes: 8 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ 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
## [0.2.6] - 2023-08-15
- optimize 16 bit interface
- add readReg16() + writeReg16()
- update performance test sketch (multi speeds in one run)
- update readme.md
- minor edits


## [0.2.5] - 2023-08-14
- 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)
Expand All @@ -18,51 +25,41 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- 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
133 changes: 114 additions & 19 deletions 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.5
// VERSION: 0.2.6
// PURPOSE: Arduino library for SPI MCP23S17 16 channel port expander
// DATE: 2021-12-30
// URL: https://github.com/RobTillaart/MCP23S17
Expand Down Expand Up @@ -359,7 +359,6 @@ void MCP23S17::setSPIspeed(uint32_t speed)
};



///////////////////////////////////////////////////////////////////
//
// 8 pins interface
Expand Down Expand Up @@ -489,8 +488,9 @@ bool MCP23S17::getPullup8(uint8_t port, uint8_t &mask)
// value = 0x0000..0xFFFF bit pattern
bool MCP23S17::pinMode16(uint16_t value)
{
writeReg(MCP23S17_DDR_A, value >> 8);
writeReg(MCP23S17_DDR_B, value & 0xFF);
writeReg16(MCP23S17_DDR_A, value);
// writeReg(MCP23S17_DDR_A, value >> 8);
// writeReg(MCP23S17_DDR_B, value & 0xFF);
_error = MCP23S17_OK;
return true;
}
Expand All @@ -499,8 +499,9 @@ bool MCP23S17::pinMode16(uint16_t value)
// value = 0x0000..0xFFFF bit pattern
bool MCP23S17::write16(uint16_t value)
{
writeReg(MCP23S17_GPIO_A, value >> 8);
writeReg(MCP23S17_GPIO_B, value & 0xFF);
writeReg16(MCP23S17_GPIO_A, value);
// writeReg(MCP23S17_GPIO_A, value >> 8);
// writeReg(MCP23S17_GPIO_B, value & 0xFF);
_error = MCP23S17_OK;
return true;
}
Expand All @@ -510,18 +511,20 @@ bool MCP23S17::write16(uint16_t value)
uint16_t MCP23S17::read16()
{
_error = MCP23S17_OK;
uint16_t value = readReg(MCP23S17_GPIO_A);
value <<= 8;
value += readReg(MCP23S17_GPIO_B);
uint16_t value = readReg16(MCP23S17_GPIO_A);
// uint16_t value = readReg(MCP23S17_GPIO_A);
// value <<= 8;
// value += readReg(MCP23S17_GPIO_B);
return value;
}


// mask = 0x0000..0xFFFF bit pattern
bool MCP23S17::setPolarity16(uint16_t mask)
{
writeReg(MCP23S17_POL_A, mask >> 8);
writeReg(MCP23S17_POL_B, mask & 0xFF);
writeReg16(MCP23S17_POL_A, mask);
// writeReg(MCP23S17_POL_A, mask >> 8);
// writeReg(MCP23S17_POL_B, mask & 0xFF);
if (_error != MCP23S17_OK)
{
return false;
Expand All @@ -533,9 +536,10 @@ bool MCP23S17::setPolarity16(uint16_t mask)
// mask = 0x0000..0xFFFF bit pattern
bool MCP23S17::getPolarity16(uint16_t &mask)
{
mask = readReg(MCP23S17_POL_A);
mask <<= 8;
mask += readReg(MCP23S17_POL_B);
mask = readReg16(MCP23S17_POL_A);
// mask = readReg(MCP23S17_POL_A);
// mask <<= 8;
// mask += readReg(MCP23S17_POL_B);
if (_error != MCP23S17_OK)
{
return false;
Expand All @@ -547,8 +551,9 @@ bool MCP23S17::getPolarity16(uint16_t &mask)
// mask = 0x0000..0xFFFF bit pattern
bool MCP23S17::setPullup16(uint16_t mask)
{
writeReg(MCP23S17_PUR_A, mask >> 8);
writeReg(MCP23S17_PUR_B, mask & 0xFF);
writeReg16(MCP23S17_PUR_A, mask);
// writeReg(MCP23S17_PUR_A, mask >> 8);
// writeReg(MCP23S17_PUR_B, mask & 0xFF);
if (_error != MCP23S17_OK)
{
return false;
Expand All @@ -560,9 +565,10 @@ bool MCP23S17::setPullup16(uint16_t mask)
// mask = 0x0000..0xFFFF bit pattern
bool MCP23S17::getPullup16(uint16_t &mask)
{
mask = readReg(MCP23S17_PUR_A);
mask <<= 8;
mask += readReg(MCP23S17_PUR_B);
mask = readReg16(MCP23S17_PUR_A);
// mask = readReg(MCP23S17_PUR_A);
// mask <<= 8;
// mask += readReg(MCP23S17_PUR_B);
if (_error != MCP23S17_OK)
{
return false;
Expand Down Expand Up @@ -726,6 +732,95 @@ uint8_t MCP23S17::readReg(uint8_t reg)
return rv;
}

// writes HIGH byte first, LOW byte last
bool MCP23S17::writeReg16(uint8_t reg, uint16_t value)
{
_error = MCP23S17_OK;

if (reg > MCP23S17_OLAT_B)
{
_error = MCP23S17_REGISTER_ERROR;
return false;
}
::digitalWrite(_select, LOW);
if (_hwSPI)
{
_mySPI->beginTransaction(_spi_settings);
// _address already shifted
_mySPI->transfer(MCP23S17_WRITE_REG | _address );
_mySPI->transfer(reg);
_mySPI->transfer(value >> 8);
::digitalWrite(_select, HIGH);

::digitalWrite(_select, LOW);
_mySPI->transfer(MCP23S17_WRITE_REG | _address );
_mySPI->transfer(reg + 1);
_mySPI->transfer(value & 0xFF);
_mySPI->endTransaction();
}
else
{
// _address already shifted
swSPI_transfer(MCP23S17_WRITE_REG | _address );
swSPI_transfer(reg);
swSPI_transfer(value >> 8);
::digitalWrite(_select, HIGH);

::digitalWrite(_select, LOW);
swSPI_transfer(MCP23S17_WRITE_REG | _address );
swSPI_transfer(reg + 1);
swSPI_transfer(value & 0xFF);
}
::digitalWrite(_select, HIGH);
return true;
}


uint16_t MCP23S17::readReg16(uint8_t reg)
{
uint16_t rv = 0;

_error = MCP23S17_OK;

if (reg > MCP23S17_OLAT_B)
{
_error = MCP23S17_REGISTER_ERROR;
return false;
}

::digitalWrite(_select, LOW);
if (_hwSPI)
{
_mySPI->beginTransaction(_spi_settings);
// _address already shifted
_mySPI->transfer(MCP23S17_READ_REG | _address );
_mySPI->transfer(reg);
rv = _mySPI->transfer(0xFF) << 8;
::digitalWrite(_select, HIGH);

::digitalWrite(_select, LOW);
_mySPI->transfer(MCP23S17_READ_REG | _address );
_mySPI->transfer(reg + 1);
rv += _mySPI->transfer(0xFF);
_mySPI->endTransaction();
}
else
{
// _address already shifted
swSPI_transfer(MCP23S17_READ_REG | _address );
swSPI_transfer(reg);
rv = swSPI_transfer(0xFF) << 8;
::digitalWrite(_select, HIGH);

::digitalWrite(_select, LOW);
swSPI_transfer(MCP23S17_READ_REG | _address );
swSPI_transfer(reg + 1);
rv += swSPI_transfer(0xFF);
}
::digitalWrite(_select, HIGH);
return rv;
}


uint8_t MCP23S17::swSPI_transfer(uint8_t val)
{
Expand Down
6 changes: 4 additions & 2 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.5
// VERSION: 0.2.6
// PURPOSE: Arduino library for SPI MCP23S17 16 channel port expander
// DATE: 2021-12-30
// URL: https://github.com/RobTillaart/MCP23S17
Expand All @@ -13,7 +13,7 @@
#include "MCP23S17_registers.h"


#define MCP23S17_LIB_VERSION (F("0.2.5"))
#define MCP23S17_LIB_VERSION (F("0.2.6"))

// ERROR CODES
#define MCP23S17_OK 0x00
Expand Down Expand Up @@ -115,6 +115,8 @@ class MCP23S17
// USE WITH CARE !!!
bool writeReg(uint8_t reg, uint8_t value);
uint8_t readReg(uint8_t reg);
bool writeReg16(uint8_t reg, uint16_t value);
uint16_t readReg16(uint8_t reg);


uint8_t _address = 0;
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ Returns true if successful.
- **bool getPullup16(uint16_t &mask)** reads pull-up for 16 channels.
Returns true if successful.

Since 0.2.6 the reading and writing to registers have been performance optimized for the 16 bit interface.
If there are problems please open an issue.


### IO Control Register

Expand Down
20 changes: 17 additions & 3 deletions examples/MCP23S17_performance/MCP23S17_performance.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,27 @@ void setup()
Serial.print("HWSPI: ");
Serial.println(MCP.usesHWSPI());

MCP.setSPIspeed(10000000);
MCP.setSPIspeed(1000000);
test();
MCP.setSPIspeed(2000000);
test();
MCP.setSPIspeed(4000000);
test();
MCP.setSPIspeed(8000000);
test();

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


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

Serial.print("\nSPISpeed:\t");
Serial.println(MCP.getSPIspeed());

Serial.println("\ntime in microseconds\n");
delay(100);

Expand Down Expand Up @@ -127,8 +143,6 @@ void setup()
Serial.println(val8);
Serial.print("VAL16:\t");
Serial.println(val16);

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


Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/MCP23S17.git"
},
"version": "0.2.5",
"version": "0.2.6",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=MCP23S17
version=0.2.5
version=0.2.6
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for SPI MCP23S17 16 channel port expander 16 IO-lines
Expand Down

0 comments on commit dd17659

Please sign in to comment.