i2c slave using AVRLib

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi,
does everyone know how to make an i2c slave device using library i2c.c under AVRLib?
I'm confused how to use it.
I've done made several projects that utilize this library as an i2c master device. but never use as an i2c slave device. I've struggled about an hour and getting tired.
PS: I'm making a master slave communication between 2 ATMega8s. Problem persists on the slave side, i just don't know how to make a program that acts as a slave using that library mentioned above.

KISS - Keep It Simple Stupid!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I'll scope my problem.
In the library i2c.c under AVRLib. Inside that library resides function

 void i2cSetSlaveReceiveHandler(void (*i2cSlaveRx_func)(u08 receiveDataLength, u08* recieveData))
 {
     i2cSlaveReceive = i2cSlaveRx_func;
 }

which is i2cSlaveRecieve declared like this

static void (*i2cSlaveReceive)(u08 receiveDataLength, u08* recieveData);

Using that function I can hooked up my function to receive i2c slave receive.
The problem is i don't know how to use it.
Please anybody kindly show me the solution.
Thanks :mrgreen:

KISS - Keep It Simple Stupid!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to write a function that will read the Rx buffer data. The i2cSetSlaveReceiveHandler() registers the function you write so the ISR knows what function to call. The first parameter, receiveDataLength, equals the number of Bytes received. The second one is a pointer to the Rx buffer. There is an example that comes with the library.

i2ctest.c

i2cSetSlaveReceiveHandler( i2cSlaveReceiveService );
// slave operations
void i2cSlaveReceiveService(u08 receiveDataLength, u08* receiveData)
{
	u08 i;

	// this function will run when a master somewhere else on the bus
	// addresses us and wishes to write data to us

	showByte(*receiveData);
	cbi(PORTB, PB6);

	// copy the received data to a local buffer
	for(i=0; i
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, I thought it was not that simple. That works perfectly! Thanks atomicdog :mrgreen:

KISS - Keep It Simple Stupid!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By the way, it's probably easier if you structure your code differently: have the I2C IRQ handler issue per-byte callbacks to your code. That way you don't need to pre-allocate a buffer, or (even worse) structure your protocol code around buffer I/O. A typical I2C protocol involves commands (often single byte) sent to the slave, often with parameters. So if you receive a buffer you'll have to parse it "late", long after you should have issued a NAK indicating bad command (or parameters).

On the other hand, if your "here's a data byte" method can parse it right away, it can say whether to ACK or NAK that byte, and can update your internal state machine so that parsing the next byte is cheap. If the command involves writing a bunch of data, you can copy it out of SRAM, EEPROM, or FLASH trivially, and write those bytes ... it's not like the library could save you any real work.

Plus, avrlib is pretty much old and unmaintained as I recall. If it's got useful code, take it ... but for something like I2C (or SMBus) don't assume what you'll find there is a good model to follow.