MCU to load PLL configuration registers


This is a work in progress, documentation of a current project that will change, a 'living' document. Consider any code published as Beta release, ie experimental. Active code development continues as the code base is generalised to support a range of applications.

This article describes a generic microcontroller to load a PLL chip's configuration registers using SPI. SPI is used by many PLL and DDS chips, data format and content varies from chip to chip.

Target chips include: Si4133, Si4133G, ADF4107, ADF4113, ADF4157, ADF4153, ADF4156, ADF4360, AD9850, AD9851, AD9833, TBB206, BH1415F, ADF4350, ADF4351, ADF4252. So far, it has been tested with ADF4156 and AD9850, AD9851, ADF4351, BH1415F, Si4133G. Some modular synthesisers also use SPI and may be configurable with this project.

The design objective is a low cost reliable platform, with all configuration data stored in EEPROM, and a flexible data structure that supports programming as many or few of the PLL registers as needed for an application. The program code in flash should not need to be changed, just an appropriate data set loaded to EEPROM. A range of user configurable data rates is desirable.

In choosing a platform, the following factors were considered:

  1. IDE that gives convenient and full access to the chip capability from high level language;
  2. low cost chip;
  3. native support for SPI;
  4. user configurable number of bytes per register write;
  5. user specified number of registers in each configuration set;
  6. EEPROM capacity to support 16x24 byte register configurations;
  7. pins to support 1/n selection from a table of configuration entries if needed;
  8. support for weak pull ups to minimise component count;
  9. In System Programming to allow writing of flash, and reading and writing of EEPROM independently;
  10. preservation of SPI bus rules to permit other attachments;
  11. availability of free multi platform EEPROM and flash programming software;
  12. availability of low cost USB programmer hardware;

Platforms considered were:

Picaxe does not yet deliver convenient and full access to the chip capability (eg weak pullups, access to true sleep with wake on pin change), the IDE lacks an adequate simulator, USB programmers were relatively expensive ($30+post). Expensive and lacking capability, loose datasheets and other documentation, and misleading diagnostics, it is perhaps unfair to make a comparison with the professional grade products.

Arduino is very capable, too capable, and not economical for the application, but meets most other requirements though like the Picaxe, the IDE is fairly basic.

Microchip's free C compiler is limited in code size, and although probably quite adequate for this project, hobbyists might be better served with an unlimited free compiler. Low end PIC chips are light on features such as USART, EEPROM.

The AVR solution meets all of the requirements. IDE and programming software is free, programming software is free, a USBASP programmer can be bought on Ebay for A$4 posted, the gcc compiler gives excellent access to the hardware, it has SPI support on chip, and programming weak pull-ups, wake on pin change interrupts, true sleep (meaning the clock stops) are all available.

The AVR solution


The solution separates PLL configuration data from algorithms, and facilitates field update or change of the configuration data stored in EEPROM, and which will be loaded to the PLL without replacement of or access to the executable code residing in the MCU flash memory. If boards were designed with a 6 pin ISCP header, low cost boards could be assembled using SMD chips and the program and data loaded post production.

The C language source was developed to run on an inexpensive series of AVR chips, the 14 pin DIP ATtiny44A (or 44A, 84, 84A). The chip accommodates selection of one of 16 configurations using four binary pins. (Note that the ATTiny84/A larger EEPROM size may be needed for the larger configuration tables.) The chips cost less than $3. The chip use the internal RC oscillator. The clock stops when configuration is complete to minimise the risk of RFI, and wakes on change to the configuration address pins to reconfigure the PLL (no need to cycle power to change configuration).

A version to run on the 8 pin ATtinyx5 series process will also be produced. It will work as that on the ATtinyx4 series, but has only on pin for selection of register configuration, so a maximum of two selectable configurations.

The hardware design is compatible with Atmel ISP, and no links or switches need to be operated to reprogram the chip, the chip will automatically start at the end of the programming cycle and load the PLL then go to sleep awaiting configuration address change.

At any time, a ground on the chip reset pin will drive a restart, and it may be prudent to link that pin to any reset pin that might exist on the PLL chip (eg the /PWRDWN on Si4133) so a hardware reset can be performed conveniently.

The AVR chip takes some time to start up (depending on the fuse bits), and PllLdr forces a further 100ms delay to allow for startup of the attached PLL chip. Additional delay can be obtained with the options bits, fuse bits, then with a capacitor on the MCU /RESET pin (though this might interfere with ISP).

The internal clock rate on the selected chip series can be user configured using the chip's FUSE bits.

Fig 00:

