23.6.2 Host Transmission (10-bit Address)

Host Transmission (10-bit Address)

#include <xc.h>


#define INIT                          0
#define ADDRESS_PHASE_UPPER_10BIT     1
#define ADDRESS_PHASE_LOWER_10BIT     2
#define DATA_WRITE                    3


unsigned char count=0;

#define mCLIENT_ADDRESS 0x14C
 

unsigned char data[10],phase;

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_UPPER_10BIT;
    I2C1CON1bits.SEN= 1;         // Send Start bit
     
        
    while(1);
}

    

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

    switch(phase)
    {
 
        case ADDRESS_PHASE_UPPER_10BIT:
		 /*Verify if start has been sent*/
            if(I2C1STAT2bits.STARTE)
            {
                /* Transmit client address with RW =0 , writing to client*/
                I2C1TRN = ((((mCLIENT_ADDRESS >> 8) & 0x03)<< 1) | 0 ) + 0b11110000  ; 
                phase = ADDRESS_PHASE_LOWER_10BIT;
            }
            break;
        case ADDRESS_PHASE_LOWER_10BIT:
		/*Verify if the upper 10bit address is ACKed*/
            if (I2C1STAT1bits.ACKSTAT ==0)
            {
                I2C1TRN = mCLIENT_ADDRESS & 0xFF  ; 
                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;
    }
}