dsPIC & MCP23017 using I2C
dsPIC & MCP23017 using I2C
Hi, I'm trying to use a dsPIC30F4011 to communicate via I2C with a MCP23017 (a 16-bit I/O port expander) but I have not fully understood how to setup the communication using the "I2C Bus Master" block. In order to read from a specific register of the MCP23017 the datasheet specifies this communication protocol:
S _ OPCODE+W _ ACK* _ ADDRESS _ ACK* _ SR _ OPCODE+R _ ACK* _ DATAOUT* _ P
where:
S = start
OPCODE+W = 7bit I2C addres of MCP23017 + LSB bit set to 0 (write instruction)
ACK* = acknowledge provided by the MCP23017
ADDRESS = register address to be read
SR = restart
OPCODE+R = 7bit I2C addres of MCP23017 + LSB bit set to 1 (read instruction)
DATAOUT* = data out from MCP23017
I'm using this sequence in the "I2C Bus Master" block: 'S A W Sr A R P' (with A1 = I2C addres of MCP23017, W2 = register address, A3 = I2C addres of MCP23017), but I get a communication error.
Can someone tell me the correct sequence that I have to use?
Thank you
S _ OPCODE+W _ ACK* _ ADDRESS _ ACK* _ SR _ OPCODE+R _ ACK* _ DATAOUT* _ P
where:
S = start
OPCODE+W = 7bit I2C addres of MCP23017 + LSB bit set to 0 (write instruction)
ACK* = acknowledge provided by the MCP23017
ADDRESS = register address to be read
SR = restart
OPCODE+R = 7bit I2C addres of MCP23017 + LSB bit set to 1 (read instruction)
DATAOUT* = data out from MCP23017
I'm using this sequence in the "I2C Bus Master" block: 'S A W Sr A R P' (with A1 = I2C addres of MCP23017, W2 = register address, A3 = I2C addres of MCP23017), but I get a communication error.
Can someone tell me the correct sequence that I have to use?
Thank you
-
- Site Admin - Expert
- Posts: 616
- Joined: Wed Mar 07, 2007 11:23 pm
- Location: Bayonne- France
- Contact:
Re: dsPIC & MCP23017 using I2C
Hi Stefano,
I2C is a very sensitive protocol and hard to debug. It greatly help to check with an oscillsocope what's going on.
you may try to use : S A W Sr A Rnack P
Good luck.
I2C is a very sensitive protocol and hard to debug. It greatly help to check with an oscillsocope what's going on.
you may try to use : S A W Sr A Rnack P
Good luck.
Re: dsPIC & MCP23017 using I2C
Thanks Lubin for your answer. In these days I have tryed to solve the communication problem, and finally I have solved it!
I have used the string that you have suggested (S A W Sr A Rnack P) where:
A = 7bit I2C addres of MCP23017 + LSB bit set to 0 (write instruction)
W = register address to read from
A = 7bit I2C addres of MCP23017 + LSB bit set to 1 (read instruction)
I'd suggest you to specify that the addresse (A) in the "I2C Bus Master" block it's not only the I2C addres of MCP23017, but it must contain the bit that specify if the subsequent instruction (W or R or Rnack) is a write or read instruction (at first I thought that this bit was automatically set by the "I2C Bus Master" block).
Stefano
I have used the string that you have suggested (S A W Sr A Rnack P) where:
A = 7bit I2C addres of MCP23017 + LSB bit set to 0 (write instruction)
W = register address to read from
A = 7bit I2C addres of MCP23017 + LSB bit set to 1 (read instruction)
I'd suggest you to specify that the addresse (A) in the "I2C Bus Master" block it's not only the I2C addres of MCP23017, but it must contain the bit that specify if the subsequent instruction (W or R or Rnack) is a write or read instruction (at first I thought that this bit was automatically set by the "I2C Bus Master" block).
Stefano
Re: dsPIC & MCP23017 using I2C
Hi Lubin, I am trying to interface with a similar device as stefano that uses the same I2C protocol - it is a 3 axis accelerometer LIS3LV02DQ. I wrote a very simple test program but I've had no success so far. You mentioned in your response that it helps to use an oscilloscope to troubleshoot, so I'm looking at the SDA and SCL with an oscilloscope but I am not seeing any signals, they are just pulled high by my 5K pull up resistors. Is there an error in my diagram that could be causing this? I attached it to this post. Thanks in advance,
Gabe
PS great job on the blockset, I see myself upgrading to 8 or 10 pins once I have a project that needs it!
Gabe
PS great job on the blockset, I see myself upgrading to 8 or 10 pins once I have a project that needs it!
- Attachments
-
- I2Ctest.mdl
- (26.49 KiB) Downloaded 704 times
-
- Site Admin - Expert
- Posts: 616
- Joined: Wed Mar 07, 2007 11:23 pm
- Location: Bayonne- France
- Contact:
Re: dsPIC & MCP23017 using I2C
Dear Gabe,
I did not see any obvious error in your model. You may add a blinking led to make sure the dsPIC is running anyway.
I do not look at the specific chip you are using, and at the I2C parameters. I2C digital bus is really a pain to debug compared to its SPI equivalent.
I am using I2C bus for one project, but I configured it quite a long time ago, I am not really up to date...
Anyway,
Look closely at initialisation time if really nothing is happening when you switch-on the system. You may have few data exchange on the SCL and SDA line and then I2C get stuck. In that case, it is a protocol problem.
Otherwise, I could only advice to play with parameters until you get something to move on your scope.
There is timeout mechanism on this I2C block that makes the execution to continue, even if the I2C bus is stuck. (Note that Real time constraints are not going to be respected if I2C bus is not working properly!)
- disturb SCL and SDA line by hand during the execution to see if nothing happens. (Sometime, I2C bus is stuck)
Or, in the simulink model:
- Enable I2C before use
- Disable I2C after use
- Force with a/several digital output to make changes on SCL and SDA signals.
That may unlock the accelerometer from a stuck state!
I wish you good luck for that part!
Lubiun
I did not see any obvious error in your model. You may add a blinking led to make sure the dsPIC is running anyway.
I do not look at the specific chip you are using, and at the I2C parameters. I2C digital bus is really a pain to debug compared to its SPI equivalent.
I am using I2C bus for one project, but I configured it quite a long time ago, I am not really up to date...
Anyway,
Look closely at initialisation time if really nothing is happening when you switch-on the system. You may have few data exchange on the SCL and SDA line and then I2C get stuck. In that case, it is a protocol problem.
Otherwise, I could only advice to play with parameters until you get something to move on your scope.
There is timeout mechanism on this I2C block that makes the execution to continue, even if the I2C bus is stuck. (Note that Real time constraints are not going to be respected if I2C bus is not working properly!)
- disturb SCL and SDA line by hand during the execution to see if nothing happens. (Sometime, I2C bus is stuck)
Or, in the simulink model:
- Enable I2C before use
- Disable I2C after use
- Force with a/several digital output to make changes on SCL and SDA signals.
That may unlock the accelerometer from a stuck state!
I wish you good luck for that part!
Lubiun
Re: dsPIC & MCP23017 using I2C
Hi, thanks for the reply.
I had already verified that it was running by flashing an LED as you suggested, so it isn't getting stuck. I ended up importing the project in to MPLAB so that I could debug a little more in detail. I noticed the timeout variable "slowDown" in several places, and so I turned on an LED if slowDown was > 4000 (it times out at 5000) after each of the timeouts. It was actually timing out at the last step of the sequence (stop).
But what is even weirder is that the acknowlegde bit from the slave, i2ccon.ACKDT, gets set to zero (slave acknowledge) even when I don't plug in my slave device! Or when I put an arbitrary slave address in. I verified this by having it turn on an LED just after it checks for an acknowledge, the first time. It actually makes it through the entire sequence, up until the end where it times out.
Anyway it got too late last night but I'll give it another stab tonight and see if I can figure it out. I must say though, even though I am having problems it is much easier to start from your generated code than starting from scratch. I'll let you know once (if) I figure it out.
Gabe
I had already verified that it was running by flashing an LED as you suggested, so it isn't getting stuck. I ended up importing the project in to MPLAB so that I could debug a little more in detail. I noticed the timeout variable "slowDown" in several places, and so I turned on an LED if slowDown was > 4000 (it times out at 5000) after each of the timeouts. It was actually timing out at the last step of the sequence (stop).
But what is even weirder is that the acknowlegde bit from the slave, i2ccon.ACKDT, gets set to zero (slave acknowledge) even when I don't plug in my slave device! Or when I put an arbitrary slave address in. I verified this by having it turn on an LED just after it checks for an acknowledge, the first time. It actually makes it through the entire sequence, up until the end where it times out.
Anyway it got too late last night but I'll give it another stab tonight and see if I can figure it out. I must say though, even though I am having problems it is much easier to start from your generated code than starting from scratch. I'll let you know once (if) I figure it out.
Gabe
Who is online
Users browsing this forum: No registered users and 4 guests