Fig 00 shows the waveforms for the SPI interface. Clock polarity (CPOL) is 0, and clock phase (CPHA) is 0 (ie the base value of the clock is low and data is captured by the slave on the even edge, rising in this case), so the SPI mode is 0 or (0,0). This limitation is imposed by the hardware on the AVR ATTiny chip.

The firmware does not write to EEPROM, EEPROM life is determined only by the number of times the EEPROM is programmed from an external programmer.

EEPROM data structures

The EEPROM contains key configuration data. The first byte is a version number for the data structure. That is followed by an options word and variable length table of contents, each entry consisting of a one byte length field and uint16 offset of a data item. The following data items are PLL register sets, each comprising a variable number of register fields. Each register field starts with a one byte length field followed by a variable number of register content bytes. (Some chips use variable length registers, eg AD9859.)

A buffer is allocated for a register set (64B for ATTINY2x build, 192 for ATTINY4x builds), register sets must each be no more than that length including the register set length byte and each register length byte. For example, a set of 5 x 4 byte registers takes 1+5*(4+1) bytes or 26 bytes of buffer space.

Register fields are transmitted EEPROM MSB first, low address to high. If a chip requires LSB first (eg AD9850), add the variable and value "rbo":"R" with an appropriate comma separator to the input file and the bit image of each register byte in the EEPROM file produced will be a reverse of the input data so that it is effectively sent LSB first.

u16 types are stored backwords or little endian in the EEPROM.

Some options bits enable PLL specific features.

Table 1: Options bits
Bits Description
0 invert sel
1 no debounce
2 unused
3 invert /CS
4 Gray code input
5:6 startup delay 0.1*(1+2^(2*x))s
7 invert SCK (CPOL)
12 one of six encoding with banking using bit 0
13 one of seven encoding
14 Reserved
15 Si4133 - Monitor LDETB

Above is a definition of the options bits. CPHA is always 0, ie first edge of a clock pulse.

Invert sel facilitates use of DIP switches from sel pins to ground, and if inverted, switch ON means logical 1 in terms of the inverted sel bits used to select a register set from EEPROM.

The sel and LDETB inputs are debounced with a 10ms delay which can be disabled using the options bits if high speed keying of the selection is required (eg a keyed beacon).

Bank selection uses sel[0] (subject to invert sel) to select odd or even frequency slots in the EEPROM table.


Table 2: Pinout
MCU ATtinyx4(A) ATtinyx5 Si4133 AD9850 ISP 10pin ISP 6pin Comments
Vcc 1 8 Vcc Vcc 2 2  
GND 14 4 GND GND 4,6,8,10 6  
/RESET 4 1 /PWDN   5 5  
USCK 9 7 SCLK W_CLK 7 3  
DO 8 6 SDATA D7 9 1  
DI 7 5 AUXOUT,LDETB   1 4  
/CS 10 2 /SENB FQ_UD      
Sel[0] 2 3         Sel[0]
Sel[1] 3           Sel[1]
Sel[2] 5           Sel[2]
Sel[3] 6           Sel[3]
Sel[4] 13           Sel[4] 1 of n mode only
Sel[5] 12           Sel[5] 1 of n mode only
Sel[6] 11           Sel[6] 1 of n mode only


Fig 0:

Fig 0 shows the schematic for a ATtiny44. J1 is the ISP connector, and J2 for connection to the target. Note that in most applications, J2 pin 2 will be connected to the target power supply, and R1 will be 0 and D1 not fitted. If DI is not needed, J2 needs only 6 pins. S1 could be DIP switches, a hex switch, or 2x4 header and shunts.

An implementation on an ATtiny25 is simpler as there is only one address select switch contact, ie S1 is a single pole switch. The pins for the ATtiny25 are given in Table 2.


The following is from a prototype implemented on an ATtiny44, and the configuration data used is for a AD9850.

Fig 1:

Fig 1 shows the chip select line (/SENB) in channel 0, the serial clock line (SCLK) in channel 1, and SDATA in channel 2/ The /SENB line is low for transmission of five bytes, and when it goes high, the 40 bits are shifted into a single configuration register. For multiple registers, the cycle is repeated for each register.

Fig 2:

Fig 2 shows the transmission of a set of three 40 bit registers. In this case, three 40 bit registers are loaded in about 120µs.

Fig 3:


Fig 3 shows the clock and data in finer timescale. Note the data transitions occur on the negative clock edge, and the positive clock edge is used to clock the data into the receiving register. The SCLK bit rate is about 2Mb/s, but can be slowed down using fuse settings as explained later. (At full clock rate, the bit rate is about 30,000 times the speed of one of the popular Picaxe based loaders.)

Fig 4:

