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.

CCS/MSP430FR2355: MSP debug call stack error

Part Number: MSP430FR2355
Other Parts Discussed in Thread: OPT3001

Tool/software: Code Composer Studio

I have attached the code and underlined the instruction which was marked as error.

I was trying to read value from an opt3001 module by witty fox.

#include <msp430.h> // Generic MSP430 Device Include
#include <stdint.h>

#define OPT3001 0x44
#define Result 0x00
#define Configuration 0x01

#define ONE_BYTE 0x1
#define TWO_BYTES 0x2
#define THREE_BYTES 0x3

unsigned long lux;

void GPIO_pin_configurations(void);

void I2C_transmission_setup(unsigned char num_of_bytes);
void I2C_write(unsigned char slave_address, unsigned char register_address, unsigned char byte_1, unsigned char byte_2);
void I2C_setup_write(unsigned char slave_address, unsigned char register_address);
void I2C_read(unsigned char slave_address);

unsigned long convert_to_lux(unsigned int exponent, unsigned int mantissa);

unsigned char TXData[3];
unsigned char RXData[2];
unsigned char ByteCtr;

void main(void)
{

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

GPIO_pin_configurations();

PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
// to activate previously configured port setting
unsigned int exponent;
unsigned int mantissa;

while(1)
{

//Write to Configuration Register (0x01) to set the operational mode of the OPT3001
I2C_transmission_setup(THREE_BYTES);
I2C_write(OPT3001, Configuration, 0xC2, 0x10);

// Delay for 100 milliseconds to allow conversion process to complete
__delay_cycles(100);

I2C_transmission_setup(TWO_BYTES);
I2C_setup_write(OPT3001, Result);

I2C_transmission_setup(ONE_BYTE);
I2C_read(OPT3001);
//Extract the upper four bits of exponent and the lower 12 bits of mantissa from the raw result value
exponent = RXData[0] >> 4;
mantissa = (RXData[0] << 8 | RXData[1]) & 0x0FFF;

//Take the exponent and mantissa values and calculate the corresponding lux value
lux = convert_to_lux(exponent, mantissa);
} // End background loop
} // End main()


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB0IV,USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts break;
case USCI_I2C_UCALIFG: break;
case USCI_I2C_UCNACKIFG:
UCB0CTL1 |= UCTXSTT; //resend start if NACK
break; // Vector 4: NACKIFG break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG break;
case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG break;
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3 break;
case USCI_I2C_UCTXIFG3: break; // Vector 14: TXIFG3 break;
case USCI_I2C_UCRXIFG2: break; // Vector 16: RXIFG2 break;
case USCI_I2C_UCTXIFG2: break; // Vector 18: TXIFG2 break;
case USCI_I2C_UCRXIFG1: break; // Vector 20: RXIFG1 break;
case USCI_I2C_UCTXIFG1: break; // Vector 22: TXIFG1 break;

case USCI_I2C_UCRXIFG0: // Vector 24: RXIFG0 break;

RXData[ByteCtr] = UCB0RXBUF; // Load RX buffer
ByteCtr++; // Increment RX byte counter

break;

case USCI_I2C_UCTXIFG0: // Vector 26: TXIFG0 break;

UCB0TXBUF = TXData[ByteCtr]; // Load TX buffer
ByteCtr++; // Increment TX byte counter

break;

case USCI_I2C_UCBCNTIFG: // Vector 28: BCNTIFG

__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0

break;

case USCI_I2C_UCCLTOIFG: break; // Vector 30: clock low timeout
case USCI_I2C_UCBIT9IFG: break; // Vector 32: 9th bit
default: break;
}
}

void I2C_transmission_setup(unsigned char num_of_bytes)
{
//Configure USCI_B0 for I2C Mode and designate the number of bytes to be transmitted/received

UCB0CTLW0 |= UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC|UCSSEL_3; // I2C master mode, SMCLK
UCB0CTLW1 |= UCASTP_2; // Automatic stop generated
// after UCB0TBCNT is reached
UCB0BRW = 0x8; // baudrate = SMCLK / 8
UCB0TBCNT = num_of_bytes; // number of bytes to be received
UCB0CTL1 &= ~UCSWRST; // clear reset register
UCB0IE |= UCTXIE0 | UCRXIE0 | UCNACKIE | UCBCNTIE; // transmit and NACK interrupt enable
}

