I am trying to create a library to enable communication between a Teensy 3.6 (master) and an AM4096 encoder (slave). The encoder requires interfacing over I2C to adjust settings before it can be accessed over SPI. So far, I have been able to get the encoder to acknowledge, but every attempt I have made to access either the EEPROM or registers over I2C ends in a NACK error. The encoder specifies that it utilizes clock stretching when accessing the EEPROM, but not for accessing the registers (trying to access either one ends in the same NACK error). Can anyone offer advice on this?
Datasheet available here:
https://www.rls.si/eng/am4096-12-bit-rotary-magnetic-encoder-chip
This is the code I am trying to use to read the register. Note that the encoder uses 16bit registers. This particular bit of code I borrowed from another I2C sensor, so I know it is functional. Here I2C_WIRE=0, i2c_address=0, and adc_command=0-55 (I think, but the manual references an 8 bit code for this value, but gives no further details).
This is a ping function that I run alongside the above function. It consistently returns 0 (good), where as the first fails (NACK) as soon as adc_command is sent over I2C.
Datasheet available here:
https://www.rls.si/eng/am4096-12-bit-rotary-magnetic-encoder-chip
This is the code I am trying to use to read the register. Note that the encoder uses 16bit registers. This particular bit of code I borrowed from another I2C sensor, so I know it is functional. Here I2C_WIRE=0, i2c_address=0, and adc_command=0-55 (I think, but the manual references an 8 bit code for this value, but gives no further details).
Code:
int8_t AM4096::AM4096_read_16_bits(uint8_t adc_command, uint16_t *adc_code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
int8_t ack;
union
{
uint8_t b[2];
uint16_t w;
} data;
// ack = i2c_read_word_data(i2c_address, adc_command, *adc_code);
if(I2C_WIRE == 0){
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(adc_command);
ack = Wire.endTransmission(false);
Wire.requestFrom(I2C_ADDRESS, (uint8_t)2);
data.b[1] = Wire.read();
data.b[0] = Wire.read();
}else if(I2C_WIRE == 1){
Wire1.beginTransmission(I2C_ADDRESS);
Wire1.write(adc_command);
ack = Wire1.endTransmission(false);
Wire1.requestFrom(I2C_ADDRESS, (uint8_t)2);
data.b[1] = Wire1.read();
data.b[0] = Wire1.read();
}else if(I2C_WIRE == 2){
Wire2.beginTransmission(I2C_ADDRESS);
Wire2.write(adc_command);
ack = Wire2.endTransmission(false);
Wire2.requestFrom(I2C_ADDRESS, (uint8_t)2);
data.b[1] = Wire2.read();
data.b[0] = Wire2.read();
}else if(I2C_WIRE == 3){
Wire3.beginTransmission(I2C_ADDRESS);
Wire3.write(adc_command);
ack = Wire3.endTransmission(false);
Wire3.requestFrom(I2C_ADDRESS, (uint8_t)2);
data.b[1] = Wire3.read();
data.b[0] = Wire3.read();
}
*adc_code = data.w;
return ack;
}
This is a ping function that I run alongside the above function. It consistently returns 0 (good), where as the first fails (NACK) as soon as adc_command is sent over I2C.
Code:
byte AM4096::Ping()
{
Wire.beginTransmission(I2C_ADDRESS);
byte error = Wire.endTransmission();
return error;
}