0
\$\begingroup\$

I've been trying to debug my I2C communication between the PIC24FJ32GA002 and the PCA9546APWR bus switch for a couple of days now. I just want to test that I could enable a channel of the bus switch, so what I've done is write to the bus switch to enable a channel, and then read from the bus switch to confirm if the selected channel is enabled. I've had no problems writing to the bus switch using the debugger; however the debugger halts and resets all the time upon a read from the bus switch afterwards, although no breakpoint is set.

I've been trying a couple of ways to find out what is causing the halt, I've implemented exception handlers provided by Microchip: http://www.embeddedcodesource.com/codesnippet/address-error-trap to see if hard traps such as address errors etc are causing this issue, but none of those handlers are entered when the debugger halts. The RCON and INTCON1 registers are zero as well.

So now I'm looking at the scope to trace the SDA signal line, somehow I couldn't capture the SCL line properly on the scope, but I assume it should be working if I see changes in the SDA line?

Here are a few pictures of the write sequence to the bus switch: enter image description here

enter image description here

I think the sequence is right, from using the cursors, if each bit is 40us long, I get the correct write sequences and ACK from the slave. The switch address is 0xE0 for a write, and I'm enabling channel 2 of the switch. This is from pg 13 of the datasheet: http://www.ti.com/lit/ds/symlink/pca9546a.pdf

Now, here is the picture of the read from the slave:

enter image description here

From where my time cursor is placed(ignoring the ACK period from slave), I can see that I'm getting the correct results from the slave which is 0x02, but somehow the debugger halts here all the time. I'm a little concerned about the SDA line not going high after the ACK from the slave though. Could that be the issue?

Here is my code for the bus read as well:

char I2C_bus_read(void){

char status;

I2C2CONbits.SEN = 1;
while(!IFS3bits.MI2C2IF);
IFS3bits.MI2C2IF = 0;
I2C2TRN = BUS_SWITCH_READ;
while(!IFS3bits.MI2C2IF);
IFS3bits.MI2C2IF= 0;
I2C2CONbits.RCEN = 1;
while(!I2C2STATbits.RBF);
status = I2C2RCV;
I2C2CONbits.ACKDT = 1;
I2C2CONbits.ACKEN = 1;
while(!IFS3bits.MI2C2IF);
IFS3bits.MI2C2IF = 0;
I2C2CONbits.PEN = 1;
while(!IFS3bits.MI2C2IF);
IFS3bits.MI2C2IF = 0; 
return status;}

EDIT: Following the comment below, my #pragma configuration bits have turned off the watchdog timer previously, and I'm running on the default 8 MHz clock. I2C is run at the standard 100 kHz.

I checked the RCON registers again, and I must have been confused prior, for RCON isn't zero as claimed, but the bits for power on reset (POR), brown out reset (BOR) and master clear reset(nMCLR) is set. What interests me the most is the (nMCLR) pin. Why is that pulled low? Could it be my hardware setup that is wrong? Attached now is my schematic for the I2C setup.

enter image description here

\$\endgroup\$
  • 1
    \$\begingroup\$ Check if you have a watchdog active. Also the PIC has a register that indicates the reset cause on reboot, you can find a hint why your PIC resets in that register. \$\endgroup\$ – le_top Apr 29 at 18:16
  • \$\begingroup\$ Are you debugging using a Microchip debugger? Try running without the debugger - they introduce overhead and sometimes timing functions are affected. \$\endgroup\$ – John Birckhead Apr 29 at 20:16
  • \$\begingroup\$ @JohnBirckhead Yes, I'm using a chipKIT programmer by Digilent. If running without the debugger, can I connect an LED and insert a statement after the read function to see if the code execution ever gets there? That's a way to test if it works, right? But I do need the debugger to read register values from the 3 light sensors to which the bus switch is connected. \$\endgroup\$ – Lim LS Apr 29 at 20:41
  • \$\begingroup\$ On a sidenote: 1k pull-up resistors on the I2C bus is a bit small. It is under the limit suggested by TI: ti.com/lit/an/slva689/slva689.pdf . \$\endgroup\$ – le_top Apr 29 at 22:46
  • 1
    \$\begingroup\$ @limls Yes, I multiply by two because of SCL and SDA. The debugger is limited with regards to the current it can provide. So your voltage drops all of a sudden. 400pF is a lot, only compute such a worst case value if you really expect it. \$\endgroup\$ – le_top May 1 at 18:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.