AN2039 - I²C Slave Interrupt file

Modifying the MPLAB® Code Configurator (MCC) created I²C Slave Interrupt file to implement Application Serial Interface

When MCC is used to generate an I²C Slave Interrupt file, MCC generates an EEPROM example for the user in i2c.c file. Since we will not be using the EEPROM code, this section will explain how to modify the existing code to accommodate the power sequencer I²C interface code. The I²C command structure receives up to four bytes of information and transmits two bytes, so we need to create and define buffers to hold that data:

unsigned char RcvBuf[4];
unsigned char TrmtBuf[2];

To access these buffers, appropriate pointers should also be defined as:

unsigned char RcvPtr=0;
unsigned char TrmtPtr=0;

The following example can be a possible scenario:
Presumably, only two commands are implemented: 0x20 (Set Start Time) and 0x24 (Read Start Time). All other commands follow the same structure as the two mentioned here and can be easily added to their respective state machine code.

void ProcessRcvBuf(void);
void LoadTrmtBuf(void);

The ProcessRcvBuf( ) function processes the received I²C data from the Master or from the Graphical User Interface (GUI).

void ProcessRcvBuf(void)
{
    unsigned int r;
    if (RcvPtr >= 4)
        RcvPtr = 0;
    switch (RcvBuf[0])
    {
        case 0x20:      // Start time int value
            r = RcvBuf[3];
            r = r << 8;
            appmData[RcvBuf[1]].OnTime = r + (int)RcvBuf[2];
            break;
        default:
            break;
    }
}

The ProcessRcvBuf() functions should be called as the last instruction in the I²C callback function after all serial data has been received. Depending on the command, two or four data bytes are received serially. The function SetDataLength( ) is called to determine the number of data bytes which will be received serially (either two or four). Once the appropriate bytes are received, the ProcessRcvBuf( ) function is called and the serial data is processed.

case SALVE_NORMAL_DATA:
default:
       // the master has written data to be processed
       RcvBuf[RcvPtr++] = I2C_slaveWriteData;
       if (RcvPtr == 1)
           SetDataLength( );
       if (RcvPtr >= DataLength)
       {RcvPtr = 0;ProcessRcvBuf( );}
       break;

The Transmit buffer is loaded as part of the ProcessRcvBuf( ) operation. Commands which need a transmit reply load the transmit buffer appropriately. The actual transmit occurs in the callback function.

     case I2C_SLAVE_READ_REQUEST:
            if (TrmtPtr == 0)
                LoadTrmtBuf();
            SSP1BUF = TrmtBuf[TrmtPtr++];
            if (TrmtPtr >= 2)
                TrmtPtr = 0;
            break;

With these modifications, the I²C interface will work as required in the application.
© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.