Let’s configure our example board’s ATTiny44(a) microcontroller to use the external 20MHz ceramic resonator. Looking at the chip’s data sheet, we want to consider the LFuse (Lower Fuse, 1byte[, t44 default=0x62 although iotn44a.h falsely states 0x6a]):
Current fuse settings of a chip can be read out to a file with avrdude:
$ avrdude -p t44 -P usb -c usbtiny -U lfuse:r:outfile:h
In Table 6-1 Device Clocking Options we see that we need to program CKSEL[3:0] to set our clock source. There’s “External Clock” (0000) but in Figure 6-2 External Clock Drive Configuration we see that would mean solely driving pin 2 (CLKI) with an external clock. What we’re doing instead on our board is what we see in Figure 6-3 Crystal Oscillator Connections: we drive pin 2 (XTAL1) and pin 3 (XTAL2) with the resonator’s input and output respectively (note that on our board we skip C1-2 suggested in this figure – maybe due to the component we’re using).
Back In Table 6-1 we find the appropriate option “Crystal Oscillator/Ceramic Resonator” (1000-1111). Since we’re using a 20MHz resonator we find in Table 6-9 Crystal Oscillator Operating Modes that for ≥8MHz we should use CKSEL[3:1]=111. We further read that for this configuration CHSEL0 together with SUT[1:0] selects start-up times of the chip.
For the higher 4 LFuse bits the default is 0x6. For our purpose we can leave Bit 7 and 6 at their default values (CKDIV8=0 and CKOUT=1) and solely consider Bit 5 and 4, which is SUT[1:0] defaulting to 10. In Table 6-10 Start-up Times for the Crystal Oscillator Clock Selection we find that for resonators 10 should be used when the Brown-out Detector (BOD) is enabled. However, since this is disabled by default and only enabled in the HFuse through BODLEVEL[2:0], we need to change this default value. We choose CHKSEL0=0 and SUT[1:0]=01 for option “Ceramic resonator, slowly rising power”, adding “an extra power-on delay for everything to settle down, which is a safer choice” (compared to “fast rising”), according to Neil Gershenfeld. Although it’s mentioned in the data sheet that this option “should only be used when not operating close to the maximum frequency”, it has been tested and works well in our context.
Combined, this results in LFuse=0x5E (01011110). Be careful when experimenting with fuses as I bricked one of my boards. There seem to be ways to reset the fuses to factory settings, e.g. through the High Voltage Serial Programming (HVSP) interface, but usually replacing the chip is a cheaper and quicker method.