Hi everyone,
I am working on a project in which I need to poll an accelerometer for motion data, however, I am running into trouble when I try to adapt the example code provided in the DriverLib documentation to my problem. When I hooked up my development board to an oscilliscope, I notice the following behaviour:
C2000: Writes address of MPU to I2C Bus
MPU: No ACK
The code below is trying to request and read back a single register address of the MPU-6050. I have attached the documentation pdf below if you would like to review it. The protocol in question is on page 34.
#include "driverlib.h"
#include <device.h>
#include <stdint.h>
#define WHO_AM_I 0x75
#define MPU_ADDRESS 0x68
void initI2C();
__interrupt void i2cFIFOISR();
uint16_t mpu_data;
uint16_t status;
void main() {
/* Setup C2000 */
Device_init();
Device_initGPIO();
/* Setup GPIO for I2C */
GPIO_setPinConfig(GPIO_35_SDAA);
GPIO_setPadConfig(35U, GPIO_PIN_TYPE_PULLUP);
GPIO_setQualificationMode(35U, GPIO_QUAL_ASYNC);
GPIO_setPinConfig(GPIO_37_SCLA);
GPIO_setPadConfig(37U, GPIO_PIN_TYPE_PULLUP);
GPIO_setQualificationMode(37U, GPIO_QUAL_ASYNC);
/* Setup interrupts */
Interrupt_initModule();
Interrupt_initVectorTable();
Interrupt_register(INT_I2CA, &i2cFIFOISR);
/* Call i2c setup function */
initI2C();
/* Enable interrupts system-wide */
Interrupt_enable(INT_I2CA);
EINT;
ERTM;
I2C_setDataCount(I2CA_BASE, 1);
while (1) {
while (I2C_isBusBusy(I2CA_BASE)) {}
// I2C_putData(I2CA_BASE, WHO_AM_I);
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
I2C_sendStartCondition(I2CA_BASE);
status = I2C_getStatus(I2CA_BASE);
}
}
void initI2C() {
I2C_disableModule(I2CA_BASE);
/* Configure for 400 kHz clock with a 50% duty cycle */
I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_33);
I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8);
I2C_setSlaveAddress(I2CA_BASE, MPU_ADDRESS);
I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN);
I2C_enableInterrupt(I2CA_BASE, I2C_INT_REG_ACCESS_RDY | I2C_INT_STOP_CONDITION);
I2C_enableFIFO(I2CA_BASE);
I2C_clearInterruptStatus(I2CA_BASE, I2C_INT_RXFF | I2C_INT_TXFF);
I2C_enableModule(I2CA_BASE);
}
__interrupt void i2cFIFOISR() {
I2C_InterruptSource source;
source = I2C_getInterruptSource(I2CA_BASE);
switch (source) {
case I2C_INTSRC_REG_ACCESS_RDY:
if((I2C_getStatus(I2CA_BASE) & I2C_STS_NO_ACK) != 0) {
I2C_sendStopCondition(I2CA_BASE);
I2C_clearStatus(I2CA_BASE, I2C_STS_NO_ACK);
}
I2C_setConfig(I2CA_BASE, I2C_MASTER_RECEIVE_MODE);
I2C_putData(I2CA_BASE, WHO_AM_I);
I2C_sendStartCondition(I2CA_BASE);
mpu_data = I2C_getData(I2CA_BASE);
I2C_sendStopCondition(I2CA_BASE);
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE);
break;
case I2C_INTSRC_STOP_CONDITION:
I2C_sendStopCondition(I2CA_BASE);
mpu_data = I2C_getData(I2CA_BASE);
break;
default:
mpu_data = I2C_getData(I2CA_BASE);
I2C_sendNACK(I2CA_BASE);
break;
}
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
}
Many thanks!MPU-6050_DataSheet_V3 4.pdf