Greetings, all.
I'm using an SB70LC in MultiMaster I2C mode.
I'm worried about safely updating my I2C Slave Transmit buffer so that I don't accidentally write to it (via I2CFillSlaveTXBuf) while someone else is reading from me.
How do I do this?
I2C Slave Transmit detection in MultiMaster Mode
-
- Posts: 11
- Joined: Mon May 11, 2009 2:01 pm
Re: I2C Slave Transmit detection in MultiMaster Mode
Wait for finish of the transmit before sending to the software transmit buffer.
The Altruist wrote:Greetings, all.
I'm using an SB70LC in MultiMaster I2C mode.
I'm worried about safely updating my I2C Slave Transmit buffer so that I don't accidentally write to it (via I2CFillSlaveTXBuf) while someone else is reading from me.
How do I do this?
Yevgeni Tunik
Embedded/RealTime software engineer
https://www.linkedin.com/in/yevgenitunik/
________________________
Embedded/RealTime software engineer
https://www.linkedin.com/in/yevgenitunik/
________________________
Re: I2C Slave Transmit detection in MultiMaster Mode
One option is to call USER_ENTER_CRITICAL(); and USER_EXIT_CRITICAL(); This will block all interrupts, you can then check what the contents of the current buffers are and then change the data without worrying about anything further being sent. You will see that in the I2CFillSlaveTXBuf function we already disable interrupts but there is a chance that the interrupt can occur between the time you check the buffer status and changing the buffer so it is better to also call these protections.
Another option if you have the latest beta NNDK...
If you get the latest beta version of the NNDK there have been some additions to this multi mode I2C driver. There are now two callback functions you can use when transmitting or receiving as a slave device. These callback functions will override the circular buffers if they are defined. This will give you much more control of exactly what is being transmitted when you are in communicating as a slave.
/*----------------------------------------------------------------------------
BYTE ( *I2C_SlaveTX_Callback )( );
If this callback is pointed to a function then it will be called when
retreiving the data to be sent to the master. This will bypass the circular
buffer funtions "I2CTXAvail" and "I2CFillSlaveTXBuf" used when transmitting
data as a slave.
returns the data to be sent to the master
*///////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------------------------------------------
void ( *I2C_SlaveRX_Callback )( BYTE RX_Data);
If this callback is pointed to a function then it will be called when
storing the data received from the master. This will bypass the circular
buffer funtions "I2CRXAvail" and "I2CGetByte" used when receiving
data as a slave.
BYTE RX_Data - Passes the recieved data to the callback function
returns nothing
*///////////////////////////////////////////////////////////////////////////////////
So just define any function that returns a byte:
BYTE MyI2C_SlaveTXFunc()
{
//return the data
}
And point the call back to this somewhere in your initialization:
I2C_SlaveTX_Callback = MyI2C_SlaveTXFunc;
Also be sure to not use OS blocking or any other other blocking since these callback functions are called from the I2C interrupt function.
-Larry
Another option if you have the latest beta NNDK...
If you get the latest beta version of the NNDK there have been some additions to this multi mode I2C driver. There are now two callback functions you can use when transmitting or receiving as a slave device. These callback functions will override the circular buffers if they are defined. This will give you much more control of exactly what is being transmitted when you are in communicating as a slave.
/*----------------------------------------------------------------------------
BYTE ( *I2C_SlaveTX_Callback )( );
If this callback is pointed to a function then it will be called when
retreiving the data to be sent to the master. This will bypass the circular
buffer funtions "I2CTXAvail" and "I2CFillSlaveTXBuf" used when transmitting
data as a slave.
returns the data to be sent to the master
*///////////////////////////////////////////////////////////////////////////////////
/*----------------------------------------------------------------------------
void ( *I2C_SlaveRX_Callback )( BYTE RX_Data);
If this callback is pointed to a function then it will be called when
storing the data received from the master. This will bypass the circular
buffer funtions "I2CRXAvail" and "I2CGetByte" used when receiving
data as a slave.
BYTE RX_Data - Passes the recieved data to the callback function
returns nothing
*///////////////////////////////////////////////////////////////////////////////////
So just define any function that returns a byte:
BYTE MyI2C_SlaveTXFunc()
{
//return the data
}
And point the call back to this somewhere in your initialization:
I2C_SlaveTX_Callback = MyI2C_SlaveTXFunc;
Also be sure to not use OS blocking or any other other blocking since these callback functions are called from the I2C interrupt function.
-Larry
-
- Posts: 11
- Joined: Mon May 11, 2009 2:01 pm
Re: I2C Slave Transmit detection in MultiMaster Mode
@lgitlitz: That is really helpful. I need to have a look at that.