23.6.3 Host Reception (7-bit Address)

Host Reception (7-bit Address)

#include <xc.h>


#define mCLIENT_ADDRESS 0x4C

#define INIT              1
#define ADDRESS_PHASE     2
#define DATA_READ         3

unsigned int hostReceived[20], phase;
unsigned char count = 0;

int main(void) {

/*Configure I2C pins as digital*/



    /*I2C1 configured as Host */

    I2C1LBRG = 38;                      // 100kHz @ 8MIPS
    I2C1HBRG = 38;                      // 100kHz @ 8 MIPS

/* Configure Bus IDle timeout*/
    I2C1CON2bits.BITE = 1;
    I2C1BITObits.BITOPR = 76;
/* Configured interrupt enable bits*/
    I2C1INTCbits.HACKSIE = 1;           // Assert HSTIF on ACK seq
    I2C1INTCbits.HDTXIE = 1;            // Assert HSTIF on TX
    I2C1INTCbits.HDRXIE = 1;            // Assert HSTIF on RX
    I2C1INTCbits.HSCIE = 1;             // Assert HSTIF on start
    I2C1INTCbits.HSTIE = 1;             // Assert I2CxIF when HSTIF is set


    I2C1CON2bits.SMEN = 1;              // Smart mode enabled
    I2C1CON2bits.ACKC = 0b10;           // ACK all the bytes expect last byte
    I2C1CON2bits.PSZ = 10;              // Packet size
    I2C1CON2bits.EOPSC = 0b01;          // End of packet will be set after data bytes
    I2C1CON1bits.ON = 1;                // Enable I2C

    IFS2bits.I2C1IF = 0;                // Clear I2C general interrupt    
    IEC2bits.I2C1IE = 1;                // Enable I2C general interrupt 


    /*wait for bus idle */
    while (!I2C1STAT2bits.BITO);

    phase = ADDRESS_PHASE;
    I2C1CON1bits.SEN = 1; // Send Start bit

    while (1) {

    }
}


void __attribute__((interrupt, no_auto_psv)) _I2C1Interrupt(void) {
    IFS2bits.I2C1IF = 0;

    switch (phase) {
        case ADDRESS_PHASE:
            /*Verify if start has been sent*/
            if (I2C1STAT2bits.STARTE) {
                phase = DATA_READ;
                /* Transmit client address with RW =1 , read  client*/
                I2C1TRN = (mCLIENT_ADDRESS << 1) | 1;
            }
            break;
        case DATA_READ:
            /* Set NDA to indicate next byte is data */
            if (I2C1CON2bits.NDA != 1) {
                I2C1CON2bits.NDA = 1;
                /*Enable receive for the 1st time*/
                I2C1CON1bits.RCEN = 1;
            }
/*Read the received data*/
            if (I2C1STAT1bits.RBF) {
                hostReceived[count++] = I2C1RCV;
            }
            /* If Packet size is 0, EOP will be asserted,send STOP on EOP*/
            if (I2C1STAT2bits.EOP == 1) {
                I2C1CON1bits.PEN = 1;
            } 

            break;
    }

}