This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Interfacing LM75 with MSP430f5510 Freezes on Sending a Byte

Other Parts Discussed in Thread: MSP430F5510

Dear TI Community I am trying to Interface LM75 with MSP430f5510 and the firware is written using DriverLib

I believe I have done the configuration correctly, When i try to send Data via I2C 

using USCI_B_I2C_masterSendSingleByte() , it send the data and hangs waiting for TX Interrupt - 

Both SDA and SCL lines are pulled up using 10k resistor

I am new to LM75 - from what i gathered from TI Data sheet was that we need to send 0x00 to LM75 and it will return temperature 

What i dont understand is that first should we send Address and follwed by pointer or just the pointer is enough ?

Either way I am stuck well before that it is successfully sending Start Condition and once it send data it freezes

Kindly help me

Below is my code

#include "driverlib.h"

// LM75
#define I2CBASE USCI_B1_BASE
#define SDA GPIO_PIN1
#define SCL GPIO_PIN2
//Set the address for slave module. This is a 7-bit address sent in the following format:
//[A6:A5:A4:A3:A2:A1:A0:RS]
#define LM75_ADDRESS 0x48
unsigned char receiveCount = 0;

void main(void)
{
//Flash Firmware onto MSP430F5510

// Stop watchdog timer
WDT_A_hold(WDT_A_BASE);

// Enable Global Interrupts
__bis_SR_register( GIE );

// Initialize Peripherals
Init_Clock();
Init_LM75();

while(1)
{

USCI_B_I2C_masterSendSingleByte(I2CBASE, LM75_ADDRESS);

//Delay until transmission completes
while(USCI_B_I2C_isBusBusy(I2CBASE))
{
;
}

receiveCount = RXCOUNT;

// Initialize multi reception
USCI_B_I2C_setMode(I2CBASE, USCI_B_I2C_RECEIVE_MODE );

USCI_B_I2C_masterReceiveMultiByteStart(I2CBASE);

__delay_cycles(90000000);

UARTSendInit(RxBuffer[0]);
UARTSendInit(RxBuffer[1]);

}

}


#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
switch(__even_in_range(UCB1IV,12))
{
case USCI_I2C_UCRXIFG:
{
//Decrement RX byte counter
receiveCount--;

if(receiveCount)
{
if(receiveCount == 1)
{
//Initiate end of reception -> Receive byte with NAK
RxBuffer[RxIndex++] = USCI_B_I2C_masterReceiveMultiByteFinish( I2CBASE );
}
else
{
//Keep receiving one byte at a time
RxBuffer[RxIndex++] = USCI_B_I2C_masterReceiveMultiByteNext( I2CBASE );
}
}
else
{
//Receive last byte
RxBuffer[RxIndex++] = USCI_B_I2C_masterReceiveMultiByteNext( I2CBASE );
}
break;
}
case USCI_I2C_UCTXIFG:
{
__no_operation();
break;
}
}
}

//Initialize Clock
void Init_Clock(void)
{

//Set VCore = 3 for 25MHz clock
PMM_setVCore(PMM_CORE_LEVEL_3);

// //ACLK, MCLK, MCLK set out to pins
// GPIO_setAsPeripheralModuleFunctionOutputPin(
// GPIO_PORT_P11,
// GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2
// );

//Set DCO FLL reference = REFO
UCS_initClockSignal(
UCS_FLLREF,
UCS_REFOCLK_SELECT,
UCS_CLOCK_DIVIDER_1
);

//VLO Clock Sources ACLK (9.4kHz)
UCS_initClockSignal(
UCS_ACLK,
UCS_VLOCLK_SELECT,
UCS_CLOCK_DIVIDER_1
);

//Set Ratio and Desired MCLK Frequency and initialize DCO
UCS_initFLLSettle(
UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ,
UCS_MCLK_FLLREF_RATIO
);

// Enable global oscillator fault flag
SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT);
SFR_enableInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT);

// Enable global interrupt
__bis_SR_register(GIE);

}

