Trying to keep this as short as possible. I have 3 I2C devices on a bus. A LSM303(accelerometer + magnetometer), a high precision temp sensor, tricolor LED driver TCA6057,and a L3GD20(gyroscope). The gyro and the accelo are made by the same company and have virtually identical register mappings. I base my library on the arduino library for the LSM303. I can read the accelo just fine and every seems to be working.
I used a similar arduino library to interact with the L3GD20. The arduino library works fine interacting with the device. However whenever I try to interact with it using my port of the arduino library it basically just returns the last address value that I set. so for example if I set it to 0x6F, and I attempt to call the readGyroReg method it returns 6F not matter what register I try to read. It has something to do with the enable method because we acutally started up our circuit and attempted a read, got 0x6F, then wired in the arduino, ran the arduino enable method, then had our device do a read and it read the values fine. I feel like I may be using the TWI functions incorrectly even though it works using almost an identical protocol for the LSM303. The problem is driving me crazy.
here is my library code where I implement the twi any ideas. relatively new to proper controller c code so criticism is welcome, but don't make me cry ;)
Code I am referring to and full files attached below.
CODE
void writeGyro(uint8_t* valToWrite, uint8_t numBytesToWrite){
uint32_t err_code;
m_tx_done = false;
err_code = nrf_drv_twi_tx(&m_twi_device, D20_SA0_HIGH_ADDRESS, (uint8_t*)valToWrite, numBytesToWrite, false);
APP_ERROR_CHECK(err_code);
while(!m_tx_done);
}
uint8_t* readGyro(uint8_t addrToRead,uint8_t numBytesToRead){
uint32_t err_code;
writeGyro(&addrToRead, 1);
m_rx_done = false;
err_code = nrf_drv_twi_rx(&m_twi_device, D20_SA0_HIGH_ADDRESS, (uint8_t*)&m_fromI2Cdevice, numBytesToRead);
APP_ERROR_CHECK(err_code);
while(!m_rx_done);
return m_fromI2Cdevice;
}
uint8_t readGyroReg(uint8_t addrToRead){
uint32_t err_code;
m_fromI2Cdevice[0] = 0x00;
writeGyro(&addrToRead, 1);
m_rx_done = false;
err_code = nrf_drv_twi_rx(&m_twi_device, D20_SA0_HIGH_ADDRESS, (uint8_t*)&m_fromI2Cdevice, 1);
APP_ERROR_CHECK(err_code);
while(!m_rx_done);
return m_fromI2Cdevice[0];
}
void enableGyro(){
// 0x00 = 0b00000000
// Low_ODR = 0 (low speed ODR disabled)
uint8_t setCtrlReg[2] = {LOW_ODR,0x00};
writeGyro(setCtrlReg, 2);
nrf_delay_ms(10);
// 0x6F = 0b01101111
// DR = 01 (200 Hz ODR); BW = 10 (50 Hz bandwidth); PD = 1 (normal mode); Zen = Yen = Xen = 1 (all axes enabled)
setCtrlReg[0] = CTRL1G;
setCtrlReg[1] = 0x6F;
writeGyro(setCtrlReg,2);//CTRL1G, 0x6F);
nrf_delay_ms(10);
// 0x00 = 0b00000000
// FS = 00 (+/- 250 dps full scale)
setCtrlReg[0] = CTRL4G;
setCtrlReg[1] = 0x00;
writeGyro(setCtrlReg,2);//CTRL4G, 0x00);
nrf_delay_ms(10);
}
int16_t* readGyroXYZ(){
uint8_t msbassert = (OUT_X_L_G | (1 << 7));
uint8_t* results = readGyro(msbassert,6);
uint8_t xla = results[0];
uint8_t xha = results[1];
uint8_t yla = results[2];
uint8_t yha = results[3];
uint8_t zla = results[4];
uint8_t zha = results[5];
// combine high and low bytes
// This no longer drops the lowest 4 bits of the readings from the DLH/DLM/DLHC, which are always 0
// (12-bit resolution, left-aligned). The D has 16-bit resolution
int16_t gx = (int16_t)(xha << 8 | xla);
int16_t gy = (int16_t)(yha << 8 | yla);
int16_t gz = (int16_t)(zha << 8 | zla);
gyroVals[0] = gx;
gyroVals[1] = gy;
gyroVals[2] = gz;
return gyroVals;
}