n0mjs710 / mcp23s17 Goto Github PK
View Code? Open in Web Editor NEWArduino Driver for Microchip MCP23S17
Arduino Driver for Microchip MCP23S17
This has reappeared: the version of pinMode() with word argument has an uncalled for negation of the argument, therefore it configures inputs and outputs reversed.
Note that INPUT is =1, both the arduino #define and on a MCP23S17.
I proposed a fix for this in April 2017 which was accepted, but this was reversed in October 2017.
Please advise.
Hi,
Do you know if it is possible to use this library with NodeMCU microcontrollers?
The way the hardware address decoder is enabled is incorrect.
/Users/jaap/Documents/Arduino/libraries/MCP23S17/MCP23S17.cpp: In member function 'void MCP::begin()':
/Users/jaap/Documents/Arduino/libraries/MCP23S17/MCP23S17.cpp:87:27: error: invalid conversion from 'int' to 'PinStatus' [-fpermissive]
::digitalWrite(_ss, HIGH); // Set SlaveSelect HIGH (chip de-selected)
^
In file included from /Users/jaap/Library/Arduino15/packages/arduino/hardware/samd/1.8.11/cores/arduino/api/Interrupts.h:8:0,
from /Users/jaap/Library/Arduino15/packages/arduino/hardware/samd/1.8.11/cores/arduino/api/ArduinoAPI.h:29,
from /Users/jaap/Library/Arduino15/packages/arduino/hardware/samd/1.8.11/cores/arduino/Arduino.h:23,
from /Users/jaap/Library/Arduino15/packages/arduino/hardware/samd/1.8.11/libraries/SPI/SPI.h:23,
from /Users/jaap/Documents/Arduino/libraries/MCP23S17/MCP23S17.cpp:43:
/Users/jaap/Library/Arduino15/packages/arduino/hardware/samd/1.8.11/cores/arduino/api/Common.h:95:6: note: initializing argument 2 of 'void digitalWrite(pin_size_t, PinStatus)'
void digitalWrite(pin_size_t pinNumber, PinStatus status);
^~~~~~~~~~~~
I've worked on implementing support for attiny85 and during that also implemented support for arduino mega.
For the attiny85 I'm using this library https://github.com/JChristensen/tinySPI
Would be great if you could include this patch:
diff -ru MCP23S17/MCP23S17.cpp MCP23S17-patched/MCP23S17.cpp
--- MCP23S17/MCP23S17.cpp 2014-07-25 22:31:20.000000000 +0200
+++ MCP23S17-patched/MCP23S17.cpp 2015-03-02 21:31:18.746218164 +0100
@@ -32,7 +32,11 @@
direct and more efficient control by writing a value to a specific register pair.
*/
+#if defined(__AVR_ATtiny85__)
+#include <tinySPI.h>
+#else
#include <SPI.h> // Arduino IDE SPI library - uses AVR hardware SPI features
+#endif
#include "MCP23S17.h" // Header files for this class
// Defines to keep logical information symbolic go here
@@ -47,7 +51,7 @@
// Here we have things for the SPI bus configuration
#define CLOCK_DIVIDER (2) // SPI bus speed to be 1/2 of the processor clock speed - 8MHz on most Arduinos
-#define SS (10) // SPI bus slave select output to pin 10 - READ ARDUINO SPI DOCS BEFORE CHANGING!!!
+#define SS (SS_PIN) // SPI bus slave select output to pin 10 - READ ARDUINO SPI DOCS BEFORE CHANGING!!!
// Control byte and configuration register information - Control Byte: "0100 A2 A1 A0 R/W" -- W=0
@@ -64,8 +68,13 @@
_pullupCache = 0x0000; // Default pull-up state is all off, 0x0000
_invertCache = 0x0000; // Default input inversion state is not inverted, 0x0000
SPI.begin(); // Start up the SPI busÉ crank'er up Charlie!
+#ifndef TINY_SPI
SPI.setClockDivider(CLOCK_DIVIDER); // Sets the SPI bus speed
SPI.setBitOrder(MSBFIRST); // Sets SPI bus bit order (this is the default, setting it for good form!)
+#endif
+#ifdef TINY_SPI
+ SPI_DDR_PORT |= _BV(SS_PIN);
+#endif
SPI.setDataMode(SPI_MODE0); // Sets the SPI bus timing mode (this is the default, setting it for good form!)
byteWrite(IOCON, ADDR_ENABLE);
};
@@ -73,22 +82,22 @@
// GENERIC BYTE WRITE - will write a byte to a register, arguments are register address and the value to write
void MCP::byteWrite(uint8_t reg, uint8_t value) { // Accept the register and byte
- PORTB &= 0b11111011; // Direct port manipulation speeds taking Slave Select LOW before SPI action
+ PORTB &= PORTB_AND_MASK; // Direct port manipulation speeds taking Slave Select LOW before SPI action
SPI.transfer(OPCODEW | (_address << 1)); // Send the MCP23S17 opcode, chip address, and write bit
SPI.transfer(reg); // Send the register we want to write
SPI.transfer(value); // Send the byte
- PORTB |= 0b00000100; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
+ PORTB |= PORTB_OR_MASK; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
}
// GENERIC WORD WRITE - will write a word to a register pair, LSB to first register, MSB to next higher value register
void MCP::wordWrite(uint8_t reg, unsigned int word) { // Accept the start register and word
- PORTB &= 0b11111011; // Direct port manipulation speeds taking Slave Select LOW before SPI action
+ PORTB &= PORTB_AND_MASK; // Direct port manipulation speeds taking Slave Select LOW before SPI action
SPI.transfer(OPCODEW | (_address << 1)); // Send the MCP23S17 opcode, chip address, and write bit
SPI.transfer(reg); // Send the register we want to write
SPI.transfer((uint8_t) (word)); // Send the low byte (register address pointer will auto-increment after write)
SPI.transfer((uint8_t) (word >> 8)); // Shift the high byte down to the low byte location and send
- PORTB |= 0b00000100; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
+ PORTB |= PORTB_OR_MASK; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
}
// MODE SETTING FUNCTIONS - BY PIN AND BY WORD
@@ -170,26 +179,26 @@
unsigned int MCP::digitalRead(void) { // This function will read all 16 bits of I/O, and return them as a word in the format 0x(portB)(portA)
unsigned int value = 0; // Initialize a variable to hold the read values to be returned
- PORTB &= 0b11111011; // Direct port manipulation speeds taking Slave Select LOW before SPI action
+ PORTB &= PORTB_AND_MASK; // Direct port manipulation speeds taking Slave Select LOW before SPI action
SPI.transfer(OPCODER | (_address << 1)); // Send the MCP23S17 opcode, chip address, and read bit
SPI.transfer(GPIOA); // Send the register we want to read
value = SPI.transfer(0x00); // Send any byte, the function will return the read value (register address pointer will auto-increment after write)
value |= (SPI.transfer(0x00) << 8); // Read in the "high byte" (portB) and shift it up to the high location and merge with the "low byte"
- PORTB |= 0b00000100; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
+ PORTB |= PORTB_OR_MASK; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
return value; // Return the constructed word, the format is 0x(portB)(portA)
}
uint8_t MCP::byteRead(uint8_t reg) { // This function will read a single register, and return it
uint8_t value = 0; // Initialize a variable to hold the read values to be returned
- PORTB &= 0b11111011; // Direct port manipulation speeds taking Slave Select LOW before SPI action
+ PORTB &= PORTB_AND_MASK; // Direct port manipulation speeds taking Slave Select LOW before SPI action
SPI.transfer(OPCODER | (_address << 1)); // Send the MCP23S17 opcode, chip address, and read bit
SPI.transfer(reg); // Send the register we want to read
value = SPI.transfer(0x00); // Send any byte, the function will return the read value
- PORTB |= 0b00000100; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
+ PORTB |= PORTB_OR_MASK; // Direct port manipulation speeds taking Slave Select HIGH after SPI action
return value; // Return the constructed word, the format is 0x(register value)
}
uint8_t MCP::digitalRead(uint8_t pin) { // Return a single bit value, supply the necessary bit (1-16)
if (pin < 1 | pin > 16) return 0x0; // If the pin value is not valid (1-16) return, do nothing and return
return digitalRead() & (1 << (pin - 1)) ? HIGH : LOW; // Call the word reading function, extract HIGH/LOW information from the requested pin
-}
\ No newline at end of file
+}
diff -ru MCP23S17/MCP23S17.h MCP23S17-patched/MCP23S17.h
--- MCP23S17/MCP23S17.h 2014-07-25 22:31:20.000000000 +0200
+++ MCP23S17-patched/MCP23S17.h 2015-03-02 21:31:18.746218164 +0100
@@ -76,6 +76,21 @@
#include "WProgram.h"
#endif
+#if defined(__AVR_ATmega2560__)
+#define SS_PIN 53
+#define PORTB_AND_MASK 0b11111110
+#define PORTB_OR_MASK 0b00000001
+#elif defined(__AVR_ATtiny85__)
+#define SS_PIN 4
+#define PORTB_AND_MASK 0b11101111
+#define PORTB_OR_MASK 0b00010000
+#define TINY_SPI
+#else
+#define SS_PIN 10
+#define PORTB_AND_MASK 0b11111011
+#define PORTB_OR_MASK 0b00000100
+#endif
+
class MCP {
public:
MCP(uint8_t); // Constructor to instantiate a discrete IC as an object, argument is the address (0-7) of the MCP23S17
It seems older versions work with your example read me. But the current does not.
error: no matching function for call to 'MCP::MCP(int)'
MCP iochip(0); // Instantiate an object called "iochip" on an MCP23S17 device at address
I tried adding a 10, so it would be MCP iochip(0, 10);
but it did not work at all...
I know it's not really an issue, because the lib is working great for the targeted hardware.
I have been using it without problems with the ESP8266 and I thought I cannot be the only one wanting to use the MCP23S17 with the ESP-32.
Anyone who have gotten it to work?
->folder/ZIP doesn't contain valid library
The version of pinMode() with word argument has an uncalled for negation of the argument, therefore it configures inputs and outputs reversed!
the pinModes in the examples are reversed
I'm right if I say it does not work completely if you have more slave select with mcp23s17.
can not make it read first chip on second slave pin but the rest
I think HIGH and LOW are reversed in the pinMode term of README.md and Manual.txt.
In the pinMode method, line 120
if (mode == INPUT) {
should be
if (mode == HIGH) {
Arduino defines INPUT as 0, so pinMode does the opposite of what you ask it to.
hello, i tried your library, but with arduino micro does not work the addresses.
The first ic, work well, while the other sends and receives random data!
The first ic have A0,A1,A2 to 0, the second A0 to vcc A1,A2 to 0
Any suggestion?
Thanks
Vincenzo
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.