JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

MCP23017 problem

Sun Nov 09, 2014 8:52 am

Hi!

I'm into old arcade PCB boards. I'm fixing and restoring them.

I thought it would be cool to have my own debug tool. A tool that replaces the processor of the board, checks that address decoding works, verifies EPROM's... Well, you get the idea.

I made a I/O board PCB for the PI using four MCP23017 and an I2C level converter (I want to run the MCP's at 5V), which gives me 64 I/O in total. I hook 40 of these up to a pod adapter resembling a 40pin DIL to be able to replace a Z80 for starts. So, I replace the Z80 with the pod and connect GND (0V) separately.

Then I wrote some SW in C++. In the end this gives me control of every pin and I can also easily group pins to form address and data buses. No problem here, it seems to work nicely.

I then used this to make a read of all adresses between $4000 and $40FF (These are EPROM addresses) on a board i use for test. I then re-read the addresses and compare them to the first read as a test. If I do the test 1000 times it works about 995 times. So, in 5 out of 1000 reads of 256 bytes I get one byte wrong. In total, 5 of 256000 is wrong.

6 of the databus pins are on one MCP23017 and two on another. The one with just two connected always read correctly. When there is a problem all bits on the MCP with 6 data bits reads as ones. If I do another read of the databus, without even changing the address bus pins or any other pin (MREQ and RD in this case) it reads correctly. Actually, if I only read the databus with a certain address statically set, I also get the error once every 50000 reads or so. So it has nothing to do with the rest of the pins in that sense, and nothing to do with what is actually read from the databus.

I don't really configure anything except the direction registers.

There is an interrupt signal coming from the PCB to the GPB7 pin of the IC that fails. This pin is configured as input. If i de-solder this pin, so no interrupt signal reaches the GPB7 pin, it all works flawlessly. The interrupt signal is a 60Hz square wave. It keeps itself within 0 and 5V. There should be no problem. I don't understand this.

The clock signal (4MHz, I think) is connected to an input of the working MCP connected to the 2 bits of the databus. And this works perfectly.

I improved 0V to the IC that fails, added more decoupling, tested decreasing the IC2 pullups, swapped IC, tried 100kHz, 400kHz, 1MHz... Nothing makes a difference (except it's faster at 1MHz).

If you got any idea of what could be causing this, please let me know!

Best regards, Jonas

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Sun Nov 09, 2014 12:28 pm

If I make a simple test program just reading the 8 input pins, printing the value when it differs from the last read, and holding the rest of the pins down to 0 using pulldowns, I get the following with about 30 seconds between:

128 10000000
0 00000000
128 10000000
0 00000000
128 10000000
0 00000000
128 10000000
0 00000000
127 01111111
128 10000000
0 00000000
128 10000000
0 00000000
128 10000000
0 00000000

127??? How did THAT happen? I touch bit 7 with a screwdriver, the other ones are held low.

I borrowed the i2c code, this is the read function I use:

int i2c8Bit::readReg(unsigned char reg_addr, unsigned char &data){

unsigned char *inbuff, outbuff;
int retVal = -1;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];

outbuff = reg_addr;
messages[0].addr = deviceAddress;
messages[0].flags= 0;
messages[0].len = sizeof(outbuff);
messages[0].buf = &outbuff;

inbuff = &data;
messages[1].addr = deviceAddress;
messages[1].flags = I2C_M_RD;
messages[1].len = sizeof(*inbuff);
messages[1].buf = inbuff;

packets.msgs = messages;
packets.nmsgs = 2;

retVal = ioctl(this->i2cDescriptor, I2C_RDWR, &packets);
if(retVal < 0)
perror("Read from I2C Device failed");

return retVal;
}

If anyone see a problem here, please let me know.

Best regards, Jonas

User avatar
joan
Posts: 14196
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: MCP23017 problem

Sun Nov 09, 2014 12:41 pm

I didn't spot the I2C bus speed you are using.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Sun Nov 09, 2014 8:15 pm

Hi,

Got the exact same problem at 100kHz, 400kHz and 1MHz.

Best regards, Jonas

User avatar
joan
Posts: 14196
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: MCP23017 problem

Sun Nov 09, 2014 8:50 pm

If you get the same error rate regardless of I2C bus speed that would seem to rule out the I2C bus itself.

You have also swapped chips which would seem to rule out the MCP23017.

That only leaves the fixed wiring to/from the chip.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Sun Nov 09, 2014 9:21 pm

The wiring consists of a "real" FR4 PCB and a short ribbon cable. I can shake things around without getting errors.

This is so strange!

Best regards, Jonas

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: MCP23017 problem

Mon Nov 10, 2014 3:30 am

Do you have the I-O pins of the 23017 configured to have a weak pullup? If not, do so.
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Mon Nov 10, 2014 8:40 am

Hm, do you think that would make a difference? I'm holding the pins low during the test using 4.7k pulldown resistors except for bit 7.

Then, if I pull bit 7 low no error occurs. If I hold it high no error occurs (I think, when I think of it I never did test this for a longer period of time). Only when bit 7 changes state, presumable at the wrong moment, the error occurs.

:evil:

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: MCP23017 problem

Mon Nov 10, 2014 1:39 pm

Try it.
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Mon Nov 10, 2014 2:13 pm

If you put it that way.... Of course I will. ;)

