I made interrupt handlers to deal with the IOCs, then used the MCC generated setter functions to assign each IOC to the relevant handler I just created. I tested this, and it appeared to work correctly. Finally, I tried pressing multiple buttons at the same time, at which point the master core of the PIC froze. The slave kept running.
Following this, I restarted the PIC, and it froze again, not even finishing the initialisation of the LCD, no buttons pressed. After some investigating, I found the problem to be it getting caught in the address error trap. I removed the code I had just added, effectively stepping back to when it worked, although now, it still gets stuck in this address error trap.
I have found the point where it hangs up to be when I try to format a byte into two nibbles, then send them via I2C. This is done in these two functions:
- Code: Select all
void LCD_WriteCommandNibble(uint8_t data)
{
I2C_WriteByte(data << 4);
I2C_WriteByte((data << 4) | 0b00000100);
__delay_us(400);
I2C_WriteByte((data << 4) | 0b00000000);
}
void LCD_WriteCommandByte(uint8_t data)
{
LCD_WriteCommandNibble(data >> 4);
LCD_WriteCommandNibble(data);
}
If I manually split the byte into two nibbles and call LCD_WriteCommandNibble() twice, it works. For example:
- Code: Select all
IO_LED3_Toggle();
data = 0b00000110;
LCD_WriteCommandByte(data);
__delay_us(53); // Would go into trap
IO_LED3_Toggle();
data = 0b0000;
LCD_WriteCommandNibble(data);
data = 0b0110;
LCD_WriteCommandNibble(data);
__delay_us(53); // Would NOT go into trap
However, looking inside I2C_WriteByte() and removing the actual function call to send the byte by I2C (I2C2_MasterWrite()), the PIC no longer gets caught in the trap. Obviously, the LCD now doesn't work. I2C2_MasterWrite() is the MCC generated function to write a byte by I2C.
- Code: Select all
void I2C_WriteByte(uint8_t data)
{
uint16_t timeOut, slaveTimeOut;
I2C2_MESSAGE_STATUS status;
status = I2C2_MESSAGE_PENDING;
timeOut = 0;
slaveTimeOut = 0;
while(status != I2C2_MESSAGE_FAIL)
{
status = I2C2_MESSAGE_PENDING;
I2C2_MasterWrite(&data, 1, LCD_DEVICE_ADDRESS, &status); //Comment this out and it works
while(status == I2C2_MESSAGE_PENDING)
{
I2C_DELAY(); // Defined as __delay_us(20);
if (slaveTimeOut == SLAVE_I2C_GENERIC_DEVICE_TIMEOUT)
{
break;
}
else
{
slaveTimeOut++;
}
}
if(status == I2C2_MESSAGE_COMPLETE)
break;
// if status is I2C2_MESSAGE_ADDRESS_NO_ACK,
// or I2C2_DATA_NO_ACK,
// The device may be busy and needs more time for the last
// write so we can retry writing the data, this is why we
// use a while loop here
if (timeOut == SLAVE_I2C_GENERIC_RETRY_MAX)
break;
else
timeOut++;
}
}
Note this is all programmed on the master core, I have another project programmed onto the slave core, which works fine, and keeps running throughout the master core getting trapped.
Have I done something stupid or have I somehow busted my PIC? Thank you!!!
dsPIC33CH512MP508
MPLAB X IDE v5.35
XC16 v1.50
PICKIT 3