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/MSP-EXP432P401R: I2C code for interfacing MPU9250 IMU

Part Number: MSP-EXP432P401R

Tool/software: Code Composer Studio

Hi, I'm using the MSP432P401R launchpad to interface an MPU9250 IMU and I'm having some problems with my I2C implementation. I had an I2C code for msp430g2553 and it works well for me so I decided to port this code using the msp432 driverlib.

These are the write, read functions and  i2c interrupt for MSP430:

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];
    }
}

I2C_Mode msp430_I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count, uint8_t *rec_buff)
{

    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    /* Initialize slave address and interrupts */
    UCB0I2CSA = dev_addr;
    IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);                                   // Clear any pending interrupts
    IE2 &= ~UCB0RXIE;                                                   // Disable RX interrupt
    IE2 |= UCB0TXIE;                                                    // Enable TX interrupt

    UCB0CTL1 |= UCTR + UCTXSTT;                                         // I2C TX, start condition
    __bis_SR_register(CPUOFF + GIE);                                    // Enter LPM0 w/ interrupts
    //rec_buff = ReceiveBuffer;

    CopyArray(ReceiveBuffer, rec_buff, count);

    return MasterMode;

}


I2C_Mode msp430_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 */
    UCB0I2CSA = dev_addr;
    IFG2 &= ~(UCB0TXIFG + UCB0RXIFG);                                      // Clear any pending interrupts
    IE2 &= ~UCB0RXIE;                                                      // Disable RX interrupt
    IE2 |= UCB0TXIE;                                                       // Enable TX interrupt

    UCB0CTL1 |= UCTR + UCTXSTT;                                            // I2C TX, start condition
    __bis_SR_register(CPUOFF + GIE);                                       // Enter LPM0 w/ interrupts

    return MasterMode;
}


//******************************************************************************
// I2C Interruptions For Received and Transmitted Data**************************
//******************************************************************************

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void)
#else
#error Compiler not supported!
#endif
{
  if (IFG2 & UCB0RXIFG)                 // Receive Data Interrupt
  {
      //Must read from UCB0RXBUF
      uint8_t rx_val = UCB0RXBUF;

      if (RXByteCtr)
      {
          ReceiveBuffer[ReceiveIndex++] = rx_val;
          RXByteCtr--;
      }

      if (RXByteCtr == 1)
      {
          UCB0CTL1 |= UCTXSTP;
      }
      else if (RXByteCtr == 0)
      {
          IE2 &= ~UCB0RXIE;
          MasterMode = IDLE_MODE;
          __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
      }
  }
  else if (IFG2 & UCB0TXIFG)            // Transmit Data Interrupt
  {
      switch (MasterMode)
      {
          case TX_REG_ADDRESS_MODE:
              UCB0TXBUF = 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:
              IE2 |= UCB0RXIE;              // Enable RX interrupt
              IE2 &= ~UCB0TXIE;             // Disable TX interrupt
              UCB0CTL1 &= ~UCTR;            // Switch to receiver
              MasterMode = RX_DATA_MODE;    // State state is to receive data
              UCB0CTL1 |= UCTXSTT;          // Send repeated start
              if (RXByteCtr == 1)
              {
                  //Must send stop since this is the N-1 byte
                  while((UCB0CTL1 & UCTXSTT));
                  UCB0CTL1 |= UCTXSTP;      // Send stop condition
              }
              break;

          case TX_DATA_MODE:
              if (TXByteCtr)
              {
                  UCB0TXBUF = TransmitBuffer[TransmitIndex++];
                  TXByteCtr--;
              }
              else
              {
                  //Done with transmission
                  UCB0CTL1 |= UCTXSTP;     // Send stop condition
                  MasterMode = IDLE_MODE;
                  IE2 &= ~UCB0TXIE;                       // disable TX interrupt
                  __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
              }
              break;

          default:
              __no_operation();
              break;
      }
  }
}

And here are the same functions for MSP432

I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count, uint8_t *rec_buff)
{
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, dev_addr);
    //MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
    //MAP_I2C_enableModule(EUSCI_B0_BASE);

    MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,
                EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);

    MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    /* Enable master transmit interrupt */
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    //MAP_Interrupt_enableInterrupt(INT_EUSCIB0);

    /* Making sure the last transaction has been completely sent out */
    while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE) == EUSCI_B_I2C_SENDING_STOP);

    /*send register to write to*/
    MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE,TransmitRegAddr);

    CopyArray(ReceiveBuffer, rec_buff, count);

    return MasterMode;
}


I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
    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;
    MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, dev_addr);
    MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
    MAP_I2C_enableModule(EUSCI_B0_BASE);

    MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE,
                EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

    /* Enable master transmit interrupt */
    MAP_I2C_enableInterrupt(EUSCI_B0_BASE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    MAP_Interrupt_enableInterrupt(INT_EUSCIB0);

    /* Making sure the last transaction has been completely sent out */
    while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE) == EUSCI_B_I2C_SENDING_STOP);

    /*send register to write to*/
    MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE,TransmitRegAddr);

    return MasterMode;
}



/*******************************************************************************/

void EUSCIB0_IRQHandler(void)
{
    uint_fast16_t status;

    status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);

    if (status & EUSCI_B_I2C_NAK_INTERRUPT)
    {
        MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_NAK_INTERRUPT );
    }

    if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
    {
        switch (MasterMode){

            case TX_REG_ADDRESS_MODE:
                  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:
                  MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

                  MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
                  MAP_I2C_masterReceiveStart(EUSCI_B0_BASE);
                  MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
                  //MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
                  //MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

                  MasterMode = RX_DATA_MODE;    // State state is to receive data
                  //UCB0CTL1 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE) == EUSCI_B_I2C_SENDING_STOP);
                      //MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_STOP_INTERRUPT);
                      MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
                  }
                  break;

              case TX_DATA_MODE:
                  if(TXByteCtr){
                      MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, TransmitBuffer[TransmitIndex++]);
                      TXByteCtr--;

                  }
                  else
                  {
                      //Done with transmission
                      MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
                      MasterMode = IDLE_MODE;
                      MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
                      MAP_Interrupt_disableSleepOnIsrExit();
                  }
                  break;
        }

    }
    /* Receives bytes into the receive buffer. If we have received all bytes,
     * send a STOP condition */
    if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
    {
        if (RXByteCtr)
        {
            ReceiveBuffer[ReceiveIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
            RXByteCtr--;
        }

        if (RXByteCtr == 1)
        {
            MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
        }
        else if (RXByteCtr == 0)
        {
            //MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
            MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
            MasterMode = IDLE_MODE;
            MAP_Interrupt_disableSleepOnIsrExit();
        }

    }
    else if (status & EUSCI_B_I2C_STOP_INTERRUPT)
    {
        MAP_Interrupt_disableSleepOnIsrExit();
        MAP_I2C_disableInterrupt(EUSCI_I2C_MODULE, EUSCI_B_I2C_STOP_INTERRUPT);
    }
}

I don't know where in the MSP432 code the problem is, but I'm not reading correct values as the IMU's who am I register is not answering the 0x71 default value. I can write and read but actually I don't know

if it's doing it well. I hope my code is readable.

best regards,

Diana

  

**Attention** This is a public forum