Hi Experts,
I have an EEPROM which I'm trying to interface to MSP430G2553. I wrote a driver for I2C, the problem is it has to send data from MSB to LSB but the controller is exactly doing the opposite. And one more thing I would like to mention is that it is coming to RX interrupt but it is checking an if statement and coming out from ISR. It is not executing the code written in RX Interrupt. Can anyone point out the issue which I mentioned here
1) MSB to LSB issue and
2) I2c Rx Interrupt it is not executing any statement just checking if condition and coming out from there.
static inline void init_sysClock(void)
{
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
BCSCTL3 = LFXT1S_0; // LFXT1 = 32KHz
BCSCTL2 = SELM_0; // select SMCLK = MCLK = DCOCLK
}
void initI2C()
{
// Init Gpio for I2C Bus
P3REN |= BIT6 + BIT7;
I2C_PIN_SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
I2C_PIN_SEL2 |= BIT6 + BIT7; // I2C Pin Configuration
UCB0CTL1 |= UCSWRST;
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC + UCMSB;
UCB0CTL1 = UCSSEL_2 + UCSWRST;
UCB0BR0 = 10; // Our SMCLK = 1MHz. SMCLK/10 = ~100KHz
UCB0BR1 = 0;
UCB0I2CSA = SLAVE_READ_ADDR;
UCB0CTL1 &= ~UCSWRST;
UCB0I2CIE |= UCNACKIE;
}
I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
UCB0_TxComplete = false;
//Copy register data to TransmitBuffer
CopyArray(reg_data, TransmitBuffer, count);
TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
/* Initialize slave address and interrupts */
UCB0I2CSA = dev_addr;
IFG2 &= ~(UCB0TXIFG + UCB0RXIFG); // Clear any pending interrupts
IE2 &= ~UCB0RXIE; // Disable RX interrupt
IE2 |= UCB0TXIE; // Enable TX interrupt
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
while(!UCB0_TxComplete);
return MasterMode;
}
I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
{
/* Initialize state machine */
UCB0_RxComplete =false;
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;
RXByteCtr = count;
TXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;
/* Initialize slave address and interrupts */
UCB0I2CSA = dev_addr;
IFG2 &= ~(UCB0TXIFG + UCB0RXIFG); // Clear any pending interrupts
IE2 &= ~UCB0RXIE; // Disable RX interrupt
IE2 |= UCB0RXIE; // Enable RX interrupt
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
while(!UCB0_RxComplete);
return MasterMode;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
init_system();
initI2C();
I2C_Master_ReadReg(SLAVE_READ_ADDR, 0x00, 1);
while(1)
{
__no_operation();
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
#else
#error Compiler not supported!
#endif
{
if (IFG2 & UCB0TXIFG) // Transmit Data Interrupt
{
switch (MasterMode)
{
case TX_REG_ADDRESS_MODE:
UCB0TXBUF = TransmitRegAddr;
if (RXByteCtr)
MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now
else
MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer
break;
case SWITCH_TO_RX_MODE:
IE2 |= UCB0RXIE; // Enable RX interrupt
IE2 &= ~UCB0TXIE; // Disable TX interrupt
UCB0CTL1 &= ~UCTR; // Switch to receiver
MasterMode = RX_DATA_MODE; // State state is to receive data
UCB0CTL1 |= UCTXSTT; // Send repeated start
if (RXByteCtr == 1)
{
//Must send stop since this is the N-1 byte
while((UCB0CTL1 & UCTXSTT));
UCB0CTL1 |= UCTXSTP; // Send stop condition
}
break;
case TX_DATA_MODE:
if (TXByteCtr)
{
UCB0TXBUF = TransmitBuffer[TransmitIndex++];
TXByteCtr--;
}
else
{
//Done with transmission
UCB0_TxComplete = true;
UCB0CTL1 |= UCTXSTP; // Send stop condition
MasterMode = IDLE_MODE;
IE2 &= ~UCB0TXIE; // disable TX interrupt
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
default:
__no_operation();
break;
}
}
}
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCIAB0RX_ISR (void)
#else
#error Compiler not supported!
#endif
{
if (IFG2 & UCB0RXIFG) // Receive Data Interrupt
{
//Must read from UCB0RXBUF
uint8_t rx_val = UCB0RXBUF;
if (RXByteCtr)
{
ReceiveBuffer[ReceiveIndex++] = rx_val;
RXByteCtr--;
}
if (RXByteCtr == 1)
{
UCB0CTL1 |= UCTXSTP;
UCB0_RxComplete = true;
}
else if (RXByteCtr == 0)
{
IE2 &= ~UCB0RXIE;
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}