This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software:
Hi champs,
I am asking this for our customer.
The user used the example and modified it a little bit by using the API, DL_I2C_getTargetStatus().
C:\ti\mspm0_sdk_2_02_00_05\examples\nortos\LP_MSPM0G3507\driverlib\i2c_target_rw_multibyte_fifo_interrupts\ticlang
On Line 116-119, the u32temp result on CCS watch window is 0xB240 on the top right, which is different from 0xB245, the CCS watch window register view I2C1_SSR on the bottom right.
The user added the codes (Line 116-119) like below with a loop and ran again up to Line 123, the user found the result became correct 0xB244, which matches I2C_SSR1 (see below).
Why the runtime result by using DL_I2C_getTargetStatus() in the first figure above is different from the watch window register I2C_SSR1?
Why the runtime result by using DL_I2C_getTargetStatus() in the second figure above becomes correct in the watch window register I2C_SSR1?
Dear expert,
We can duplicate this.
Here is my testing, I create three variables to get the I2C Slave Register in different ways and timing.
u32temp1 => From the API
u32temp2 => From the memory location for the register
u32temp3 => From the API after running 100 cycles
DL_I2C_flushTargetTXFIFO(I2C_INST); u32temp1 = DL_I2C_getTargetStatus(I2C_INST); //API read slave register u32temp2 = *(uint32_t *)0x400F325C; //read the slave register memory location value for(int i=0;i<100;i++) { __NOP(); } u32temp3 = DL_I2C_getTargetStatus(I2C_INST); //the value stabled __NOP(); break;
Shouldn't the value we get from memory the same as we saw from the memory browser?
Best Regards,
Eric Chen
The example i2c_controller_rw_multibyte_fifo_interrupts doesn't appear to read any of the Target-side status (since it's running as a Controller).
Supposing this is actually something like i2c_target_rw_multibyte_fifo_interrupts, I suspect you're seeing a race between the target-side I2C unit and the debugger. Even with PDBGCTL=0, I expect the I2C unit can take some finite time to halt at a breakpoint, so something very dynamic like BUSBSY (0x0040) could change in the meantime.
I suggest you mask off the fields you're not interested in before comparing.
Hi Bruce,
There was a typo. Yes, we are talking about Target side (G3507 I2C acts as target) rather than Controller side and I already changed the path in the first post.
Would you please make it clearer "a race between the target-side I2C unit and the debugger"?
Do you mean even we set a breakpoint right after var = DL_I2C_getTargetStatus(I2C_INST);, but the debugger still could not get it at the same time?
That is, you meant the CCS window result is not correct at the breakpoint?
You mentioned "I suggest you mask off the fields you're not interested in before comparing." In fact, we were only trying to get the R/W bit right after the address, and found it was hard to identify it by comparing our codes and CCS watch window.
Do you have any suggestion how we should do here if we want to get the R/W bit? Would you please elaborate it?
Is this a CCS bug or a debugger (XDS110) limitation?
There are two separable things here:
1) Dynamic bits: These change due to events outside your program. In general, their state can change between two successive reads of the register. Not all of them are like this, but it's not always obvious which ones are, based on a quick read of the TRM.
2) Unrelated bits: These are bits you aren't interested in, and may or may not be =1; these prevent using a simple compare such as "(u32temp == 0x80)", since some other (unrelated) bits might be set as well.
Such a test should look more like
> if ((u32temp & 0x80) == 0x80) // Tx mode?
or more formally:
> if ((u32temp & I2C_SSR_TXMODE_MASK) == I2C_SSR_TXMODE_SET) // Tx mode?
-------------
Usually fixing (2) also fixes (1).
Hi Bruce,
This is resolved by the above method + loop-based statements.
Thank you for your information.