My code worked fine if I only connect msp430 to one sensor. However, when I connect msp430 to 4 sensors. I try to read to only one sensor but it just stop at stop condition.
I expected to read sensor values by passing the corresponding sensor address. But I'm sure what is wrong. I would appreciated any help or suggestion.
#include <msp430.h>
#include "tmp117_i2C.h"
volatile uint8_t rx_val = 0;
char uartBuffer[MAX_BUFFER_SIZE];
unsigned int len;
int i;
// GPIO
void initGPIO()
{
// LED
P1OUT &= ~0x01; // P1.0 = 0
P1DIR |= 0x01; // P1.0 output
// I2C Pins
P3SEL |= BIT1 + BIT2; // P3.0,1 option select
// I2C Pins
P9SEL |= BIT1 + BIT2; // P9.0,1 option select
// UART pins
P3SEL |= BIT4+ BIT5; // P3.3,4 = USCI_A0 TXD/RXD
}
// UART Initialization
void initUART(void)
{
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 9; // 1MHz 115200 (see User's Guide)
UCA0BR1 = 0; // 1MHz 115200
UCA0MCTL |= UCBRS0; // Modulation UCBRSx = 1
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
}
// I2C Initialization
void initI2C(void)
{
UCB2CTL1 |= UCSWRST; // Enable SW reset
UCB2CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB2CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK
UCB2BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB2BR1 = 0;
UCB2CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCTXIE + UCRXIE; // Enable both RX and TX interrupts
// UCB0IE is the interrupt register
UCB0IE |= UCSTTIE; // Enable STT interrupt
}
void initI2C_Port3(void) {
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK
UCB0BR0 = 12; // Set baud rate
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCRXIE + UCTXIE; // Enable RX and TX interrupt
}
// Function to send a string
void sendString(char *str) {
while (*str != 0) {
while (!(UCA0IFG & UCTXIFG)); // Wait until the buffer is ready
UCA0TXBUF = *str++; // Send the current character
}
}
/**
* main.c
*/
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
char text[] = "MSP430 \r\n";
// Initialize
initGPIO();
initUART(); //for debug purpose
initI2C();
initI2C_Port3();
uint8_t sensorAddrs[] = {TMP117_ADDR_1, TMP117_ADDR_2, TMP117_ADDR_3, TMP117_ADDR_4};
uint8_t* receiveBuffers[] = {ReceiveBuffer1, ReceiveBuffer2, ReceiveBuffer3, ReceiveBuffer4};
__bis_SR_register(GIE); // Enable global interrupts
// Main loop
while (1)
{
sendString(text);
P1OUT ^= BIT0; // Toggle P1.0 using exclusive-OR
__delay_cycles(2000000); // Delay between messages
// for (i = 0; i < 4; i++) {
// I2C_Master_ReadReg(sensorAddrs[i], TMP117_TEMP_REG, TYPE_1_LENGTH);
// CopyArray(ReceiveBuffer, receiveBuffers[i], TYPE_1_LENGTH);
// }
I2C_Master_ReadReg(TMP117_ADDR_1, TMP117_TEMP_REG, TYPE_1_LENGTH);
CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
double sensorValue = processSensorData(ReceiveBuffer[0], ReceiveBuffer[1]);
sprintf(uartBuffer, "Received: %x %x \r\n", ReceiveBuffer[0], ReceiveBuffer[1]);
sendString(uartBuffer);
// floatToString(uartBuffer, sensorValue, 6);
sprintf(uartBuffer, "Sensor Value: %f \r\n", sensorValue);
}
}
//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
#else
#error Compiler not supported!
#endif
{
// Must read from UCB2RXBUF
// uint8_t rx_val = 0;
switch(__even_in_range(UCB2IV,0xC)) {
case USCI_NONE:break; // Vector 0 - no interrupt
case USCI_I2C_UCALIFG:break; // Interrupt Vector: I2C Mode: UCALIFG
case USCI_I2C_UCNACKIFG:break; // Interrupt Vector: I2C Mode: UCNACKIFG
case USCI_I2C_UCSTTIFG: // Interrupt Vector: I2C Mode: UCSTTIFG
// UCB0STAT &= ~UCSTTIFG;
break;
case USCI_I2C_UCSTPIFG:break; // Interrupt Vector: I2C Mode: UCSTPIFG
case USCI_I2C_UCRXIFG:
rx_val = UCB2RXBUF;
if (RXByteCtr) {
ReceiveBuffer[ReceiveIndex++] = rx_val;
RXByteCtr--;
}
if (RXByteCtr == 1) {
UCB2CTL1 |= UCTXSTP;
} else if (RXByteCtr == 0) {
UCB2IE &= ~UCRXIE;
MasterMode = IDLE_MODE;
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break; // Interrupt Vector: I2C Mode: UCRXIFG
case USCI_I2C_UCTXIFG:
switch (MasterMode) {
case TX_REG_ADDRESS_MODE:
UCB2TXBUF = TransmitRegAddr;
if (RXByteCtr)
MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now
else
MasterMode = TX_DATA_MODE; // Continue to transmission with the data in Transmit Buffer
break;
case SWITCH_TO_RX_MODE:
UCB2IE |= UCRXIE; // Enable RX interrupt
UCB2IE &= ~UCTXIE; // Disable TX interrupt
UCB2CTL1 &= ~UCTR; // Switch to receiver
MasterMode = RX_DATA_MODE; // State state is to receive data
UCB2CTL1 |= UCTXSTT; // Send repeated start
if (RXByteCtr == 1) {
//Must send stop since this is the N-1 byte
while((UCB2CTL1 & UCTXSTT));
UCB2CTL1 |= UCTXSTP; // Send stop condition
}
break;
case TX_DATA_MODE:
if (TXByteCtr) {
UCB2TXBUF = TransmitBuffer[TransmitIndex++];
TXByteCtr--;
} else {
// Done with transmission
UCB2CTL1 |= UCTXSTP; // Send stop condition
MasterMode = IDLE_MODE;
UCB2IE &= ~UCTXIE; // disable TX interrupt
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
break;
default:
__no_operation();
break;
}
break; // Interrupt Vector: I2C Mode: UCTXIFG
default: break;
}
}