Attiny817 TWI/I2C

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

hI,someone has simple functions for i2c?

example from xplained_mini is too complicated for me.

 

void TWI_init();

void TWI_start(uint8_t slaveAddr);

uint8_t TWI_read(uint8_t ACK);                                          

void TWI_write(uint8_t write_data);

void TWI_stop(void);

TWI_write_buf( , , , );

This topic has a solution.
Last Edited: Fri. Feb 9, 2018 - 02:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Master or Slave?

 

Jim

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?

 

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

Master

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

The 817 is a new breed of AVR, so not sure if standard AVR code will work, but Peter Fluery has an I2C code that most freaks will recommend.

Just google Fluery and I2C and you should be able to find it. 

The other alternative is to got to Atmel Start and pull code from there.

 

Come back if you have questions.

 

Jim

 

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?

 

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

Don't panic. I intend to write a twimaster_t817.c that should be a replacement. I will probably post something tomorrow.
.
David.

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

I am waiting patiently :) I hope that it will be simple and basic functions :)
I can not decipher the sample i2c code from xplained_mini.

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

AT_TRUCK wrote:
I hope that it will be simple and basic functions

It is interesting that your proposed (or example) "driver" function prototypes shown have no return values...how will you even know, then, if ANYTHING works?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

My apologies.   I am having problems with a Tiny817 version of Fleury's twimaster.c

 

However the simplest thing is to bit-bang the Tiny817 i.e. configure the regular i2cmaster.S

;***** Adapt these SCA and SCL port and pin definition to your target !!
;
; .kbv  use VPORTs on Tiny817 or Xmega.
; .kbv  I use delay loop instead on NOPs if F_CPU > 4MHz
#define SDA     1		// SDA PB1 (alternate func PA1 on tiny817)   
#define SCL		0		// SCL PB0 (alternate func PA2) 
#define SDA_PORT        VPORTB_OUT           //
#define SCL_PORT        VPORTB_OUT           // .kbv

;******

;-- map the IO register back into the IO address space
#define SDA_DDR		(_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR		(_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT		_SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT		_SFR_IO_ADDR(SCL_PORT)

#if defined(VPORTB_OUT) || defined(VPORT1_OUT)        //.kbv Tiny817 or Xmega
#warning using VIRTUAL PORT
#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) + 1)
#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) + 1)
#else
#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2)           //.kbv regular Tiny or Mega
#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2)
#endif

You need to change the pins if you are using the alternate TWI pin mapping.

Note that you can use VPORTn for an Xmega

 

This is annoying me.   I will get a polled twimaster_t817.c running one day.   Then I will attach it to this thread.

 

David.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define TWI0_BAUD   (F_CPU / (2 * 400000) - 5)//TWI0_BAUD(F_SCL)  ((((float)F_CPU / (float)F_SCL)) - 10 )


void TWI_init()
{

	TWI0.MBAUD = TWI0_BAUD;   //(uint16_t)TWI0_BAUD(400000);           
	TWI0.MCTRLA |= TWI_ENABLE_bp;  

	TWI0.MCTRLA |=  TWI_WIEN_bp;  //Enable: INTERRUPT WRITE
	
	PORTB.DIRSET |=  (PIN1_bm | PIN0_bm) ;
	
	_delay_us(30); //Errata
}



void TWI_start()

{
	TWI0.MADDR = 0x78;   
	while (!(TWI0.MSTATUS & (TWI_WIF_bm)   )) ;   //
}


void TWI_write(uint8_t write_data)

{
	TWI0.MDATA = write_data; 
    while (!(TWI0.MSTATUS & (TWI_WIF_bm)   ))  ;
}


void TWI_stop(void)

{
	TWI0.MCTRLB |= (1<<TWI_ACKACT_bp);  
	TWI0.MCTRLB |= (TWI_MCMD_gm);      
}

Nothing works :(, but I feel I'm close :P

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

How would you know if it works, all of your functions return void???

start should at least return a status so you know if you got an ACK or a NAK from a device on the bus!

same for read and write, how will you know if they succeed or not?  

 

 

 

Jim

 

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?

 

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

I control the OLED display, if I see something, it means that it works :)
(on the atmega328 library works).
I will have to try as you write.

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

david.prentice wrote:
This is annoying me
My sympathies...

I2C is from 1982.

https://en.wikipedia.org/wiki/I%C2%B2C

There must be an compelling reason to change the hardware ( yet again !) for a new chip after 36 years...

Maybe something to do with smbus?

 

-----------

Or you turn it around.

Why does OP want to use a tiny817 ?

There are plenty of working libraries around for for example the M328.

Seems to be a much better fit for a relatively new member with not enough experience to fully understand his Xample code...

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

Last Edited: Thu. Feb 8, 2018 - 12:47 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

This is the basic code I use for TWI transmit on a ATTINY1616.  Maybe it will work for you.

 

void initI2C(void) {

	TWI0.MBAUD = (uint8_t)TWI0_BAUD(400000);		// set MBAUD register for 400kHz
	TWI0.MCTRLB = 0;
	TWI0.MCTRLA = TWI_ENABLE_bm;					// TWI Enabled
	TWI0.MSTATUS = TWI_BUSSTATE_IDLE_gc;           // Set the BUS state to idle
}

uint8_t i2cStartTransmit(uint8_t address) 
{
	if ((TWI0.MSTATUS & TWI_BUSSTATE_gm) != TWI_BUSSTATE_BUSY_gc)			//Verify Bus is not busy
	{
		TWI0.MADDR = (address << 1);
		return 0;
	}
	else
		return 1; //Bus is busy
}

uint8_t i2cSend(uint8_t data)
{
	if ((TWI0.MSTATUS&TWI_BUSSTATE_gm) == TWI_BUSSTATE_OWNER_gc)			//Verify Master owns the bus
	{
		TWI0.MDATA = data;
		while(!(TWI0.MSTATUS&TWI_WIF_bm) | (TWI0.MSTATUS&TWI_RXACK_bm)) ;		//Wait until WIF set and RXACK cleared
		return 0;
	}
	else
		return 1;	//Master does not own the bus
}

void i2cStop(void)
{
	TWI0.MCTRLB = TWI_MCMD_STOP_gc;
}

 

 

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

There is no problem with polled writes to the Xmega / Tiny817 TWI.

 

Reading TWI and getting the correct NAK for the last read is awkward.

 

The Interrupt code in twi_master_driver.c (Xmega) or twi_master.c (Tiny817)  works fine.    Sets NAK correctly.

 

I seem to have written some polling code for Xmega about 9 years ago.   It must have passed simple tests.

It does not pass my current test suite.   In fact the 24LC512 chip used in the tests locks up.

Both Fleury bit-bang and Atmel Interrupt code pass all the tests.

 

The Xmega has been on the market for 10 years now.   I am sure that reliable polled TWI must be out there somewhere.

Yes,  the Tiny817 TWI is very similar to the Xmega TWI.    Debugging is much easier on Xmega than on the XMINI-817.

 

Polled TWI would be simpler than interrupts.   And quite honestly a TWI Master is seldom worried about efficiency.

 

David.