Electrical – PIC18LF24K40 I2C read and write using Polling method

ci2cmicrochippicxc8

I'm trying to implement read and write routines using Polling method for a PIC18LF24K40, write seems to work, but not read. I cannot figure out what i am doing wrong.

EDIT: Reading a byte stored in a register on a slave chip:

   void read_LDC_reg(U8 *dest_addr)
   {
      U8 temp=0;   

      if( ( check_for_bus_free_iic() == 1) )   
      send_start();

      PIR3bits.SSP1IF=0;
      I2C_wait();  

      send_address(U8_LDC_I2C_ADDRESS,READ_BIT);

      send_start();
      SSP1CON2bits.RCEN1=1;

      while(SSP1STATbits.BF==0);
      temp=read_from_slave();

      PIR3bits.SSPIF = 0;

      dest_addr =  &temp;

      send_stop();

}

send_start() looks like this:

void send_start()
{
    while(SSP1STATbits.RW);          // wait for write to complete
    SSP1CON2bits.SEN=1;              //set start enable bit

    if(PIR3bits.BCLIF==1)
        PIR3bits.BCLIF =0;  //Clear collision bit in PIR register

    while(SSP1CON2bits.SEN);         //waits to get cleared by hardware 
}  

I2C_wait looks like this:

void I2C_wait(void)
{
    while( (SSP1STAT & 0x04) | (SSP1CON2 & 0x1F) );

    PIR3bits.BCL1IF=0;

}

send_address() looks like this:

void send_address(unsigned char addr,unsigned char ReadWrite_bit)
{
    unsigned char temp=0;
    temp = ( (addr <<1u ) | (ReadWrite_bit & (unsigned char)0x01) ); 
    write_to_bus(temp);


}

write_to_bus() looks like this:

void write_to_bus(unsigned char data)
{

    send_start();
    I2C_wait();

    send_byte(data);
    I2C_wait(); 

    send_stop();        
}

read_from_slave() looks like this:

unsigned char read_from_slave(void)
{  
    unsigned char rcvd_byte=0;   

    rcvd_byte = SSP1BUF;     
    return rcvd_byte;    
}

I am getting unexpected values from the slave register, i do not know why i believe i have initialised correctly, i can see the SCL and SDA waveforms on Oscilloscope.

EDIT: Hardware is fine, I2C works perfectly when i use the I2C Driver code generated from MCC(MPLAB Code Generator), i want to reduce the overhead caused by MCC in my project, thats the reason im going for I2C using Polling option.

Best Answer

Load test values in a dummy MCU and try simulating with the Proteus design suite, but i agree with Buhra with checking the flag for successful reception from the slave, and if possible check necessary flags that indicate a free buffer and transmission-ready state.