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.
Part Number: BOOSTXL-SENSORS
Hello,
Currently, I am trying to run the BOOSTXL-BASSENSORS boosterpack on the MSP430FR6989 and was attempting to port some I2C driver code from the BOOSTXL-Sensors and MSP430FR5994 OOB code examples. However, I kept running into an error on the driver where "while(!(UCB0IFG & UCTXIFG0));" during I2C communication, making me think the slave is not registering. Then, when I tried the OOB code on the BOOSTXL-Sensors and the MSP430FR5994 combination, I received the same error, even though this is example code that is built for these devices.
Is there a reason I am running into this error? If any more information is needed please let me know, thanks!
Hi Domenick,
Attached is example code using FR6989 to acquire data from the OPT3001 on the BOOSTXL-BASSENSORS boosterpack.
//****************************************************************************** // MSP430FR6989 Demo - BOOSTXL- BASSENSORS BOOSTERPACK // // //****************************************************************************** #include <msp430.h> #include <stdint.h> #include <stdbool.h> //****************************************************************************** // General I2C State Machine *************************************************** //****************************************************************************** typedef enum I2C_ModeEnum{ IDLE_MODE, NACK_MODE, TX_REG_ADDRESS_MODE, RX_REG_ADDRESS_MODE, TX_DATA_MODE, RX_DATA_MODE, SWITCH_TO_RX_MODE, SWITHC_TO_TX_MODE, TIMEOUT_MODE } I2C_Mode; /* Used to track the state of the software state machine*/ I2C_Mode MasterMode = IDLE_MODE; /* The Register Address/Command to use*/ uint8_t TransmitRegAddr = 0; /* ReceiveBuffer: Buffer used to receive data in the ISR * RXByteCtr: Number of bytes left to receive * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer * TransmitBuffer: Buffer used to transmit data in the ISR * TXByteCtr: Number of bytes left to transfer * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer * */ #define MAX_BUFFER_SIZE 20 uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0}; uint8_t RXByteCtr = 0; uint8_t ReceiveIndex = 0; uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0}; uint8_t TXByteCtr = 0; uint8_t TransmitIndex = 0; /* I2C Write and Read Functions */ /* For slave device with dev_addr, writes the data specified in *reg_data * * dev_addr: The slave device address. * Example: SLAVE_ADDR * reg_addr: The register or command to send to the slave. * Example: CMD_TYPE_0_MASTER * *reg_data: The buffer to write * Example: MasterType0 * count: The length of *reg_data * Example: TYPE_0_LENGTH * */ I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count); /* For slave device with dev_addr, read the data specified in slaves reg_addr. * The received data is available in ReceiveBuffer * * dev_addr: The slave device address. * Example: SLAVE_ADDR * reg_addr: The register or command to send to the slave. * Example: CMD_TYPE_0_SLAVE * count: The length of data to read * Example: TYPE_0_LENGTH * */ I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count); void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count); I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count) { /* Initialize state machine */ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; RXByteCtr = count; TXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB1I2CSA = dev_addr; UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB1IE &= ~UCRXIE; // Disable RX interrupt UCB1IE |= UCTXIE; // Enable TX interrupt UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts return 0; } I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count) { /* Initialize state machine */ MasterMode = TX_REG_ADDRESS_MODE; TransmitRegAddr = reg_addr; //Copy register data to TransmitBuffer CopyArray(reg_data, TransmitBuffer, count); TXByteCtr = count; RXByteCtr = 0; ReceiveIndex = 0; TransmitIndex = 0; /* Initialize slave address and interrupts */ UCB1I2CSA = dev_addr; UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB1IE &= ~UCRXIE; // Disable RX interrupt UCB1IE |= UCTXIE; // Enable TX interrupt UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts return MasterMode; } void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count) { uint8_t copyIndex = 0; for (copyIndex = 0; copyIndex < count; copyIndex++) { dest[copyIndex] = source[copyIndex]; } } //****************************************************************************** // Device Initialization ******************************************************* //****************************************************************************** void initGPIO() { P1OUT = 0; P1DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P2OUT = 0; P2DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P3OUT = 0; P3DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P4OUT = 0; P4DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P4SEL0 = 0; P4SEL1 = (BIT0 | BIT1); // ENABLE I2C P5OUT = 0; P5DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P6OUT = 0; P6DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P7OUT = 0; P7DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); P8OUT = BIT6; // ENABLE PULLUP FOR INTERRUPT P8DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT7); // BIT6 IS OPT3001 INTERRUPT P8REN = BIT6; // ENABLE PULLUP FOR INTERRUPT P9OUT = BIT0; // APPLY OPT3001 POWER P9DIR = (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6 | BIT7); // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5; } void initClockTo16MHz() { // Configure one FRAM waitstate as required by the device datasheet for MCLK // operation beyond 8MHz _before_ configuring the clock system. FRCTL0 = FRCTLPW | NWAITS_1; // Clock System Setup CSCTL0_H = CSKEY >> 8; // Unlock CS registers CSCTL1 = DCOFSEL_4 | DCORSEL; // Set DCO to 16MHz CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Set SMCLK = MCLK = DCO // ACLK = VLOCLK CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // Set all dividers to 1 CSCTL0_H = 0; // Lock CS registers } void initI2C() { UCB1CTLW0 = UCSWRST; // Enable SW reset UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK UCB1BRW = 40; // fSCL = SMCLK/40 = ~400kHz UCB1CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation UCB1IE |= UCNACKIE; } //****************************************************************************** // Main ************************************************************************ // Send and receive three messages containing the example commands ************* //****************************************************************************** #include <math.h> #define HDC2010_ADDRS 0x40 #define OPT3001_ADDRS 0x44 #define OPT3001_RESULT_REG 0x00 #define OPT3001_CONFIG_REG 0x01 #define OPT3001_LLIMIT_REG 0x02 #define TMP116_ADDRS 0x48 #define LIGHT_SENSOR 2 uint8_t LightSensorConfigWrite [2] = {0xCE , 0x10}; //AUTOMATIC FULLSCALE, 800MS CONVERSION, CONTINUOUS uint8_t LightSensorDataRead [2] = {0}; // DATA WILL ALWAYS BE 2 BYTES uint8_t LightSensorLLimitWrite [2] = {0xC0, 0x00}; //ENABLE INTERRUPT PIN AFTER EVERY CONVERSION uint8_t LightSensorConfigRead [2] = {0}; // CONFIG WILL ALWAYS BE 2 BYTES float lux; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer initClockTo16MHz(); initGPIO(); initI2C(); _delay_cycles(100000); // allow some time for OPT3001 I2C_Master_WriteReg(OPT3001_ADDRS, OPT3001_CONFIG_REG, LightSensorConfigWrite, 2); I2C_Master_WriteReg(OPT3001_ADDRS, OPT3001_LLIMIT_REG, LightSensorLLimitWrite, 2); while(1) { while(P8IN & BIT6); // POLL THIS PIN (GOES LOW EVERY 800MS) I2C_Master_ReadReg(OPT3001_ADDRS, OPT3001_RESULT_REG, 2); CopyArray(ReceiveBuffer, LightSensorDataRead, 2); // COPY RESULTS FROM RECEIVE BUFFER I2C_Master_ReadReg(OPT3001_ADDRS, OPT3001_CONFIG_REG, 2); // CLEAR THE INTERRUPT BIT CopyArray(ReceiveBuffer, LightSensorConfigRead, 2); // COPY RESULTS FROM RECEIVE BUFFER } } //****************************************************************************** // I2C Interrupt *************************************************************** //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B1_VECTOR __interrupt void USCI_B1_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void) #else #error Compiler not supported! #endif { //Must read from UCB1RXBUF uint8_t rx_val = 0; switch(__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG)) { case USCI_NONE: break; // Vector 0: No interrupts case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG break; case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3 case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3 case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2 case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2 case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1 case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1 case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0 rx_val = UCB1RXBUF; if (RXByteCtr) { ReceiveBuffer[ReceiveIndex++] = rx_val; RXByteCtr--; } if (RXByteCtr == 1) { UCB1CTLW0 |= UCTXSTP; } else if (RXByteCtr == 0) { UCB1IE &= ~UCRXIE; MasterMode = IDLE_MODE; __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; case USCI_I2C_UCTXIFG0: // Vector 24: TXIFG0 switch (MasterMode) { case TX_REG_ADDRESS_MODE: UCB1TXBUF = TransmitRegAddr; if (RXByteCtr) MasterMode = SWITCH_TO_RX_MODE; // Need to start receiving now else MasterMode = TX_DATA_MODE; // Continue to transmision with the data in Transmit Buffer break; case SWITCH_TO_RX_MODE: UCB1IE |= UCRXIE; // Enable RX interrupt UCB1IE &= ~UCTXIE; // Disable TX interrupt UCB1CTLW0 &= ~UCTR; // Switch to receiver MasterMode = RX_DATA_MODE; // State state is to receive data UCB1CTLW0 |= UCTXSTT; // Send repeated start if (RXByteCtr == 1) { //Must send stop since this is the N-1 byte while((UCB1CTLW0 & UCTXSTT)); UCB1CTLW0 |= UCTXSTP; // Send stop condition } break; case TX_DATA_MODE: if (TXByteCtr) { UCB1TXBUF = TransmitBuffer[TransmitIndex++]; TXByteCtr--; } else { //Done with transmission UCB1CTLW0 |= UCTXSTP; // Send stop condition MasterMode = IDLE_MODE; UCB1IE &= ~UCTXIE; // disable TX interrupt __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; default: __no_operation(); break; } break; default: break; } }
**Attention** This is a public forum