MCP230xx i2c Port expander

A forum where Flowcode v7 user created components can be shared, discussed and reviewed.

Moderator: Benj

mnf
Valued Contributor
Valued Contributor
Posts: 607
Joined: Wed May 31, 2017 11:57 am
Has thanked: 56 times
Been thanked: 336 times
Contact:

MCP230xx i2c Port expander

Postby mnf » Sun Dec 17, 2017 10:17 am

An idea for a (some) new components.

I've created a (very) small component for the MCP23008 port expander chip which works well and am about to extend it to the MCP23016/7/8.

My questions (mostly questions of style):

What is preferable: a single component with the chip type as a property or multiple components - one for each chip type? (and if I added support for the SPI version of the chips - would that be better pulled to a separate component or left in one?) I don't currently have an SPI version - and I had MCP23008 and 16 in my parts bin!
How many 'helper' routines are preferable - for example, as a minimum, a SetReg/ReadReg (so SetReg(IODIR, b10001000) - to set input/output pins) or more 'helper' macros such as SetIO(b10010001)
I used I2C master instead of cal_i2c (and I'm just playing at the moment) - but what are the advantages to using cal_i2c in a component?
I created a small helper routing for the MCP23016 to create a clock output on an ATMega328p pin - this is by necessity not portable. Anyone out there able to offer alternate routines PIC/ARM etc or better yet a portable alternative? (Though this is probably overkill - clk signal can be generated using a resistor and capacitor - I just didn't have the recommended values to hand and the MCP23016 has really been superseded by 17 and 18 which don't need a clock signal)
As ever - I don't really have many ideas for what simulation should do here - suggestions/help welcome!

If anyone wants to play - here is the code for the MCP23008 with a simple demo that puts 0..255 - 255..0 onto the output port. I used an Arduino Nano with hardware i2c and the usual pullups.

mcp2308.fcfx
(16.87 KiB) Downloaded 69 times


Martin

User avatar
Benj
Matrix Staff
Posts: 14467
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4531 times
Been thanked: 4200 times
Contact:

Re: MCP230xx i2c Port expander

Postby Benj » Wed Dec 20, 2017 5:49 pm

Hi Martin,

We are using one of these I/O expander chips on one of the new (to be released) EB2 boards. Thanks for providing your code. We've come across these before and a component does make sense.

We are hoping we can find a way to allow the expander component to be added to the Flowcode panel and this in turn will create more device pins that you can attach other components to. This way you're basically using the port expander in a transparent indirect mode and not having to control the I/O states manually. For example driving an LCD via the port expander.

This will also help with things like Arduino where the name of the pin doesn't necessarily match the name of the chip port pin.

mnf
Valued Contributor
Valued Contributor
Posts: 607
Joined: Wed May 31, 2017 11:57 am
Has thanked: 56 times
Been thanked: 336 times
Contact:

Re: MCP230xx i2c Port expander

Postby mnf » Fri Dec 22, 2017 10:33 pm

That sounds like a very cool feature.... (Volunteers to beta test this: queue here !)

My first attempts to get the MCP23016 working failed - it doesn't seem to like a 1MHz pulse at the clock pin. I've not much time to play at the moment - work is ridiculously busy :-(
Hope to get a a 23017/8 after the holidays - they should work as easily as the 23008 (ever the optimist).

Martin

mnf
Valued Contributor
Valued Contributor
Posts: 607
Joined: Wed May 31, 2017 11:57 am
Has thanked: 56 times
Been thanked: 336 times
Contact:

Re: MCP230xx i2c Port expander

Postby mnf » Sat Dec 23, 2017 10:50 pm

Tried to get a MCP23S09 to work using cal_spi and failed....

However something weird is going on:

mcp23s09.fcfx
(13.27 KiB) Downloaded 46 times


Demonstrates....

Using cal_spi in software mode gives a reasonable trace on a logic analyser. However, in hardware mode it is just flat lining..... No output on the SPI port at all?

I've tried with and without the output to B2 (CSN) *and the delay too and at various speeds - with SPI Master pulling the CSN low is necessary (and seems to be for cal_spi - though do get a trace without in software mode). Very odd - any one able to test cal_spi on an Arduino (I'm using a Nano). FlowCode v7.3 - and the usual Arduino pins for SPI..
Using SPI master from the comms components gives a trace for hardware and software modes.

No joy getting the MCP2309 to work in software mode either though (cal_spi or spi_master) :(

Anyone any ideas where I'm going wrong?

Edit:
To test the hardware setup - I changed to a MCP23S08 chip (I found some Arduino source for a small test which I modified) - and the hardware is working correctly...
I know that the address for the GPIO register is incorrect in the above - according to my logic analyser the value seemed to be shifted left one bit at one stage - I did try (the correct value) 9 too!

The forum doesn't seem to allow .ino files but the main part of the sketch is:

Code: Select all

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void loop() {
  int i;
  digitalWrite(10, LOW);  // Set MCP pins to output
  spi_transfer(SLAVE_ADDRESS);
  spi_transfer(0);
  spi_transfer(0);
  digitalWrite(10, HIGH);

  while(1) {
    for (i = 0; i < 256; i++) {  // Output some data to MCP pins
      digitalWrite(10, LOW);
      spi_transfer(SLAVE_ADDRESS);
      spi_transfer(REG_GPIO);
      spi_transfer(i);
      digitalWrite(10, HIGH);
      delay(500);
    }
  }
}


- making a FlowCode macro as per spi_transfer in the code snippet above and abandoning cal_spi altogether also didn't work (with a little extra startup code as per the Arduino C code - SPCR = (1<<SPE)| (1<<MSTR); ).

mcp23s08.fcfx
(11.72 KiB) Downloaded 43 times


Tried with & without the call to cal_spi initialise.

Martin