Please review the following code and let me know why my i2c interrupts are not occuring either during read or write operation. The interrupt occurs only once when the system clock is started. Please ignore the variable reset_count which i am using to break any while loop after sometime.
void InitI2C(unsigned char eeprom_i2c_address,unsigned char i2c_port_sel,unsigned char i2c_port_out,
unsigned char i2c_port_dir, unsigned int sda_pin, unsigned int scl_pin, unsigned char scl_clock_div)
{
//i2c_port_sel |= sda_pin | scl_pin; // Assign I2C pins to USCI_B0
P2SEL |= sda_pin | scl_pin; // Assign I2C pins to USCI_B0
// Recommended initialization steps of I2C module as shown in User Guide:
UCB0CTLW0 |= UCSWRST; // Enable SW reset
UCB0CTLW0 |= UCMST | UCMODE_3 | UCSSEL_2; // I2C Master, synchronous mode
//UCB0CTL1 = UCSSEL_2 + UCTR + UCSWRST; // Use SMCLK, TX mode, keep SW reset
UCB0BR0 = scl_clock_div; // fSCL = SMCLK(16 MHz) / 40 = ~400kHz
UCB0BR1 = 0;
UCB0I2CSA = eeprom_i2c_address; // define Slave Address
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE = UCTXIE0 | UCRXIE0 | UCNACKIE | UCSTTIE | UCALIE;
_enable_interrupts();
}
void I2CWriteInit(void)
{
UCB0CTLW0 |= UCTR; // UCTR=1 => Transmit Mode (R/W bit = 0)
UCB0IE &= ~UCRXIE0; // disable Receive ready interrupt
UCB0IE |= UCTXIE0; // enable Transmit ready interrupt
}
void I2CReadInit(void)
{
UCB0CTLW0 &= ~UCTR; // UCTR=0 => Receive Mode (R/W bit = 1)
UCB0IE &= ~UCTXIE0; // disable Transmit ready interrupt
UCB0IE |= UCRXIE0; // enable Receive ready interrupt
}
bool EEPROM_PageWrite(unsigned int StartAddress, unsigned char * Data, unsigned int Size)
{
unsigned char BytePtr = 0;
unsigned char Len, i;
unsigned int WriteAddr = StartAddress;
unsigned char BytesToTransfer = Size;
while (UCB0STAT & UCBUSY); // wait until I2C module has
// finished all operations.
while(BytesToTransfer)
{
if (BytesToTransfer > MAXPAGEWRITE)
{
Len = MAXPAGEWRITE;
}
else
{
Len = BytesToTransfer;
}
I2CBufferArray[Len+1] = WriteAddr >> 8; // calculate high byte
I2CBufferArray[Len] = WriteAddr & 0xFF; // and low byte of address
for (i=0; i<Len; i++)
{
I2CBufferArray[Len-i-1] = Data[BytePtr+i];
}
PtrTransmit = Len+2;
I2CWriteInit();
// => I2C communication is started
TxInProgress = 1;
UCB0CTL1 |= UCTXSTT; // start condition generation
__bis_SR_register( GIE); // Enter LPM0 w/ interrupts
reset_count = 0;
while (1)
{
if (TxInProgress != 1)
{
break;
}
reset_count++;
if(reset_count >= RESET_COUNT)
return FALSE;
}
UCB0CTL1 |= UCTXSTP; // I2C stop condition
reset_count = 0;
while(UCB0CTL1 & UCTXSTP) // Ensure stop condition got sent
{
reset_count++;
if(reset_count >= RESET_COUNT)
return FALSE;
}
EEPROM_AckPolling(); // Ensure data is written in EEPROM
WriteAddr += Len;
BytePtr += Len;
BytesToTransfer -= Len;
}
return TRUE;
}
bool EEPROM_SequentialRead(unsigned int Address , unsigned char * Data , unsigned int Size)
{
unsigned char adr_hi;
unsigned char adr_lo;
unsigned int counterSize;
while (UCB0STAT & UCBUSY); // wait until I2C module has
// finished all operations
// Write Address first
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 = 2; // set I2CBufferArray Pointer
I2CWriteInit();
TxInProgress = 1;
UCB0CTL1 |= UCTXSTT; // start condition generation
// => I2C communication is started
__bis_SR_register(GIE);
reset_count = 0;
while (1)
{
if (TxInProgress != 1)
{
break;
}
reset_count++;
if(reset_count >= RESET_COUNT)
return FALSE;
}
// Read Data byte
I2CReadInit();
RxLen = Size;
UCB0CTL1 |= UCTXSTT; // I2C start condition
//while(UCB0CTL1 & UCTXSTT); // Start condition sent?
__bis_SR_register(GIE);
reset_count = 0;
while(RxLen)
{
reset_count++;
if(reset_count >= RESET_COUNT)
return FALSE;
}
UCB0CTL1 |= UCTXSTP; // I2C stop condition
reset_count = 0;
while(UCB0CTL1 & UCTXSTP) // Ensure stop condition got sent
{
reset_count++;
if(reset_count >= RESET_COUNT)
return FALSE;
}
for(counterSize = 0 ; counterSize < Size ; counterSize++)
{
Data[counterSize] = I2CBufferArray[counterSize];
}
return TRUE;
}
void EEPROM_AckPolling(void)
{
while (UCB0STAT & UCBUSY); // wait until I2C module has
// finished all operations
do
{
UCB0CTL1 |= UCTR; // I2CTRX=1 => Transmit Mode (R/W bit = 0)
UCB0CTL1 &= ~UCTXSTT;
UCB0CTL1 |= UCTXSTT; // start condition is generated
while(UCB0CTL1 & UCTXSTT) // wait till I2CSTT bit was cleared
{
if(!(UCNACKIFG & UCB0IFG)) // Break out if ACK received
break;
}
UCB0CTL1 |= UCTXSTP; // stop condition is generated after
// slave address was sent => I2C communication is started
while (UCB0CTL1 & UCTXSTP); // wait till stop bit is reset
__delay_cycles(96000); // Software delay
}while(UCNACKIFG & UCB0IFG);
}
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch(__even_in_range(UCB0IV,30))
{
case USCI_I2C_UCNACKIFG: // RXIFG0
TxInProgress=2; // The main function needs to act based on noack
UCB0CTL1 |= UCTXSTP; // I2C stop condition
LPM0_EXIT; // Exit LPM0
break;
case USCI_I2C_UCRXIFG0: // RXIFG0
if (RxLen)
{
I2CBufferArray[PtrReceive++] = UCB0RXBUF; // store received data in buffer
if (PtrReceive >= RxLen)
{
//UCB0CTL1 |= UCTXNACK;
PtrReceive = 0;
RxLen = 0;
}
}
break;
case USCI_I2C_UCTXIFG0: // TXIFG0
if (PtrTransmit > 0) // Check TX byte counter
{
UCB0TXBUF = I2CBufferArray[--PtrTransmit]; // Load TX buffer
}
else
{
TxInProgress = 3;
LPM0_EXIT;
}
break;
default:
break;
}
}