I have chinese UNO 3 w/ mega328p connected to SEN0142 from DFRobot with a MPC6050 IMU (3 DOF gyro + 3 DOF accel).
UNO 3 <--> IMU
+5V <---> Vin
GNC <---> GND
SCL <---> SCL
SDA <---> SDA
I'm using command line on Linux. Upload program with avrdude. Reading output using minicom.
I have a "dump" routine that outputs the "data" array of 16 bytes at each stage.
I initialize "data" to all 0xff. When the program runs, I get one line of all FF's, so I conclude that TWINT is never set after the START is sent.
The documentation and example code both indicate address can be 0x68 or 0x69. pEDIT: I get same result with both addresses.]
I'd appreciate any feedback on the initialization etc.
#include <stdint.h> #include <avr/io.h> #include <util/delay.h> #include <util/twi.h> #include "../uart.c" void dump_data(uint16_t addr) { dump_data16(addr); uart_putchar('\r'); uart_putchar('\n'); } uint8_t data[16]; /* * TWBR bit rate * TWCR control reg: TWINT | TWEA | TWSTA | TWSTO | TWWC | TWEN | | TWIE * TWSR status reg * TWDR data register * TWAR slave addr reg * TWAMR slave addr mask reg */ /* * loop_until... means wait for ACK (or NACK -- deal with later) */ uint8_t i2c_read(uint8_t sla_, uint8_t reg) { uint8_t val; uint8_t i = 0; dump_data((uint16_t) data); /* send START and wait */ TWCR = TWINT | TWSTA | TWEN; loop_until_bit_is_set(TWCR, TWINT); data[i++] = TWSR; dump_data((uint16_t) data); /* send device address */ TWDR = sla_ | 1; TWCR = TWINT | TWEN; loop_until_bit_is_set(TWCR, TWINT); data[i++] = TWSR; dump_data((uint16_t) data); /* send register address */ TWDR = reg; TWCR = TWINT | TWEN; loop_until_bit_is_set(TWCR, TWINT); data[i++] = TWSR; dump_data((uint16_t) data); /* send START */ TWCR = TWINT | TWSTA | TWEN; loop_until_bit_is_set(TWCR, TWINT); data[i++] = TWSR; dump_data((uint16_t) data); /* send device address again */ TWDR = sla_ | 0; TWCR = TWINT | TWEN; loop_until_bit_is_set(TWCR, TWINT); data[i++] = TWSR; dump_data((uint16_t) data); /* recv register contents */ val = TWDR; TWCR = TWINT | TWEN; loop_until_bit_is_set(TWCR, TWINT); data[i++] = TWSR; dump_data((uint16_t) data); /* send STOP */ TWCR |= TWINT | TWSTO | TWEN; loop_until_bit_is_set(TWCR, TWINT); data[i++] = TWSR; dump_data((uint16_t) data); return val; } void twi_init(void) { TWBR = 12; /* to get 400 kHz bit rate */ TWSR = 0; /* prescalar of 1 */ } #define SLA_ (0x68 << 1) /* 7-bit IMU address */ int main(void) { uart_init(); twi_init(); for (uint8_t i = 0; i < 16; i++) data[i] = 0xff; _delay_ms(500); _delay_ms(500); _delay_ms(500); data[8] = i2c_read(SLA_, 67); /* X.hi */ DDRB |= _BV(DDB5); for (;;) { PINB = _BV(PINB5); _delay_ms(100); } return 0; }