Part Number: MSP432P401R
Tool/software: Code Composer Studio
Hello there,
I am trying to write and I2C interface for the mpu6050.
For the IC there shall be single and multi byte receptions and i am trying to write and generic code.
My code does the mutli byte transfers well but single byte transfers doesnot work. Also this code does the i2c transmissions and again the single byte transfers doesnot work.
I would appreciate if you could help me.
I always frustrate when i am writing I2C drivers with texas instruments. I know the I2C protocol so well but when it comes to writing a code for the microcontroller i spend hours.
IS there a way that i could learn how to code for I2C drivers.
Kind Regards
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include "MPU6050.h"
const uint8_t port_mapping_3_3[] =
{
//Portmapping EUSCI_B0_SPI_I2C.SCL to P3.5, EUSCI_B0_SPI_I2C.SDA to P3.7
PM_NONE, PM_NONE, PM_NONE, PM_NONE, PM_NONE, PM_UCB0SCL, PM_NONE, PM_UCB0SDA,
};
#define SLAVE_ADDRESS 0x68
uint8_t NUM_OF_REC_BYTES_B0 = 2;
//const uint8_t TXData[] = {0x07};
//const uint8_t TXData[] = {0x00};
//static uint8_t RXData[NUM_OF_REC_BYTES];
uint8_t TXData_B0[256] = {0x07};
uint8_t* TXDataPtr_B0;
uint8_t RXData_B0[256];
static volatile uint32_t xferIndex_B0;
volatile char stopSent_B0;
uint8_t transmitting_B0 = 0;
uint8_t TXByteCtr_B0 = 0;
uint8_t single = 0;
const eUSCI_I2C_MasterConfig i2cConfig_B0 =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
12000000, // SMCLK = 3MHz
EUSCI_B_I2C_SET_DATA_RATE_100KBPS, // Desired I2C Clock of 100khz
0, // No byte counter threshold
EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};
void Setup_MPU6050()
{
// Portmapping the corresponding pins. See above array for details
MAP_PMAP_configurePorts((const uint8_t *) port_mapping_3_3, P3MAP, 1, PMAP_DISABLE_RECONFIGURATION);
// Configure P3.5 for EUSCI_B0_SPI_I2C EUSCI_B0_SPI_I2C.SCL
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN5, GPIO_PRIMARY_MODULE_FUNCTION);
// Configure P3.7 for EUSCI_B0_SPI_I2C EUSCI_B0_SPI_I2C.SDA
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
// Configure as pull-up resistor enabled pins for P5.1
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P5, GPIO_PIN1);
// Enable interrrupt for P5.1
MAP_GPIO_enableInterrupt(GPIO_PORT_P5, GPIO_PIN1);
// Select interrrupt edge (high-to-low) for P5.1
MAP_GPIO_interruptEdgeSelect(GPIO_PORT_P5, GPIO_PIN1, GPIO_HIGH_TO_LOW_TRANSITION);
stopSent_B0 = 0;
I2C_initMaster(EUSCI_B0_BASE, &i2cConfig_B0);
I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);
I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
I2C_enableModule(EUSCI_B0_BASE);
I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
Interrupt_enableInterrupt(INT_EUSCIB0);
}
void MPU6050_ReadReg(uint8_t RegAddress, uint8_t length)
{
stopSent_B0 = 0;
transmitting_B0 = 0;
NUM_OF_REC_BYTES_B0 = length;
if (length == 1)
single = 1;
else
single = 0;
I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
I2C_masterSendMultiByteStart(EUSCI_B0_BASE, RegAddress);
I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
xferIndex_B0 = 0;
while (!stopSent_B0);
return ((RXData_B0[0] << 8) + RXData_B0[1]);
return 0;
}
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t* TxBuffer, uint8_t length)
{
transmitting_B0 = 1;
stopSent_B0 = 0;
TXByteCtr_B0 = length;
TXDataPtr_B0 = &TXData_B0[0];
I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
I2C_masterSendMultiByteStart(EUSCI_B0_BASE, RegAddress);
I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
while (!stopSent_B0);
}
void EUSCIB0_IRQHandler(void)
{
uint_fast16_t status;
status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);
if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
{
if (transmitting_B0)
{
if (TXByteCtr_B0)
{
/* Send the next data and decrement the byte counter */
MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, *TXDataPtr_B0++);
TXByteCtr_B0--;
} else
{
MAP_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
stopSent_B0 = 1;
}
}
else
{
I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
I2C_masterReceiveStart(EUSCI_B0_BASE);
I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
}
}
/* Receives bytes into the receive buffer. If we have received all bytes,
* send a STOP condition */
if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
{
if (xferIndex_B0 == NUM_OF_REC_BYTES_B0 - 2)
{
//MAP_I2C_disableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
//MAP_I2C_enableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_STOP_INTERRUPT);
/*
* Switch order so that stop is being set during reception of last
* byte read byte so that next byte can be read.
*/
MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
RXData_B0[xferIndex_B0++] = MAP_I2C_masterReceiveMultiByteNext(
EUSCI_B0_BASE);
}
else if(xferIndex_B0 == NUM_OF_REC_BYTES_B0 - 1)
{
RXData_B0[xferIndex_B0++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
xferIndex_B0 = 0;
stopSent_B0 = 1;
}
else
{
RXData_B0[xferIndex_B0++] = MAP_I2C_masterReceiveMultiByteNext(
EUSCI_B0_BASE);
}
}
else if (status & EUSCI_B_I2C_STOP_INTERRUPT)
{
MAP_I2C_disableInterrupt(EUSCI_B0_BASE,
EUSCI_B_I2C_STOP_INTERRUPT);
}
}