Other Parts Discussed in Thread: TMP006, ADS7924
HI,
Hoping this is a code issue someone might has crossed before. I can successfully read the various control and status registers via I2C, with a slave device (running CCS V7.1.0.00016 debugger,, no rtos, custom board with TM4C129ENCZAD master, and slave device IIS2DH).
When I write to one of the control registers (for ex., CTRL_REG1) on the slave device, and then read back the new state, the original (power-up default) value is returned, not the new value just written.
This register has a power-on default of 0x07. It never changes for any write op that I have come up with. After studying the forums herein, at this point, have the code inserted at the end of this post.
The code first reads current (default, 0x07)) state of ctrl1. Then a new value (0x23) is written to ctrl1. Finally, the new state of ctrl1 is read back.
The problems:
1) A write to a control register appears to not be latched by device. This may be a device issue and not a code issue but I am wondering if it may be something in the write sequence I have arrived at (see code below...)
2) The last read op repeats 2x's. No clue why.
The following screen capture shows the bit sequences transmitted across the I2C SDA/SCL for the above 3 ops.
As can be seen, the state of ctrl1 does not change in response to the write op. And the final read op repeats 2x.
The following is the code:
//program CTRL_REG1[7:4] to 0111 - 400Hz HR/NORMAL/Low Power Mode (def = 0000 - PowerDn) //Read current state of CTRL_REG1 SlaveAddress = 32; //CTRL_REG1 address (x20) //SlaveAddress = 15; //WHOAMI address (x0F) I2CMasterSlaveAddrSet(I2C2_BASE, Board_FBB_TM4C129_ACCEL_ADDR, false); //false = write SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 delay issue - from TI forums. Subsequent code steps will not work reliably w/o this!!!) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterDataPut(I2C2_BASE, SlaveAddress); I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_SEND); SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterSlaveAddrSet(I2C2_BASE, Board_FBB_TM4C129_ACCEL_ADDR, true); //true = read SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); Slave_CTL_Reg1_State = I2CMasterDataGet(I2C2_BASE); //Set bits [7:4] = 0111, ODR field for NORMAL Mode ops MasterTxData_R = Slave_CTL_Reg1_State; MasterTxData_S = (MasterTxData_R & 0x00) | 0x23; SlaveAddress = 32; //CTRL_REG1 address (x20) I2CMasterSlaveAddrSet(I2C2_BASE, Board_FBB_TM4C129_ACCEL_ADDR, false); //false = write. This transmits correctly, when I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_SEND) is run SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterDataPut(I2C2_BASE, SlaveAddress); I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_SEND); SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterDataPut(I2C2_BASE, MasterTxData_S); //write updated CTRL_REG1 setting I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_SEND); SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); //Check new state of CTRL_REG1 SlaveAddress = 32; //CTRL_REG1 address (x20) I2CMasterSlaveAddrSet(I2C2_BASE, Board_FBB_TM4C129_ACCEL_ADDR, false); //false = write. SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterDataPut(I2C2_BASE, SlaveAddress); I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_SEND); SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterSlaveAddrSet(I2C2_BASE, Board_FBB_TM4C129_ACCEL_ADDR, true); //true = read. SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); SysCtlDelay(1000); // Allow Busy flag to set (TM4C129 issue) //while(!(I2CMasterBusy(I2C2_BASE))); while(I2CMasterBusBusy(I2C2_BASE)); Slave_CTL_Reg1_State_Verify = I2CMasterDataGet(I2C2_BASE); if(uint8_t(Slave_CTL_Reg1_State_Verify) !=MasterTxData_S) { System_printf("I2C Rd/Wr to CTRL_Reg1 Error"); return 0; }
Have read, re-read, and read again the user guide for the I2C slave peripheral. No special commands to enable register changes are mentioned. I posted to the tech support site for the part but have not received any feedback yet. Again, hoping its something in my code that is not right.
Thank you in advance.