All You Ever Needed To Know About UPDI, And Then Some!

This entry is part 1 of 1 in the series IMPLEMENTING UPDI FROM SCRATCH
  • All You Ever Needed To Know About UPDI, And Then Some!

Post Stastics

  • This post has 6200 words.
  • Estimated read time is 29.52 minute(s).

Table of Contents

Part I — Foundations, Electrical Interface, Protocol, and High-Voltage Activation

There was a time when connecting a programmer to an AVR microcontroller could consume a surprisingly large number of pins. Traditional AVR In-System Programming used SPI-like signaling. JTAG used four principal signaling wires plus reset and power references. DebugWIRE reduced debugging to essentially one signal, but came with its own peculiarities. The XMEGA family introduced PDI.

Modern AVR microcontrollers took the idea considerably further.

For many of Microchip’s current AVR devices, programming, fuse access, memory inspection, chip erase, and on-chip debugging can all be reached through one signal wire.

That interface is called UPDI — Unified Program and Debug Interface.

Do not let the single wire fool you.

Behind that pin lies a surprisingly complete communications system containing a UART-like physical layer, synchronization and collision handling, an instruction protocol, address-space access mechanisms, protected activation keys, nonvolatile-memory controllers, an on-chip debug system, and—in some devices—a special high-voltage activation mechanism capable of recovering a chip whose normal UPDI pin function has been disabled.

The goal of this article is not merely to tell you how to connect an existing programmer.

We are going considerably farther.

By the end of this series we will understand UPDI well enough to build a working programmer around an ordinary ATmega328P Arduino Nano, communicate with real modern AVR devices, read and write their memory, erase them, manipulate fuses safely, add externally generated high-voltage UPDI activation, and explore what would be necessary to extend our implementation toward actual on-chip debugging.

The example hardware will deliberately remain accessible to the hobbyist:

  • an ordinary 5 V, 16 MHz Arduino Nano based on the ATmega328P;
  • Arduino IDE as the development environment and toolchain;
  • a small number of passive components;
  • a target AVR supporting UPDI;
  • and, for the high-voltage experiments, an external bench power supply rather than an onboard high-voltage converter.

The design will nevertheless be approached as an engineer should approach it: by understanding what every wire, byte, timing interval, fuse, and voltage actually does.


1. What Is UPDI?

UPDI stands for Unified Program and Debug Interface.

Microchip describes it as a proprietary interface intended for external programming and on-chip debugging of AVR microcontrollers. It succeeds the two-wire PDI physical interface used by the AVR XMEGA family. UPDI reduces that connection to a bidirectional, half-duplex, asynchronous one-wire interface.

That last sentence contains several important ideas.

UPDI is:

Bidirectional.
Information travels both from programmer to target and from target to programmer.

Half duplex.
Both ends use the same communication line, but they do not normally transmit simultaneously.

Asynchronous.
There is no separate clock wire. Timing is recovered from the serial data stream.

UART-like.
At the physical level, UPDI deliberately resembles ordinary asynchronous serial communication.

More than a programming interface.
The same physical connection reaches programming resources and the device’s on-chip debug infrastructure.

A conceptual connection can consequently be as simple as:

     Programmer                         Target AVR

     +-----------+                      +-----------+
     |           |                      |           |
     |      UPDI |----------------------| UPDI      |
     |           |                      |           |
     |       GND |----------------------| GND       |
     |           |                      |           |
     +-----------+                      +-----------+

                           optional:
                  VTARGET/reference/power

That is the attraction of UPDI from a PCB designer’s perspective.

A production board can potentially expose only three programming contacts:

UPDI
VCC
GND

and sometimes only UPDI and GND are electrically necessary when the target supplies its own power and the programmer has another method of determining its logic level.

This makes UPDI extremely attractive for:

  • tiny production test pads;
  • pogo-pin programming fixtures;
  • hobby boards;
  • small embedded systems;
  • factory programming;
  • bootstrapping new boards;
  • debugging assembled hardware;
  • devices where connector area is scarce.

But UPDI’s simplicity exists primarily at the connector, not necessarily inside the protocol.


2. Where UPDI Fits in AVR History

AVR programming interfaces have evolved considerably.

Classic AVR devices commonly used SPI-based ISP programming. Larger devices frequently provided JTAG. DebugWIRE allowed debugging using the RESET connection on many smaller classic AVR parts. XMEGA devices introduced PDI.

UPDI is the next major simplification of that concept.

Microchip explicitly identifies UPDI as the successor to XMEGA’s PDI physical interface.

Today UPDI appears throughout several generations of the modern AVR architecture, including members of:

  • tinyAVR 0-series;
  • tinyAVR 1-series;
  • tinyAVR 2-series;
  • megaAVR 0-series;
  • AVR DA;
  • AVR DB;
  • AVR DD;
  • and additional newer AVR families.

For example, Microchip documents the megaAVR 0-series as providing a single-pin Unified Program Debug Interface, and current AVR DD devices likewise advertise single-pin programming and debugging.

There is an important engineering warning, however:

UPDI compatibility does not mean that every UPDI AVR uses the same Flash-programming procedure.

The UPDI communications mechanism is only one part of programming the microcontroller.