Best regards, Jonas

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Mon Nov 10, 2014 7:10 pm

I added code for activating weak pullups, wrote 0xFF to 0x0C and 0x0D. I can see the effect on the pins but no, it did not solve the problem.

Best regards, Jonas

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 12124
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: MCP23017 problem

Mon Nov 10, 2014 7:27 pm

JonasE wrote:I added code for activating weak pullups, wrote 0xFF to 0x0C and 0x0D. I can see the effect on the pins but no, it did not solve the problem.

Best regards, Jonas
off course not! There are already external 1K8 pullups to 3V3 present, so adding the weak (~50K) pullups won't matter at all!

note that if you power this chip with 5V, the minimum high level voltage becomes 4V (0.8 x VCC) so 3V3 won't work, and thus you need a level converter. Solution, power the chip with 3V3, so Vih-min becomes 2,64V.

User avatar
joan
Posts: 14196
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: MCP23017 problem

Mon Nov 10, 2014 7:50 pm

mahjongg wrote:
JonasE wrote:I added code for activating weak pullups, wrote 0xFF to 0x0C and 0x0D. I can see the effect on the pins but no, it did not solve the problem.

Best regards, Jonas
off course not! There are already external 1K8 pullups to 3V3 present, so adding the weak (~50K) pullups won't matter at all!

note that if you power this chip with 5V, the minimum high level voltage becomes 4V (0.8 x VCC) so 3V3 won't work, and thus you need a level converter. Solution, power the chip with 3V3, so Vih-min becomes 2,64V.
I think the OP is referring to pull-ups on the 16 gpios on the MCP23017 chip, not the I2C bus.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Mon Nov 10, 2014 8:55 pm

Yes. And I do have level converters. I need to power the IC's using 5V as the boards I will debug using it runs at 5V.

I have tried everything now. The bus now sees pullups of about 600 ohms, and still the problem remains. I don't use 5V from the Pi anymore, I added a 7805 to get super smooth 5V. Didn't help either. On my scope the signals look good, there should be no problems at all.

And I guess the Pi has seen a lot of testing when it comes to reading from the I2C, so I most probably cannot blame that either.

I will design a new PCB running SPI instead. I hope that works better.

ddahms
Posts: 67
Joined: Tue Mar 18, 2014 3:38 pm

Re: MCP23017 problem

Tue Nov 11, 2014 3:07 am

My gut feeling is that I2C is not the problem because it works perfectly when communicating with the other 3 MCP23017 chips. The effect of the 60Hz signal on GPB7 that you observed seems more suspicious to me. The datasheet does not specify a setup time for inputs or what happens if an input changes exactly when it is sampled. As an experiment, you could connect the GPB7 pin to an external square wave source, increase the frequency, and see if the error rate increases. For another test, temporarily attach the 60Hz signal to an input pin on a different MCP23017, run your repetitive read test on it, and see if that induces flakiness in that chip. If it does, at least you would know the cause. If your tester doesn't need the function of the 60Hz signal on GPB7, you could tie it hi or low and move on.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Tue Nov 11, 2014 8:58 am

Hm, I haven't actually made the exact same test on another of the four. I can do that, no problem. Also hooking it up to my frequency generator is a good idea.

I don't think it is a general problem with timing. I can do the same test on another pin on the same port without seeing the problem. It seems it's only bit 7 of port B (have not tested port A either).

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Tue Nov 11, 2014 5:29 pm

Did a quick test now.... Same thing happened on another IC on the board, and I also tested PORT A with the same problem. Only bit 7 gives the problem.

ddahms
Posts: 67
Joined: Tue Mar 18, 2014 3:38 pm

Re: MCP23017 problem

Wed Nov 12, 2014 2:44 am

Let me reiterate the situation as I understand it: You have a 60Hz square wave applied to GPB7 and GPB6-0 are tied low. You read PortB rapidly, usually getting 0x00 or 0x80 as expected, but occasionally getting something else. Is it 0x7F or 0xFF or both? The same thing happens if you apply the 60Hz signal to GPA7 with GPA6-0 tied low and read PortA. When you apply the 60Hz to some other pin such as GPB6 with GPB7,5-0 tied low, it reads back 0x00 or 0x40 consistently. Is this accurate?

Doing the function generator test at a higher frequency would still be worthwhile.

Ii can think of two more things to try, although both are long shots:
Are you always reading and writing the MCP23017 one byte at a time? I can't tell from the C code because it uses sizeof a passed parameter. You could temporarily change the code to "messages[1].len = 1;" to be sure. Same thing in your write function.

