Jump to content
I2Cdevlib Forums

anwu93

Members
  • Posts

    4
  • Joined

  • Last visited

anwu93's Achievements

Newbie

Newbie (1/14)

0

Reputation

  1. Figured out my issue. Apparently my read function was acknowledging the last byte of read data, which was causing the slave to hold the SDA line low. Fixed it by not acknowledging the last byte I read.
  2. Looks like I'm getting an I2C_ARBITRATION_LOSS when my program hangs there.
  3. 1) Sketch is the Arduino source file containing the main program. 2) MPU is the MPU6050, MPU stands for Motion Processing Unit 3) DMP is the Digital Motion Processing Unit
  4. Hi all, thanks in advance for reading. I am interfacing the PIC32MX320F128H with the MPU6050 over I2C. For some reason my program hangs when I try to initiate a start condition through I2C using plib. More specifically, when I call I2CGetStatus, the I2C_STATUS never returns I2C_START. Without changing the program on the microcontroller, I can get the program to work by doing a hack I've discovered. I unplug my microcontroller from power, I hold the reset button on the microcontroller, plug in the power, and release the reset button, and then my program runs fine. I get values from my accelerometer and gyroscope on the device. But then after reading from the device, I try to initiate a stop condition with I2CStop, but I get no I2C_STOP condition when I call I2CGetStatus afterwards. So I'm starting to think my original issue is related to my issue I get even when I use my workaround. I'm using the MPU6050 from sparkfun. https://www.sparkfun.com/products/11028 My schematic is very simple. VDD - 3.3v from microcontroller GND - GND from microcontroller SCL - A5 SDA - A4 VIO - 3.3v from microcontroller I have been looking at the power on procedure as listed on page 23 of 52 on the datasheet. https://www.cdiweb.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf I have hooked up my VDD and VIO lines to the oscilloscope, and I have looked at both cases when I use my workaround and normal power up, I don't see anything different, so I am very lost. I have successfully been able to interface and use the HMC5883L so I know how I2C works, and I know my I2C library works. But here is my code anyway. main.c #include "xc.h" #include <stdio.h> #include "serial.h" #include "BOARD.h" #include "IO_Ports.h" #include "I2Cpic32.h" #include <plib.h> #define SYS_CLOCK 80000000 #define SLV_CLOCK 400000 #define SLV_ADDR 0x68 #define DELAY(x) for (wait = 0; wait <= x; wait++) {asm("nop");} #define A_BIT 183000 #define A_LOT 18300000 int wait; int main(void) { int p_size, id; UINT32 actualClock; UINT8 packet[10], read_data[14]; uint8_t powerManagementReg; INT16 AcX, AcY, AcZ, GyX, GyY, GyZ, temp; // temp is temperature I2C_7_BIT_ADDRESS slave7BitAddress; DELAY(A_BIT); BOARD_Init(); printf("Board initialized\n"); DELAY(A_LOT); actualClock = I2CSetFrequency(I2C1, SYS_CLOCK, SLV_CLOCK); if ( abs(actualClock-SLV_CLOCK) > SLV_CLOCK/10 ) printf("Error: I2C1 clock frequency (%u) error exceeds 10%%.\n", (unsigned)actualClock); printf("Clock set: %u\n", actualClock); I2CEnable(I2C1, TRUE); printf("I2C Enabled\n"); DELAY(A_LOT); I2C_FORMAT_7_BIT_ADDRESS(slave7BitAddress, SLV_ADDR, I2C_WRITE); DELAY(A_BIT); // wakes up the MPU packet[0] = slave7BitAddress.byte; packet[1] = 0x6b; packet[2] = 0x00; p_size = 3; send_packet(packet, p_size); // gyro config packet[1] = 0x1b; packet[2] = 0x08; send_packet(packet, p_size); // sample rate config packet[1] = 0x19; packet[2] = 0x07; send_packet(packet, p_size); DELAY(A_LOT); for (; { I2C_FORMAT_7_BIT_ADDRESS(slave7BitAddress, SLV_ADDR, I2C_WRITE); packet[0] = slave7BitAddress.byte; packet[1] = 0x3b; p_size = 2; send_packet(packet, p_size); StartTransfer(FALSE); I2C_FORMAT_7_BIT_ADDRESS(slave7BitAddress, SLV_ADDR, I2C_READ); TransmitOneByte(slave7BitAddress.byte); read_data[0] = read_byte(I2C1); // ACCEL_XOUT[15:8] read_data[1] = read_byte(I2C1); // ACCEL_XOUT[7:0] read_data[2] = read_byte(I2C1); // ACCEL_YOUT[15:8] read_data[3] = read_byte(I2C1); // ACCEL_YOUT[7:0] read_data[4] = read_byte(I2C1); // ACCEL_ZOUT[15:8] read_data[5] = read_byte(I2C1); // ACCEL_ZOUT[7:0] read_data[6] = read_byte(I2C1); // TEMP_OUT[15:8] read_data[7] = read_byte(I2C1); // TEMP_OUT[7:0] read_data[8] = read_byte(I2C1); // GYRO_XOUT[15:8] read_data[9] = read_byte(I2C1); // GYRO_XOUT[7:0] read_data[10] = read_byte(I2C1); // GYRO_YOUT[15:8] read_data[11] = read_byte(I2C1); // GYRO_YOUT[7:0] read_data[12] = read_byte(I2C1); // GYRO_ZOUT[15:8] read_data[13] = read_byte(I2C1); // GYRO_ZOUT[7:0] AcX = (read_data[0] << 8) | read_data[1]; AcY = (read_data[2] << 8) | read_data[3]; AcZ = (read_data[4] << 8) | read_data[5]; temp = (read_data[6] << 8) | read_data[7]; GyX = (read_data[8] << 8) | read_data[9]; GyY = (read_data[10] << 8) | read_data[11]; GyZ = (read_data[12] << 8) | read_data[13]; printf("AcX: %d\n", AcX); printf("AcY: %d\n", AcY); printf("AcZ: %d\n", AcZ); printf("temp: %d\n", temp); printf("GyX: %d\n", GyX); printf("GyY: %d\n", GyY); printf("GyZ: %d\n", GyZ); check_status(I2C1); StopTransfer(); DELAY(A_LOT); } return 0; } I2Cpic32.c // Standard headers #include <stdbool.h> #include <stdint.h> // Microchip headers #include <xc.h> #include <plib.h> // User headers #include "I2Cpic32.h" BOOL ret; I2C_RESULT res; BOOL StartTransfer( BOOL restart ) { I2C_STATUS status; // Send the Start (or Restart) signal if(restart) { I2CRepeatStart(I2C1); } else { // Wait for the bus to be idle, then start the transfer while( !I2CBusIsIdle(I2C1) ); if(I2CStart(I2C1) != I2C_SUCCESS) { printf("Error: Bus collision during transfer Start\n"); return FALSE; } } // Wait for the signal to complete do { status = I2CGetStatus(I2C1); } while ( !(status & I2C_START) ); return TRUE; } BOOL TransmitOneByte( UINT8 data ) { // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(I2C1)); // Transmit the byte if(I2CSendByte(I2C1, data) == I2C_MASTER_BUS_COLLISION) { printf("Error: I2C Master Bus Collision\n"); return FALSE; } // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(I2C1)); return TRUE; } void StopTransfer( void ) { I2C_STATUS status; // Send the Stop signal I2CStop(I2C1); // Wait for the signal to complete do { status = I2CGetStatus(I2C1); printf("asuh\n"); } while ( !(status & I2C_STOP) ); } void check_status(I2C_MODULE id) { I2C_STATUS stat = I2CGetStatus(id); if (stat&I2C_TRANSMITTER_FULL) printf("check_status: I2C_TRANSMITTER_FULL\n"); if (stat&I2C_DATA_AVAILABLE) printf("check_status: I2C_DATA_AVAILABLE\n"); if (stat&I2C_SLAVE_READ) printf("check_status: I2C_SLAVE_READ\n"); if (stat&I2C_START) printf("check_status: I2C_START\n"); if (stat&I2C_STOP) printf("check_status: I2C_STOP\n"); if (stat&I2C_SLAVE_DATA) printf("check_status: I2C_SLAVE_DATA\n"); if (stat&I2C_RECEIVER_OVERFLOW) printf("check_status: I2C_RECEIVER_OVERFLOW\n"); if (stat&I2C_TRANSMITTER_OVERFLOW) printf("check_status: I2C_TRANSMITTER_OVERFLOW\n"); if (stat&I2C_10BIT_ADDRESS) printf("check_status: I2C_10BIT_ADDRESS\n"); if (stat&I2C_GENERAL_CALL) printf("check_status: I2C_GENERAL_CALL\n"); if (stat&I2C_ARBITRATION_LOSS) printf("check_status: I2C_ARBITRATION_LOSS\n"); if (stat&I2C_TRANSMITTER_BUSY) printf("check_status: I2C_TRANSMITTER_BUSY\n"); if (stat&I2C_BYTE_ACKNOWLEDGED) printf("check_status: I2C_BYTE_ACKNOWLEDGED\n"); } BYTE read_byte(I2C_MODULE id) { BYTE val; ret = I2CReceiverEnable(I2C1, TRUE); //printf("I2CReceiverEnable(I2C1, TRUE): %d\n", ret); while(!(ret = I2CReceivedDataIsAvailable(I2C1))); ret = I2CReceivedDataIsAvailable(I2C1); //printf("I2CReceivedDataIsAvailable(I2C1): %d\n", ret); I2CAcknowledgeByte(I2C1, TRUE); val = I2CGetByte(id); //printf("val: %x\n", val); while(!(ret = I2CAcknowledgeHasCompleted(I2C1))); //printf("I2CAcknowledgeHasCompleted(I2C1): %d\n", ret); return val; } void send_packet(UINT8 data[], int size) { int i; // Start transfer ret = StartTransfer(FALSE); //printf("StartTransfer(FALSE): %d\n", ret); for (i = 0; i < size; i++) { ret = TransmitOneByte(data[i]); //printf("TransmitOneByte(%x): %d\n", data[i], ret); ret = I2CByteWasAcknowledged(I2C1); //printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); } // Stop transfer StopTransfer(); } uint8_t I2C_ReadReg(uint8_t address, uint8_t reg) { uint8_t val; printf("asuh\n"); StartTransfer(FALSE); ret = TransmitOneByte(address << 1); printf("TransmitOneByte(%x): %d\n", (address << 1), ret); ret = I2CByteWasAcknowledged(I2C1); printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); ret = TransmitOneByte(reg); printf("TransmitOneByte(%x): %d\n", reg, ret); ret = I2CByteWasAcknowledged(I2C1); printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); StartTransfer(TRUE); ret = TransmitOneByte((address << 1) + 1); printf("TransmitOneByte(%x): %d\n", ((address << 1) + 1), ret); ret = I2CReceiverEnable(I2C1, TRUE); printf("I2CReceiverEnable(I2C1, TRUE): %d\n", ret); while(!(ret = I2CReceivedDataIsAvailable(I2C1))); ret = I2CReceivedDataIsAvailable(I2C1); val = I2CGetByte(I2C1); printf("val: %x\n", val); StopTransfer(); return val; } int16_t I2C_ReadReg16(uint8_t address, uint8_t reg) { int16_t val; StartTransfer(FALSE); ret = TransmitOneByte(address << 1); printf("TransmitOneByte(%x): %d\n", (address << 1), ret); ret = I2CByteWasAcknowledged(I2C1); //printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); ret = TransmitOneByte(reg); printf("TransmitOneByte(%x): %d\n", reg, ret); ret = I2CByteWasAcknowledged(I2C1); //printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); StartTransfer(TRUE); ret = TransmitOneByte((address << 1) + 1); printf("TransmitOneByte(%x): %d\n", ((address << 1) + 1), ret); ret = I2CReceiverEnable(I2C1, TRUE); //printf("I2CReceiverEnable(I2C1, TRUE): %d\n", ret); while(!(ret = I2CReceivedDataIsAvailable(I2C1))); ret = I2CReceivedDataIsAvailable(I2C1); val = I2CGetByte(I2C1) << 8; ret = I2CReceiverEnable(I2C1, TRUE); //printf("I2CReceiverEnable(I2C1, TRUE): %d\n", ret); while(!(ret = I2CReceivedDataIsAvailable(I2C1))); ret = I2CReceivedDataIsAvailable(I2C1); val |= I2CGetByte(I2C1); printf("val: %x\n", val); StopTransfer(); return val; } void I2C_WriteReg(UINT8 address, UINT8 reg, UINT8 val) { // Start transfer ret = StartTransfer(FALSE); //printf("StartTransfer(FALSE): %d\n", ret); ret = TransmitOneByte(address); //printf("TransmitOneByte(%x): %d\n", address, ret); ret = I2CByteWasAcknowledged(I2C1); //printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); ret = TransmitOneByte(reg); //printf("TransmitOneByte(%x): %d\n", reg, ret); ret = I2CByteWasAcknowledged(I2C1); //printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); ret = TransmitOneByte(val); //printf("TransmitOneByte(%x): %d\n", val, ret); ret = I2CByteWasAcknowledged(I2C1); //printf("I2CByteWasAcknowledged(I2C1): %d\n", ret); // Stop transfer StopTransfer(); }
×
×
  • Create New...