RobTillaart / MCP23S17

Arduino library for SPI based MCP23S17 16 channel port expander
MIT License
27 stars 11 forks source link

adding possibility to have à chipselect that is not directly from MCU but with though a chipselect decoder #35

Closed joellecam closed 8 months ago

joellecam commented 8 months ago

I try to modify the MCP23S17 with the addition of a chip selector between MCU and MCP23S17. 74HC138 is perfect for making 7 chipselect with 3 output of the MCU . I made this library 74HC138 v1.0.zip

I am not an expert in CPP and I try this but I have an error

in your MCP23S17.h library I modify this

#ifdef _74HC138_H_
  #define __DECODE1ON8__                  decode3to8
#endif

#ifndef __SPI_CLASS__
  #if defined(ARDUINO_ARCH_RP2040)
  #define __SPI_CLASS__   SPIClassRP2040
  #else
  #define __SPI_CLASS__   SPIClass
  #endif
#endif

const uint32_t MCP23S17_TYP_SPI_SPEED =  8000000;
const uint32_t MCP23S17_MAX_SPI_SPEED = 10000000;

class MCP23S17
{
public:
  //  SOFTWARE SPI
  MCP23S17(uint8_t select, uint8_t dataIn, uint8_t dataOut, uint8_t clock, uint8_t address = 0x00);
  //  HARDWARE SPI

//  MCP23S17(uint8_t select, __SPI_CLASS__ * spi);
  MCP23S17(uint8_t select,__DECODE1ON8__ * decode3to8, __SPI_CLASS__ * spi);

//  MCP23S17(uint8_t select, uint8_t address = 0x00, __SPI_CLASS__ * spi = &SPI);
  MCP23S17(uint8_t select, uint8_t address, __DECODE1ON8__ * decode3to8 = &dec3t8, __SPI_CLASS__ * spi = &SPI);

and this at the end of the MCP23S17.h

  bool     _hwSPI = true;

  decode3to8     * _mydec3to8 ;
  //  10 MHz is maximum, 8 is a better clock divider on AVR.
  uint32_t    _SPIspeed = MCP23S17_TYP_SPI_SPEED;
  __SPI_CLASS__ * _mySPI;
  SPISettings     _spi_settings;

I modify the MCP23S17.cpp by this

//  HARDWARE SPI
MCP23S17::MCP23S17(uint8_t select,__DECODE1ON8__ * decode3to8, __SPI_CLASS__ * spi)
{
  MCP23S17(select, 0x00, decode3to8, spi );
}

MCP23S17::MCP23S17(uint8_t select, uint8_t address,__DECODE1ON8__ * decode3to8 = &dec3t8 , __SPI_CLASS__ * spi = &SPI )
{
  _address = (address << 1);
  _select  = select;
  _error   = MCP23S17_OK;
  _mySPI   = spi;
  _hwSPI   = true;
  _mydec3to8 = decode3to8 ;
}

and on the rest of cpp code I change evey:

all  // ::digitalWrite(_select, HIGH);  are replaced by
  _mydec3to8->set_cs_high(_select);
and   //::digitalWrite(_select, LOW); are replaced by
  _mydec3to8->set_cs_low(_select);

But I have an error with VScode and I don't understant what is?

[{
    "resource": "/c:/Users/joell/Desktop/VScode_Workbench/12-ESP32-S3_DAB_Radio/lib/MCP23S17-0.5.0/MCP23S17_via_74HC138.cpp",
    "owner": "cpp",
    "severity": 8,
    "message": "default argument given for parameter 3 of 'MCP23S17::MCP23S17(uint8_t, uint8_t, decode3to8*, SPIClass*)' [-fpermissive]",
    "startLineNumber": 33,
    "startColumn": 119,
    "endLineNumber": 33,
    "endColumn": 119
}]

Have you ideas ? where I do wrong?

(updated code tags for readability)

RobTillaart commented 8 months ago

Hi Joel (?), Will try to have a look this evening, otherwise tomorrow.

I am from Netherlands, which time zone are you in? (Helps with my planning)

joellecam commented 8 months ago

Hi Rob,

I am French in Normandy. using a chip select decoder is required in many design.

RobTillaart commented 8 months ago

Some observations and notes

Another observation is that you need to learn some bit math AND OR XOR etc. This set_cs_high(uint8_t out) function would do the same.

void decode3to8::set_cs_low(uint8_t out)
{
  if out > 7 return;
  ::digitalWrite(In2, out & 0x04); 
  ::digitalWrite(In1, out & 0x02); 
  ::digitalWrite(In0, out & 0x01);
}

In your .h file you use

#ifndef _74HC138_H_
#define _74HC138_H_

It is enough to place on the first line

#pragma once
RobTillaart commented 8 months ago

I try to modify the MCP23S17 with the addition of a chip selector between MCU and MCP23S17.

What are you trying to accomplish, in more detail?

RobTillaart commented 8 months ago

@joellecam had a second look at the error message in your original question.

I modify the MCP23S17.cpp by this

MCP23S17::MCP23S17(uint8_t select, uint8_t address,__DECODE1ON8__ * decode3to8 = &dec3t8 , __SPI_CLASS__ * spi = &SPI )
{
  _address = (address << 1);
  _select  = select;
  _error   = MCP23S17_OK;
  _mySPI   = spi;
  _hwSPI   = true;
  _mydec3to8 = decode3to8 ;
}

should be

MCP23S17::MCP23S17(uint8_t select, uint8_t address,__DECODE1ON8__ * decode3to8, __SPI_CLASS__ * spi )
{
  _address = (address << 1);
  _select  = select;
  _error   = MCP23S17_OK;
  _mySPI   = spi;
  _hwSPI   = true;
  _mydec3to8 = decode3to8 ;
}

The default parameters should only be given in the .h file

joellecam commented 8 months ago

Hi Rob,

Thanks you very much. I have no error. I try the code in the next month after I receive the PCB

Best regards Joël

RobTillaart commented 8 months ago

OK, I close the issue. FYI, inspired by your library I decided to write my own and one for the 74HC154 too (4 to 16)

https://assets.nexperia.com/documents/data-sheet/74HC_HCT154.pdf

RobTillaart commented 8 months ago

@joellecam

just published the two libraries

There is also a 1 to 2 multiplexer in this range but that is left for the future. If you have time, please give them (or the 138 only) a try.

Again thanks for the inspiration.