Programming ATtiny412

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

Hi everyone,

 

I want to program ATtiny 412 with i2c communication protocol. Can anybody please help me how to start with for i2c programming?

 

Thank you

Kishore.G

Last Edited: Tue. Jun 11, 2019 - 06:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Hi gkishor,

 

Welcome to AVRfreaks,

 

have you tried to look for examples in ATMEL start ?. The attiny412 MUX table in the datasheet is somehow wrong and contains wrong information..this is the right table:

 

 

for a simple application you can start looking in this forum for some codes, you can find it easily by a simple search.

 

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

Hi sir,

 

Thanks for your response. I am trying to understand some example i2c codes. After some study, I have following doubts

 

1) Which register & bits [SCTRLA, SCTRLB, SDATA], I have to configure to Enable TWI, Enable ack generation

2) Which register & bits are to be checked for,  whether the master is requesting data or sending data to slave

3) How to use SDATA register to transmit multiple bytes of data to i2c master

4) How to configure PA3/PA6/PA7 to use them as GPIO pins

 

figure: TWI registers

 

I have read the datasheet, regarding configuration of the above registers for i2c slave operation. But I'm not getting proper information from datasheet.

Please help me.

 

Thank you sir,

Kishore.G

Last Edited: Tue. Jun 11, 2019 - 11:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

have you checked the forum for examples ?

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

First Wecome to AVRFreaks!

 

Can you start by telling us what your experience writing micro controller code is? 

If this is your first project, you are starting with a fairly complex project.   Tell us what your I2C slave will do other then communicating with an I2C master (and tell us what your I2C master is as well).

 

Jim

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

Try to start from here:

 

https://www.avrfreaks.net/forum/...

 

these application notes descibes most of the functions to get through in ATtiny 1 & 0 series (compatible with your attiny412)

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

gkishore wrote:
Can anybody please help me how to start with for i2c programming?
Couldn't find any app notes on unified memory AVR TWI; hopefully AVR libc's TWI will work.

avr-libc: Example using the two-wire interface (TWI)

 

"Dare to be naïve." - Buckminster Fuller

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

gchapman wrote:

hopefully AVR libc's TWI will work.

That would be QUITE a stretch. The tiny412 IO header has:

/* Two-Wire Interface */
typedef struct TWI_struct
{
    register8_t CTRLA;  /* Control A */
    register8_t reserved_0x01;
    register8_t DBGCTRL;  /* Debug Control Register */
    register8_t MCTRLA;  /* Master Control A */
    register8_t MCTRLB;  /* Master Control B */
    register8_t MSTATUS;  /* Master Status */
    register8_t MBAUD;  /* Master Baurd Rate Control */
    register8_t MADDR;  /* Master Address */
    register8_t MDATA;  /* Master Data */
    register8_t SCTRLA;  /* Slave Control A */
    register8_t SCTRLB;  /* Slave Control B */
    register8_t SSTATUS;  /* Slave Status */
    register8_t SADDR;  /* Slave Address */
    register8_t SDATA;  /* Slave Data */
    register8_t SADDRMASK;  /* Slave Address Mask */
    register8_t reserved_0x0F;
} TWI_t;

The avr-libc example code has:

C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\doc\avr-libc\examples\twitest>grep "TW.. " twitest.c
 * register to have valid contents while the TWINT bit in TWCR is set.
  /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
  TWSR = 0;
  TWBR = 10;                    /* smallest TWBR value, see note [5] */
  TWBR = (F_CPU / 100000UL - 16) / 2;
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWDR = sla | TW_WRITE;
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWDR = (eeaddr >> 8);         /* 16-bit word address device, send high 8 bits of addr */
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWDR = eeaddr;                /* low 8 bits of addr */
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send (rep.) start condition */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWDR = sla | TW_READ;
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
      TWCR = twcr;              /* clear int to start transmission */
      while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* send start condition */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWDR = sla | TW_WRITE;
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWDR = (eeaddr>>8);           /* 16 bit word address device, send high 8 bits of addr */
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWDR = eeaddr;                /* low 8 bits of addr */
  TWCR = _BV(TWINT) | _BV(TWEN); /* clear interrupt to start transmission */
  while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
      TWDR = *buf++;
      TWCR = _BV(TWINT) | _BV(TWEN); /* start transmission */
      while ((TWCR & _BV(TWINT)) == 0) ; /* wait for transmission */
  TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN); /* send stop condition */

To quote Sesame Street "one of these things is not like the other one" ;-)

 

