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