Notifications
Clear all

Xiao to Xiao I2C communication demo

21 Posts
4 Users
2 Reactions
3,164 Views
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@jfabernathy

Posted by: @jfabernathy

Oh!, I did get chastised for having variable in my callback functions that were not declared volatile, so I'm going to clean it up, but with my check for false triggering installed, I should be okay using the Xiao.

Why do you need volatile in your code for this situation?


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@jfabernathy

Posted by: @jfabernathy

Now to the puzzling part.  The Xiao, like some other Arduino parts in the past, like Arduino Due, have been seeing the OnRecieve callback function triggered with the argument "howmany" equal to zero. This is not suppose to happen. It was explained to me that if the sending program sent 5 bytes, then when the callback function was triggered howmany would be 5 and Wire.available() would also return 5 on the first call to Wire.read() and then 4 on the second call, etc. When it got to zero you were done.

I was getting some triggers where howmany was zero and Wire.available() returned 0 on the first trigger of the OnReceive callback function. I  have a workaround to test for these conditions. It appears that the OnReceive callback function gets triggered for each message once with howmany = 0 and then again with the right number. I'm going to do further testing and send different number of bytes in the initial message to the slave.

So this is a bug that has been seen before. I'll see if the Seeedunio folks can do something about it.

Back to this, not sure if this may help the situation, as I don't have the board to test it, but looking through the header and implementation file I noted the following comments:

Wire.cpp

//  Originally, 'endTransmission' was an f(void) function.
//  It has been modified to take one parameter indicating
//  whether or not a STOP should be performed on the bus.
//  Calling endTransmission(false) allows a sketch to 
//  perform a repeated start. 
//
//  WARNING: Nothing in the library keeps track of whether
//  the bus tenure has been properly ended with a STOP. It
//  is very possible to leave the bus in a hung state if
//  no call to endTransmission(true) is made. Some I2C
//  devices will behave oddly if they do not see a STOP.
//
uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
 // [snipped out by frogandtoad for brevity]
}

...and also:

// behind the scenes function that is called when data is received
void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
{
  // don't bother if user hasn't registered a callback
  if(!user_onReceive){
    return;
  }
  // don't bother if rx buffer is in use by a master requestFrom() op
  // i know this drops data, but it allows for slight stupidity
  // meaning, they may not have read all the master requestFrom() data yet
  if(rxBufferIndex < rxBufferLength){
    return;
  }
  // copy twi rx buffer into local read buffer
  // this enables new reads to happen in parallel
  for(uint8_t i = 0; i < numBytes; ++i){
    rxBuffer[i] = inBytes[i];    
  }
  // set rx iterator vars
  rxBufferIndex = 0;
  rxBufferLength = numBytes;
  // alert user program
  user_onReceive(numBytes);
}

Might be worth a try?


   
ReplyQuote
(@jfabernathy)
Member
Joined: 3 years ago
Posts: 141
Topic starter  
Posted by: @frogandtoad

@jfabernathy

Posted by: @jfabernathy

Oh!, I did get chastised for having variable in my callback functions that were not declared volatile, so I'm going to clean it up, but with my check for false triggering installed, I should be okay using the Xiao.

Why do you need volatile in your code for this situation?

I think the professionals view the callback function for I2C like an ISR so you need to alert the main loop that those variables can change without them knowing, but in this case, I don't think I do that.

I'm going to dig into what you pointed out and learn from it.

If your code won't compile, have another glass of bourbon. Eventual the problem will be solved.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@jfabernathy

Posted by: @jfabernathy
Posted by: @jfabernathy

Oh!, I did get chastised for having variable in my callback functions that were not declared volatile, so I'm going to clean it up, but with my check for false triggering installed, I should be okay using the Xiao.

Why do you need volatile in your code for this situation?

I think the professionals view the callback function for I2C like an ISR so you need to alert the main loop that those variables can change without them knowing, but in this case, I don't think I do that.

I'm going to dig into what you pointed out and learn from it.

The function pointers for those callbacks that we discussed recently are defined as static in Wire.h, so I don't see any concern in that regard.

Cheers.


   
ReplyQuote
(@jfabernathy)
Member
Joined: 3 years ago
Posts: 141
Topic starter  

odd, now that I have my routine working, I can remove the & in the registering of the call back functions and they now compile cleaning.

Go figure!

If your code won't compile, have another glass of bourbon. Eventual the problem will be solved.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@jfabernathy

Posted by: @jfabernathy

odd, now that I have my routine working, I can remove the & in the registering of the call back functions and they now compile cleaning.

Go figure!

No, not at all... that's why I said your problem must be something else 🙂


   
ReplyQuote
Page 2 / 2