EDIT working on the assumption that in an AVR-0/AVR-1 there's got to be a strong chance that TWIn.MCTRLA is going to be accessed at some stage then a google for:

 

avr twi "MCTRLA"

 

seems quite fruitful (mainly back here at Freaks in fact)

Last Edited: Tue. Jun 11, 2019 - 03:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have checked some threads in the forum. Still I didn't get specific information

Kishore.G

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

Hi Sir,

 

I am new to microcontroller programming.

Functions of ATtiny I2C slave

  • To transmit some bytes of information to I2C master and processing the information sent by I2C master and acting according to it
  • Driving some data to some other I2C slave through GPIOs available with it

 

 

Kishore.G

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

This thread has useful information regarding bit checks for slave read/write

https://www.avrfreaks.net/forum/attiny416-acting-twii2c-slave-device-failure-second-read

 

But how to configure registers to use ATtiny pins as GPIOs?

 

Kishore.G

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

gkishore wrote:

This thread has useful information regarding bit checks for slave read/write

https://www.avrfreaks.net/forum/attiny416-acting-twii2c-slave-device-failure-second-read

 

But how to configure registers to use ATtiny pins as GPIOs?

 

 

What is your experience in programming ? maybe you should start with arduino better

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

ASF4?

ASF4 API Reference Manual - I2C Drivers

via START (Help tab)

 

No TWI in ASF3 for tinyAVR.

 

"Dare to be naïve." - Buckminster Fuller

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

I am trying to program ATtiny416 which is embedded in ATtiny416 xplained nano board for I2C communication . One ATtiny416 is used as master and another ATtiny416 as slave.

In atmel start I have configured the following to use ATtiny416 as I2C master

1) I2C master

2) PB0 & PB1 as SCL & SDA

3) Clock frequency: 416kHz (20Mhz/48 prescaler division)

4) PB5: digital output which is connected to a test LED on Xnano board

5) Fast mode plus is enabled

6) Pull up resistor is connected between Vcc & PB0

 

The reference code with the above configuration is exported to atmel studio IDE. And the code is dumped to ATtiny416. 

When I checked the clock signal frequency using oscilloscope, it is highly fluctuating. I tried blinking LED, which is working fine.

 

Here I am attaching solution explorer also. Kindly requesting you to help.

Attachment(s): 

Kishore.G

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

gkishore wrote:
Kindly requesting you to help.
But you haven't said what's wrong?

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

I am not able to observe clock frequency 416kHz.

And, where can I observe printf statements in atmel studio?

Kishore.G

Last Edited: Tue. Aug 13, 2019 - 09:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gkishore wrote:
And, where can I observe printf statements in atmel studio?
You need to provide an output channel such as UART or LCD then you use FDEV_SETUP_STREAM to associate this with a filing stream with stdout and then printf()/puts()/etc will redirect to the output device. See the user manual:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#details

 

BTW your .rar file above does not contain all your project files. It has only the single .atsln file so is of no use to explore your code.

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

clawson wrote:

gkishore wrote:
And, where can I observe printf statements in atmel studio?
You need to provide an output channel such as UART or LCD then you use FDEV_SETUP_STREAM to associate this with a filing stream with stdout and then printf()/puts()/etc will redirect to the output device. See the user manual:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#details

 

BTW your .rar file above does not contain all your project files. It has only the single .atsln file so is of no use to explore your code.

 

Whole project is attached now

Attachment(s): 

Kishore.G

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

Clock issue is resolved. Now I am able to use i2c for data transfer.

New issue araised regarding serial communication.

 

I am using ATtiny416 Xnano board to program on board ATtiny416.

I have programmed i2c & USART in ATtiny416. I am using puTTy to 

observe the log of serial communication.

Configuration:

1) Tx & Rx pins of ATtiny416 are connected to Tx & Rx of USB to serial converter. 

And I tried vice versa connections also.

2) I have configured to puTTy to COM1 port and baud rate to 9600.

 

But I am not able to watch log on puTTy terminal window.

 

 

Kishore.G

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

gkishore wrote:
of USB to serial converter. 
USB-RS232 or USB-TTL ?

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

Now I am able to observe the log. But the displayed hex values are not as expected.

 

I am sending 0x12 but I am getting C9 C9.

Attachment(s): 

Kishore.G

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

Wha do you want your application to do exactly, I just see that you are initializing the driver ? look at your code...what is your expectation out of this ?

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

Moe123 wrote:

Wha do you want your application to do exactly, I just see that you are initializing the driver ? look at your code...what is your expectation out of this ?

