Hello everybody!
Started to work with I2C bus, but something goes wrong with it. First of all there is my source code to msp430f169
//******************************************************************************
// MSP-FET430P140 Demo - SMBus Master Interface to SMBus Slave TMP175
//
// Description: I2C/SMBus interface to TMP175 temperature sensor in 9-bit mode.
// TimerA0 CCR0 interrupt is used as a wake up and to read
// the TMP175 temperatre register. If the temperature is greater than 28c,
// P1.0 is set, else reset. CPU is normally off and used only during TA_ISR.
// P2.0 is used for responding to the ALERT response from the Slave TMP175.
// A Slave Alert Response is sent by the master and TMP175 puts its address
// on the bus.
// ACLK = n/a, MCLK = SMCLK = TACLK = I2CIN = DCO~ 800k
// //* MSP430F169 Device Required *//
//
// /|\
// /|\ /|\ | /|\
// | TMP175 10k 10K 10k MSP430F169
// | ------- | | | -----------------
// +--|Vcc SDA|<-|---+---|->|P3.1 P1.0|--->LED
// | | | | | |
// +-|A2,A1,A0| | | | |
// | | ALERT|--|-------+->|P2.0 |
// +--|Vss SCL|<-+----------|P3.3 |
// \|/ ------- | |
//
//
// H. Grewal
// Texas Instruments Inc.
// Feb 2005
// Built with IAR Embedded Workbench Version: 3.21A
//******************************************************************************
#include <msp430x16x.h>
typedef enum {
SMBS_MISC = (unsigned char) 0x4E,
SMBS_DEVICE_DFLT = (unsigned char) 0x61,
SMBS_ALERT_RESPONSE = (unsigned char) 0x0C,
SMBS_HOST = (unsigned char) 0x08,
SMBS_10BIT_ADD = (unsigned char) 0x78,
SMBS_DFLT_ADD = (unsigned char) 0x37,
SMBS_ACCESS_HOST = (unsigned char) 0x28,
SMBS_CBUS = (unsigned char) 0x01,
SMBS_GCAL = (unsigned char) 0x00
}SMBS_Address_t;
/*---------------------------------------------------------------------------*/
void SMBS_Init (SMBS_Address_t Add_Param,unsigned char Slave_Add);
void setupTMP175 (void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog
P1DIR |= 0xFF; // Set P1.0 to output direction
// unused ports to output
P3DIR = 0xFF;
P3SEL |= 0x0A; // Assign I2C pins to module
P4DIR = 0xFF;
P5DIR = 0xFF;
P6DIR = 0xFF;
SMBS_Init (SMBS_MISC,0x4E); // Slave address configured as 4Eh
P2DIR = 0xFE; // set P2.0 to input
P2IES = 0x01; // Interrupt edge select for push buttons
P2IFG = 0; // Clear pending P2 interrupts
P2IE = 0x01; // Enable P2.0 interrupt
setupTMP175();
CCTL0 = CCIE; // CCR0 interrupt enabled
TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
void SMBS_Init (SMBS_Address_t Add_Param,unsigned char Slave_Add)
{
U0CTL |= I2C + SYNC + MST; // Recommended init procedure
U0CTL &= ~I2CEN; // Recommended init procedure
I2CTCTL |= I2CSSEL1; // SMCLK
I2CPSC = 0x04;
I2CSCLH = 0x01;
I2CSCLL = 0x01;
//I2CNDAT = 0x01; // Read one byte
U0CTL |= I2CEN; // Enable I2C
if (Add_Param == SMBS_MISC)
{
I2CSA = Slave_Add; // Slave Address is 048h
}
else
I2CSA = (unsigned char) Add_Param ;
U0CTL |= I2CEN; // Enable I2C
}
void setupTMP175(void)
{
I2CNDAT = 0x03;
U0CTL |= MST; // Master mode
I2CTCTL |= I2CRM+I2CSTT+I2CTRX; // Initiate transfer
while ((I2CIFG & TXRDYIFG) == 0); // Wait for transmitter to be ready
I2CDRB = I2CSA << 1; // Load Slave address
while ((I2CIFG & TXRDYIFG) == 0); // Wait for transmitter to be ready
I2CDRB = 0x03; // Load Pointer register--T(high)
while ((I2CIFG & TXRDYIFG) == 0); // Wait for transmitter to be ready THERE IS PROBLEM
I2CTCTL |= I2CSTP;
I2CDRB = 0x18; // Load T(high) register
while ((I2CTCTL & I2CSTP) == 0x02); // Check STP condition
U0CTL |= MST; // Master mode
I2CTCTL |= I2CSTT+I2CSTP+I2CTRX; // Initiate transfer
while ((I2CIFG & TXRDYIFG) == 0); // Wait for transmitter to be ready
I2CDRB = 0x01; // Load Pointer register--Config reg
while ((I2CIFG & TXRDYIFG) == 0); // Wait for transmitter to be ready
I2CDRB = 0x02; // Load Configuration register--TM mode
while ((I2CTCTL & I2CSTP) == 0x02); // Check STP condition
I2CNDAT = 0x01;
U0CTL |= MST; // Master mode
I2CTCTL |= I2CSTT+I2CSTP+I2CTRX; // Initiate transfer
while ((I2CIFG & TXRDYIFG) == 0); // Wait for transmitter to be ready
I2CDRB = 0x00; // Load Pointer register--Temp Reg
while ((I2CTCTL & I2CSTP) == 0x02); // Check STP condition
I2CTCTL &= ~I2CTRX; // Master receiver
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
if (I2CDRB > 0x20) P1OUT |= 0x01; // LED on
else P1OUT &= ~0x01; // LED off
U0CTL |= MST; // Master
I2CTCTL |= I2CSTT + I2CSTP; // Read, ST, SP (clears MST)
}
#pragma vector=PORT2_VECTOR
__interrupt void p2_isr(void)
{
P2IFG = 0;
I2CSA = 0x0C; // SMBus Alert response
U0CTL |= MST; // Master
I2CTCTL |= I2CSTT + I2CSTP; // Read, ST, SP (clears MST)
while ((I2CTCTL & I2CSTP) == 0x02); // If Stop generated
I2CSA = 0x4E; // Slave Address
}
When execution comes to transmit the third data byte, it halts in the final while loop(regardless of the value of I2CNDAT). It seems the bus never gets ready to transmit. When I check I2CTCTL register, the I2CSTT bit is not cleared after start condition. I2CSTP bit is also not cleared any time. I2CTCTL register remains constant. Moreover after start condition is sent, I2CBUSY bit is set but I2CBB bit never gets set. Also When I set MST bit I2CSCLLOW bit is set. It seems something is going wrong in my initialization procedure but I couldn't figure it out. Could anyone help me with that?