I2C problems in MZ rev B2 not A3
I'm using a PIC32MZ2048EFG064, xc32 V2.40, no Harmony.
I'm having some I2C problems. The PIC is an I2C master to a single device, a touch screen controller. Previous boards were built with rev A3 and have been working flawlessly. I built another board and the touch screen didn't work....exact same layout, exact same code. I verified no solder bridges, and continuity is where it should be. I have 2.2K pull-ups on both lines and they measure correctly. I swapped LCDs and I know the LCD touchscreen is good. Upon throwing the debugger on it I'm seeing that the I2C peripheral appears to stop working after setting the I2C5CON.PEN. The chip acting screwy is rev B2.
I found someone else having trouble with B2 parts despite having working code on A3: https://www.microchip.com/forums/m1103301.aspx
....but, the issue they seem to be having is based upon not clearing the lower bits of I2CxCON when the bus is disabled/enabled. I never disable the bus, and it's not clear that I'd have to.
First, I've avoided I2C until this, so it's not second nature like most other PIC peripherals. Since I'm not using an RTOS and can't have blocking code, I kick off a transaction like this from an interrupt the LCD touchscreen generates:
I2C5CONbits.SEN = 1;
step = 1;
Then in the I2C interrupt I have a switch statement that processes the entire transaction in steps so I'm not waiting in while() loops. The 'step' variable is to keep track of progress:
I2C5TRN = ((0x38 << 1) | 0);
step = 2;
I2C5TRN = 0x03;
step = 3;
I2C5CONbits.RSEN = 1;
step = 4;
I2C5TRN = ((0x38 << 1) | 1); //Sends the slave address over the I2C line.
step = 5;
I2C5CONbits.RCEN = 1;
step = 6;
x = (unsigned int)((I2C5RCV & 0x0F) * 256);
I2C5CONbits.PEN = 1;
step = 7;
(the other steps omitted)
IFS5bits.I2C5MIF = 0;
Like I said, this worked perfectly on rev A3. Now on B2, it's not going past step 6 (case 6). There's over 30 steps to pull the LCD touchscreen coordinates and I didn't put it all here because it doesn't go further than this because the I2C interrupt stops firing.
First, is there a better way to do this without blocking code? I'm ok with this method if it works on all the part revs. And second, why does the interrupt stop firing on rev B2 parts!? According to the errata, rev B2 should only have an issue for clock rates >400kHz. I was running at 333, but reduce it to under 100KHz for troubleshooting.
Am I doing something fundamentally incorrect?