UPDI gives us a means of accessing internal resources. Actual Flash and EEPROM programming is performed through the target’s Nonvolatile Memory Controller — NVMCTRL.

Microchip has changed that controller architecture across generations.

Therefore:

UPDI physical/link protocol
           |
           v
Memory/register access
           |
           v
Target-specific NVM controller
           |
           v
Flash / EEPROM / fuses / USERROW

A programmer may understand UPDI perfectly and still fail to program a newer device if it does not understand that device’s NVM controller.

This distinction will become particularly important when we design our Nano firmware.

It is also visible in existing open-source projects. The well-known jtag2updi project supports a large collection of earlier UPDI devices, but an open issue documents that newer NVMv3 devices such as AVR EA/EB require additional NVM support.

So throughout this article we will keep three concepts separate:

  1. UPDI communications
  2. UPDI programming-mode activation
  3. device-family-specific NVM programming

That separation makes both the protocol and our eventual software architecture much easier to understand.


3. UPDI Is Really Several Layers

The easiest way to understand UPDI is to stop thinking of it as a magic programming wire.

Think instead of a small communications stack.

Conceptually:

+--------------------------------------------------+
| Host software                                    |
| Arduino IDE / programmer utility / debugger      |
+--------------------------------------------------+
                       |
+--------------------------------------------------+
| Programmer command protocol                      |
| Our own protocol, jtagice2, serial commands, etc.|
+--------------------------------------------------+
                       |
+--------------------------------------------------+
| Programming / debugging algorithm                |
| NVMCTRL operations, keys, erase, OCD control     |
+--------------------------------------------------+
                       |
+--------------------------------------------------+
| UPDI instruction layer                           |
| LDS STS LD ST LDCS STCS REPEAT KEY               |
+--------------------------------------------------+
                       |
+--------------------------------------------------+
| UPDI serial/data-link layer                      |
| SYNCH, ACK, BREAK, framing, turn-around           |
+--------------------------------------------------+
                       |
+--------------------------------------------------+
| Electrical physical layer                        |
| Single bidirectional signal + ground             |
+--------------------------------------------------+

This distinction is particularly useful when debugging your own programmer.

For example:

  • If the waveform has the wrong parity, the problem is in the serial layer.
  • If LDCS returns nonsense, the problem may be instruction framing or synchronization.
  • If register reads work but Flash writing does not, UPDI itself may be perfectly functional and the error may instead be in the NVMCTRL programming algorithm.
  • If programming works but AVRDUDE cannot recognize your programmer, the problem may be entirely in the host-to-programmer protocol.

This is why statements such as “AVRDUDE speaks UPDI” can be misleading.

AVRDUDE normally communicates with a programmer using a programmer protocol. The programmer then communicates with the target using UPDI.

Those are different links.


4. The Physical Connection

The ordinary UPDI connection is refreshingly small.

At minimum:

PROGRAMMER                        TARGET

GND  --------------------------- GND
UPDI --------------------------- UPDI

In most practical systems you will also want access to the target supply voltage:

PROGRAMMER                        TARGET

GND  --------------------------- GND
UPDI --------------------------- UPDI
VTG  --------------------------- VDD

VTG may mean one of two things depending on the programmer:

  1. the programmer supplies target power; or
  2. it merely senses the target voltage and adjusts its I/O accordingly.

Professional tools frequently use the second arrangement because the target may already be powered from its own circuit.

Our first Arduino Nano implementation will be simpler.

We will initially assume that the Nano and target operate at compatible logic voltages.

Later we will discuss voltage translation and the limitations of using a 5 V ATmega328P Nano with lower-voltage targets.


5. One Wire, Two Transmitters

Because UPDI is half-duplex, both devices must share one conductor.

At some moments the programmer drives the line.

At other moments the target drives it.

At still other moments neither side should drive it.

Conceptually:

             programmer drives
                    |
                    v
HIGH  ----+    +----+       +----
          |    |
LOW       +----+


             programmer releases
                    |
                    v

HIGH  ----------------+     +-----
                       |     |
LOW                    +-----+
                       ^
                       |
                  target drives

That requirement explains why a straightforward UART TX output cannot simply be hard-wired against another UART TX output.

If one device drives HIGH while the other drives LOW, we have bus contention.

At best, communication fails.

At worst, excessive current flows through two output drivers.

UPDI interfaces therefore use some method of:

  • sharing transmit and receive paths;
  • releasing the line rapidly;
  • controlling direction;
  • and preventing destructive contention.

A microcontroller GPIO whose firmware can rapidly change between output and high-impedance input is particularly convenient.

That is exactly why the ATmega328P can implement a low-cost UPDI interface surprisingly well.


6. UPDI’s UART-Like Frame

UPDI uses a fixed asynchronous serial frame.

Microchip specifies a DATA frame consisting of:

1 start bit
8 data bits
1 even-parity bit
2 stop bits

In conventional UART notation:

8E2

That is:

8 data bits
Even parity
2 stop bits

Microchip’s documentation describes the frame as one LOW start bit, eight data bits, an even-parity bit, and two HIGH stop bits.

Graphically:

Idle  Start     Data bits              Parity  Stop Stop
 HIGH   LOW   D0 D1 D2 D3 D4 D5 D6 D7    P     1    1

 -----+     +--+--+--+--+--+--+--+--+---+----+----+----
      |     |
      +-----+

