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: 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
Hi Diana,
You can see the code example for a Multi-byte Master code at https://dev.ti.com/tirex/explore/node?node=APSsCjrOyrT6CYSTci9Sqg__z-lQYNj__LATEST. Is that the mode you are trying to operate? At least, in this mode the
void EUSCIB0_IRQHandler(void)
has the following
if (status & EUSCI_B_I2C_NAK_INTERRUPT)
{
MAP_I2C_masterSendStart(EUSCI_B0_BASE);
}
which differs from what you have.
If you are using a different mode, you will also find examples for other modes.
Srinivas
Hi Srinivas, thanks your answer. I've already seen the examples in the TIREX. The mode I'm trying to operate would be read/write master multibyte but I'm not an expert in i2c protocol.
I tried the the change in my code you told me above, but I'm getting the same results.
Any other suggestions? I've been in this for a while and I don't know what else to do :(
Diana
**Attention** This is a public forum