Fig 4 shows the power on timing with the long delay option selected, data transmission occurs just over 500ms from power on to the chip. The options provide for various startup delays.

Fig 5:

Fig 4 shows the prototype on Veroboard. S1 has been split across two 2 pole switches for convenient mounting on the Veroboard tracks. The DIP switches select one of 16 register sets. Alternatively a rotary binary or Gray code switch could be used for 'front panel' selection.

A Gray code switch is an excellent option for frequency changes  as only one bit changes between any two adjacent switch positions, so other code combinations are not emitted due to switching transitions. The Gray code configuration option converts the select pin Gray code to binary on the fly, so the register sets 0,1,2,3,4 are accessed by switch positions 0,1,2,3,4 Gray encoded as 0,1,3,6 etc.


EEPROM holds the configuration data. The EEPROM image is field replaceable.

Developing the EEPROM image

The EEPROM data structures are moderately complex to provide for flexibility, present and future, in use.


Above is an example for a SI4133 which uses 5 three byte registers, two sets are defined in the file.

The input file is formatted in JSON, and the example above defines the version byte, options word, and two sets of five register (0,1,2,3 and 6). As many registers and register sets as required can be defined, but the number addressable depends on the chip used and the available EEPROM size. All input data are hex strings, two characters per byte, and each value must be written out in full (eg for a three byte register value, a six character hex string is required). The conversion script allocates the version and options bytes, builds and populates a table of contents of the regs entries, and then the regs entries. If you want to populate unused but addressable register set entries for reliable results, use an empty entry ([""]) for each register set. Empty entries result in predictable EEPROM entries, and If an empty entry is selected, no data will be transmitted.


The input file is converted to Intel Hex format (above) for the device programmer. You cannot simply edit this file by hand as there are checksums on each record.

EEPROM hex file image generator

Conforming JSON format configuration data (PllLdr V2) can be pasted into the form below to generate an Intel Hex format EEPROM data file for download for a device programmer (ag AVRDUDE).

Paste JSON encoded data here:


This generator is a support tool for this specific project. It is not a generalised converter from JSON to Intel Hex format, it will insert some data components that are specific to this application.

Recent changes in PHP have broken the code that automatically created a download, you must now do a File / SavePageAs from the menu in your browser to save the hex or binary. The automatic download will be restored if ever PHP is restored to its previous function.

Javascript style comments are acceptable in the above calculator.

A PERL script and batch file to generate the Intel Hex file are also available for download, j2h.pl, j2h.bat .

It would be wise to archive a copy of the JSON input data for each application so that if changes occur to the firmware which require regeneration of the EEPROM image, you have the data on hand.

Fuse settings

AVR Fuse settings select appropriate Brown Out Detector (BOD) threshold, and can be used to slow the data rate down by reducing the clock rate using the times eight divider in the AVR chip.

Table 4: Fuse high byte
Value Description
0xD4 BOD 4.3V (normal for 5V supply)
0xD5 BOD 2.7V (normal for 3.3V supply)
0xD7 BOD disabled

Table 4 shows the recommended relevant bit combinations for the fuse high byte

Table 4: Fuse low bits
Value Description Effective clock SCK
0xE2 8MHz, 64ms startup (normal) 8MHz 2Mb/s
0x62 8MHz clock, 64ms startup, CKDIV8 (use to slow data rate down) 1MHz 250kb/s
0xE4 128kHz clock, 64ms startup (use to slow data rate down) 128kHz 32kb/s
0x64 128kHz clock, 64ms startup, CKDIV8 (use to slow data rate down) 16kHz 4kb/s

Table 5 shows the recommended relevant bit combinations for the fuse low byte.

To use the ATBootloader, extended fuse bit needs SLFPRGEN (0xFE), add  -U efuse:w:0xFE:m to the command line in the bat file for setting fuses. 

Programming the chip

There are many programmers available for the AVR microcontrollers. This section describes an inexpensive and easily obtained programmer, free software, and a programming example.

Fig 6:

Fig 6 shows an example inexpensive implementation of a 5V/3.3V USBASP programmer for AVR chips. Do not buy boards branded Baite or betamcu.cn, they have varying resistors on board and some work and some don't.

 Some implementations have a link to enable powering the target from USB, the one pictured above does not and the track should be cut adjacent to pin 2 (labelled VCC above) of the 10 pin connector OR no connection made to pin 10 on the target board if you do not want to power the target. It is a good idea to NOT power the target from the programmer without good reason.