The data bits are transferred least-significant bit first, as with the conventional AVR UART.

The additional stop bit is useful on a half-duplex link because it provides some settling and turnaround time.


7. Why Even Parity?

Parity provides a simple error-detection mechanism.

With even parity, the parity bit is selected so that the total number of logical ones among:

D0 ... D7 + parity

is even.

Consider:

data = 0b00000001

The data contains one logical 1, so parity must also be 1:

ones = 2

Even.

For:

data = 0b00000011

there are already two logical ones, so parity is 0.

The mechanism cannot detect every possible transmission error, but it catches many single-bit errors essentially for free.

Some UPDI implementations allow parity checking to be disabled internally, but our implementation should initially obey the protocol and generate correct parity rather than depending on that feature. Microchip documents a parity-disable option in the UPDI control registers.


8. UPDI Does Not Use a Fixed Baud Rate in the Ordinary UART Sense

One of UPDI’s clever features is automatic baud synchronization.

The target does not simply assume:

9600
19200
115200
225000

or another predefined UART baud rate.

Instead, the programmer sends a special synchronization byte:

0x55

before each new UPDI instruction.

Why 0x55?

In binary:

0x55 = 01010101

This gives a highly regular alternating pattern of edges:

0 1 0 1 0 1 0 1

which makes it ideal for timing measurement.

The target observes that pattern and adjusts its baud-rate generator.

Microchip states that every new UPDI instruction must be preceded by a SYNCH character.

Therefore an instruction transmission generally begins:

0x55   instruction ...
^^^^
SYNCH

This property is extremely useful for a homemade programmer because the target continuously gets opportunities to resynchronize to us.


9. The Important UPDI Frame Types

Besides ordinary DATA frames, UPDI defines several special conditions or frames:

  • IDLE
  • BREAK
  • SYNCH
  • ACK

Microchip’s current documentation describes them explicitly.

Understanding these four mechanisms is essential.


10. IDLE

An idle UPDI line is HIGH.

An IDLE condition consists of at least twelve HIGH bit periods.

Conceptually:

UPDI

HIGH  ------------------------------------
LOW
             >= 12 bit periods

In practice, releasing the bus and allowing it to remain HIGH produces this condition.

The exact electrical source of the HIGH state depends on the target/interface implementation, but from the protocol perspective, HIGH means idle.


11. BREAK

BREAK is the opposite.

A UPDI BREAK consists of the line being held LOW for at least the required interval.

At the basic frame level Microchip describes BREAK as at least 12 LOW bits. Its function is important:

BREAK resets UPDI’s communication state machine.

It is therefore our principal recovery tool when:

  • synchronization has been lost;
  • a malformed packet was sent;
  • the target and programmer disagree about link state;
  • an aborted transaction left UPDI expecting another byte.

Think of BREAK as:

“Forget what we were doing and return the communications interface to a known state.”

Microchip recommends a double BREAK for robust recovery because the first BREAK can abort an operation already in progress and the second can then reset the now-receptive interface.

This is an important implementation detail for our Nano.


12. BREAK Timing Is More Subtle Than Twelve Ordinary Bits

If both ends already agree on the baud rate, twelve LOW bit periods make sense.

But what if synchronization has been lost so badly that the target no longer agrees with us about timing?

Microchip consequently specifies conservative BREAK durations based on UPDI’s internal clock selection.

For devices using the documented 4/8/16 MHz UPDI clock selections, representative recommended BREAK durations are:

UPDI clock        Recommended BREAK

16 MHz               6.15 ms
 8 MHz              12.30 ms
 4 MHz              24.60 ms

The 4 MHz condition is commonly the default, making approximately 24.6 ms the conservative recovery BREAK duration on affected implementations.

Notice how different that is from transmitting twelve bits at 225 kbaud:

12 / 225000 ≈ 53.3 µs

A robust “I have no idea what state the target is in” BREAK can therefore be dramatically longer than an ordinary frame-level BREAK.

This distinction will matter when we write:

updiBreak();

for the Arduino.


13. SYNCH

After BREAK, and before every normal instruction, comes:

0x55

The SYNCH byte lets the target determine our bit timing.

A typical command therefore looks conceptually like:

BREAK       // when needed
0x55        // SYNCH
COMMAND
OPERANDS

Not every command needs a BREAK.

Every new instruction does require synchronization.


14. ACK

Some write operations require the UPDI target to tell the programmer:

“I have accepted that operation and obtained bus access.”

That is the ACK response.

Microchip specifically associates ACK generation with successful ST and STS operations crossing the synchronization boundary and acquiring bus access.

This means our programmer cannot blindly throw bytes onto the wire as quickly as its CPU can produce them.

It must respect the request/response nature of the protocol.

That leads naturally to our next topic.


15. The UPDI Instruction Set

UPDI has a pleasantly small core instruction set.

The principal instructions are:

LDS
STS
LD
ST
LDCS
STCS
REPEAT
KEY

Microchip documents these as the UPDI Data Link instruction set.

Although eight instructions may not sound like much, together they provide enough functionality to reach essentially everything needed for programming and debugging.

