dsPIC33CH Address Error Trap Caused by MCC I2C/IOC

dsPIC33CH Address Error Trap Caused by MCC I2C/IOC

Postby willj002 » Tue Nov 17, 2020 7:50 pm

I have been using I2C to communicate with a small LCD interface board, which uses a PCF8574. I was able to communicate fine with the board, and I moved onto the next section of the development, interfacing with a couple of momentary switches. For these, I used interrupt on change pins, configured to "any" in MCC.

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
willj002
 
Posts: 1
Joined: Tue Nov 17, 2020 7:46 pm
PIC experience: EE Student

Return to dsPIC33CH

Who is online

Users browsing this forum: No registered users and 3 guests

cron