Skip to content

Commit

Permalink
fix #47, enable interrupts. (#49)
Browse files Browse the repository at this point in the history
- fix #47, interrupt handling. Kudos to GlibSkunk!
- update readme.md
- minor edits.
  • Loading branch information
RobTillaart authored Nov 22, 2024
1 parent 3d03c7d commit ee545d9
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 90 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.6.0] - 2024-11-19
- fix #47, interrupt handling. Kudos to GlibSkunk!
- update readme.md
- minor edits.

----

## [0.5.4] - 2024-07-04
- fix #45, documentation bug

Expand Down
147 changes: 70 additions & 77 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.5.4
// VERSION: 0.6.0
// PURPOSE: Arduino library for SPI MCP23S17 16 channel port expander
// DATE: 2021-12-30
// URL: https://github.com/RobTillaart/MCP23S17
Expand Down Expand Up @@ -570,114 +570,108 @@ bool MCP23S17::enableInterrupt(uint8_t pin, uint8_t mode)
_error = MCP23S17_PIN_ERROR;
return false;
}

uint8_t INTCONREG = MCP23x17_INTCON_A;
uint8_t DEFVALREG = MCP23x17_DEFVAL_A;
uint8_t GPINTENREG = MCP23x17_GPINTEN_A;
uint8_t DEFVALREG = MCP23x17_DEFVAL_A;
uint8_t GPINTENREG = MCP23x17_GPINTEN_A;
if (pin > 7)
{
INTCONREG = MCP23x17_INTCON_B;
DEFVALREG = MCP23x17_DEFVAL_B;
GPINTENREG = MCP23x17_GPINTEN_B;
DEFVALREG = MCP23x17_DEFVAL_B;
GPINTENREG = MCP23x17_GPINTEN_B;
pin -= 8;
}
uint8_t mask = 1 << pin;
uint8_t mask = 1 << pin;

uint8_t intcon = readReg(INTCONREG);
uint8_t pre_intcon = intcon;
uint8_t pre_intcon = intcon;
if (_error != MCP23S17_OK)
{
return false;
}
if (mode == CHANGE)
{
// Compare to previous value
intcon &= ~mask;
}
else
{
// Compare to DEFVALREG
intcon |= mask;
// Get and Modify Pin's Value in DEFVALREG
uint8_t defval = readReg(DEFVALREG);
uint8_t pre_defval = defval;

if (mode == CHANGE)
{
// Compare to previous value
intcon &= ~mask;
}
else
{
// Compare to DEFVALREG
intcon |= mask;

// Get and Modify Pin's Value in DEFVALREG
uint8_t defval = readReg(DEFVALREG);
uint8_t pre_defval = defval;
if (mode == RISING)
{
defval &= ~mask; // RISING == compare to 0
defval &= ~mask; // RISING == compare to 0
}
else if (mode == FALLING)
{
defval |= mask; // FALLING == compare to 1
}
// only write when changed.
if (pre_defval != defval)
{
writeReg(DEFVALREG, defval);
if (_error != MCP23S17_OK)
{
return false;
}
}
}
// only write when changed.
if (pre_intcon != intcon)
{
writeReg(INTCONREG, intcon);
if (_error != MCP23S17_OK)
{
return false;
}
}
defval |= mask; // FALLING == compare to 1
}
// only write when changed.
if (pre_defval != defval)
{
writeReg(DEFVALREG, defval);
if (_error != MCP23S17_OK)
{
return false;
}
}
}
// only write when changed.
if (pre_intcon != intcon)
{
writeReg(INTCONREG, intcon);
if (_error != MCP23S17_OK)
{
return false;
}
}

// enable interrupt
uint8_t gpinten = readReg(GPINTENREG);
uint8_t pre_gpinten = gpinten;
gpinten |= mask;
if (pre_gpinten != gpinten)
{
return writeReg(GPINTENREG, gpinten);
}
else
{
return true; // Already enabled for pin
}
uint8_t gpinten = readReg(GPINTENREG);
uint8_t pre_gpinten = gpinten;
gpinten |= mask;
if (pre_gpinten != gpinten)
{
return writeReg(GPINTENREG, gpinten);
}
return true; // Already enabled for pin
}