Let’s understand what each category does before worrying about individual binary encodings.


16. LDS — Load Direct from Data Space

LDS means approximately:

Read data directly from a specified address.

Conceptually:

value = memory[address]

A programmer sends an address and receives data from that location.

Suppose we wanted to inspect a peripheral register at some memory-mapped address.

Conceptually:

LDS  address
     |
     +------> target memory map
                   |
                   +------> return byte/word

Because modern AVR peripherals and memories are largely memory mapped, this seemingly simple capability gives UPDI enormous reach.


17. STS — Store Direct to Data Space

STS is the complementary operation:

memory[address] = value

This allows the programmer to modify a directly addressed memory location.

That might be:

  • SRAM;
  • an I/O register;
  • an NVMCTRL register;
  • a fuse-related memory location where permitted;
  • or another memory-mapped resource.

When programming Flash, however, it is important to understand that we generally do not merely perform an STS directly to the Flash array and magically have Flash programming occur.

Instead, the programmer interacts with the target’s NVM controller according to that target family’s documented programming procedure.

Again:

UPDI supplies memory access.

NVMCTRL performs nonvolatile-memory operations.

That conceptual separation will save us a great deal of confusion later.


18. LD and ST — Indirect Access

LD and ST use UPDI’s internal pointer mechanism.

Instead of repeatedly transmitting a complete address, we can establish a pointer and then operate through it.

Conceptually:

pointer = 0x2000

LD pointer
pointer++

LD pointer
pointer++

LD pointer
pointer++

That is much more efficient for reading or writing blocks of sequential memory.

If we want to transfer a 64-byte page, sending a full address for every byte would be wasteful.

Indirect access allows UPDI to behave more like a small streaming memory interface.


19. REPEAT — The Key to Efficient Block Transfers

The REPEAT instruction tells UPDI to repeat the following operation multiple times.

This becomes extremely useful when combined with pointer-based LD and ST.

Conceptually:

set pointer = buffer_start

REPEAT 63
ST pointer++, data

allowing a block of sequential bytes to be transferred with far less protocol overhead.

Exact repeat-count semantics and supported data widths must be implemented according to the device documentation, but the architectural purpose is straightforward:

REPEAT turns repeated memory transfers into efficient block operations.

That matters enormously for programmer performance.

Without such mechanisms, programming tens or hundreds of kilobytes through a one-wire serial connection would become unnecessarily slow.


20. LDCS and STCS — UPDI’s Own Control Registers

UPDI contains its own internal control and status register space.

This is distinct from ordinary target memory.

LDCS reads that control/status space:

LDCS = Load Control/Status

and STCS writes it:

STCS = Store Control/Status

This space contains registers involved in such things as:

  • UPDI status;
  • control configuration;
  • reset requests;
  • error information;
  • interface state.

An early milestone for our Arduino programmer will therefore be:

  1. send BREAK;
  2. send SYNCH;
  3. issue LDCS;
  4. successfully read a known UPDI status/control value.

If that works reliably, we know that:

  • our electrical connection works;
  • transmission timing works;
  • direction switching works;
  • parity works;
  • stop bits work;
  • synchronization works;
  • and target-to-programmer receive works.

That is a much better first test than immediately attempting a chip erase.


21. KEY — Opening Protected Doors

The KEY instruction is particularly interesting.

Some sensitive UPDI operations are not activated merely because the programmer has electrical access.

UPDI uses keys to authorize protected functions.

Among these are keys associated with operations such as:

  • entering NVM programming;
  • chip erase;
  • user-row access on applicable devices.

Existing implementations make the mechanism easy to see. For example, jtag2updi contains eight-byte constants for NVM programming, chip erase, and user-row operations, then transmits them using UPDI’s KEY mechanism.

This is not encryption.

It is better thought of as a protocol-level intent confirmation / activation mechanism.

The target effectively requires us to say:

“I deliberately request access to this protected subsystem.”

before permitting the operation.

KEY becomes especially important when discussing high-voltage activation.


22. UPDI and the AVR Memory Map

A major architectural advantage of UPDI is its ability to reach the AVR’s address space.

Microchip’s UPDI debugging capabilities explicitly include memory-mapped access to:

  • NVM;
  • RAM;
  • I/O space.

That means the same fundamental communication mechanism can participate in both programming and debugging.

For programming:

UPDI
  |
  +--> NVMCTRL registers
  |
  +--> Flash programming buffers
  |
  +--> EEPROM
  |
  +--> fuses

For debugging:

UPDI
  |
  +--> SRAM
  |
  +--> peripheral registers
  |
  +--> OCD registers
  |
  +--> CPU state

Microchip also documents OCD support for program-flow control, CPU PC/SP/SREG observation, break detection, hardware breakpoints, and other debug functionality on applicable devices.

This is why the word Unified in UPDI is meaningful.

Programming and debugging no longer require separate physical interfaces.


23. What Happens When a Device Is Locked?

Security changes what UPDI can see.

On a locked device, unrestricted access to program memory would obviously defeat the purpose of code-protection features.

Microchip documents that, for devices such as the megaAVR 0-series, a locked part prevents UPDI from accessing the normal system bus. UPDI can still access its own internal control/status areas and the asynchronous system interface, allowing the programmer to determine state and perform permitted recovery operations such as the appropriate chip-erase process.

