Preface: As I am not an native english speaker, you are more than welcome to fix any mistakes in grammar or spelling. It will help me improving my foreign language skills. This page is meant as an first overview over all digispark related hardware-programming methods. It's meant as a kind of landing page where users can link from the forums.
There are three ways you can store binary program code into an AVR controller: ISP, HVSP, and Self-Programming. When you start playing around with a digispark you are using the self-programming feature of the Attiny.
To enable that feature you need to use one of the other two methods mentioned before to get a piece of code on the attiny. This will then allow you to pull additional code into the attiny or change the additional code. Uploading that initial code is one of the tasks in the digispark-production.
The code making this possible is the bootloader micronucleus, which is written and maintained by the board-member bluebie.
This bootloader resides in the first 2k of the 8k memory of the attiny and allows you to use the remaining 6k for your programs. The big benefit of that piece of smart code is that you need no other hardware tool to program a digispark as you would for the other two methods. It will even go one step further and make it possible for you to use the digispark for programming other core attinys in two (or lets say one and a half) different ways.
For that purpose micronucleus emulates USB hardware as the attiny has no on-board USB device. Communication is done with a host component called micronucleus. On Windows systems it's micronucleus.exe.
To facilitate this special way of programming the digispark, digistump has patched the IDE by adding a custom version of avrdude (a program which is mostly used in the arduino world). Digistump's custom version of avrdude is a wrapper which calls either the original avrdude for everything which is not a digispark, or micronucleus in the case of a digispark. There are however some drawbacks:
The emulation of a USB interface affects the usage of 2 I/O pins, P3 (analog3) and P4 (analog2). Both are regulated with a Zener diode which limits the voltage on those two pins to a max of 3.6V. This affects some uses like analogRead() or high levels resulting from digitalWrite(). P3 also has a 1.5K pullup-resistor creating even more problems for this kind of usage.
An advantage of the emulated USB solution is that this way of programming the Attiny frees one more GPIO pin; pin PB5. This pin is otherwise used as reset, which is needed for programming the chip with an external ISP programmer.
You need to be very careful, when it comes to PIN names on the AVR microcontrollers. There are plenty of names around depending on functions or locations. Further enumeration depends, if that is done logical or physical.
There are the pin numbers of the core chip, starting with one at the special marked pin going counter-clockwise around the chip. Then there are the numbers of GPIO-pins which AVR groups to internal ports, where up to 8 pins can be aggregated. Those ports are named with letters (A, B, ..). Unfortunately the attiny85 is missing port A, so the GPIO pins are called PB0 to PB5. And as you see, in the logical enumeration they start with 0 and there is no match to the physical pin number. When it comes down to the digispark itself, those 6 pins are named P0 to P5 on the PCB; however in the schematics enumeration starts with 1.
There are a lot of other names, depending of functions for special protocols or chip-functions, like SCK, MISO, MOSI. Those additional functions are even not related to corresponding GPIO-pins. On the attiny85 SCK is together with PB2 on physical pin7. On the attiny167, for example, SCK resides with PA5 on physical pin 8. So always pay attention to documentation before making assumptions!
Its not much more to say, about the internal programming, as that is the out-of-the box behaviour.
In-circuit programing (ISP) was developed to allow manufacturers using the microcontroller chips to program them, even while soldered on the final PCB.
That is meant to provide a cheap way to update code, to fix bugs, or to extend capabilities without unsoldering the chip. There are, however,some restrictions to this mode as well: ISP uses MISO, MOSI and SCK (as well as RESET), and there is limited interference with those three pins allowed. Atmel recommends using resistors between these ISP pins and their other uses in a circuit. In general it's a good recommendation, to read design considerations:
As ISP connection needs the enabled RESET function (and therefore disabled GPIO function of the shared physical pin), there is no way, to program an off-the-shelf digispark with any ISP device, because the digispark has disabled the reset function.
Disabling the reset-function is something, you can do with either ISP or HVSP programming. An attiny fuse has nothing to do, with fuses you know from electrical devices. It's a one bit in a register of bits, which are stored independently in the attiny. Those registers control the behavior of the attiny when the attiny starts. Some of those fuses and additional registers have an strong influence on the way to program an attiny or any other Atmel device. There are three fuse bytes which control the behavior: The extended fuse byte, where bit number 0 controls whether self-programming is enabled or not. For the disgispark self-programming is enabled. The high fuse byte, where bit 7 controls whether external reset is disabled, bit 6 switches debug wire, bit 5 the capability of ISP The low fuse byte controls the clock settings. If the clock settings are don't match the expectation of a preloaded bootloader, like the micronucleus, the chip won’t start and therefore programming the core this way, is, as well, disabled. The lock byte is also important; two bits control whether ISP and HVSP are allowed to change and/or verify flash and eeprom. If one of the lockbits is set, the chip needs to be erased (which will automatically reset the lockbits) before further programming. Erasing can only be done using HVSP but will not change the three fuse bytes.
The digispark cannot be programmed via ISP (at least not without prior modification), but the digispark itself is already an ISP programmer! All you need is the right connection between the digispark and the target device.
Staying in the digispark world, we assume as a programming target another attiny85 chip.
There is another open source project out there, the littlewire from Ihsan Kehriban, whom you can meet as well in the digispark forum, as both projects have much in common, as you will see very soon:
Compare the schematics of both projects, and you will see that both implementations share the same basics: They both have the zeners and the pull-up resistor for USB communication. They are now both using micronucleus as boot loader.
The difference is only that the digispark has a voltage-regulator on board to power the attiny85 and additional devices, and the digispark makes all GPIO pins available on the breakout, while the littlewire makes only MISO, MOSI, SCK and RESET together with +5V and GND available on an AVR compatible layout.
The most simple way, to use the digispark as an ISP is:
Take the digispark prototype shield kit and an 8 pin IC-socket.
Connect Vcc and GND to pin 8 and 4 of the socket, connect all other pins 1:1 (PB1 to PB1, PB2 to PB2, …) The reason, why you should connect all pins, will be explained later.
Here you see the front and backside from an prototype shield:
And so it looks, when the shield is connected to the digispark:
Your tiny IS-Programmer is ready to run!
Now go to bluebies Tutorial in the forum, where she explains, how you can install littlewire on your digispark.
Under Linux you will find it in ./DigisparkArduino-Linux32/Digispark-Arduino-1.0.4/hardware/tools/micronucleus
Under Windows usually in .\Digispark-Arduino-1.0.4\hardware\tools\avr\bin\micronucleus.exe
You can download the ready compiled binary from the littlewire webpage, currently it is v12
and start the micronucleus binary and give the full path to the micronucleus hex file as an parameter.
under Linux/Mac: /path/to/micronucleus /path/to/littlewire_v12.hex
under Windows: \path\to\micronucleus \path\to\littlewire_v12.hex
micronucleus will ask you, to plugin the digispark, as you will already know it from the arduino IDE.
You will see the usual dialog, when micronucleus is uploading the littlewire software. This way is necessary, as micronucleus.hex is not an arduino-sketch, but written directly in c.
Additional to the digispark driver Windows needs an libusb-driver. Under Linux/Mac libusb is part of the operating system, so this step is not necessary. If you have trouble with that driver (which is available from littlewire), you can go to the libusb-win32 project, where you find additional tips.
Ok, now we will adapt the Arduino-IDE, so that we can use our ISP programmer, to write programs to core attiny85 chips. This addition we can make in the boards.txt, which is located in the ./hardware/digispark subdirectory of the Arduino-IDE.
We add the following two sections:
attiny85-RESET-enabled.name=attiny85 with Reset enabled (5 Pin) attiny85-RESET-enabled.upload.maximum_size=8192 attiny85-RESET-enabled.build.mcu=attiny85 attiny85-RESET-enabled.build.f_cpu=16000000L attiny85-RESET-enabled.build.core=tiny attiny85-RESET-enabled.upload.using=USBtinyISP attiny85-RESET-enabled.bootloader.low_fuses=0xf1 attiny85-RESET-enabled.bootloader.high_fuses=0xdf attiny85-RESET-enabled.bootloader.extended_fuses=0xfe attiny85-RESET-enabled.bootloader.path=micronucleus attiny85-RESET-enabled.bootloader.file=micronucleus-1.06-upgrade.hex attiny85-RESET-disabled.name=attiny85 with Reset disabled (6 Pin!) attiny85-RESET-disabled.upload.maximum_size=8192 attiny85-RESET-disabled.build.mcu=attiny85 attiny85-RESET-disabled.build.f_cpu=16000000L attiny85-RESET-disabled.build.core=tiny attiny85-RESET-disabled.upload.using=USBtinyISP attiny85-RESET-disabled.bootloader.low_fuses=0xf1 attiny85-RESET-disabled.bootloader.high_fuses=0x5f attiny85-RESET-disabled.bootloader.extended_fuses=0xfe attiny85-RESET-disabled.bootloader.path=micronucleus attiny85-RESET-disabled.bootloader.file=micronucleus-1.06-upgrade.hex
After (Re-)start of the IDE we see under Tools/Board the additional devices. As long, as we use the 5-pin device, we can program each core attiny85 using our digispark-littlewire ISP.
Select under Tools→Board the attiny85 with Reset enabled (5 Pin) from above and under Tools→Programmer USBtinyISP
We are now able uploading programs to connected core attiny85 chips, with the only limitation, that we can’t use PB5, as we need RST for programming. However we are able to use up to 8192 bytes of memory.
As an first test, upload the digispark-start-sketch to the attiny, and because the pins are connected 1:1, the onboard-led of the digispark will start blinking, even when the code is running on the target controller, once you have uploaded the sketch!
We are also able, to make digispark compatible devices from an core attiny85: We still select the 5-pin version of the attiny, the USBtinyISP and select Tools→Burn Bootloader.
After the bootloader is burned, the chip is an digispark, but still with enabled reset (and therefore disabled PB5).
To make it a full compatible digispark, choose now the 6-pin version of the board, and repeat uploading the boot loader. That step will reset the fuse settings, so reset is disabled.
It will not again upload the boot loader, as uploading the boot-loader is done in two steps by the IDE:
First the IDE sets the fuses according to the configuration, in the next step it will upload the bootloader. So when you choose from the beginning the six pin layout, the chip is unusable, as the reset function gets disabled, but you get no bootloader installed. Check the correct function of the bootloader first, before disabling RESET!
Further you need to be aware, that as soon, as you are uploading another arduino-sketch via USBtinyISP to that device, where you have before installed the micronucleus boot-loader, the bootloader is gone and replaced the the program, you uploaded after it!
To use this chip in the digispark way, you have two possibilities: You can create either an adapter with the zener-diodes and the three resistors for example with an old USB-cable (following the schematics from littlewire or digispark)
or you use an digispark and cut off the attiny with an sharp knife (which is a wonderful second life for an digispark, where the controller is already dead):
If you use now the digispark prototype shield kit with the 8pin socket you created before, you can plug the prepared chip into that device, and upload sketches using the digispark-programmer. That is the reason, why you should connect all six pins of the extension-shield, when you not are planning to build two of this kind of shields.
After that you can take out the chip and place it in that application, where you need six pins of the attiny, without the influence of the zeners and the pullup resistor.
One device with six lines connected and the attiny cut off on the digispark besides the digispark littlewire ISP
Once you have created your digispark, and plug it to your PC, you will realize, that it generates trouble with USB device recognition. This is caused by the fact, that there is only the bootloader installed and no program. The bootloader starts the chip, waits the usual 5 seconds for possible programming action and gives control to the non-existent program. That causes the digispark to run into reset. So you should upload a small sketch, like the start-sketch after installing the boot-loader.
Now comes the day that you accidentally fused some chips with reset-disabled before the bootloader was installed. Or you killed the bootloader, tried different clock-sources, or whatever. In that case there is only one way to correct the problem; you will need to use high-voltage serial programming (HVSP). High voltage is 12 Volt, so there is no risk. The problem is however, that the protocol used for this kind of programming differs from SPI and makes HVSP-programmers more complicated.
You will only need HVSP in cases where you have locked the controller down, and the digispark is able to unlock these doors. Read recipe of Fuse Resetting in the forum for instructions on how to reset fuses. With this little extension to the digispark you will be able to reset the fuses to values where ISP and Self-Programming are once again enabled.