Any recent changes to the Wire library?l

This worked last week -

uint16_t spark_BMP::read16(uint8_t a) {
  uint16_t ret;

  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
  Wire.write(a); // sends register address to read from
  Wire.endTransmission(); // end transmission

  Wire.requestFrom(BMP085_I2CADDR, 2);// send data n-bytes read
  while (Wire.available()< 2)
		;
  ret = Wire.read(); // receive DATA
  ret <<= 8;
  ret |= Wire.read(); // receive DATA

  return ret;
}

In my build today it seems to not work. After spending hours debugging I think it is narrowed to the following command -

  while (Wire.available()< 2)
		;

Was there any software changes in the past several days to the firmware that would cause the Wire to behave differently?

@mtnscott,

I don’t think there were changes to the build farm recently. Can you change to
while (Wire.available() < 2); instead of

Thanks @kennethlimcp I can’t quite figure out what is going on. I have two BMP085 sensors and two different prototype setups. I can interchange the sensors and they both work on an older build but not on the newer build. At first I suspected the statement

while (Wire.available() < 2) ;

But with that disabled I still get wrong readings, so I may have a hardware problem. Can’t quite figure out what’s going on. I guess I will have to dig deeper. At least I know my sensors are working properly and I’m glad I had an older configuration running long term tests - just had to terminate the test to swap sensors.

I’m not sure of your question now. :smiley:

Is it that the firmware did not managed to compile successfully or the hardware just did not work.

That makes a whole lot of difference. :wink:

Hi @mtnscott

Do you get any data back over i2c?

The most common problem is forgetting the pull-up resistors which are required on Spark and optional on Arduino.

1 Like

@kennethlimcp So I don’t understand how I can recompile a few days later and it works differently. I’m guessing it may be hardware as I rebuilt the prototype to make room for more stuff. But - Is there any way to find out if a release has been applied to the core firmware in the IDE? Maybe somewhere I can check when I have problems to understand if there was an update? I know the source is in GitHub buy I’m not sure how to determine which version is on the IDE.

@bko Yes, I get data back over the i2c. I have 10K pullups and I have tried 4.7K as well but it does not seem to make a difference. I have tried different libraries (my own BMP085 and the Adafruit_BMP on the IDE) both give me the same bad values for temperature and pressure. I have placed that sensor in a different setup (my other prototype running an older version of the SW) and it gives correct values. - Very strange - the only difference is that I added 1-wire sensors to this configuration and am using D3 for the 1-wire with a 4.7K pullup, D0 & D1 are the I2C with 10K pullups. So all I did was add the 1-wire library and code to read the new sensors.

Anyway at this point I have to debug further as it does not appear that the firmware was changed. Thank you both for your responses and if you have any ideas please let me know!

If you see under the Settings tab for Web IDE, there’s a display of which version of firmware is the build farm compiling against. :slight_smile:

HI @mtnscott

I looked at the github repository and there were some changes in Wire about a month ago. The changes added slave mode, speed select, clock stretching (in hardware) and DMA and fixed some bugs. Nothing seems related to reading data and none of that code changed that I could see and you would not touch any of the new features with your old code.

Maybe you should try commenting out the 1-wire code and see if that is related. I don’t see how it is, but if that is the only change it is worth verifying.

The Adafruit library changed too on June 12, 2014 but that doesn’t seem to fit your timing.

2 Likes

Well it looks like I’m not the only person with problems.

What I don’t understand is why the following hangs -

while ( !Wire.available() ) ;
ret = Wire.read();

This does not hang, however does not always return the correct data

//while( !Wire.available() ) ;
ret = Wire.read();

I’m not good enough with GitHub to compare the spark_wiring_i2c.cpp today vs a month ago.

Have you tried this yet?

@bko Yes, I backed out all my recent changes and I have the same problem. The sensor reads incorrectly and the data does not change - and it only works if I remove the

while( !Wire.available() ) ;

From my sensor read library.

1 Like

My i2c device and core are “in production” and I can’t easily test it right now, sorry. It may just be that you and @ryotsuke are the first to compile after the change.

I know that Spark team runs regression tests to avoid situations like this, so that’s why I was hesitant to blame that commit.

@kennethlimcp is escalating your issue and has filled a github issue as well as pulling @satishgn and @zachary in to this thread.

If you build locally on your own computer, you can back out this change, but I know that can be time consuming to setup if you are not used to it.

1 Like

@bko it’s been a while - actually 6 months since I built locally :frowning: For now I think I will give them a chance to investigate.

Looks like @satishgn fixed it in pull request 322. We’ll get it out in the next release.

2 Likes

Hi @zachary when is the next release?

We’re reviewing a sprint today. By the end of the next sprint (October 15) we plan to release a firmware version.

So I woudn’t be able to recompile by 15th with spark.cli?

If you can build the firmware locally (setup instructions in the firmware readme) then you can build with Satish’s fix right now. If you want to use the web IDE or the spark compile command of the CLI, then you’ll have to wait until we release the next firmware version, sometime between now and Oct 15.

Today’s 15 Oct, is fix online for spark.cli?

I’m integrating MPU9250 sensor into spark and run into the issue when requests for 1 byte would hang I2C.
And after I found a fix and planned to raise an issue I found it is already here.
Looks like default DMA code will not work as is, so I changed the following in the spark_wiring_i2c.cpp

See //Special handling of the 1 byte read
section

uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
system_tick_t _millis;

// clamp to buffer length
if(quantity > BUFFER_LENGTH)
{
quantity = BUFFER_LENGTH;
}

/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);

_millis = millis();
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
{
if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
}

/* Send Slave address for read */
I2C_Send7bitAddress(I2C1, address, I2C_Direction_Receiver);

_millis = millis();
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
}

if(quantity == 1) { //Special handling of the 1 byte read
    /* Disable Acknowledgement */
    I2C_AcknowledgeConfig(I2C1, DISABLE);
    /* Send STOP Condition */
    I2C_GenerateSTOP(I2C1, ENABLE);
    /* Test on I2C1 EV7 and clear it */
    _millis = millis();
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))
    {
        if(EVENT_TIMEOUT < (millis() - _millis)) return 0;
    }
    rxBuffer[0] =  I2C_ReceiveData(I2C1);
    /* Enable Acknowledgement to be ready for another reception */
    I2C_AcknowledgeConfig(I2C1, ENABLE);
    // set rx buffer iterator vars
    rxBufferIndex = 0;
    rxBufferLength = 1;
    return rxBufferLength;
}

TwoWire_DMAConfig(rxBuffer, quantity, RECEIVER);

/* Enable DMA NACK automatic generation */
I2C_DMALastTransferCmd(I2C1, ENABLE);

/* Enable I2C DMA request */
I2C_DMACmd(I2C1, ENABLE);

/* Enable DMA RX Channel */
DMA_Cmd(DMA1_Channel7, ENABLE);

/* Wait until DMA Transfer Complete */
_millis = millis();
while(!DMA_GetFlagStatus(DMA1_FLAG_TC7))
{
if(EVENT_TIMEOUT < (millis() - _millis)) break;
}

/* Disable DMA RX Channel */
DMA_Cmd(DMA1_Channel7, DISABLE);

/* Disable I2C DMA request */
I2C_DMACmd(I2C1, DISABLE);

/* Clear DMA RX Transfer Complete Flag */
DMA_ClearFlag(DMA1_FLAG_TC7);

/* Send STOP Condition /
if(sendStop == true)
{
/
Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
}

/* Enable Acknowledgement to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);

// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = quantity - DMA_GetCurrDataCounter(DMA1_Channel7);

return rxBufferLength;
}