So:

Unlocked device:

UPDI ---> system bus ---> memories/peripherals


Locked device:

UPDI -X-> protected system bus
  |
  +------> limited UPDI/ASI resources remain reachable

That is an important distinction when troubleshooting.

A programmer that can communicate with UPDI but cannot read Flash may not be malfunctioning at all.

The device may simply be locked.


24. The Often-Misunderstood “High Voltage” in UPDI

Now we reach one of the most frequently misunderstood UPDI topics.

You will often hear:

“UPDI uses 12-volt programming.”

That statement can be badly misleading.

In UPDI, the high-voltage pulse is generally not the voltage used to write Flash memory.

Microchip states this explicitly:

the high-voltage source is an activation mechanism for the UPDI physical interface and plays no part in programming the memory itself.

This is fundamentally different from some older AVR high-voltage programming methods.

Think of the HV pulse as a special knock on the door:

               HV pulse
                  |
                  v
        +--------------------+
        | Re-enable UPDI pin |
        +--------------------+
                  |
                  v
          ordinary UPDI
                  |
                  v
       normal NVM programming

Once UPDI has been activated, normal digital signaling performs the actual communications.


25. Why Is High-Voltage Activation Needed?

Some AVR packages have very few pins.

Dedicating one pin permanently to programming would reduce the number available to the application.

Microchip therefore allows the UPDI pin on some devices to be configured as:

UPDI
RESET
GPIO

through fuse settings.

That is extremely useful.

But it creates an obvious problem.

Suppose you configure the pin as GPIO.

How do you later communicate using UPDI when the UPDI function is no longer connected to that pad?

That is what high-voltage activation solves.

The special voltage tells the input pad:

Temporarily override its fused GPIO/RESET function and return this pad to UPDI control.

Microchip documents this shared-pin arrangement for tinyAVR 0-, 1-, and 2-series devices.


26. Not Every UPDI Device Needs High Voltage

This point is extremely important when designing a universal programmer.

Microchip identifies several UPDI pin arrangements.

Arrangement 1 — Shared UPDI/RESET/GPIO pin

Typical of a number of small tinyAVR devices.

The pin may be configured away from UPDI.

Recovering UPDI can require approximately:

12 V

applied according to the device’s specified activation sequence.


Arrangement 2 — Dedicated UPDI pin

Used on devices including megaAVR 0-series and AVR DA/DB families.

UPDI remains physically available.

Consequently the high-voltage recovery concept generally does not apply to this dedicated UPDI pin arrangement.


Arrangement 3 — Newer split RESET/UPDI/GPIO arrangements

Devices such as members of the AVR DD generation introduce another arrangement.

Here UPDI functionality may share a pin with GPIO while RESET exists separately. High-voltage activation is then applied according to that family’s specific mechanism—often to RESET—and the required voltage is not necessarily 12 V.

Microchip describes this newer class as requiring approximately:

VDD + 2 V

and instructs designers to consult the individual device data sheet.

For documented AVR devices using this mechanism, representative electrical specifications show:

VHV minimum:   VDD + 2 V
typical:       7.5 V
maximum:       8.5 V

with the explicit requirement that the absolute maximum rating of the relevant pin not be exceeded.

This immediately leads us to one of the most important design rules in this entire article.

Never design a UPDI programmer on the assumption that “HV UPDI means 12 V.”

The correct voltage depends on the target family.


27. What High Voltages Should Our Programmer Eventually Support?

Because our educational programmer will use a bench supply for its high-voltage source, we can make the system unusually flexible.

We should architect it around at least two HV classes:

HV12:
    nominal 12 V class
    for older shared-pin tinyAVR UPDI activation

HVLOW:
    device-specific lower-voltage activation
    often roughly VDD + 2 V
    with target-specific limits

Before applying either one, software should know:

target device
target VDD
HV activation class
HV destination pin
allowed HV range
required pulse timing

A future universal programmer should ideally maintain this information in a device database rather than asking the operator to remember it.

For our Arduino experiment, however, we will deliberately make high-voltage selection a manual and explicit operation.

That minimizes the possibility of accidentally applying 12 V to a device that expects a maximum near 8.5 V.


28. Never Apply 12 V Blindly to “A UPDI Pin”

This deserves emphasis.

A programmer capable of producing 12 V is also capable of damaging circuitry.

Microchip warns that circuitry attached to a high-voltage-activated UPDI line must not interfere with the activation sequence or be damaged by it.

The danger extends beyond the AVR.

Imagine:

                    +---------- target AVR
                    |
12 V pulse ----------+---------- logic buffer
                    |
                    +---------- LED
                    |
                    +---------- sensor IC

If those branches are not designed for 12 V, the high-voltage recovery feature may destroy them.

This is why production hardware often uses:

  • isolation;
  • series resistance;
  • switching devices;
  • dedicated programming pads;
  • protection components;
  • carefully chosen buffer topology.

Our Nano experiment will keep HV isolated from the Nano’s GPIO circuitry.

We will not route bench-supply 12 V directly through an ATmega328P I/O pin.


29. HV Activation Is a Pulse, Not a Programming Supply

Again, the high voltage is temporary.

