Quick and short code for setting up and reading a MCP23S17

I have a MCP23S17 device and i need help making a very short code for setting up the IC. I only need 2 things from it. Set the port A and B into an Input, and read the state of port A and B

Please check if my code is correct:


#define WR_CMD 0x40  //control byte, slave address 0, R/nW=0 (write)
#define RD_CMD 0x41  //control byte, slave address 0, R/nW=1 (read)

#define IODIRA 0x00  //direction register for PORTA
#define IODIRB 0x01 //direction register for PORTB

#define GPIOA 0x12   //status register for PORTA
#define GPIOB 0x13  //status register for PORTB

void setup() {

  //initialize the SPI
  SPI.begin();
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  //setup registers port A and B into intput
    digitalWrite(9, LOW);

    SPI.transfer(WR_CMD); //is this the correct sequence for PORTA?
    SPI.transfer(IODIRA);
    SPI.transfer(0xff);

    SPI.transfer(WR_CMD); // do you have to do it one register at a time? 
    SPI.transfer(IODIRB);
    SPI.transfer(0xff);

    digitalWrite(_pinSS, HIGH);


    //read PORTA
    read16(GPIOA);
    //read PORTB
    read16(GPIOB);

}



  uint16_t read16(uint8_t addr) {

    uint16_t retval = 0;

    digitalWrite(9, LOW);

    SPI.transfer(RD_CMD);
    SPI.transfer(addr);
    retval |= SPI.transfer(0);
    retval |= (uint16_t)(SPI.transfer(0) << 8);

    digitalWrite(_pinSS, HIGH);

    return retval;

  } 

Can you read portA and B in one spi transaction? or you really have to send the read command again

No one knows, no one ever tried.


Wait, someone probably knows. Maybe they just know, or read the datasheet or… tried it to see what happens.

a7

not all people have the technical knowhow to fully understand a datasheet, hence asking speeds up the process :slight_smile:

it would help if you point me the specific portion of the datasheet that tell me how i can do this.

My reading glasses are in the dish washer, sorry.

1 Like

Sry, fair points. There may be more to it than…

I should have just said "what happens when you try it?", thinking that I would just try it if I wa in my lab, not under the umbrella. And I happened to have an MCP23S17 lying around.

See section

  3.2.1 BYTE MODE AND SEQUENTIAL MODE

it seems to indicate that put in the correct mode, you can read read read.

On the other hand, so what if you could not? If the several lines of code it takes is offensive in some way, just make your own function that hides that low level stuff.

Unless you are pressed for time, a good reason to want to boost efficiency wherever you c an.

a7

I'm going to go out on a limb here and say yes.

Having briefly looked at the 23S17 datasheet, I think you can do this by:

  1. Set IOCON.BANK=0 (interleaves the 2 sets of port registers)
  2. Set IOCON.SEQOP=0 (enables auto address pointer incrementing)

Then I think you can do your SPI transaction by sending out the 23S17 device address (inc R/W bit), then the register address of GPIOA (=12), and then 2 additional SPI transfers that should return the values in GPIOA followed by GPIOB with the 23S17 auto incrementing the address pointer from 12 to 13.

1 Like

Hi, @anon19524084

Have you looked here;

If you read the page you will find a link to a Library that may make you project easier.

OR;
Google;

arduino MCP23S17 library

OR
Check the Library Manager in the Arduino IDE.

Tom.. :smiley: :+1: :coffee: :australia:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.