Do you initialize all the registers in the MCP23017 chip? Perhaps some lingering bits remain set after power up.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Wed Nov 12, 2014 7:33 am

Yes, you are absolutely correct in your summary. Both 0x7F and 0xFF show up occasionally.

Ok, I will hook up my frequency generator tonight.

Nope, I don't initialize anything. So far I have trusted the reset circuit. I can try this as well!

Thanks alot for your input!

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Wed Nov 12, 2014 7:35 am

And yes, one byte at a time.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Wed Nov 12, 2014 7:39 am

Also, the return value of the ioctl is always 2, no matter if i see the error or not.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Wed Nov 12, 2014 7:16 pm

Ok, now I tried using my function generator.

At about 50Hz i got the same result as before. At about 1kHz I get something like one error/second. At 100kHz i get this:

128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
127 01111111 2
128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
255 11111111 2
128 10000000 2
0 00000000 2
255 11111111 2
0 00000000 2
128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
255 11111111 2
128 10000000 2
127 01111111 2
0 00000000 2
128 10000000 2
0 00000000 2
128 10000000 2
127 01111111 2
0 00000000 2
128 10000000 2
0 00000000 2
128 10000000 2
0 00000000 2
255 11111111 2
0 00000000 2
128 10000000 2
0 00000000 2
255 11111111 2
0 00000000 2

...and at 1MHz i get this:

255 11111111 2
0 00000000 2
255 11111111 2
0 00000000 2
127 01111111 2
255 11111111 2
0 00000000 2
127 01111111 2
0 00000000 2
255 11111111 2
0 00000000 2
127 01111111 2
255 11111111 2
0 00000000 2
255 11111111 2
127 01111111 2
255 11111111 2
0 00000000 2
127 01111111 2
255 11111111 2
127 01111111 2
0 00000000 2
255 11111111 2
127 01111111 2
255 11111111 2
0 00000000 2
255 11111111 2
0 00000000 2
255 11111111 2
0 00000000 2
255 11111111 2
0 00000000 2
255 11111111 2
0 00000000 2
127 01111111 2
0 00000000 2
255 11111111 2
0 00000000 2
255 11111111 2
127 01111111 2
255 11111111 2
127 01111111 2
0 00000000 2
255 11111111 2
0 00000000 2

...which is more wrong than right.

Tried giving it 1MHz on all other PORT A pins, no problems.

I will test the other suggestions as well.

Best regards, Jonas

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Wed Nov 12, 2014 7:47 pm

Initializing all registers had no effect, neither did setting the length to 1.

With some delay in the code I could get a reasonable sync on my scope. There is no question about it, the MCP outputs only 1:s when the error occurs. Except for bit 7 (the first one sent) sometimes.

JonasE
Posts: 24
Joined: Sun Nov 09, 2014 8:18 am

Re: MCP23017 problem

Wed Nov 12, 2014 8:04 pm

If at all possible I would be very grateful if someone would test this. I find it hard to believe that Microchip makes bad IC's. (Or are there bad copies around? :?) There must be another explanation.

User avatar
joan
Posts: 14196
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: MCP23017 problem

Wed Nov 12, 2014 9:38 pm

JonasE wrote:If at all possible I would be very grateful if someone would test this. I find it hard to believe that Microchip makes bad IC's. (Or are there bad copies around? :?) There must be another explanation.
I may have duplicated your results.
mcp23017.jpg
mcp23017.jpg (50.77 KiB) Viewed 4305 times
Port A7 is connected to a gpio. The rest of the port is tied to ground.

The code cycles through frequencies between 10Hz and 8000Hz and generates a square wave fed to port A7. 20 seconds is spent at each frequency. The port is continually read and if it's other than 0 or 128 the value is printed.

Code: Select all

#!/usr/bin/env python

import time

import pigpio

A7=24 # gpio connected to port A7.

PWM=[10, 20, 40, 100, 200, 400, 800, 1000, 2000, 4000, 8000]

pi = pigpio.pi("tom") # Connect to tom.

chip = pi.i2c_open(0, 0x20) # tom is a Rev.1 board.

pi.set_PWM_dutycycle(A7, 128) # Square wave.

for p in PWM:

   freq = pi.set_PWM_frequency(A7, p)

   print("Frequency {}".format(freq))

   start = time.time()

   while (time.time() - start) < 20:
      now = pi.i2c_read_byte_data(chip, 18)
      if (now != 0) and (now != 128):
         print(now)

pi.i2c_close(chip)

pi.stop()

Code: Select all

mercury:.../common/code$ ./JonasE.py  
Frequency 10
Frequency 20
Frequency 40
Frequency 100
Frequency 200
Frequency 400
255
255
255
255
255
Frequency 800
255
255
255
255
255
Frequency 1000
255
255
255
Frequency 2000
255
255
255
255
255
255
255
255
255
255
255
Frequency 4000
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
Frequency 8000
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
255
mercury:.../common/code$ 

Return to “Interfacing (DSI, CSI, I2C, etc.)”