For older shared-pin UPDI devices Microchip documents a pulse-type activation sequence rather than continuous 12 V programming.

One documented 12 V sequence recommends a pulse duration in the neighborhood of:

100 µs to 1 ms

before returning the programming driver to a high-impedance state.

Other, newer families have different timing requirements. Some documented low-voltage-HV mechanisms specify a minimum HV duration around 10 µs and a target-specific voltage range.

Therefore our software will eventually represent HV activation as a target-specific operation, not as:

digitalWrite(HV, HIGH);
delay(whatever);

with one universal delay.


30. The 65 Millisecond Window

High-voltage activation contains another clever safety mechanism.

A random electrostatic-discharge event can momentarily produce a voltage far above the normal supply voltage.

Without protection against false activation, an ESD transient on the pin might accidentally switch the target into UPDI mode.

Microchip therefore requires a valid UPDI key shortly after the high-voltage event.

Microchip’s current guidance describes approximately a:

65 ms

window in which a valid key—such as an NVM enable or chip-erase key—must be supplied following the HV event.

Conceptually:

            HV pulse
               |
               v
time ----------+----------------------------------->
               |<--------- ~65 ms --------->|
               |
               +---- establish UPDI
               |
               +---- transmit valid KEY
               |
               +---- issue required reset

If the correct key is not received, the device assumes that the event may have been accidental and restores normal operation.

This is a sophisticated little mechanism hiding behind what appears from the outside to be “just a 12 V pulse.”


31. HV Activation Can Be Volatile

High-voltage entry does not necessarily rewrite the fuse that disabled UPDI.

It can temporarily override that fuse-selected behavior.

Microchip notes that the original pin function may return after events including:

  • reset;
  • power cycling;
  • leaving programming mode,

depending on implementation and sequence.

Therefore you can use HV activation to recover a device without necessarily permanently sacrificing the GPIO configuration.

If you actually want normal UPDI access on subsequent resets, you may need to rewrite the relevant fuse.

This also matters for debugging.

Repeated debugger entry/exit sequences can otherwise require repeated high-voltage activation.


32. The Special Problem of a UPDI Pin Configured as an Output

Suppose the shared UPDI/GPIO pin is currently configured by the running application as:

GPIO output LOW

and our programmer suddenly tries to force that same node toward 12 V.

That produces an ugly electrical condition.

The microcontroller output transistor is trying to pull the line toward ground while our programmer is trying to pull it toward 12 V.

Potential results include:

  • excessive current;
  • pad damage;
  • programmer damage;
  • disturbed target power;
  • unpredictable activation.

Microchip explicitly cautions against blindly performing simple HV activation on a shared pin actively configured as an output.

Their documented solution takes advantage of behavior immediately following reset or power-on, before the application can resume driving the pin.

This is why professional tools provide procedures involving target power cycling.


33. Safe Power-Toggle HV Entry

A safer strategy is conceptually:

1. Remove target power.

2. Ensure programmer UPDI/HV output is high impedance.

3. Restore target power.

4. Detect that VDD has risen.

5. Before user firmware begins actively driving the shared pin:
       apply HV activation pulse.

6. Remove HV.

7. Establish ordinary UPDI communications.

8. Send the required key inside the allowed interval.

Microchip describes both user-assisted and automatically controlled power-toggle modes for this purpose.

This tells us something important about the hardware architecture of a really good UPDI programmer:

Target power control is useful for much more than convenience.

It can become part of safe HV recovery.

Our simple Nano implementation will initially rely on the human operator and bench supply.

A later dedicated programmer can automate this using MOSFET-switched target power.


34. Why We Are Using an External Bench Supply for HV

Generating 12 V onboard is entirely practical.

One could use:

  • a boost converter;
  • a charge pump;
  • a flyback topology;
  • a dedicated programming-voltage generator.

But that obscures the real subject.

Our purpose is to understand UPDI.

Therefore the experimental programmer will initially use:

bench supply ---> HV switching circuit ---> target

The Arduino will control only the switching event.

It will not generate the high voltage.

This has several educational advantages.

First, we can set the correct voltage for different target classes.

Second, voltage and current can be directly observed.

Third, we avoid adding a switching-converter design problem to an already substantial communications project.

Fourth, a current-limited bench supply gives us another layer of protection while experimenting.


35. The Arduino Must Never See the HV Rail Directly

A safe conceptual arrangement looks like this:

                           BENCH SUPPLY
                              +12 V
                                |
                                |
                         +--------------+
                         | HV SWITCH    |
                         | transistor / |
                         | MOSFET stage |
                         +--------------+
                                |
                                +-------> target HV activation node
                                |

[protection]

Arduino Nano +————-+ | | | HV_ENABLE –+—-> low-voltage control of switch | | | UPDI ——–+—-> ordinary UPDI interface | | | GND ———+—————- target GND +————-+

The high-voltage switching device provides isolation between:

Arduino logic domain

and:

HV activation domain

When HV is disabled, the switching arrangement must not leave the 12 V supply coupled onto the normal UPDI communication node.

Designing that circuit correctly will be one of the practical exercises in the next installment.


36. Why an Arduino Nano Is a Good Teaching Platform

