Other Parts Discussed in Thread: OPT3001
Tool/software: Code Composer Studio
Hello,
I've been working through DriverLib examples and am trying to develop i2c driver to read/write to opt3001 ALS. I'm relatively new to understanding interrupt & ISRs and believe I have some issue debugging my code in that at the end i2c_write, the device goes into LPM0+GIE, and the presumably through ISR, but I am unable to to step through OR exit the LPM & corresponding ISR.
Since I am new to interrupts, its distinctly possible that something is not correct with my ISR code, but since I can't step through it I am having a hard time pin pointing what is going wrong. Line 113 is where I first run into the problem, but i expect that 155 will also have the same problem.
Anything look very wrong?
"MSP430: Can't Single Step Target Program: CPU is currently OFF and debugging capabilities will be limited."
/* * i2c_driver.c * * Created on: July 16, 2014 * Author: a0272990 * * Copyright 2014 Texas Instruments Incorporated. All rights reserved. * */ //***************************************************************************** // #includes //***************************************************************************** #include "driverlib.h" #include "i2c_driver.h" #include "QmathLib.h" #include "IQmathLib.h" #include "math.h" //***************************************************************************** // #defines //***************************************************************************** #define OPT3001_ADDRESS 0x44 //I2C address for OPT3001 #define CHECK_POLARITY 0x80 //Polarity flag (MSB of MSB) //***************************************************************************** // Global Variables //***************************************************************************** #define RXCOUNT 0x05 #define TXLENGTH 0x04 uint8_t i2c_transmitCounter = 0; //Variable to store transmit status for I2C uint8_t i2c_transmitData[40]; // uint8_t *p_i2c_transmitData; //Pointer to transmit data uint8_t i2c_receivedCounter = 0; //Variable to store receive status for I2C uint8_t i2c_receivedBuffer[40]; // uint8_t *p_i2c_receivedBuffer; //Pointer to received data //unsigned char receiveBuffer[10] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; //unsigned char *receiveBufferPointer; //unsigned char receiveCount = 0; uint16_t i2c_mode = 0; //Variable to store i2c mode (tx or rx) //***************************************************************************** // I2C Library functions //***************************************************************************** void init_i2c(void) { //Assign I2C pins to USCI_B1 GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN1 + GPIO_PIN2); //Initialize Master USCI_B_I2C_initMasterParam param = {0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK(); param.dataRate = USCI_B_I2C_SET_DATA_RATE_100KBPS; USCI_B_I2C_initMaster(USCI_B1_BASE, ¶m); //Enable I2C Module to start operations USCI_B_I2C_enable(USCI_B1_BASE); //Enable master Receive interrupt USCI_B_I2C_enableInterrupt(USCI_B1_BASE, USCI_B_I2C_RECEIVE_INTERRUPT); } void i2c_write(uint8_t SLAVE_ADDRESS) { //Initialize Master USCI_B_I2C_initMasterParam param = {0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK(); param.dataRate = USCI_B_I2C_SET_DATA_RATE_400KBPS; USCI_B_I2C_initMaster(USCI_B1_BASE, ¶m); //Specify slave address USCI_B_I2C_setSlaveAddress(USCI_B1_BASE, SLAVE_ADDRESS ); //Set Transmit mode USCI_B_I2C_setMode(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_MODE ); //Enable I2C Module to start operations USCI_B_I2C_enable(USCI_B1_BASE); while (1) { //Enable transmit Interrupt USCI_B_I2C_clearInterrupt(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT); USCI_B_I2C_enableInterrupt(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT ); //Delay between each transaction __delay_cycles(50); //Replace with timer ISR? //Load TX byte counter i2c_transmitCounter = 1; //Initiate start and send first character USCI_B_I2C_masterSendMultiByteStart(USCI_B1_BASE, i2c_transmitData[0] ); //Enter LPM0 with interrupts enabled __bis_SR_register(LPM0_bits + GIE); __no_operation(); //Delay until transmission completes while (USCI_B_I2C_isBusBusy(USCI_B1_BASE)) ; } } void i2c_read_byte(uint8_t SLAVE_ADDRESS, uint8_t BYTE_COUNT) { //Initialize Master USCI_B_I2C_initMasterParam param = {0}; param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = UCS_getSMCLK(); param.dataRate = USCI_B_I2C_SET_DATA_RATE_100KBPS; USCI_B_I2C_initMaster(USCI_B1_BASE, ¶m); //Specify slave address USCI_B_I2C_setSlaveAddress(USCI_B1_BASE, SLAVE_ADDRESS); //Set receive mode USCI_B_I2C_setMode(USCI_B1_BASE, USCI_B_I2C_RECEIVE_MODE); //Enable I2C Module to start operations USCI_B_I2C_enable(USCI_B1_BASE); //Enable master Receive interrupt USCI_B_I2C_enableInterrupt(USCI_B1_BASE, USCI_B_I2C_RECEIVE_INTERRUPT); //wait for bus to be free while (USCI_B_I2C_isBusBusy(USCI_B1_BASE )) ; while (1) { p_i2c_receivedBuffer = (unsigned char *)i2c_receivedBuffer; i2c_receivedCounter = sizeof i2c_receivedBuffer; //Initialize multi reception USCI_B_I2C_masterReceiveMultiByteStart(USCI_B1_BASE); //Enter low power mode 0 with interrupts enabled. __bis_SR_register(LPM0_bits + GIE); __no_operation(); } } void OPT3001_init(void) { uint8_t OPT3001_Config_SW_reset[3] = { 0x01, //CDC Config register address 0xC2, //MSB of configuration (sets 100ms conversion time, single shot mode) 0x10 //LSB of configuration }; p_i2c_transmitData = (uint8_t *)OPT3001_Config_SW_reset; //Transmit array start address i2c_transmitCounter = sizeof OPT3001_Config_SW_reset; //Load transmit byte counter i2c_write(OPT3001_ADDRESS); __delay_cycles(DELAY_10_MS); } int32_t OPT3001_singleRead(void) { //uint8_t CDC_Config[2] = {0}; //Test variable uint8_t Lux_Meas1_MSB[2] = {0x00,0x00}; //MSBs of capacitance MEAS1 //uint32_t luxVal=0; int32_t Lux_MEAS1 = 0; //24-bit Lux value from MEAS1 (32bit variable) uint8_t OPT3001_initMEAS1[3] = { 0x01, //OPT Config register address 0xC2, //MSB of configuration (sets 100ms conversion time, single shot mode) 0x10 //LSB of configuration }; const uint8_t OPT3001_ResultAddr[1] = {0x00}; //Lux_MEAS1_MSB register address p_i2c_transmitData = (uint8_t *)OPT3001_initMEAS1; //Transmit array start address i2c_transmitCounter = sizeof OPT3001_initMEAS1; //Load transmit byte counter i2c_write(OPT3001_ADDRESS); __delay_cycles(DELAY_10_MS); p_i2c_transmitData = (uint8_t *)OPT3001_ResultAddr; //Transmit array start address i2c_transmitCounter = sizeof OPT3001_ResultAddr; //Load transmit byte counter i2c_write(OPT3001_ADDRESS); p_i2c_receivedBuffer = (uint8_t *)Lux_Meas1_MSB; //Receive array start address i2c_read_byte(OPT3001_ADDRESS, sizeof Lux_Meas1_MSB); //Read two bytes of lux data form result register Lux_MEAS1 = 0x0FFF & (uint16_t)Lux_Meas1_MSB[0] << 8 | (uint16_t)Lux_Meas1_MSB[1]; int8_t exp = Lux_Meas1_MSB[0]>> 4; //exponent is top four bits Lux_MEAS1 = 0.01 * pow(2,exp) * Lux_MEAS1; return Lux_MEAS1; } //****************************************************************************** // //This is the USCI_B1 interrupt vector service routine. // //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_B1_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(USCI_B1_VECTOR))) #endif void USCI_B1_ISR (void) { switch (__even_in_range(UCB1IV,12)){ case USCI_I2C_UCTXIFG: { //Check TX byte counter if (i2c_transmitCounter < sizeof i2c_transmitData) { //Initiate send of character from Master to Slave USCI_B_I2C_masterSendMultiByteNext(USCI_B1_BASE, i2c_transmitData[i2c_transmitCounter] ); //Increment TX byte counter i2c_transmitCounter++; } else { //Initiate stop only USCI_B_I2C_masterSendMultiByteStop(USCI_B1_BASE); //Clear master interrupt status USCI_B_I2C_clearInterrupt(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT); //Exit LPM0 on interrupt return __bic_SR_register_on_exit(LPM0_bits); } break; } case USCI_I2C_UCRXIFG: { //Decrement RX byte counter i2c_receivedCounter--; if (i2c_receivedCounter) { if (i2c_receivedCounter == 1) { //Initiate end of reception -> Receive byte with NAK *p_i2c_receivedBuffer++ = USCI_B_I2C_masterReceiveMultiByteFinish( USCI_B1_BASE ); } else { //Keep receiving one byte at a time *p_i2c_receivedBuffer++ = USCI_B_I2C_masterReceiveMultiByteNext( USCI_B1_BASE ); } } else { //Receive last byte *p_i2c_receivedBuffer = USCI_B_I2C_masterReceiveMultiByteNext( USCI_B1_BASE ); __bic_SR_register_on_exit(LPM0_bits); } break; } } }