Thanks for code, just perfect, I works without much effort.
I just modified the code a little bit to provide for ACKs. The only noticable change is the last section of the i2c_read() where IIF flag is rechecked. If I don't do this, I'm unable to do a read operation again??. For simplicity sake I've removed the arguments to these functions, read and writes are always done to address 0xaa55 (32K Bytes eeprom). The write forces a write 35 always.
void i2c_write(void)
{
I2CR &= ~I2CR_TXAK_BITMASK; // enable the ACK
I2CR |= I2CR_MTX_BITMASK; // Set the Transmit Mode
I2CR |= I2CR_MSTA_BITMASK; // Generate the START condition
I2DR = 0xa0; // Send the Control byte to the EEPROM
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
return;
}
I2DR = 0xaa; // Send the word Address high byte to the EEPROM
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
return;
}
I2DR = 0x55; // Send the word Address Low byte to the EEPROM
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
return;
}
I2DR = 35; // Write Data
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
return;
}
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
}
void i2c_read(void)
{
UINT8 data=0;
/* Check Bus Busy. */
if(!st_exp_cent_timer(ST_I2C_CENT_TIMER))
return;
st_arm_cent_timer(ST_I2C_CENT_TIMER, 2);
I2CR &= ~I2CR_TXAK_BITMASK; // enable the ACK
I2CR |= I2CR_MTX_BITMASK; // Set the Transmit Mode
I2CR |= I2CR_MSTA_BITMASK; // Generate the START condition
I2DR = 0xa0; // Send the Control byte to the EEPROM
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
mtac_obj_tbl[0].r_phase.vtg = data;
return;
}
I2DR = 0xaa; // Send the word Address high byte to the EEPROM
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
mtac_obj_tbl[0].r_phase.vtg = data;
return;
}
I2DR = 0x55; // Send the word Address Low byte to the EEPROM
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
mtac_obj_tbl[0].r_phase.vtg = data;
return;
}
I2CR |= I2CR_RSTA_BITMASK; // Send a re-start condition.
I2DR = 0xa1; // Send the control byte to EEPROM
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
if (I2SR & I2SR_RXAK_BITMASK) // Check for ack bit.
{
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
mtac_obj_tbl[0].r_phase.vtg = data;
return;
}
I2CR |= I2CR_TXAK_BITMASK; // Disable the TACK
I2CR &= ~I2CR_MTX_BITMASK; // Change the direction to receive.
I2DR; // Dummy Read to trigger receive.
while(~I2SR & I2SR_IIF_BITMASK){}; // then wait for the control byte done
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
data = I2DR;
while(~I2SR & I2SR_IIF_BITMASK){}; // Wait for one byte transfer is done.
I2SR &= ~I2SR_IIF_BITMASK; // clear the flag
I2CR &= ~I2CR_MSTA_BITMASK; // Send the stop condition
mtac_obj_tbl[0].r_phase.vtg = data;
}