Part Number: MSP-EXP432P401R
Other Parts Discussed in Thread: MSP430G2553
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