23.6.1 Host Transmission (7-bit Address)

Host Transmission (7-bit Address)

#include <xc.h>


#define mCLIENT_ADDRESS 0x4C

#define INIT              0
#define ADDRESS_PHASE     1
#define DATA_WRITE        2


unsigned char data[10], 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.HSCIE = 1; // Assert HSTIF on start
    I2C1INTCbits.HSTIE = 1; // Assert I2CxIF when HSTIF is set

    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) {
                /* Transmit client address with RW =0 , writing to client*/
                I2C1TRN = (mCLIENT_ADDRESS << 1) | 0;
                phase = DATA_WRITE;
            }
            break;
        case DATA_WRITE:
            /* Set NDA to indicate next byte is data */
            if (I2C1CON2bits.NDA != 1) {
                I2C1CON2bits.NDA = 1;
            }
            /* If Packet size is 0, EOP will be asserted,send STOP on EOP*/
            if (I2C1STAT2bits.EOP) {
                I2C1CON1bits.PEN = 1;

            } else {
                if ((I2C1STAT1bits.ACKSTAT == 0) && (!I2C1STAT1bits.TBF) && (!I2C1STAT1bits.TRSTAT)) {
                    I2C1TRN = count++; // Send data to client
                }
            }
            break;
    }
}