These type of programmers can be found on Ebay for less that $4 including a cable and post. The programmer plugs into a USB port and a 10 pin ribbon cable connects to the in system programming connector on the target. If the target uses a 6 pin ISP header, 10/6 pin converters are available on Ebay. If the target uses a 3.3V supply, configure the programmer for 3.3V (usually a link or solder bridge, see the programmer documentation). Don't supply power from the programmer to the target (again a link on some programmers, see the programmer documentation).

Adapters from 10 pin to the newer 6 pin ISP configuration are readily available at low cost on Ebay.

@echo off
if *%1==* goto usage
set id='$Id: prg.bat 673 2011-12-08 09:16:36Z owen $';

echo Processing %1
set PRG=usbasp
set PORT=usb
set OPTS=-B 5

if *%2==* goto eeprom
echo program flash (%2.hex)...
avrdude %OPTS% -c %PRG% -P %PORT% -p t44 -U flash:w:%2.hex
sleep 1

echo program eeprom (%1.hex)...
avrdude %OPTS% -c %PRG% -P %PORT% -p t44 -U eeprom:w:%1.hex 
sleep 1

if not *%3==*fuse goto lock
echo program fuses ...
avrdude %OPTS% -c %PRG% -P %PORT% -p t44 -U hfuse:w:0xD4:m -U lfuse:w:0xE2:m  
sleep 1

if not *%4==*lock goto cleanup
echo program lock (after everything else) ...
avrdude %OPTS% -c %PRG% -P %PORT% -p t44 -U lock:w:0x0:m 
goto cleanup

echo usage: prg eepromfile flashfile fuse lock
goto end


Above is a batch file (prg.bat) to program an ATtiny44 using AVRDUDE. Though this is a Windows batch file, the programmer and AVRDUDE work also on Linux.

Processing 10368
set PRG=usbasp

avrdude: set SCK frequency to 93750 Hz
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x1e9108
avrdude: reading input file "10368.hex"
avrdude: input file 10368.hex auto detected as Intel Hex
avrdude: writing eeprom (51 bytes):

Writing | ################################################## | 100% 0.53s

avrdude: 51 bytes of eeprom written
avrdude: verifying eeprom memory against 10368.hex:
avrdude: load data eeprom data from input file 10368.hex:
avrdude: input file 10368.hex auto detected as Intel Hex
avrdude: input file 10368.hex contains 51 bytes
avrdude: reading on-chip eeprom data:

Reading | ################################################## | 100% 0.03s

avrdude: verifying ...
avrdude: 51 bytes of eeprom verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

Above is a console output from the batch file which programs only the EEPROM, the executable in flash memory and the fuses are not touched.

Special features

1 of n

Two options are provided for interpreting the sel pins as a priority 1 of n encoder.

In the case of the 1 of 7 encoder, the address selected is simply the bit number (1-7) of the highest order 'active' bit (ie priority to high sel bits). sel=0 results in addres zero. 7 wires gives effectively selection of 1 of 8 channels.

In the case of the 1 of 6 encoder with banking, the LSB is used as an offset to be added to the address obtained from a 1 of 6 priority encoder of the higher bits. The channel banking gives selection of one of two sets of 7 channels from 6+1 wires. The banking may be of advantage it transmit / received switching of a transceiver.


Fig 7:
Placeholder: a better pic in time...

Fig 7 shows an example of the AD9850 purchased as a module on eBay for around $12 including post.

The AD9850 requires the register data be sent LSB first. Though PllLdr sends the data stored in EEPROM MSB first, the LSB first transmission required by the AD9850 can be achieved by storing the register bit patterns in reverse. The conversion tools provided for this project have a special flag'"rbo"="R" which will store a reversed bit pattern in the EEPROM hex file.


Above is an example configuration for an AD9850 showing use of the reverse bit order flag, and variable register lengths.

Several AD chips can be put into a test state by writing to the registers and requre a reset to recover. To prevent unintentional writing to the register during power up, it is advisable to use an external pullup resistor on the /CS line. PllLdr will supply a pullup once it has initialised, but an external pullup ensures that the synthesiser chip will not be accidentally loaded prior to that.


Support for test and diagnosis

The SI4133 VCOs have a limited tuning range and setting the centre frequency may be important to reliable lock under a range of environmental conditions and over time, more so if the "self tuning algorithm" is not driven from time to time by power up or frequency change (Silicon Labs 2010).

Although the range of a VCO has been reported at 15% to 20% (Byrnes 2010), the question is whether 'production' units will reliably lock over that range under a range of temperature conditions etc. The datasheet lists the tuning range from centre frequency as just 5%. That suggests that if reliability is important (eg that it works under adverse weather such at 0° to 40° temperatures for field activity), attention to centre frequency tuning may be important.