I am sending a byte 0x12 using function USART_0_WRITE(0x12); over serial port TX.

But output on serial port terminal is C9 C9 instead of 0x12

Kishore.G

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

Serial comms issues asked here usually relates to improper baud rate due to not knowing what the cpu clock rate really is set to.

Where in your code above do you set the baud rate and what is the real cpu clock rate on your hardware.

Also one more tip, if you send the letter "U" repeatedly, it produces a square wave at the actual baud rate freq, easy to measure with scope or frequency counter.

Compare this value with what you expect to see and note any difference.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

ki0bk wrote:

Serial comms issues asked here usually relates to improper baud rate due to not knowing what the cpu clock rate really is set to.

Where in your code above do you set the baud rate and what is the real cpu clock rate on your hardware.

Also one more tip, if you send the letter "U" repeatedly, it produces a square wave at the actual baud rate freq, easy to measure with scope or frequency counter.

Compare this value with what you expect to see and note any difference.

 

Jim

 

with the above configuration: 1)F_CPU=250000 

baud rate at Tx pin of serial port the clock frequency is 9.6kHz.[Tested with sending 'U' repeatedly]

still I am getting wrong output

Kishore.G

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

Why are you using 250kHz as the clock speed in one place and 16MHz in another?

 

The idea would be that you define one system wide symbol somewhere (often on the command line with a -D) and then use that symbol (traditionally most use "F_CPU") to make all other temporal calculations. That way is you one day switch from a 16MHz crystal to a 1.8432MHz crystal you just change that one define, in one place and all the calculations are re-done for the new speed.

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

Besides, all those numbers are irrelevant to the actual speed the chip is running, which is set by the OSCCFG fuse (which is a permanent setting at run time), as well as the CLKCTRL.MCLKCTRLA and CLKCTRL.MCLKCTRLB registers (which can be changed at run time).

 

So please let us know how/if you changed these values.

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

El Tangas wrote:

Besides, all those numbers are irrelevant to the actual speed the chip is running, which is set by the OSCCFG fuse (which is a permanent setting at run time), as well as the CLKCTRL.MCLKCTRLA and CLKCTRL.MCLKCTRLB registers (which can be changed at run time).

 

So please let us know how/if you changed these values.

I am not configuring  anything CLKCTRL.MCLKCTRLA and CLKCTRL.MCLKCTRLB registers.

Kishore.G

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

clawson wrote:

Why are you using 250kHz as the clock speed in one place and 16MHz in another?

 

The idea would be that you define one system wide symbol somewhere (often on the command line with a -D) and then use that symbol (traditionally most use "F_CPU") to make all other temporal calculations. That way is you one day switch from a 16MHz crystal to a 1.8432MHz crystal you just change that one define, in one place and all the calculations are re-done for the new speed.

I have configured 250kHz clock frequency in atmel start. Hence F_CPU is 250000.

But with 250000 in USART_BAUD_RATE(BAUD_RATE) the displayed bytes are wrong.

So I have changed it to 16000000. Then I am getting Baud rate 9600 on Tx pin of ATtiny416.

Kishore.G

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

gkishore wrote:
So I have changed it to 16000000.
Then the CPU is clearly running at 16MHz and what you have configured is ignored. This probably relates back to the point El Tangas made.

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

That's the problem of using Atmel Start without knowing what's happening.

Please post the content of the clkctrl.c file, namely the CLKCTRL_init function.

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

El Tangas wrote:

That's the problem of using Atmel Start without knowing what's happening.

Please post the content of the clkctrl.c file, namely the CLKCTRL_init function.

Kishore.G

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

you are commenting out the whole main clk settings...I never used your chip, but what does the guys think about this ?

 

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

So, you are setting a 64x divisor in  CLKCTRL.MCLKCTRL. This means the CPU frequency is either 20MHz/64 (312.5 KHz) or 16MHz/64 (250KHz) depending on the  OSCCFG fuse.

 

Have you changed this fuse? The factory setting is 20MHz.

 

Moe123 wrote:
you are commenting out the whole main clk settings...I never used your chip, but what does the guys think about this ?

 

That's done by Atmel Start automatically, it has generic code and comments out the unused stuff.

Last Edited: Wed. Aug 21, 2019 - 11:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With baud rate 4

gkishore wrote:

ki0bk wrote:

Serial comms issues asked here usually relates to improper baud rate due to not knowing what the cpu clock rate really is set to.

