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.