(Silicon Labs 2010) (AN31) gives two procedures for checking the VCO frequency:

  1.  measuring the tuning range of the VCO using test registers; and
  2. reading the Tuning Code when locked at the upper and lower frequencies of the required range as an indicator of margin.

PllLdr supports both methods.

Method 1

The test registers can be loaded by specifying them in EEPROM in quite the same way as normal registers.

A EEPROM image is developed to contain the test registers for upper and lower limits for the VCOs and loaded. The configurations are selected and the output frequency measured.

This is the simplest test, and can be performed for a range of environmentals.

Power down

ZL2BKC and VK3PY reported problems with degraded output from the RF PLL in the VK3XDK Agile PLL board. ZL2BKC removed the IF tuning inductor which fixed the problems, and VK3PY solved his problem the same way. This measure is probably a circumvention rather than attacking the underlying cause. It seems that the production Picaxe shipped on the boards does not load the IF divider and does not power the IF PLL down, and the apparently unlocked IF PLL can cause degraded output from the RF PLL. Though I do not know if this fixes it, I would not power up either PLL unless divider values appropriate to the VCO range were loaded (ie divider values that should result in a locked VCO).


The Si4133 datasheet states [i]n applications where the ambient temperature can drift substantially after self-tuning, it might be necessary to monitor the lock-detect bar (LDETB) signal on the AUXOUT pin to determine whether a PLL is about to run out of locking capability.

PllLdr can monitor LDETB and resend the current configuration to redrive the Si4133 self-tuning feature. If options[5] and /LDETB some microseconds after sending a register set to the Si4133, LDETB is monitored and configuration resent if it becomes a logical 1.


Above is an example configuration file for an Si4133 with 10MHz ref. It contains three register sets for 10368MHz with IFs of 432, 438, 144MHz, and test registers for setting RF1 VCO to the bottom and top of its range to check its tuning range. It inverts sel inputs, de-bounces the input, and enables monitoring of LDETB. This configuration takes just under 128 bytes and will fit in any of the chips. Note, this configuration file does not suit the Si4133G, but a configuration subject to the limitations of the Si4133 could be built. 438MHz was chosen to be displaced from the normal 432MHz weak signals band and still have a high PD frequency for best phase noise.

Elcom synthesisers

PllLddr should work with the Elcom sythesisers that use SPI. Elcom's documentation on the serial interface does not specify critical timings in much detail. Program the AVR chip low fuse to 0x64 to use the internal 128kHz and CKDIV8 clock so that the signaling speed is slow enough for the Elcom.

The Elcom synthesisers appear to use a 32 bit frequency register loaded LSB first (so use the rbo option in the PllLder config file) as a series of packed BCD digits.

For example, to set a single frequency of 12660MHz on a DFS-1301, 12660/5=2532 is loaded as 0x25320000 LSB first, the following configuration should work. (Of course, more frequencies can be specified as in the examples above.)


Whilst this should work, it is untested and derived from poor documentation. If you have tested it, I am interested in the outcome.

Getting PllLdr

The hex code for PllLdr is copyright © Owen Duffy, 2011. All rights reserved. Permission is granted for non commercial use (ie for non commercial application and use in products not commercially manufactured. For other uses, contact the webmaster for further licensing information. The hex code is available subject to those conditions at the link below.


During the draft phase of this project, if the hex files are updated, recreate the EEPROM image from current utilities as the EEPROM mapping may have changed.


ATB - Bootloader for ATTiny microcontrollers

Another project has been spawned to develop a reliable bootloader suited to the AVR ATTiny series microcontrollers, ATB - a bootloader for AVR Tiny microcontrollers.

ATB firmware for PllLdr uses pin A0 (DIP 13) on the ATTinyx4 for a single wire interface, and pin B4 (DIP 5) on the ATTinyx5. Being a single wire interface, an external pullup resistor of 10k is needed on the interface pin.

The work in in development, a prototype firmware and client loader are under test and suitable beta testers are sought (@ 03/09/12).


Version Date Description
1.01 28/11/2011 Initial.
1.02 24/12/2011 Added more detail on fuses, timing, and example applications.
1.03 04/08/2012 Various minor changes, testing of Si4133 facilities.
1.04 08/08/2012  Changes for bootloader.
1.05 31/10/2012 EEPROM format change, needs updated flash and EEPROM.
1.06 26/06/2014 EEPROM map changed to V2. New features. Needs updated flash and EEPROM.
1.07 01/06/2020 Added option to invert SCK.
1.08 25/06/2020 Revised SPI mode 2 - dfcac8c


© Copyright: Owen Duffy 1995, 2021. All rights reserved. Disclaimer.