core13: An Arduino core for the Attiny13 *testers wanted*

furri: Where is the attiny def for boards.txt?

There is a lot of boards.txt that are kicking around. Some are more correct than others. I hacked this together:

########################

attiny13a.name=Attiny 13A standalone 128khz
attiny13a.upload.using=arduino:arduinoisp
attiny13a.upload.maximum_size=1024
attiny13a.upload.speed=19200
attiny13a.bootloader.low_fuses=0x7b
attiny13a.bootloader.high_fuses=0xFF
attiny13a.bootloader.path=empty
attiny13a.bootloader.file=empty
attiny13a.bootloader.unlock_bits=0xFF
attiny13a.bootloader.lock_bits=0xFF
attiny13a.build.mcu=attiny13
attiny13a.build.f_cpu=128000L
attiny13a.build.core=core13
#######################

attiny13f.name=Attiny 13A standalone 600khz
attiny13f.upload.using=arduino:arduinoisp
attiny13f.upload.maximum_size=1024
attiny13f.upload.speed=19200
attiny13f.bootloader.low_fuses=0x69
attiny13f.bootloader.high_fuses=0xFF
attiny13f.bootloader.path=empty
attiny13f.bootloader.file=empty
attiny13f.bootloader.unlock_bits=0xFF
attiny13f.bootloader.lock_bits=0xFF
attiny13f.build.mcu=attiny13
attiny13f.build.f_cpu=600000L
attiny13f.build.core=core13
#######################

attiny13c.name=Attiny 13A standalone 1.2mhz
attiny13c.upload.using=arduino:arduinoisp
attiny13c.upload.maximum_size=1024
attiny13c.upload.speed=19200
attiny13c.bootloader.low_fuses=0x6a
attiny13c.bootloader.high_fuses=0xFF
attiny13c.bootloader.path=empty
attiny13c.bootloader.file=empty
attiny13c.bootloader.unlock_bits=0xFF
attiny13c.bootloader.lock_bits=0xFF
attiny13c.build.mcu=attiny13
attiny13c.build.f_cpu=1200000L
attiny13c.build.core=core13

#######################
attiny13d.name=Attiny 13A standalone 4.8Mhz
attiny13d.upload.using=arduino:arduinoisp
attiny13d.upload.maximum_size=1024
attiny13d.upload.speed=19200
attiny13d.bootloader.low_fuses=0x79
attiny13d.bootloader.high_fuses=0xFF
attiny13d.bootloader.path=empty
attiny13d.bootloader.file=empty
attiny13d.bootloader.unlock_bits=0xFF
attiny13d.bootloader.lock_bits=0xFF
attiny13d.build.mcu=attiny13
attiny13d.build.f_cpu=4800000L
attiny13d.build.core=core13
#######################
attiny13e.name=Attiny 13A standalone 9.6Mhz
attiny13e.upload.using=arduino:arduinoisp
attiny13e.upload.maximum_size=1024
attiny13e.upload.speed=19200
attiny13e.bootloader.low_fuses=0x7A
attiny13e.bootloader.high_fuses=0xFF
attiny13e.bootloader.path=empty
attiny13e.bootloader.file=empty
attiny13e.bootloader.unlock_bits=0xFF
attiny13e.bootloader.lock_bits=0xFF
attiny13e.build.mcu=attiny13
attiny13e.build.f_cpu=9600000L
attiny13e.build.core=core13

It works with Attiny13A?

It works on all Attiny13 series

Yay! My AtTiny13A's just arrived. 10 days from Shenzhen to Scandinavia must be some kind of record :-)

Just received two attiny13a PU. Plan 1: use it to drive a 4-pin RGB led. User shud be able to control intensity of each color using a push-button.

