Go Down

Topic: ATtiny104 (Read 682 times) previous topic - next topic

ArduD2

Hi,

does anybody have some experience using the new ATtiny104?

My goal is to use my Arduino as an ISP programmer for the ATtiny104 (if that is even possible).

Currently I am trying to figure out how to modify the available ATtiny support files (like these for example) in order to make them work for the ATtiny104.

If anybody has some helpful hints or experience on this subject...I would be happy if you share your thoughts with me and other interested users.

I will let you know if I make any progress..


Best regards




DrAzzy

#1
Apr 05, 2017, 09:46 pm Last Edit: Apr 05, 2017, 09:49 pm by DrAzzy
Well, the first issue is that you can't program them via SPI like other AVRs, you have to use TPI, which is a different protocol. You would need to write an arduino sketch to speak STK500 (most likely) on it's serial port, and TPI, which you'd probably have to implement in software, since it's neither serial, SPI, nor I2C (it's most similar to I2C, but not close enough to use the builtin I2C hardware)

Then you'd need to make a core to support it - I'd start from hansibul's MicroCore which already has some optimizations for the tiny13's similarly miniscule flash. It's timer 0 is not the standard 8-bit timer, but a 16-bit one, so you might need to rework millis() if you wanted to include that functionality at all (it takes up a large portion of the flash). Frankly this is easy compared to the above, though.

And in the end you get a chip with a truly miniscule amount of flash.

For $0.65 each (digikey).
For just 23 cents more per part, you could get an attiny441. Same number of pins, 4 times the flash memory, a second UART, 1 8-bit and 2 16-bit timers, programmable via SPI, and there's already an excellent (if I do say so myself) core for it maintained by yours truly. $1.06 gets you an 841 with 8k of flash. The attiny24/44/84 are around the same price as well, with same number of pins, more flash, and an arguably richer set of peripherals.

I can't imagine justifying that effort. I also haven't heard of any cheap TPI-capable programmers available off the shelf.
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

pert

My understanding is that USBasp will do TPI. The latest (2011) USBasp firmware says it supports TPI:
http://www.fischl.de/usbasp/
Also, not the best reference, but a quick search found multiple reports of it working here:
http://www.avrfreaks.net/forum/avrdude-tpi-devices
but I don't mean to disagree with your argument for using a different chip. However, I'm sure if ArduD2 created an ATtiny104 hardware package it would be a useful contribution to the Arduino community as well as a fun project. I think the more microcontrollers that can easily be used via the Arduino IDE the better, even if I will never use them.

Jiggy-Ninja

Apparently AVRDude has a TPI programming option for bit-bang programming that was added way back in 2011. I'm not sure which of the 3 optiosn I see (c2n232i, dasa, or dasa3) is right, but it's supposed to be there.

Reference: http://irq5.io/2010/07/15/programming-the-attiny10/
Hackaday: https://hackaday.io/MarkRD
Advanced C++ Techniques: https://forum.arduino.cc/index.php?topic=493075.0

ArduD2

Hi and thanks for your input.

I can't imagine justifying that effort. I also haven't heard of any cheap TPI-capable programmers available off the shelf.
In the meantime I decided to go with Atmel Studio and and this programmer this programmer. I think the price is okay and it works just fine with plug and play.

What I want to do is shown in the following (working) Arduino code:

const byte LED = 11;  // Timer 2 "A" output: OC2A

void setup() {
 pinMode (LED, OUTPUT);
 pinMode (10, OUTPUT);
 pinMode (9, OUTPUT);
 pinMode (8, OUTPUT);
 pinMode (4, INPUT);
 // set up Timer 2
 TCCR2A = _BV (COM2A0) | _BV(WGM21);  // CTC, toggle OC2A on Compare Match
 TCCR2B = _BV (CS20);   // No prescaler
 OCR2A =  209;          // compare A register value (210 * clock speed)
                        //  = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095

}  // end of setup

void loop() {

   if(digitalRead(4)){
   
      digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
   }
   else{
        digitalWrite(10, HIGH);
    digitalWrite(9, HIGH);
    digitalWrite(8, HIGH);
   }
}


I wrote a similar C Code for the ATtiny104 (8MHz), but I can`t generate a 38kHz signal:

// Timer setup
TCCR0A |= (1<<COM0A0);//| (1<<WGM02);   //toggle OC0A on Compare Match
TCCR0B |= (1<<CS00) | (1<<WGM02);           // CTC, no Prescaling
OCR0A =  104;                  // compare A register value (105 * clock speed) (209?)
//  = 13.125 nS , so frequency is 1 / (2 * 13.125) = 38095


Does anyone have an idea what I am doing wrong? Do I need an extern oscillator?

DrAzzy

What does it output instead?
ATtiny core for 841+1634+828 and x313/x4/x5/x61/x7/x8 series Board Manager:
http://drazzy.com/package_drazzy.com_index.json
ATtiny breakouts (some assembled), mosfets and awesome prototyping board in my store http://tindie.com/stores/DrAzzy

Smajdalf

Do you configure the pin as output?
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

ArduD2

yes I configured the pin as an output.

with

OCR0A = 104

I have a frequency of ~4850 Hz.

ArduD2

with

OCR0A = 12

I have a frequency of ~39180 Hz.

Smajdalf

You probably run on 1 MHz clock, not 8 MHz as you think. The Datasheet says: "After powering up the device or after a reset the system clock is automatically set to calibrated internal 8MHz oscillator, divided by 8"
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

ArduD2

That is my conclusion, too. Now I am trying to configure the ┬ÁC to run at 8MHz...
Hope I will get this right

Bits 3:0 - CLKPS[3:0]: Clock Prescaler Select
These bits define the division factor between the selected clock source and the internal system clock.
These bits can be written run-time to vary the clock frequency to suit the application requirements. As the
divider divides the master clock input to the MCU, the speed of all synchronous peripherals is reduced
when a division factor is used. The division factors are given in the table below.

...

To avoid unintentional changes of clock frequency, a protected change sequence must be followed to
change the CLKPS bits:
1. Write the signature for change enable of protected I/O register to register CCP
2. Within four instruction cycles, write the desired value to CLKPS bits

...

Bits 7:0 - CCP[7:0]: Configuration Change Protection
In order to change the contents of a protected I/O register, the CCP register must first be written with the
correct signature. After CCP is written, the protected I/O registers may be written to during the next four
CPU instruction cycles. All interrupts are ignored during these cycles. After these cycles interrupts are
automatically handled again by the CPU, and any pending interrupts will be executed according to their
priority.
When the protected I/O register signature is written, CCP[0] will read as one as long as the protected
feature is enabled, while CCP[7:1] will always read as zero.
When the NVM self-programming signature is written, CCP[1] will read as one for four CPU instruction
cycles , other bits will read as zero and CCP[1] will be cleared automatically after four cycles. The
software should write data to flash high byte within this four clock cycles to execute self-programming.
Table 8-2. Signatures Recognized by the Configuration Change Protection Register
Signature Group Description
0xD8 IOREG: CLKMSR, CLKPSR, WDTCSR Protected I/O register
0xE7 SPM NVM self-programming enable

ArduD2

// Timer setup
CCP = 0xD8;
CLKPSR &= ~(1<<CLKPS0);
CLKPSR &= ~(1<<CLKPS1);
//CLKPSR &= ~(1<<CLKPS2);
//CLKPSR &= ~(1<<CLKPS3);


TCCR0A |= (1<<COM0A0);//| (1<<WGM02);   // CTC, toggle OC0A on Compare Match
TCCR0B |= (1<<CS00) | (1<<WGM02);            // no Prescaling
OCR0A = 26;

-->results i a output frequency of 37677.
                  

Smajdalf

I think the
CLKPSR &= ~(1<<CLKPS1);
command is not executed because write to CCP does not allow more than one change of prescaler.
Another explanation may be the second write is not in the 4 CK window. Depending if cbi is possible to use the statement takes 1 or 3 CK to execute (load CLKPSR, modify it and write it back).
So you are running at 2 MHz. Use CLKPSR=0 and it should work as expected.
On 8-bit (i.e. Uno) use "byte" instead of "int" if possible - it is faster and saves resources!

ArduD2

It does work as expected, thank you very much!

Go Up