Hi Pylon,
Thanks for the response! The code is so long I was hesitant to post it; I use a Bit-Bang approach that has generally been working fine. Anyways, the INT1 pin goes high in setup until I press the button. Then it goes to the main loop and it no longer triggers, presumably after the first read clears it. I bypass the FIFO explicitly, so I didn't think that was the issue.
#include <TinyWireS.h>
#include <EEPROM.h>
#include <avr/io.h>
#include <util/delay.h>
#define output(directions,pin) (directions |= pin) // set port direction for output
#define input(directions,pin) (directions &= (~pin)) // set port direction for input
#define clear(port,pin) (port &= (~pin)) // clear port pin
#define pin_test(pins,pin) (pins & pin) // test for port pin
#define I2C_slave_address 0x53 // ADXL345 alt address
#define I2C_delay() _delay_us(5)
#define SCL_pin (1 << PA3)
#define SCL_pins PINA
#define SCL_port PORTA
#define SCL_direction DDRA
#define SDA_pin (1 << PA2)
#define SDA_pins PINA
#define SDA_port PORTA
#define SDA_direction DDRA
#define LED 8
#define buttonPin 7
#define INT2 1
#define INT1 0
unsigned char data[6];
unsigned char cmd[6];
unsigned char ret;
unsigned char tiny_slave_addr = 0x26;
void setup() {
EEPROM.write(10, tiny_slave_addr);
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
pinMode(LED, OUTPUT);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH); //set pullups
pinMode(INT1, INPUT);
digitalWrite(INT1, LOW); //set pullups
I2C_init();
cmd[0] = 0x2D; // POWER_CTL register
cmd[1] = 8; // turn on measure bit
ret = I2C_master_write(cmd, 2, I2C_slave_address);
cmd[0] = 0x31; // format register
cmd[1] = 11; // set +-16g range
ret = I2C_master_write(cmd, 2, I2C_slave_address);
cmd[0] = 0x38; // FIFO control register
cmd[1] = 0; // FIFO bypass
ret = I2C_master_write(cmd, 2, I2C_slave_address);
cmd[0] = 0x2F; // interrupt map Register
cmd[1] = 0; // map DataReady interrupt to pin INT1
ret = I2C_master_write(cmd, 2, I2C_slave_address);
cmd[0] = 0x2E; // interrupt enable register
cmd[1] = 128; // enable DataReady interrupt
ret = I2C_master_write(cmd, 2, I2C_slave_address);
while (digitalRead(buttonPin) == HIGH) {}
}
void loop() {
readVals();
}
void readVals() {
while(digitalRead(INT1) == LOW){}
cmd[0] = 0x32; // X0 register
ret = I2C_master_write(cmd, 1, I2C_slave_address);
ret = I2C_master_read(data, 6, I2C_slave_address);
}
void SCL_write(char bit) {
if (bit == 0) {
output(SCL_direction, SCL_pin);
clear(SCL_port, SCL_pin);
}
else {
input(SCL_direction, SCL_pin);
while (pin_test(SCL_pins, SCL_pin) == 0); // check for clock stretching
}
}
void SDA_write(char bit) {
if (bit == 0) {
output(SDA_direction, SDA_pin);
clear(SDA_port, SDA_pin);
}
else
input(SDA_direction, SDA_pin);
}
void I2C_init() {
SDA_write(1);
SCL_write(1);
}
char I2C_master_write_byte(unsigned char byte) {
unsigned char bit;
for (bit = 0; bit < 8; ++bit) {
if ((byte & 0x80) == 0)
SDA_write(0);
else
SDA_write(1);
SCL_write(1);
I2C_delay();
SCL_write(0);
I2C_delay();
byte <<= 1;
}
SDA_write(1);
SCL_write(1);
I2C_delay();
if (pin_test(SDA_pins, SDA_pin) != 0) {
return 1;
}
SCL_write(0);
I2C_delay();
return 0;
}
char I2C_master_write(unsigned char* data, unsigned char nbytes, unsigned char slave_address) {
unsigned char index, ret, slave_address_write;
SDA_write(0);
I2C_delay();
SCL_write(0);
I2C_delay();
slave_address_write = slave_address << 1;
if (I2C_master_write_byte(slave_address_write) != 0)
return 1;
for (index = 0; index < nbytes; ++index) {
ret = I2C_master_write_byte(data[index]);
if (ret != 0)
break;
}
SCL_write(1);
I2C_delay();
SDA_write(1);
I2C_delay();
return ret;
}
void I2C_master_read_byte(unsigned char* data, unsigned char index, unsigned char nbytes) {
unsigned char byte, bit;
SDA_write(1);
byte = 0;
for (bit = 0; bit < 8; ++bit) {
SCL_write(1);
I2C_delay();
if (pin_test(SDA_pins, SDA_pin) != 0)
byte |= (1 << (7 - bit));
SCL_write(0);
I2C_delay();
}
data[index] = byte;
if (index < (nbytes - 1)) {
SDA_write(0);
SCL_write(1);
I2C_delay();
SCL_write(0);
SDA_write(1);
I2C_delay();
}
else {
SDA_write(1);
SCL_write(1);
I2C_delay();
SCL_write(0);
I2C_delay();
}
}
char I2C_master_read(unsigned char* data, unsigned char nbytes, unsigned char slave_address) {
unsigned char index, slave_address_read;
//
// send start
//
SDA_write(0);
I2C_delay();
SCL_write(0);
I2C_delay();
//
// send slave address
//
slave_address_read = (slave_address << 1) + 1;
if (I2C_master_write_byte(slave_address_read) == 1)
//
// no ACK, return 1
//
return 1;
//
// loop over bytes
//
for (index = 0; index < nbytes; ++index)
I2C_master_read_byte(data, index, nbytes);
//
// send stop
//
SCL_write(1);
I2C_delay();
SDA_write(1);
I2C_delay();
return 0;
}
A related question I have is, is there a good way to tell the Master Master(a Rpi) communicating via I2C with my Tiny84 when there is data available, other than just not sending an ACK and waiting for the pi to timeout?
thanks again for the help!