Plan 2: use it to drive a single(may be multiple, but don't really need it now) WS2812 based neoPixcel. Here also user should be able to control the individual color using push buttons.

In both of above case, either 3 push switch can be used to change individual color intensity with a step value of say 32 or 64. OR 2 push switch can be used; one for select the color to change and other to change the color intensity by a step value.

Should I burn a bootloader to the tiny? Please suggest how can I keep the code below 1K.

sudhirkhamari: Plan 2: use it to drive a single(may be multiple, but don't really need it now) WS2812 based neoPixcel. Here also user should be able to control the individual color using push buttons.

I did THIS on attiny13a, most is not relevant here, but I wrote a fast ws2812 driving routine in assembler which works a treat !!

Thanks mcnobby. I hv gone through your post on dmx/attiny. I am planning to leverage from the same. This is the t13 i bought:http://m.ebay.com/itm/201190520005?nav=SEARCH
Could you please suggest me what should i put in boards.txt file.

I've found this WorldSemi library useful: https://github.com/cpldcpu/light_ws2812

I've used it on attiny13 with the raw avr libraries.

I use this boards.txt entry for 9.6mhz attiny13a

attiny13at9.name=ATtiny13 @ 9.6MHz (internal 9.6 MHz clock)
attiny13at9.bootloader.low_fuses=0x3a
attiny13at9.bootloader.high_fuses=0xff
attiny13at9.upload.maximum_size=1024
attiny13at9.build.mcu=attiny13
attiny13at9.build.f_cpu=1200000
attiny13at9.build.core=core13

and this entry for driving at 32mhz from an external clock

attiny13-32.name=ATtiny13A (32mhz MHz clock gen)
attiny13-32.bootloader.low_fuses=0x70
attiny13-32.bootloader.high_fuses=0xff
attiny13-32.upload.maximum_size=1024
attiny13-32.build.mcu=attiny13
attiny13-32.build.f_cpu=9600000L
attiny13-32.build.core=core13

sudhirkhamari: Just received two attiny13a PU. Plan 1: use it to drive a 4-pin RGB led. User shud be able to control intensity of each color using a push-button.

Plan 2: use it to drive a single(may be multiple, but don't really need it now) WS2812 based neoPixcel. Here also user should be able to control the individual color using push buttons.

In both of above case, either 3 push switch can be used to change individual color intensity with a step value of say 32 or 64. OR 2 push switch can be used; one for select the color to change and other to change the color intensity by a step value.

Should I burn a bootloader to the tiny? Please suggest how can I keep the code below 1K.

The Attiny13 has 5 usable I/O pins so it should be okay to drive a 4 pin RGB LED and two push buttons. You may be able to use multiplexing to use less I/O pins.

Keeping the code under 1k ... well you should follow common sense to optimize code and then just try it out and see where it lands.

No bootloader needed when programming with SPi

I use this boards.txt entry for 9.6mhz attiny13a

This is wrong.

attiny13at9.build.f_cpu=1200000

should be

attiny13at9.build.f_cpu=9600000

smeezekitty:
This is wrong.

attiny13at9.build.f_cpu=1200000

should be

attiny13at9.build.f_cpu=9600000

I think I went through this before trying to set frequency to 9.6mhz, bot sure why I ended up with the first entry but it seems to work fine.

As far as I know low fuse bits 0 & 1 also select internal oscillator and divider.

Is F_CPU only in there as a contant for the compiler ?

mcnobby: I think I went through this before trying to set frequency to 9.6mhz, bot sure why I ended up with the first entry but it seems to work fine.

As far as I know low fuse bits 0 & 1 also select internal oscillator and divider.

Is F_CPU only in there as a contant for the compiler ?

F_CPU is a constant used by avr-libc and any Arduino core. If it is incorrect, all timing and delay functions will be wrong. And the ADC may be set up incorrectly.

ah ok, so thats probably why I didnt notice any problem, if I wasnt using any timing related functions it wouldnt matter

Thanks for the heads up :)

hi!

analogWrite makes 4 KHz output frequency.

Is it possible to make it approx 10 times smaller? e.g. 400-800 Hz

Thanks!

Winnie_The_Pooh: hi!

analogWrite makes 4 KHz output frequency.

Is it possible to make it approx 10 times smaller? e.g. 400-800 Hz

Thanks!

I'm curious why? To be honest, I have never actually measured the frequency.

You could lower the microcontroller clock which would no doubt slow down the PWM rate

I’m using PWM to dim LED driver. Manual says that pwm frequency should be lower than 1000 Hz.

Lowering the clock is a little bit brute :slight_smile:

May be I can play with divider here:

void analogWrite(uint8_t pin, uint8_t val){

24
if(pin == 0){
25
TCCR0A |= (1 << COM0A1);
26
OCR0A = (val / 16) * 16;

Changing COM0A1 to COM0A2 will encrease the divider to 8. I think so :slight_smile:

Any side effects?

Winnie_The_Pooh:
I’m using PWM to dim LED driver. Manual says that pwm frequency should be lower than 1000 Hz.

Lowering the clock is a little bit brute :slight_smile:

May be I can play with divider here:

void analogWrite(uint8_t pin, uint8_t val){

24
if(pin == 0){
25
TCCR0A |= (1 << COM0A1);
26
OCR0A = (val / 16) * 16;

Changing COM0A1 to COM0A2 will encrease the divider to 8. I think so :slight_smile:

Any side effects?

It should be okay. Just toss this

(val / 16) * 16

and make it just “val”

That was part of testing code that has since been removed. Newer versions fixed it

Hi!

Check the attiny13 manual and find out that PWM freq can be set by the last 3 bits of TCCR0B register.

Use that code in setup section:

/* 
Setting Divisor Frequency PWM on 9.6, 4.8, 1.2 MHz CPU 
  0x01 divisor is 1      37500, 18750, 4687 Hz 
  0x02 divisor is 8      4687, 2344, 586 Hz 
  0x03 divisor is 64     586, 293, 73 Hz 
  0x04 divisor is 256    146, 73, 18 Hz 
  0x05 divisor is 1024   36, 17, 5 Hz 
  */ 

 TCCR0B = TCCR0B & 0b11111000 | 0x02; // 0x02 divisor is 8   586 Hz

Measured real frequency is 555 Hz.

The question is - does this influence delay() function? Will test this in a near future :)

I believe the timer-counter is derived from the main CPU clock via the prescaler, so changing the timer-counter prescaler should not affect the main clock.

Since the delay functions are based on counting clock cycles, they should remain tied to F_CPU. (So long as F_CPU is defined correctly in your boards.txt file and you’ve burned the fuses accordingly.)

However, the millis and micros functions are based on counting timer-counter overflows, and this will be affected by changing the prescaler.

Also note that there are two PWM modes, fast and phase correct. The core files set fast mode by default. If you switch to phase-correct [TCCR0A = _BV(WGM00);] the frequency is halved. (Actually 256/510.)

Actual output frequencies will not be exactly as listed in the ATtiny13a manual. 10% slower is not uncommon. If you need an exact frequency output, you’ll need an external clock.

kosine: However, the millis and micros functions are based on counting timer-counter overflows, and this will be affected by changing the prescaler.

Also note that there are two PWM modes, fast and phase correct. The core files set fast mode by default. If you switch to phase-correct [TCCR0A = _BV(WGM00);] the frequency is halved. (Actually 256/510.)

Actual output frequencies will not be exactly as listed in the ATtiny13a manual. 10% slower is not uncommon. If you need an exact frequency output, you'll need an external clock.

Check out what I did to improve delayMicroseconds() It is a hybrid of your code and my original code (your code bombed at low clock speeds)

Its a little bigger but it is the most accurate I could make it over a wide range of clock speeds and delay lengths.

I noticed the update to wiring.c in your latest v20, but haven't had chance to play around with it yet. Will try and find some time soon.

I've also been meaning to have a look at using CLKPR as a runtime reference instead of F_CPU during compilation. Would be nice to switch speeds on-the-fly and still retain some timing functionality, at least in ms.

With a 256 prescaler (37.5kHz) each clock cycle is 26.66us, so an ASM loop using 38 clocks would return after 1013.33us, which is close enough given the chip tolerances. Repeating the loop 256/CLKPR times would give the same 1ms regardless of operating frequency. (9 to choose from and no fuses to worry about!)

Seems fairly simple if using the internal 9.6MHz oscillator, and not much more complex with an external clock. (Adjust for that with F_CPU at compile time.)

Downside is that it's not going to work with us delays, but millis() and micros() might be possible with some work. The upside is that it would offer a lot of different PWM frequencies (20 I think) from 37.5kHz right down to 0.07Hz.

I've also been meaning to have a look at using CLKPR as a runtime reference instead of F_CPU during compilation. Would be nice to switch speeds on-the-fly and still retain some timing functionality, at least in ms.

With a 256 prescaler (37.5kHz) each clock cycle is 26.66us, so an ASM loop using 38 clocks would return after 1013.33us, which is close enough given the chip tolerances. Repeating the loop 256/CLKPR times would give the same 1ms regardless of operating frequency. (9 to choose from and no fuses to worry about!)

Seems fairly simple if using the internal 9.6MHz oscillator, and not much more complex with an external clock. (Adjust for that with F_CPU at compile time.)

Downside is that it's not going to work with us delays, but millis() and micros() might be possible with some work. The upside is that it would offer a lot of different PWM frequencies (20 I think) from 37.5kHz right down to 0.07Hz

To be honest, I don't think I would implement that in the main core distribution. Arduino doesn't implement it and I am trying to avoid bloat.