The classic Nano gives us:

  • ATmega328P;
  • 16 MHz clock;
  • 5 V logic;
  • USB-to-serial interface;
  • Arduino IDE support;
  • hardware UART;
  • timers;
  • predictable GPIO;
  • enormous community familiarity.

Most importantly, it is fast enough to implement a useful UPDI bit engine in software.

The well-known jtag2updi project demonstrates precisely this approach. Its normal ATmega328P configuration uses Arduino digital pin D6 / PD6 for the UPDI connection and defaults to a UPDI rate around 225 kbaud. It can be built from the Arduino IDE.

That provides excellent independent confirmation that the hardware concept is practical.

We will learn from that architecture without treating the project as a black box.

Our objective is to understand why it works.


37. Our Initial Nano Hardware

For ordinary, same-voltage UPDI operation our first test circuit can be remarkably small:

                    Arduino Nano
                    ATmega328P

                         D6
                         |
                       4.7 kΩ
                         |
                         +---------------- UPDI
                                          |
                                     +---------+
                                     | TARGET  |
Nano 5V -----------------------------| VDD     |
                                     |         |
Nano GND ----------------------------| GND     |
                                     +---------+

This basic 4.7 kΩ series arrangement is consistent with common Arduino jtag2updi implementations; documented user setups connect Nano D6 to the target UPDI pin through approximately 4.7 kΩ.

The resistor serves an extremely useful purpose.

If the Nano accidentally drives HIGH while the target drives LOW, or vice versa, the resistor limits contention current.

Approximate worst-case current with a full 5 V disagreement would be:

I = V / R

I = 5 V / 4700 Ω

I ≈ 1.06 mA

Ignoring device output resistance.

That is far preferable to hard-wiring opposing push-pull outputs together.


38. Why D6?

There is nothing mystical about the Arduino label D6.

On an ATmega328P Nano:

Arduino D6 = AVR PD6

Existing jtag2updi firmware uses that pin in its normal ATmega328P configuration.

For our implementation, using the same pin gives us a convenient reference point when comparing behavior with known working hardware.

Later, once the bit engine is abstracted properly, the pin can be made configurable.


39. The Programmer Has Two Serial Links

This is another conceptual point worth getting straight before we write a single line of code.

Our Nano programmer actually participates in two completely different serial conversations.

The first is:

PC <---- USB serial ----> Arduino Nano

The second is:

Arduino Nano <---- UPDI ----> target AVR

They are not the same protocol.

The host link might run:

115200 baud, 8N1

while the UPDI link might run something like:

225 kbaud equivalent timing, 8E2

with SYNCH, BREAK, ACK, UPDI instructions, and half-duplex turnaround.

Graphically:

+------------+
| PC         |
|            |
| AVRDUDE or |
| our tool   |
+-----+------+
      |
      | USB serial
      | HOST PROTOCOL
      |
+-----v------+
| Arduino    |
| Nano       |
|            |
| translates |
| commands   |
+-----+------+
      |
      | one-wire UPDI
      | UPDI PROTOCOL
      |
+-----v------+
| Target AVR |
+------------+

This is the architecture we will implement.


40. Our Programmer Firmware Should Be Layered the Same Way

Rather than writing one enormous Arduino sketch, we will divide responsibilities.

A sensible architecture is:

NanoUPDI/
|
+-- NanoUPDI.ino
|
+-- updi_phy.h
+-- updi_phy.cpp
|
+-- updi_link.h
+-- updi_link.cpp
|
+-- updi_commands.h
+-- updi_commands.cpp
|
+-- updi_nvm.h
+-- updi_nvm.cpp
|
+-- updi_device.h
+-- updi_device.cpp
|
+-- hv_control.h
+-- hv_control.cpp
|
+-- host_protocol.h
+-- host_protocol.cpp
|
+-- tests/

Conceptually:

updi_phy
    |
    +-- send bit
    +-- receive bit
    +-- send byte 8E2
    +-- receive byte 8E2
    +-- line direction
    +-- BREAK


updi_link
    |
    +-- SYNCH
    +-- ACK
    +-- recovery
    +-- transaction timing


updi_commands
    |
    +-- LDS
    +-- STS
    +-- LD
    +-- ST
    +-- LDCS
    +-- STCS
    +-- REPEAT
    +-- KEY


updi_nvm
    |
    +-- enter programming
    +-- chip erase
    +-- flash erase
    +-- flash write
    +-- EEPROM
    +-- fuses


hv_control
    |
    +-- HV activation
    +-- timing
    +-- safety interlocks


host_protocol
    |
    +-- PC/Nano communications

That structure follows the architecture of UPDI itself.

It also makes testing dramatically easier.

If LDCS fails, we can test the physical layer independently rather than hunting through Flash-programming code.


41. Our First Development Milestones

We will not begin by trying to upload a Blink sketch.

The project will progress in controlled stages.

The first milestones will be:

Milestone 1
Nano can generate accurate UPDI 8E2 bytes.

Milestone 2
Nano can generate robust BREAK.

Milestone 3
Nano sends SYNCH successfully.

Milestone 4
Nano can read a UPDI control/status register.

Milestone 5
Nano can read the target device identification/signature.

Milestone 6
Nano enters NVM programming mode.

