I have the atmega2560 on the APM 2.6 board so the MPU-6050 is wired so I'm unable to mess with resistors and what not.
I'm trying to talk to the MPU on startup but am unable. My understanding is that I need to be in master transmitter mode to send the SLA+W and then in the data sequence I write a byte which is the address in the MPU that I'm requesting. From there I go into master receiving mode. I'm unable to get a good response after the first SLA+W. Instead of getting 0x18 (ACK) I get 0x20 (NACK). One possible issue I'm question now is in the MPU datasheet I see normal mode is 100kHz and fast mode is 400kHz. I'm running at 400kHz but would using something besides those two values cause a problem? This isn't my issue but it is something I'm curious about.
Here is my current sequence.
F_CPU = 8000000 // defined by the compiler const uint32_t I2C_BAUD = 400000; // fast mode (400 kHz) // TWI Bit Rate Register TWBR = ((F_CPU / I2C_BAUD) - 16)/2; comms.putChar(TWBR); // Set prescalar to 1 (0x00) TWSR |= (0 << TWPS1) | (0 << TWPS0);
Looking through this now I noticed I don't have the *4^TWPS in my TWBR formula and I'm confused if the equation is taking TWPS to be the prescalar value or the value of the bits? My equation is assuming the latter where the bits show 0 so 4^0 = 1. Is this correct or should the formula be 4^1 = 4.
Anyways, I'll continue because I think the above is correct the way it is.
bool twi::TwiMgr::idle() { while ((TWCR & (1 << TWINT)) == 0) comms.putChar(1); ; return true; } void twi::TwiMgr::sendStart() { TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); } void twi::TwiMgr::request_read(uint8_t addr, uint8_t reg) { print_status(); sendStart(); idle(); print_status(); TWDR = (addr << 1); // SLA + W //TWDR = addr; // SLA + W TWCR = (1 << TWINT) | (1 << TWEN); idle(); print_status(); //TWDR = 0x6B; // pwr register TWDR = 0x75; // who am i register TWCR = (1 << TWINT) | (1 << TWEN); idle(); print_status(); } void twi::TwiMgr::print_status() { comms.putChar(TWCR); comms.putChar(TWSR & 0xF8); comms.putChar(TWDR); comms.putChar('-'); }
Before calling request_read I delay for 2 seconds to make sure everything has settled and is stable. As you can see I print the current registers after each step in the sequence. First print_status() doesn't really provide much. I send the start condition and wait for the hardware to set the TWINT flag at which point I check the registers. Checking the registers I see that 0x08 is reported (START condition). After that I load the slave address (0x68) into the register. I have the line below it commented out because it seems like in the atmel TWI driver it doesn't shift the address to the left by 1 so I tried it with no luck. I believe what is not commented out is correct. Someone could maybe confirm that. I then set the control register to transmit the SLA+W, wait for the hardware to set the TWINT flag and print the registers once more. At this point I should expect 0x18 to be in the status register however this is where I'm receiving the 0x20. The next step after it is kind of pointless at this point because I am stuck on trying to receive an ACK isntead of a NACK.
Does anyone have any ideas what could be going wrong here? I've been stuck for a few days and would love some help.
Thank you in advance.