I am trying to read a EEPROM connected to MSP430G2553 on a Launchpad V1.5 using I2C.
I have been partially successful, i.e I can do a random read. This involves no write operation.
However if I want to read from a particular address of the EEPROM, I have to perform a write operation with the Word Address, followed by a read, in this case my code hangs during the writing of the Word address.
I have a bus pirate and I have read as well as written data in to the EEPROM through it.
I am using UCA0 for UART so that I can display the data read from the EEPROM. UCB0 for I2C with the EEPROM
void readFromAddress(unsigned int Address , unsigned char * Data , unsigned int Size)
{
unsigned char adr_hi;
unsigned char adr_lo;
counterSize = Size;
memoryData = Data;
while (UCB0STAT & UCBUSY); // wait until I2C module has
// finished all operations
adr_hi = Address >> 8; // calculate high byte
adr_lo = Address & 0xFF; // and low byte of address
I2CBufferArray[1] = adr_hi; // store single bytes that have to
I2CBufferArray[0] = adr_lo; // be sent in the I2CBuffer.
PtrTransmit = 1; // set I2CBufferArray Pointer
// Write Address first
I2CWriteInit();
UCB0CTL1 |= UCTXSTT; // start condition generation
// => I2C communication is started
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
// Read Data byte
I2CReadInit();
UCB0CTL1 |= UCTXSTT; // I2C start condition
if(UCB0STAT & UCNACKIFG) // nack received this should not happen if address is correct
{
UCB0STAT &= ~UCNACKIFG;
UCB0CTL1 |= UCTXSTP; //stop...
while(UCB0CTL1 & UCTXSTP);
return ; //... and exit
}
while(UCB0CTL1 & UCTXSTT); // Start condition sent?
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void TX_ISR_I2C(void)
{
if(UCB0TXIFG & IFG2)
{
UCB0TXBUF = I2CBufferArray[PtrTransmit];// Load TX buffer
PtrTransmit--; // Decrement TX byte counter
if(PtrTransmit < 0)
{
while(!(IFG2 & UCB0TXIFG));
IE2 &= ~UCB0TXIE; // disable interrupts.
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
else if(UCB0RXIFG & IFG2)
{
counterSize--;
if(counterSize>-1)
{
*memoryData++ = UCB0RXBUF;
if(counterSize==1)
{
UCB0CTL1|=UCTXSTP; // send stop
while(UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
}
}
// store received data in buffer
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
In the above snippet, in the first function after a I2CwriteInit and I2C start condition, the code branches to this interrupt routine and executes once it goes through the following if block
if(UCB0TXIFG & IFG2)
After that it kind of hangs at I2CReadInit call, the debugger kind of gives up at this stage.
Can some one help me out as to what I am doing incorrectly which is causing this to hang.
void I2CWriteInit(void)
{
UCB0CTL1 |= UCTR; // UCTR=1 => Transmit Mode (R/W bit = 0)
IFG2 &= ~UCB0TXIFG;
IE2 &= ~UCB0RXIE; // disable Receive ready interrupt
IE2 |= UCB0TXIE; // enable Transmit ready interrupt
}
/*----------------------------------------------------------------------------*/
// Description:
// Initialization of the I2C Module for Read operation.
/*----------------------------------------------------------------------------*/
void I2CReadInit(void)
{
UCB0CTL1 &= ~UCTR; // UCTR=0 => Receive Mode (R/W bit = 1)
IFG2 &= ~UCB0RXIFG;
IE2 &= ~UCB0TXIE; // disable Transmit ready interrupt
IE2 |= UCB0RXIE; // enable Receive ready interrupt
}