I2C master/slave code for ATtiny series 1

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

Since I found Atmels's I2C sample code somewhat confusing I wrote my own code for 

 

a) polled master, including functions to access slave c)

b) interrupt driven slave

c) as b), organized as addressable byte array, similar to EEPROM

 

The code is much more compact and robust against transmission faults than Microchip's original code. I have made extensive tests arbitrarily shorting the signal lines against ground. During these tests both master and slave recovered under all circumstances. Code development was somewhat tricky since the processors did not behave under all circumstances as expected from Microchips's documentation.

 

The code has been tested with two ATtiny processors operatings as master and slave. So far I have not done any tests with "real life" I2C chips. I would be glad to receive comments, enhancements, criticism, especially from interested forum members that could provide tests with I2C periphery.

 

A ZIP file is included, please ask questions if code usage needs additional explanation.

Attachment(s): 

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

not quite sure if this is the right place for this post. maybe in tutorials section is better ?

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

Nicely done, I've grabbed a copy I hope to try out on a t4809 when I have the time.

I might suggest you put a copy on github, then you will only need to post a link to it.

Thanks again for the contribution.

 

Jim

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

 

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

Drei,

 

I downloaded your I2C library and attempted to use it to get an SSD1306 Display working using an Attiny 1614.  I am using Atmel Studio 7.  When I added your I2C.c it failed with it could not find the following "#include <lx-ctrl5.h>".  I commented that out and it compiled.  However, I was not able to get anything to display.  I attempted to make use of the U8G2 library and then another one that was more basic but in both cases nothing displayed (looks like for the second library I used there was a very fast flashing of text).  I am sure that I am doing something minor wrong but do you happen to have an Atmel Studio solution for the attiny 1-series with a SSD1306 (or other oled) that you could provide.  I know this is asking a lot but I have tried every I2C library I could find (even Atmels) but yours as least made the display flash :)

 

Edit:  I managed to get a noisy looking screen (using both U8G2 and generic OLED library) after changing the F_CPU to the correct frequency.  Since I am using Atmel Studio I did not realize that the prescaler was set and I used the standard 8Mhz for the frequency.  Wrong.  The 1614s are 20MHz.  Still not working thou.  I might now go back and try other I2C solutions to see if they work.

 

 

Thanks

P

Last Edited: Thu. Aug 8, 2019 - 04:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, Dieter,
I have successfully established communication as a slave (ATTIny1614) with a master based on your code of the I2C slave.
Now I want the slave to be able to set the I2C bus on hold (stretch the clock) as long as it wants. Unfortunately I can't find a solution for this.

Background:

After power-up, the master scans all XBus addresses from 0x01 to 0x7f and checks which slaves respond. My slave should first go through a few routines after power-up and then decide which address it should respond to. Therefore I want to slow down the master as long as the slave makes its decision

 

Best regards

Jürgen

Last Edited: Wed. May 27, 2020 - 09:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Drei,

 

Your code has been extremely helpful especially for someone like me who is just getting into AVR programming. In your code, the variable 'timeout_cnt" seems to be undeclared. Where should it be defined? I have commented out 

 

#include <driver_init.h> and #include <lx-ctrl5.h>

 

and I don't know if they were defined as a Macro there. Any help is greatly appreciated.

 

Thanks,

I

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

ivzn wrote:
In your code, the variable 'timeout_cnt" seems to be undeclared.
Which of the files are you looking at?

>grep -i timeout_cnt *
I2C.c:  timeout_cnt = 0;                                                                                                // reset timeout counter, will be incremented by ms tick interrupt
I2C.c:          if (timeout_cnt > ADDR_TIMEOUT) return 0xff;                            // return timeout error
I2C.c:  timeout_cnt = 0;                                                                                                // reset timeout counter, will be incremented by ms tick interrupt
I2C.c:                  if (timeout_cnt > READ_TIMEOUT) return 0xff;                    // return timeout error
I2C.c:  timeout_cnt = 0;                                                                                                // reset timeout counter, will be incremented by ms tick interrupt
I2C.c:                  if (timeout_cnt > WRITE_TIMEOUT) return 0xff;                   // return timeout error
I2CS.c:uint8_t timeout_cnt;                                                     // 1ms timeout tick counter
I2CS.c:extern uint8_t timeout_cnt;
I2CS.c: timeout_cnt++;;                                         // increment timeout counter
I2CS.c:                 timeout_cnt = 0;                                                                        // reset timeout counter, will be incremented by ms tick interrupt
I2CS.c:                         if (timeout_cnt > 2) return;                                    // return if timeout error
I2CS.c:                         timeout_cnt = 0;                                                                // reset timeout counter, will be incremented by ms tick interrupt
I2CS.c:                                 if (timeout_cnt > 2) return;                            // return if timeout error
I2CSD.c:volatile uint8_t timeout_cnt;                                   // 1ms timeout tick counter
I2CSD.c:extern uint8_t timeout_cnt;
I2CSD.c:        timeout_cnt++;;                                         // increment timeout counter
I2CSD.c:                        timeout_cnt = 0;                                                                        // reset timeout counter, will be incremented by ms tick interrupt
I2CSD.c:                                if (timeout_cnt > 2) return;                                    // return if timeout error
I2CSD.c:                                timeout_cnt = 0;                                                                // reset timeout counter, will be incremented by ms tick interrupt
I2CSD.c:                                        if (timeout_cnt > 2) return;                            // return if timeout error

So it's in I2CS.c and in I2CSD.c.

 

To be honest I have no idea why there are so many similarly named files ?

 

Judging from this:

volatile uint8_t timeout_cnt;					// 1ms timeout tick counter

// timeout is handled by 1 millisecond RTC PIT interrupt as follows:

/*
extern uint8_t timeout_cnt;

ISR(RTC_PIT_vect) {						// PIT interrupt handling code, 1 ms interrupt
	timeout_cnt++;;						// increment timeout counter
	RTC.PITINTFLAGS = RTC_PI_bm;		// clear interrupt flag
}
*/

it seems the idea is that the I2C files "own" this timeout_count" but in another file (for timer) you would set up a 1ms ISR() then increment that as an "extern" from within.

 

It looks like I2C.c has forgotten to duplicate the same sequence that appears in the other two variants (S and SD).

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

 

Thank you the code File "ATTiny_series1_I2C_DR_2019-05-13", with code in file "I2CS.c and I2CS.h," I can get the value of Atmega328PB master go to ATtiny3216SN slave.

Just add some note: up till now, I can not let I2C work with the sample code from AtmelStart generate. Code sample from AtmelStart can work OK with ADC, Uart but no with I2C, I do not know where I make mistake with that code .

 

 

Electronic Engineer
3D component /Orcad 17.4/ Eagle 7 and Eagle 9/Kicad 5/Altium Designer17/Fusion360/FreeCad- Expert skill at soldering and desoldering with iron tip
Live in VietNam

Last Edited: Mon. Jun 7, 2021 - 08:53 AM