void Init_LM75(void)
{
//Assign I2C pins to USCI_B1
GPIO_setAsPeripheralModuleFunctionInputPin(
UART_SPI_Port, SDA + SCL );

//Initialize Master
USCI_B_I2C_initMasterParam param = {0};
param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_ACLK;
param.i2cClk = UCS_getACLK();
param.dataRate = USCI_B_I2C_SET_DATA_RATE_100KBPS;

USCI_B_I2C_initMaster(I2CBASE, &param);

//Specify slave address
USCI_B_I2C_setSlaveAddress(I2CBASE, LM75_ADDRESS);

//Set Master in transmit mode
USCI_B_I2C_setMode(I2CBASE, USCI_B_I2C_TRANSMIT_MODE );

//Enable I2C Module to start operations
USCI_B_I2C_enable(I2CBASE);

//Enable master Receive interrupt
USCI_B_I2C_clearInterrupt(I2CBASE, USCI_B_I2C_RECEIVE_INTERRUPT );
USCI_B_I2C_enableInterrupt(I2CBASE, USCI_B_I2C_RECEIVE_INTERRUPT );

//Enable TX interrupt
USCI_B_I2C_clearInterrupt(I2CBASE,
USCI_B_I2C_TRANSMIT_INTERRUPT
);
USCI_B_I2C_enableInterrupt(I2CBASE,
USCI_B_I2C_TRANSMIT_INTERRUPT
);

}

void USCI_B_I2C_masterSendSingleByte(uint16_t baseAddress,
uint8_t txData)
{
//Store current TXIE status
uint8_t txieStatus = HWREG8(baseAddress + OFS_UCBxIE) & UCTXIE;

//Disable transmit interrupt enable
HWREG8(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);

//Send start condition.
HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTR + UCTXSTT;

//Poll for transmit interrupt flag.
while(!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG))
{

}

//Send single byte data.
HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;

//Poll for transmit interrupt flag.
while(!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG))
{

}

//Send stop condition.
HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;

//Clear transmit interrupt flag before enabling interrupt again
HWREG8(baseAddress + OFS_UCBxIFG) &= ~(UCTXIFG);

//Reinstate transmit interrupt enable
HWREG8(baseAddress + OFS_UCBxIE) |= txieStatus;
}

  • Please make sure that the A0-A2 pins on the LM75 device are grounded. The freezing state of the MSP430F5510 as described is unclear, does the LM75 return an ACK after you send the single byte? USCI_B_I2C_masterSendSingleByte() will send a stop condition before exiting, which while loop does it get stuck in before this happens? Why are there functions extracted from the DriverLib? And why are you enabling interrupts when driverlib I2C functions operate by polling? Please provide debugger and oscilloscope/logic analyzer screen shots further describing your issue, and reference the DriverLib example code for a better idea of how to use I2C properly.

    Regards,
    Ryan
  • Hello ryan,

    A0-A2 are grounded .

    I do not know how to check for acknowledgement ( Kindly help me ) - I am sorry its a custom board with USB so I do not have Debugger - However I have UART pins with headers so I can print some Serial Data only

    Functions are not extracted from driver lib I just copy pasted it in the question just to show you
    It freezes in this function ( Inside the while )

    //Send single byte data.
    HWREG8(baseAddress + OFS_UCBxTXBUF) = txData;

    //Poll for transmit interrupt flag.
    while(!(HWREG8(baseAddress + OFS_UCBxIFG) & UCTXIFG))
    {

    }

    I enabled Interrupts because in the Driver Lib examples they have enabled it too
  • An ACK signal would be visible with the oscilloscope/logic analyzer, which is vital for debugging communication (I2C, UART, SPI, etc.) issues. Printing serial data will not do you much good here, you need to access a debugger using some form of FET tool. Extracting and pasting driverlib only makes your code more confusing. UCTXIFG staying set means that new data is never ready to be written into UCAxTXBUF, most likely because the slave is not returning an ACK. You can view the UCNACKIFG bit to see if this is the case.

    Regards,
    Ryan

**Attention** This is a public forum