void I2C_write(unsigned char slave_address, unsigned char register_address, unsigned char byte_1, unsigned char byte_2)
{
UCB0I2CSA = slave_address; // Set the slave address
TXData[0] = register_address; // Set the control register address
TXData[1] = byte_1; // Set the Register Data LSB
TXData[2] = byte_2; // Set the Register Data MSB
ByteCtr = 0; // Load byte counter
while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
UCB0CTLW0 |= UCTR; // I2C TX
UCB0CTLW0 |= UCTXSTT; // I2C start condition
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data
// is TX'd
}

void I2C_setup_write(unsigned char slave_address, unsigned char register_address)
{
UCB0I2CSA = slave_address; // Set the slave address
TXData[0] = register_address; // Set the control register address
ByteCtr = 0; // Load byte counter
while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
UCB0CTLW0 |= UCTR; // I2C TX
UCB0CTLW0 |= UCTXSTT; // I2C start condition
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data
// is TX'd
}

void I2C_read(unsigned char slave_address)
{
UCB0I2CSA = slave_address; // Set the slave address
ByteCtr = 0; // Load byte counter
while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
UCB0CTLW0 &= ~UCTR; // I2C RX
UCB0CTLW0 |= UCTXSTT; // I2C start condition
__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data
// is RX'd
}

unsigned long convert_to_lux(unsigned int exponent, unsigned int mantissa)
{
// Convert the Result Register into a lux measurement based on formula below:
// lux = 0.01 * (2^E[3:0]) * R[11:0]

unsigned int result;
unsigned int count;
unsigned long converted_lux;

result = 1;
for(count = exponent; count > 0; count--)
{
result = result * 2;
}
converted_lux = mantissa / 100;
converted_lux *= result;

return converted_lux;
}

void GPIO_pin_configurations(void)
{
//Set P1.2 and P1.3 pins for I2C functionality
P4SEL0 |= BIT6 | BIT7;
}

Edit: Here's the line of code that was underlined.

__bis_SR_register(LPM0_bits | GIE); // Enter LPM0 w/ interrupts
  • Hi Sahil,

    As good practice, I would not recommend dumping all your code into a thread and mentioning there's an error. Please be more specific about the error and what you've done to solve it so far. Our community will be more likely to give guidance.

    Also, in future posts, please use the Syntax Highlighter when inserting any code. It helps readability and again makes it easier for community members to help. I've gone ahead and formatted your code.

    Now, the code you underlined above is where the CPU goes to sleep. If you're trying to debug your code, I wouldn't recommend using LPMx modes. Instead, just put a while(1) loop and inside the loop, put a nop() where you can halt the debugger. Also, compiler optimization levels can affect debugging behavior, so check that those levels are low.

    Regards,

    James

  • I'M sorry for dumping my code like this, I will make sure this will not happen again.

    I have used 

    __bis_SR_register(LPM0 | GIE);

    so that my MCU is consuming less power while it is communicating using I2C till an interrupt occurs i.e either UCRXIFG0 or UCTXIFG0 is set.

    I tried executing my code line by line and after 

    I2C_write(OPT3001, Configuration, 0xC2, 0x10);

    I2C_write function is called and the program never came out of the write function. I think my MCU is not waking up after entering LPM0, maybe because my data is not getting transmitted hence UCTXIFG0 is never set. 

    I'm working on your suggestion.

    I was just curious to know why using LPMx during debugging is not recommended.

  • > //Set P1.2 and P1.3 pins for I2C functionality
    > P4SEL0 |= BIT6 | BIT7;
    Per data sheet (SLASEC4D) Table 6-66, P4.6/7 are UCB1, not UCB0. To get UCB0 you should be using P1.2/3 [Ref data sheet Table 6-63]
  • Yes , now the code is working.

    Thank you and sorry for the silly mistake.

**Attention** This is a public forum