bool MCP23S17::disableInterrupt(uint8_t pin)
{
if (pin > 15)
{
_error = MCP23S17_PIN_ERROR;
return false;
}
uint8_t GPINTENREG = MCP23x17_GPINTEN_A;

uint8_t GPINTENREG = MCP23x17_GPINTEN_A;
if (pin > 7)
{
GPINTENREG = MCP23x17_GPINTEN_B;
GPINTENREG = MCP23x17_GPINTEN_B;
pin -= 8;
}
uint8_t mask = 1 << pin;

uint8_t mask = 1 << pin;

// disable interrupt
uint8_t gpinten = readReg(GPINTENREG);
uint8_t pre_gpinten = gpinten;
if (_error != MCP23S17_OK)
// disable interrupt
uint8_t gpinten = readReg(GPINTENREG);
uint8_t pre_gpinten = gpinten;
if (_error != MCP23S17_OK)
{
return false;
}
gpinten &= ~mask;
if (pre_gpinten != gpinten)
{
return writeReg(GPINTENREG, gpinten);
}
else
{
return true; // Already disabled for pin
}
gpinten &= ~mask;
if (pre_gpinten != gpinten)
{
return writeReg(GPINTENREG, gpinten);
}
return true; // Already disabled for pin
}


Expand All @@ -692,15 +686,14 @@ bool MCP23S17::enableInterrupt16(uint16_t mask, uint8_t mode)
}
else
{
intcon = mask;
if (mode == RISING)
{
intcon = mask;
defval = ~mask; // RISING == compare to 0
}
else if (mode == FALLING)
{
intcon = mask;
defval = mask; // FALLING == compare to 1
defval = mask; // FALLING == compare to 1
}
writeReg16(MCP23x17_DEFVAL_A, defval);
}
Expand Down
8 changes: 4 additions & 4 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.5.4
// VERSION: 0.6.0
// 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 "MCP23x17_registers.h"


#define MCP23S17_LIB_VERSION (F("0.5.4"))
#define MCP23S17_LIB_VERSION (F("0.6.0"))

// ERROR CODES
#define MCP23S17_OK 0x00
Expand Down Expand Up @@ -70,7 +70,7 @@ class MCP23S17

// 8 pins interface
// port = 0..1
// mask = 0x00..0xFF bit pattern,
// mask = 0x00..0xFF bit pattern,
// bit 0 = output mode, bit 1 = input mode
// value = bit pattern.
bool pinMode8(uint8_t port, uint8_t mask);
Expand Down Expand Up @@ -101,7 +101,7 @@ class MCP23S17
// pin = 0..15, mode = { RISING, FALLING, CHANGE }
bool enableInterrupt(uint8_t pin, uint8_t mode);
bool disableInterrupt(uint8_t pin);

// mask = 0x0000..0xFFFF (overrides all earlier settings.
bool enableInterrupt16(uint16_t mask, uint8_t mode);
bool disableInterrupt16(uint16_t mask);
Expand Down
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,18 @@ Programming Interface is kept the same as much as possible.
The **write1(pin, value)** is optimized.
If a pin is not changed it will not be written again to save time.

### 0.6.0 Breaking change

#### 0.5.0 Breaking change
Fix for #47, bug in enable interrupt handling.
Pre 0.6.0 versions are obsolete.

### 0.5.0 Breaking change

Version 0.5.0 introduced a breaking change to improve handling the SPI dependency.
The user has to call **SPI.begin()** or equivalent before calling **MCP.begin()**.
Optionally the user can provide parameters to the **SPI.begin(...)**


#### 0.4.0 Breaking change
### 0.4.0 Breaking change

The version 0.4.0 has breaking changes in the interface.
The rationale is that the programming environment of the **Arduino ESP32 S3**
Expand All @@ -54,15 +57,15 @@ The following library functions have been renamed:
| digitalWrite() | write1() |


#### 0.3.0 Breaking change
### 0.3.0 Breaking change

The version 0.3.0 has breaking changes in the interface.
The essence is removal of ESP32 specific code from the library.
This makes it possible to support the ESP32-S3 and other processors in the future.
Also it makes the library a bit simpler to maintain.


#### Related
### Related

16 bit port expanders

Expand Down Expand Up @@ -111,7 +114,7 @@ The two hardware constructors allow to call 4 different constructors.
```


#### Sharing SELECT lines
### Sharing SELECT lines

(verified in #19)
Technically two chips could use the same SELECT pin and a different address.
Expand Down Expand Up @@ -184,7 +187,6 @@ If there are problems please open an issue.
### Interrupts (experimental 0.5.2)

Read the datasheet for the details, page 24,25.
Note: Error handling is limited.

pin = 0..15
mode = { RISING, FALLING, CHANGE }
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.5.4",
"version": "0.6.0",
"license": "MIT",
"frameworks": "*",
"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.5.4
version=0.6.0
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 ee545d9

Please sign in to comment.