Theprocess is very simple as you can see. The User turns on the button on the Master and the signal goes through the I2C lines and turns on the LED on the slave. ( Both Master and Slave are NANOs in this case. )
If you look closely at the "DATA" column in Pic 1 and Pic 2, the value changes from 0x64 to 0x65. Why does it change and what does it mean? Does it mean it is transitioning from 'case 100' to 'case 101'? ( The cases are in the slave sketch)
All of these are related and I'd suggest you read up on I2C operation. The slave address is always sent first, but it is 7 bits left justified with the least significant bit being an indicator of it being a read or write command. So the slave address of 0x8 looks like 0x10 when sent. The data you are sending, 100 or 101 (in decimal) are 0x64 and 0x65 in hexadecimal.
The pink trace, SDA, is the data, but each bit is only captured on the rising edge of the yellow trace, SCL. Your scope conveniently decodes all of this for you so you don't have to examine the traces.
What I have learned trying to make the chip work, is that if you send data to the chip you are supposed to send it to the registers 0x64 and 0x65, then reading 0x66 to be able to confirm the action wanted. However in this document when trying to erase the IF rows the flowchart tells me to:
Which would mean that the checksum to be written to 0x64 would be 0x04 yet the flowchart claims it should be 0x03, therefore it would seem that the two lines is an error? Furthermore I have found another of your chips equivelant document ( ) the issue with the document is that the checksum isnt even being written to 0x64.
My question here is an error or is this how its supposed to be? If thats the case, where do i learn why this is the case?. Because I am getting an error when reading from 0x66 and trying to compare it with 0, and i cannot seem to be able to salvage the chip, as it will be stuck in an eternal ROM mode, even when I try to pull it out of rom mode by writing:
Underneath is a snip of both the flowcharts in question. The first is from the BQ275xx and the second is BQ274xx both on page 9. I have also included a snip of the implementation of the send commands. The timer sleep is in msec. I found that the chip is more responsive if the delay was added.
I'm facing an issue while breeding the NFTs. The first test case for initializing the parent and the second test case for computing the child run successfully. This means that the child generation is created successfully. However, when the 'mint NFT' test case runs, it shows an error.I'd following this repo to breed the NFT -breeding
I noticed that when I talk to the fuel gauge (i2c address 0x64), the i2c clock line (SCL) idles low. But when I talk to the battery charger (i2c address 0x10) the SCL line idles high. Notice the SCL line behavior after the address byte in the provided pictures (links below). Per the MSP430 datasheet, it is my understanding that the SCL line should be idling LOW after the slave the address is pushed on the line (see page 833 of the MSP430 family guide here:
www.ti.com/.../slau367p.pdf). There's a comment that says: "Bus stalled (SCL held low) until data available".
Why does the SCL line idle differently on those two devices (see picture links below) even though they are on the same i2c bus and we are performing the same 2-byte read operation and using the same i2c driver code?
The MSP430 family guide (page 833) has that comment that says: "Bus stalled (SCL held low) until data available". Whose responsibility it is to hold the SCL low in this case? Is it the master (MSP430) or the slave device?
In the same page of the family guide (page 833), there are cases where it appears that a certain action needs to be performed DURING the transmission of a data byte, is this a hard requirement? For example, let's consider the case where we want to write one byte to the slave device, then follow it with a repeated start and then read one byte. The timing diagram on page 833 implies that we need to set UCTR=0 and UCTXSTT=1 DURING the transmission of the current data byte. What would happen if we set these registers AFTER the data byte has been transmitted?
The 'ghost' byte that I am seeing when talking with the battery charger is basically the MSP430 pushing the contents of the TXBUF out on the bus again! This occurs even after we have already configured the the MSP430 to be in receive mode. Please notice how/when/where I am toggling P4.6 in code as well as in the logic captures (see pictures). Why does this ghost byte happen?! Why does the MSP430 push it's TXBUF out on the line again?
The clock is normally driven by the master but can be held low by the slave (clock stretching) if it needs more time to do something. The master will also hold the clock low waiting for data to be put into TXBUF. See the discussion on page 459.
Thanks David, I am planning to include the code later today. I believe it is the master that is supposed to be holding the SCL line low until data is put into TXBUF. This is consistent with what I'm seeing when talking with the LTC2943. But I don't understand why the line is getting pulled high when talking with the LT8491, they are both using the identical code. I know it may be hard to answer this without looking at the code; I do plan to share that later today. But I hope you can at least see the difference in the logic captures (SCL lines) from my pictures.
Hi David Schultz, I just updated the original posting: provided code and updated pictures. Please take a look at the pictures, I added some annotations that clearly show the issue that I am running into.
You should read the section on timer A. It recommends stopping the timer before changing things like TA1R. And before reading TA1R when the clocks are asynchronous like they are here. It might not be causing trouble here, but then again it might. Or cause trouble later at random times.
You get different results using the same code on two devices. Do the results vary when you alter the order you access them in? If they do, then examine what state the hardware is in at the end of your functions and how that changes from the start.
When receiving data you can send a stop condition if you do it before reading RXBUF. Reading RXBUF causes the hardware to generate an ACK and begin receiving the next byte. So if you set the stop bit after reading RXBUF, the stop happens after it finishes receiving that byte.
Oh, it appears you have left MCLK at its default of 1MHz. So you have only 80 MCLKs per data byte. That might seem like a lot but it can introduce delays at unexpected points if you aren't aware of it. Like that race to set the stop flag before the next byte is received.
2. I modified the code such that I no longer use any driverlib functions (i.e. I am configuring the clocks, registers and i2c bus on the MSP430 manually, register by register). The issue still persists.
3. I tried reversing the order of communicating with the devices as you suggested (i.e. talk to battery charger first, then talk to fuel gauge and then switch that order around). The issue still persists and it's always following the battery charger regardless of its sequence.
But then as I was tinkering with the code, I was actually able to make the ghost byte issue appear when talking to the other 'good device' (the fuel gauge). And I think I know what condition causes the MSP430 to push this 'ghost' byte over the i2c but I don't understand why. Basically, if I try to issue the repeated start condition during or after the ACK from the previous byte has been issued, the MSP430 pushes the contents of the TXBUF over the line. Please take a look at the image attached to this comment, I added an explanation to show what condition causes this 'ghost byte' to appear.
From what I can tell, the reason this ghost byte was more pronounced/frequent on the battery charger is because the SCL line is getting pulled up very quickly after any byte transmitted by the MSP430 (including the i2c address byte or any other data byte). When the SCL line is pulled up quickly like this, it causes the MSP430 to register an ACK much quicker than expected, so then any action we perform (e.g. send a repeated start), ends up missing it's 'window of opportunity'.
Now I have two questions remaining:
1. Why does the SCL line gets pulled up high quickly when talking with the battery charger? For example after sending the battery charger address, the SCL line should idle LOW by the MSP430 until a data byte is written to the TXBUF. It's my understanding that an i2c slave device should NOT be pulling the line high like this.
2. Why are we required to switch to receiver mode and set the start bit during the current byte (as shown in the attached pictures)? Why is it bad if we perform those two actions AFTER the current byte finished transmission? (your explanation about the stop condition and reading RXBUF makes sense, but now I am looking for a similar explanation specific to why we need to switch to receive mode and issue start condition before the current byte is done flushing).
Devices on the I2C bus can only pull the signal lines down. Normally the clock is only pulled down by the master (MSP430) but the slave can stretch the clock if it needs extra time. I dug up the data sheets for the two devices and one is slow (100KHz max) while the other is fast. (at least 400KHz) So their timing could be different.
Running MCLK faster than 1MHz should help with race conditions like requesting a repeated start before a byte gets shifted out. Your code organization is unconventional and contributes to this problem. Running at higher frequencies shouldn't impact power consumption much since the MSP430 should be sleeping in a low power mode most of the time.
Thanks for the feedback David Schultz, I took another look at the datasheets of those two devices (LTC2943 and LT8491) and I believe both of them support 100KHz I2C bus speed so there should not be a conflict there with regards to timing.
From the LTC2943 datasheet: "Data on the I2C bus can be transferred at rates of up to 100kbit/s in standard mode and up to 400kbit/s in fast mode."
From the LT8491 datasheet: "The charger supports clock speeds up to 100kHz for the I2C interface."
3a8082e126