Operating AVR as I2C Slave

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

I am planning to make one of the AVR processor as a slave and one of them as master in my project. From master processor, I should be able to operate I/Os of other slave using I2C (Interrupt driven). I should also be able to control many slave processor functionality from master such as PWM configuration, writing to EEPROM of the slave etc. Did anyone do similar projects so that I can kick start easily? 

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

Hello,  

   What is your level of technical expertise?   Are you a beginner with microcontrollers?   Have you been able to program in C or assembler a working I2C interface for other non-AVR microcontrollers? 

 

    If you are near beginner then I suggest getting two Arduino Nano clones for about $3-$4 USD each on eBay.  In this case you can be assured that your Arduino's Wire library (that handles the Master and Slave devices for I2C) is working and that the hardware CPU ICs are configured correctly and their bootloaders are good.    Be sure to get Arduinos with the CH340G USB-serial IC since they are the new cheap and reliable standard.  Also download and install the CH341 USB IC driver on your PC (I assume that you are using Windows).  Plug in both Arduinos and verify that there are two instances of COM ports (use the Device Manager) that were created by two Arduinos.

 

   Next review the simplest downloadable tutorial for Arduino Wire Master/Slave demo.  Review the tutorials for the I2C format, and then review the (not-so-intuitive) keywords that the Wire library uses to work the I2C format on the Arduino.  Wire.h has specific functions like OnReceive() and OnRequest(), etc.... to do all the common I2C tasks.  Learn what these are.

 

If you're not an expert, then don't bother fooling around with usual libraries recommended by most users here, like the Fleury library and all the others.  They are much too complicated because they are designed to work with AVR Studio IDE on nearly every variety of AVR device.   You don't want this.  You want to limit your hardware specification to a very specific framework (the mega328P or Mega2650) and a very specific software development toolchain (the Arduino IDE).  The more that a library can be configured for general use, the less likely the library is to work reliably with one specific framework without expert-level troubleshooting and software parameter adjustment.   In embedded design, maximize the possibility of everything going right by minimizing the number of things that can go wrong.  Hence the Arduino recommendation.

 

  I2C format basically sends numbers back and forth between the Master and the Slave.  The slave will  interpret from the numbers that it receives from the master what the master wants the slave to do.  Again start with very simple tutorials that do very simple things.   Things like "...being able to control many slave processor functionality from master such as PWM configuration, writing to EEPROM of the slave etc."  are not simple, although they may appear to be in the software specification.  Having the Slave receive (and display on a terminal program ) an ASCII letter character that was typed into the Master reliably is the kind of thing that you should get working first.

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

Thank you @Simonetta for your suggestion. Though I am not an expert programmer, I am able to manage simple programmers, timers, PWM etc without arduino libraries. I do not want to use any arduino stuff and want to learn and do myself. I am hoping someone must have written a library to control AVR processor using I2C. There may be a simple protocol also developed over I2C I guess. Also I am looking for interrupt based. 

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

Did you examine Peter's code?

 

http://homepage.hispeed.ch/peter...

 

 

Ross McKenzie ValuSoft Melbourne Australia

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

There is a big difference between normal ATmega I2C interface and the USI interface. It is hard to make a working I2C Slave. Even the Arduino "Wire" library for the most common ATmega328P had recently some serious bugs fixed (with Arduino.cc IDE 1.6.9).

 

When searching in the Projects section for I2C or TWI, I can find just one link to code that has also a Slave mode : https://spaces.atmel.com/gf/project/twi/frs/

You could try that.

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

Yes, I have used this library. I need to further extend this for my requirement and also make it interrupt driven. I thought someone might have already done something similar. 

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

I don't know a good library sad

 

The Arduino Wire library is interrupt driven, but if the Master is writing or receiving data, it waits until all data has been transferred. That is of course very silly for an embedded system. That means that even the Cortex-M0+ with the Arduino Wire library has to wait a full millisecond to receive a few bytes from a sensor. And the Arduino Wire library for the ATmega328P is 'blocking'. If the SDA or SCL is shortcut to ground, the Arduino Wire library waits forever en halts the code.

 

The Arduino Wire library for a Slave is fully interrupt driven. But it also stretches the clock, so the Master has to be able to deal with that.

 

If you find something better, please let me know.

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

Koepel wrote:
But it also stretches the clock, so the Master has to be able to deal with that.

Wouldn't any reasonable master implementation deal with that, as per the standard? I mean, I'd understand if multiple masters arbitration was left aside, but slave clock stretching…

ɴᴇᴛɪᴢᴇᴎ

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

Koepel wrote:
There is a big difference between normal ATmega I2C interface and the USI interface.

That's a good point: I don't believe OP has mentioned what's his target chip family…

ɴᴇᴛɪᴢᴇᴎ

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

joneewheelock wrote:
I am hoping someone must have written a library to control AVR processor using I2C. There may be a simple protocol also developed over I2C I guess.

I'm personally not aware of any such protocol (but it doesn't mean much!).

If you want to be able to control any part of the chip easily, why not just make it possible to read/write remote SFRs?

Like:

  • SLA+R, 8-bit SFR address -> SFR value
  • SLA+W, 8-bit SFR address, byte value

Or do you need a higher abstraction?

ɴᴇᴛɪᴢᴇᴎ

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

The reason to use Arduino libraries is so that you can learn the Arduino format and then use the exact same code on other CPU's; either AVR, ARM, or otherwise.   This avoids having to learn a new processor every few years.   I've learned the original Motorola 6803 from the RadioShack micro-Color computer (1982),  the Motorola 6809 RS Color-Computer (1984),  the 6502 (Commodore and Apple II , mid-1980s, the Intel 8080, the Zilog Z-80, the Intel 8086 (the foundation of the PC), the Intel 8051, and the AVR.   I don't want to learn any more new CPUs, but will have to get an overview of the ARM.   When you learn a new CPU, it's usually because the older ones are obsolete and not used in new designs.   So all your brain cycles are wasted from learning all the previous CPU architectures.   

   It would be much better to learn only Arduino and let the CPU manufacturers make their CPUs Arduino-compatable with custom libraries for their IC's characteristics.   Then if you get assigned to build a prototype using a new "XKE" CPU, then you can just take the .ino file for what your prototype should do and change your sketch from "include Wire.h" to "include WireXKE.h", which you downloaded from the company that makes the XKE.   Mastering individual CPU architectures and instruction op-code sets is 20th-century thinking: adapting pre-written code that is in a standardized format like Arduino is the 21st-century way because it is so much more productive.

 

An example of a slave I2C might be a four-port MIDI interface that uses a Mega2650 because that CPU has four serial ports.  MIDI (Musical Instrument Digital Interface) uses an 8/N/1 31,250-baud serial port.  Here the Mega2650 would act as a slave I2C.   Each 1/10 second, the master would request the number of new bytes that have arrived on each MIDI channel from the slave in the previous 1/10 second.  Or it would send bytes like SysEx dump or Note-On command to an individual channel using pre-determined commands that are exchanged between the master and the slave.

 

To read/write the individual special function registers of an AVR, one would use a single-stepping, BREAK-enabled debug system like JTAG or Atmel ICE, not I2C.