Milestone 7
Nano reads Flash.

Milestone 8
Nano performs chip erase.

Milestone 9
Nano writes and verifies Flash.

Milestone 10
Nano reads/writes EEPROM.

Milestone 11
Fuse support with safeguards.

Milestone 12
External-HV recovery.

Milestone 13
Host-side programming utility integration.

Milestone 14
Explore OCD/debug support.

Every destructive feature will come after read-only communications have been demonstrated.

That is both safer and easier to debug.


42. A Note About Debugging

UPDI is not merely capable of programming.

The interface connects to the AVR’s On-Chip Debug system — OCD.

Microchip documents features on applicable devices including:

  • memory-mapped access to NVM, RAM, and I/O;
  • program run/stop/reset control;
  • two hardware breakpoints;
  • effectively unlimited software/user-program breakpoints where supported by the tool chain;
  • PC, stack-pointer, and status-register observation;
  • nonintrusive runtime monitoring capabilities.

Microchip demonstrates actual source-level debugging over UPDI using supported development tools such as MPLAB X and UPDI-capable hardware.

So in principle:

our one-wire interface
        |
        v
      UPDI
        |
        +-------- NVM programming
        |
        +-------- memory inspection
        |
        +-------- OCD
                    |
                    +-- halt
                    +-- run
                    +-- reset
                    +-- breakpoint
                    +-- inspect CPU state

But implementing a useful debugger is substantially more difficult than implementing a programmer.

Why?

Because a debugger requires two protocols at once:

  1. communicating with the target’s OCD machinery;
  2. presenting that capability to a host debugger/IDE in a format it understands.

We will therefore build programming first.

Only after the physical layer and memory operations are proven will we add the debugging architecture.


43. What We Now Know

At this point UPDI should no longer seem like mysterious Microchip magic.

At its heart it is remarkably understandable.

Electrically:

one bidirectional signal
common ground
optional target-voltage reference/power

At the data-link level:

UART-like
half duplex
8E2
BREAK
SYNCH 0x55
ACK

At the instruction level:

LDS
STS
LD
ST
LDCS
STCS
REPEAT
KEY

At the programming level:

UPDI memory access
        +
target-specific NVMCTRL procedure
        =
Flash/EEPROM/fuse programming

At the debugging level:

UPDI
  +
OCD
  =
single-wire on-chip debugging

And high voltage is not the voltage used to burn Flash.

It is a temporary physical-interface activation mechanism required by certain pin configurations and device families.

Most importantly:

12 V is NOT universal.

Older shared-pin tinyAVR arrangements commonly use the 12 V class.

Dedicated-UPDI devices do not ordinarily need HV activation.

Some newer families use a lower target-specific voltage, often approximately VDD + 2 V and subject to strict device-specific limits.

Always read the target data sheet before applying HV.


44. Where We Go Next

In Part II we will move from theory to hardware and code.

We will build the Arduino Nano UPDI interface from the ground up and cover:

  • a detailed Nano schematic;
  • why the 4.7 kΩ resistor works;
  • pin states during transmit and receive;
  • bus contention;
  • 5 V versus 3.3 V targets;
  • why naïve level shifting can break UPDI;
  • timing requirements;
  • implementing 8E2 in software;
  • generating even parity;
  • generating BREAK correctly;
  • sending 0x55 SYNCH;
  • receiving target responses;
  • turnaround timing;
  • detecting framing/parity errors;
  • implementing LDCS;
  • implementing STCS;
  • implementing LDS;
  • implementing STS;
  • implementing LD and ST;
  • implementing REPEAT;
  • implementing KEY;
  • reading the System Information Block where supported;
  • obtaining device identification;
  • building a simple serial command console;
  • and testing each layer before allowing destructive programming operations.

After that, Part III will implement the actual programmer:

  • programming-mode entry;
  • NVM keys;
  • NVM controller differences;
  • Flash reads;
  • chip erase;
  • page writes;
  • verification;
  • EEPROM;
  • fuses;
  • USERROW;
  • lock handling;
  • error recovery;
  • host communications;
  • integration possibilities with AVRDUDE and other tools.

Part IV will then add high-voltage recovery:

  • 12 V-class UPDI;
  • newer VDD+2 V-class activation;
  • externally supplied bench HV;
  • transistor/MOSFET switching;
  • isolation from the Nano;
  • target power sequencing;
  • pulse timing;
  • the 65 ms key window;
  • output-pin contention;
  • software interlocks;
  • family-specific safety rules;
  • and actual recovery procedures.

Finally, Part V will examine UPDI debugging:

  • OCD architecture;
  • entering debug mode;
  • halting and running the CPU;
  • reset control;
  • memory and register inspection;
  • PC/SP/SREG access;
  • hardware breakpoints;
  • software breakpoints;
  • single stepping;
  • what must be implemented in the Nano;
  • what must be implemented on the PC;
  • debugger front-end options;
  • limitations of an ATmega328P implementation;
  • comparison with Microchip hardware;
  • testing and validation;
  • troubleshooting;
  • final design review;
  • and an extensive source/resource bibliography.

By that point we will not merely know how to use UPDI.

We will understand enough of it to build the machinery that uses it.

Leave a Reply

Your email address will not be published. Required fields are marked *