Where in your code above do you set the baud rate and what is the real cpu clock rate on your hardware.

Also one more tip, if you send the letter "U" repeatedly, it produces a square wave at the actual baud rate freq, easy to measure with scope or frequency counter.

Compare this value with what you expect to see and note any difference.

 

Jim

 

with the above configuration: 1)F_CPU=250000 

baud rate at Tx pin of serial port the clock frequency is 9.6kHz.[Tested with sending 'U' repeatedly]

still I am getting wrong output

 

If I am setting USART_BAUD_RATE(460000), I am getting the data on Tx pin properly. But I am not understanding why it should be 460000 instead of 4600 which is one of the standard baud rates.

 

Kishore.G

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

gkishore wrote:
If I am setting USART_BAUD_RATE(460000), I am getting the data on Tx pin properly. But I am not understanding why it should be 460000 instead of 4600 which is one of the standard baud rates.

 

That's because you are telling the baud_rate function the CPU is running at 16MHz, when in fact it is running at 312.5KHz.

 

I suggest you try this:

#define USART0_BAUD_RATE(BAUD_RATE) ((float)(312500.0 * 64 / (16 * (float)BAUD_RATE)) + 0.5)

 

Then set the baud rate as 9600, as it should.

USART0.BAUD = (uint16_t)USART0_BAUD_RATE(9600);

 

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

El Tangas wrote:
16MHz/64 (250KHz)
which are the two constants in the code. I don't know these chips but doe that mean that while the CPU is clocked at 250kHz the UART is clocked at 16MHz ?

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


 

No, the UART clock is connected after the clock divisor, so the base clock for the UART is also 250KHz (or 312.5KHz). See this annotated scheme:

 

 

The problem is the fuse, the OP doesn't say anything about it, so it's impossible to know if the base clock is 20 or 16MHz just from looking at the code.

 

edit: sorry the control registers are reversed, let me correct the pic... done.

 

Last Edited: Wed. Aug 21, 2019 - 12:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:
so it's impossible to know if the base clock is 20 or 16MHz
Well I think he said that UART code based on 16MHz in the calculation appears to generate the right baud rate so it would seem to suggest the UART is being clocked at 16MHz.

 

BTW that diagram is confusing - it shows two outputs from "Main Clock Prescaler" so is that saying that CLK_CPU might be set to one thing (250kHz) while CLK_PER is 16MHz ?

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

clawson wrote:
BTW that diagram is confusing - it shows two outputs from "Main Clock Prescaler" so is that saying that CLK_CPU might be set to one thing (250kHz) while CLK_PER is 16MHz ?

 

Yeah, it's misleading, you could conclude they can be connected to different taps in the prescaler, but reading the datasheet, in practice CLK_CPU and CLK_PER are always the same.

Maybe it will be different in future chips.

 

edit: I remembered discussing this previously https://www.avrfreaks.net/forum/...

Last Edited: Wed. Aug 21, 2019 - 01:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am transmitting N bytes using I2C communication. To transmit 'N' bytes, If a delay of 1sec is given after transmitting each byte, the data transfer is proper.

Otherwise intended data is not transferred. Why the delay is required after transmitting each byte in I2C?.

Kishore.G

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

.

Last Edited: Wed. Aug 28, 2019 - 06:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gkishore wrote:

I am transmitting N bytes using I2C communication. To transmit 'N' bytes, If a delay of 1sec is given after transmitting each byte, the data transfer is proper.

Otherwise intended data is not transferred. Why the delay is required after transmitting each byte in I2C?.

the nice thing about I2C is it will tell you what is wrong IF you look at the return status value and act accordingly. 

Do your I2C functions return status?  If not, then you need better I2C functions, we see a lot of bad home made I2C functions here with void return values.

If they do return status values, Are you using it?

If not, why not?

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

Last Edited: Wed. Aug 28, 2019 - 01:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

gkishore wrote:

I am transmitting N bytes using I2C communication. To transmit 'N' bytes, If a delay of 1sec is given after transmitting each byte, the data transfer is proper.

Otherwise intended data is not transferred. Why the delay is required after transmitting each byte in I2C?.

the nice thing about I2C is it will tell you what is wrong IF you look at the return status value and act accordingly. 

Do your I2C functions return status?  If not, then you need better I2C functions, we see a lot of bad home made I2C functions here with void return values.

If they do return status values, Are you using it?

If not, why not?

 

Jim

 

Following is the function I am using for "master transmit data to slave". It has proper return type And more over the function is generated by atmel start

Kishore.G