IMPLEMENTING UPDI FROM SCRATCH
Post Stastics
- This post has 6586 words.
- Estimated read time is 31.36 minute(s).
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, on some devices, a special high-voltage activation mechanism capable of recovering a device 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 examine the architecture needed to extend our implementation into a useful on-chip debugger.
The example hardware deliberately remains 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 handful of inexpensive resistors, diodes, and small-signal transistors;
- a target AVR supporting UPDI;
- and, for high-voltage experiments, an external current-limited bench power supply rather than an onboard high-voltage converter.
The finalized reference hardware also provides:
- target-voltage sensing;
- high-voltage sensing;
- independent target reset control;
- separately switched and routable high voltage;
- an optional target-power control output;
- and a transistor-translated UPDI interface that keeps the Nano’s 5 V GPIO pins electrically separated from the target voltage domain.
The completed article schematic implements those functions around an Arduino Nano while still presenting the target with the normal four useful development connections: RESET, VTARGET, UPDI, and GND.
The design will nevertheless be approached as an engineer should approach it:
By understanding what every wire, byte, timing interval, fuse, transistor, resistor, 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
communications interface.
That sentence contains several important ideas.
Bidirectional
Information travels both:
programmer → target
and:
target → programmer
over the same physical UPDI conductor.
Half duplex
Both ends use the same communication line, but they do not normally transmit simultaneously.
At any given moment:
programmer transmits
or:
target transmits
or:
line is released
but both sides should not intentionally drive conflicting states at the same time.
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 both:
programming resources
and:
on-chip debugging resources
on applicable devices.
A conceptual minimum connection can consequently be as simple as:
PROGRAMMER TARGET AVR +-----------+ +-----------+ | | | | | UPDI |----------------------| UPDI | | | | | | GND |----------------------| GND | | | | | +-----------+ +-----------+
Frequently we also want:
VTARGET / VDD
as a voltage reference or power connection.
That is the attraction of UPDI from a PCB designer’s perspective.
A production board may require only a tiny number of programming contacts.
This makes UPDI especially attractive for:
- production test pads;
- pogo-pin programming fixtures;
- hobby boards;
- small embedded systems;
- factory programming;
- bootstrapping new boards;
- debugging assembled hardware;
- designs where connector area is scarce.
But UPDI’s simplicity exists primarily at the connector.
The protocol behind that connector is considerably richer.
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 through RESET on many smaller classic AVR devices.
XMEGA introduced PDI.
UPDI is the next major simplification of that concept.
Microchip 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;
- AVR DU;
- and additional newer AVR families.
There is, however, an extremely important engineering warning:
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 way to access internal resources.
Actual Flash and EEPROM programming is performed through the target’s:
Nonvolatile Memory Controller — NVMCTRL
Microchip has changed that controller architecture across device 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 communications 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 implementations.
Different modern programmers contain separate NVM backends precisely because the same UPDI link may sit in front of different NVM-controller generations.
Throughout this article we will therefore keep three concepts separate:
UPDI communications UPDI programming-mode activation 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 of it instead as a small communications stack.
Conceptually:
+--------------------------------------------------+
| Host software |
| Arduino IDE / programmer utility / debugger |
+--------------------------------------------------+
|
+--------------------------------------------------+
| Programmer command protocol |
| Our protocol / serial commands / GDB RSP 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, turnaround |
+--------------------------------------------------+
|
+--------------------------------------------------+
| Electrical physical layer |
| Single bidirectional target signal + ground |
+--------------------------------------------------+
This distinction becomes extremely useful when debugging our own programmer.
For example:
If the waveform has the wrong parity:
physical/serial-layer problem
If LDCS returns nonsense:
instruction framing, synchronization, or receive problem
If register reads work but Flash writes fail:
UPDI may be completely functional; the problem may be the NVM algorithm
If programming works from our console but AVRDUDE cannot use our programmer:
host-to-programmer protocol problem
That is why statements such as:
“AVRDUDE speaks UPDI”
can sometimes obscure what is actually happening.
There may be several separate communications links involved.
4. The Physical Connection
The ordinary target-side UPDI connection is refreshingly small.
At minimum:
PROGRAMMER TARGET GND --------------------------- GND UPDI --------------------------- UPDI
In most practical systems we also want access to the target supply voltage:
PROGRAMMER TARGET GND ----------------------- GND UPDI ----------------------- UPDI VTARGET ----------------------- VDD
VTARGET may serve several different purposes.
A programmer may:
- supply target power;
- merely measure target voltage;
- use target voltage as a logic-domain reference;
- verify that a target is actually powered;
- or use it when selecting a safe programming/HV mode.
Our final Nano design primarily treats VTARGET as:
target-voltage sense + target logic-domain reference
although an optional power-control circuit is also provided.
For a more complete development connection, we also expose RESET:
PROGRAMMER TARGET RESET ----------------------- RESET VTARGET ----------------------- VDD UPDI ----------------------- UPDI GND ----------------------- GND
Our reference target connector therefore uses four useful signals:
1 RESET 2 VTARGET 3 UPDI 4 GND
RESET is not required for ordinary UPDI communication on every AVR.
We expose it because:
- ordinary target reset is useful;
- automated test systems may need it;
- debugging may benefit from independent reset control;
- and some newer AVR devices use a separate RESET pin for high-voltage UPDI activation.
The communication interface itself remains:
one-wire UPDI.
5. One External Wire, Separate Internal TX and RX
Because UPDI is half duplex, programmer and target share one physical data conductor.
At some moments the programmer drives the line.
At other moments the target drives it.
At still other moments neither side should actively pull it LOW.
Conceptually:
programmer transmits
|
v
HIGH ----+ +----+ +----
| |
LOW +----+
programmer releases
|
v
HIGH ----------------+ +-----
| |
LOW +-----+
^
|
target transmits
A very simple Arduino implementation can connect one GPIO to UPDI through a resistor and repeatedly change that GPIO between output and input states.
That approach is practical and has been demonstrated by projects such as jtag2updi.
Our final article hardware uses a somewhat more capable arrangement.
Externally there is still only one UPDI conductor.
Internally we split it into:
UPDI_TX
and:
UPDI_RX
using two inexpensive transistors.
Conceptually:
Nano D6 / UPDI_TX
|
v
open-collector TX
|
+-------------------+
|
TARGET
UPDI
|
+-------------------+
|
v
transistor RX
|
Nano D5 / UPDI_RX
This provides several useful advantages:
- the Nano never directly drives a 5 V HIGH into the target;
- target HIGH levels remain referenced to the target voltage domain;
- lower target voltages are easier to accommodate;
- the receive path returns a normal Nano-domain logic signal;
- Nano GPIO pins are isolated from an older 12 V UPDI activation pulse;
- TX and RX timing are easier to reason about;
- and RX can remain active while TX is operating, allowing useful echo/line-state checks.
This is a very important distinction:
UPDI remains one wire externally.
The two-GPIO arrangement exists only inside our programmer.
6. UPDI’s UART-Like Frame
UPDI uses a fixed asynchronous DATA frame.
Microchip specifies:
1 start bit 8 data bits 1 even-parity bit 2 stop bits
In conventional UART notation:
8E2
That means:
8 data bits Even parity 2 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.
The second stop bit is useful on a half-duplex link because it provides additional settling and turnaround time.
7. Why Even Parity?
Parity provides a simple error-detection mechanism.
With even parity, the parity bit is chosen so that the total number of logical ones among:
D0 ... D7 + parity
is even.
For:
00000001
the data contains one logical 1, so parity must also be 1.
Total ones:
2
which is even.
For:
00000011
the data already contains two logical ones.
Parity is therefore:
0
Parity cannot detect every possible transmission error, but it detects many common single-bit errors essentially for free.
Our implementation will generate and check correct parity rather than depending on any optional parity-disable mechanism.
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 permanently fixed rate.
Instead, before each new UPDI instruction, the programmer sends:
0x55
as a synchronization character.
Why 0x55?
Binary:
01010101
This produces a highly regular alternating edge pattern:
0 1 0 1 0 1 0 1
which is ideal for measuring bit timing.
The target observes this pattern and adjusts its serial timing.
Therefore a normal instruction begins conceptually with:
55 instruction operands... ^^ SYNCH
This property is particularly useful for a homemade programmer because the target repeatedly receives opportunities to synchronize itself to our transmitter.
9. Important UPDI Frame Types
Besides ordinary DATA frames, UPDI defines several important special conditions or frames:
IDLE BREAK SYNCH ACK
Understanding these mechanisms is essential before we begin writing firmware.
10. IDLE
An idle UPDI line is HIGH.
An IDLE condition consists of the line remaining HIGH for at least the required number of bit periods.
Conceptually:
UPDI
HIGH ------------------------------------
LOW
sustained HIGH / released bus
The exact electrical source of that HIGH state depends on the target and programmer interface.
From the protocol perspective:
HIGH means idle.
Our open-collector transmitter therefore creates a HIGH state by:
turning its transistor OFF
and releasing the target line.
11. BREAK
BREAK is the opposite.
A UPDI BREAK holds the line LOW for an extended period.
At the basic frame level, BREAK may be understood as a LOW condition lasting at least the required number of bit periods.
Its role is extremely important.
BREAK resets UPDI’s communications state machine.
It is our primary recovery tool when:
- synchronization has been lost;
- a malformed packet was transmitted;
- target and programmer disagree about transaction state;
- an interrupted operation left UPDI waiting for more data.
Think of BREAK as:
“Forget what we were doing and return the communication interface to a known state.”
A double BREAK provides particularly robust recovery because the first BREAK can terminate an operation already in progress and the second can reset the newly receptive interface.
12. BREAK Timing Is More Subtle Than Twelve Ordinary Bits
If both ends already agree on the baud rate, expressing BREAK as a number of bit periods is straightforward.
But what happens if synchronization has been lost completely?
Microchip consequently documents conservative BREAK durations based on UPDI’s internal clock.
Representative documented recovery durations include approximately:
UPDI clock recommended BREAK 16 MHz 6.15 ms 8 MHz 12.30 ms 4 MHz 24.60 ms
For implementations whose default internal UPDI clock is around 4 MHz, approximately:
24.6 ms
is therefore a useful conservative recovery BREAK.
Compare that with twelve bit periods at 225 kbaud:
12 / 225000 ≈ 53.3 µs
Those are very different durations.
This is why our eventual firmware should distinguish between:
ordinary frame-level BREAK
and:
robust unknown-state recovery BREAK
rather than assuming one timing value is universally appropriate.
13. SYNCH
After recovery if required, and before every new UPDI instruction, comes:
0x55
A typical command therefore looks conceptually like:
BREAK // when recovery is needed 0x55 // SYNCH COMMAND OPERANDS
Not every command needs a BREAK.
Every new UPDI instruction does need synchronization.
14. ACK
Some write operations require the target to tell the programmer:
“I accepted that operation and successfully obtained access.”
That response is:
ACK
ACK is especially associated with writes such as ST and STS when synchronization and bus-access conditions require confirmation.
This means our programmer cannot simply throw bytes onto UPDI as fast as its CPU can generate them.
The protocol contains real:
request response turnaround
behavior.
That brings us naturally to the UPDI instruction set.
15. The UPDI Instruction Set
UPDI has a pleasantly small core instruction vocabulary.
The principal instructions are:
LDS STS LD ST LDCS STCS REPEAT KEY
Although eight instruction families may not sound like much, together they provide enough functionality to reach almost everything needed for programming and debugging.
Before worrying about binary opcode encoding, it is useful to understand what each instruction category means conceptually.
16. LDS — Load Direct from Data Space
LDS means approximately:
read data directly from a specified address
Conceptually:
value = memory[address]
Suppose we want to inspect a memory-mapped peripheral register.
LDS address
|
v
target address space
|
v
return byte/word
Because modern AVR peripherals and memories are extensively memory mapped, this apparently simple operation 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 location where access is permitted;
- or another memory-mapped resource.
When programming Flash, however, we generally do not merely issue a generic STS and expect a Flash cell to magically change.
Instead:
UPDI | v NVMCTRL | v Flash operation
The programmer must follow the target family’s NVM-controller procedure.
Again:
UPDI supplies access.
NVMCTRL performs the nonvolatile-memory operation.
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 operate through it.
Conceptually:
pointer = 0x2000 LD pointer pointer++ LD pointer pointer++ LD pointer pointer++
That becomes much more efficient when transferring sequential blocks of memory.
19. REPEAT — Efficient Block Transfers
The REPEAT instruction tells UPDI to repeat a following operation multiple times.
Combined with pointer-based LD/ST access:
set pointer = buffer_start REPEAT count ST pointer++, data
can transfer a sequential block with much less protocol overhead.
The exact count semantics and supported transfer widths must be implemented according to the relevant UPDI documentation.
The architectural purpose is straightforward:
REPEAT makes sequential memory transfers efficient.
That becomes very important when programming Flash or reading blocks of data.
20. LDCS and STCS — UPDI’s Own Control Registers
UPDI contains its own internal control/status register space.
This is distinct from ordinary target memory.
LDCS means:
Load Control/Status
and STCS means:
Store Control/Status
These registers contain information associated with such things as:
- UPDI status;
- control configuration;
- reset requests;
- error state;
- system/interface status.
An excellent early milestone for our Arduino programmer is therefore:
generate BREAK send SYNCH issue LDCS receive a known value
If that works reliably, then we know that:
- the electrical connection works;
- TX works;
- RX works;
- timing works;
- inversion handling works;
- parity works;
- stop bits work;
- SYNCH works;
- and target-to-programmer communication works.
That is a much better first experiment than immediately attempting chip erase.
21. KEY — Opening Protected Doors
The KEY instruction is particularly interesting.
Some sensitive UPDI operations are not enabled merely because the programmer has electrical access.
UPDI uses specific keys to activate protected functions.
These include operations associated with:
- NVM programming;
- chip erase;
- USERROW access on applicable devices;
- and other protected modes.
This is not encryption.
It is better thought of as a protocol-level authorization or intent mechanism.
Conceptually the target requires the programmer to say:
“I deliberately request access to this protected subsystem.”
before the operation becomes available.
KEY becomes especially important when we discuss high-voltage activation.
22. UPDI and the AVR Memory Map
One of UPDI’s most powerful architectural characteristics is its ability to reach the AVR address space.
Applicable UPDI debugging capabilities include access to:
NVM RAM I/O space
This means the same fundamental communication mechanism participates in both programming and debugging.
For programming:
UPDI | +--> NVMCTRL | +--> Flash | +--> EEPROM | +--> fuses
For debugging:
UPDI | +--> SRAM | +--> peripheral registers | +--> OCD resources | +--> CPU state
Applicable devices also provide OCD capabilities involving:
- program flow control;
- PC/SP/SREG observation;
- breakpoint handling;
- register access;
- runtime monitoring.
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 is permitted to see.
If a locked device allowed unrestricted reads of program memory, its protection mechanism would be meaningless.
On applicable locked AVR devices, ordinary UPDI access to protected system resources is restricted.
UPDI itself may remain capable of communicating with:
its own control/status areas + the asynchronous system interface
so that the programmer can determine target state and perform permitted recovery operations.
Conceptually:
UNLOCKED: UPDI ---> system bus ---> memory/peripherals LOCKED: UPDI -X-> protected system bus | +-----> permitted UPDI/ASI functions
This distinction is important when troubleshooting.
A programmer that communicates correctly with UPDI but cannot read protected Flash may be operating exactly as intended.
The target may simply be locked.
24. The Often-Misunderstood “High Voltage” in UPDI
Now we reach one of the most frequently misunderstood topics.
You will often hear:
“UPDI uses 12-volt programming.”
That statement is badly incomplete.
In UPDI, the high-voltage pulse is generally not the voltage used to physically program Flash memory.
Instead, high voltage is an:
interface activation mechanism.
Conceptually:
HV activation
|
v
+------------------+
| Make UPDI |
| accessible |
+------------------+
|
v
normal UPDI
|
v
ordinary NVM control
Once UPDI has been activated, normal digital UPDI signaling performs the communications.
High voltage does not become a Flash programming supply.
25. Why Is High-Voltage Activation Needed?
Some AVR packages have very few pins.
Dedicating one pin permanently to programming reduces the number available to the application.
Some AVR families therefore allow a shared pin to function as:
UPDI RESET GPIO
depending on configuration.
That is useful.
But it introduces an obvious problem.
Suppose the application configuration assigns that pin to GPIO.
How can the programmer recover UPDI access?
High-voltage activation provides a special override mechanism.
Conceptually:
configured GPIO/RESET
|
| special HV sequence
v
temporary UPDI access
The exact mechanism depends on the AVR family.
26. Not Every UPDI Device Needs the Same High Voltage
This is one of the most important rules in the entire article.
There are several relevant physical arrangements.
Arrangement 1 — Shared UPDI/RESET/GPIO
This arrangement appears on a number of small devices.
Recovering UPDI access may require approximately:
12 V
on the shared UPDI pin according to the target’s documented activation sequence.
Arrangement 2 — Dedicated UPDI
Other devices provide a dedicated UPDI pin.
If UPDI remains dedicated and physically available, the same high-voltage recovery mechanism is generally unnecessary.
Arrangement 3 — UPDI/GPIO with Separate RESET
Some newer AVR families provide UPDI/GPIO functionality together with a separate RESET pin.
In these devices, high-voltage activation may instead be applied to:
RESET
at a target-specific voltage.
Representative documented values for this class include approximately:
minimum: VDD + 2 V typical: 7.5 V maximum: 8.5 V
subject always to the exact target’s electrical specifications and absolute maximum ratings.
This produces one of our strongest design rules:
Never assume that “UPDI HV” always means 12 V.
The voltage, destination pin, and timing depend on the target device.
27. What High Voltages Should Our Programmer Support?
Because our educational programmer uses an external bench supply, it can remain unusually flexible.
We will conceptually distinguish at least two high-voltage classes.
HV12
Approximately:
12 V
for applicable older shared-pin UPDI activation.
HVLOW / RESET-HV
Target-specific lower-voltage activation, commonly around:
VDD + 2 V
on applicable newer devices.
Before applying either one, the programmer should eventually know:
target identity target VDD HV activation class HV destination pin allowed HV range required pulse timing
A mature programmer should obtain this information from a device database.
For our educational system, HV selection remains deliberately explicit.
The bench supply is set manually.
The programmer measures the HV rail.
A physical route/arm jumper determines where the switched HV is sent.
This is safer than assuming that one high-voltage mode applies universally.
28. Never Apply 12 V Blindly to “A UPDI Pin”
A programmer capable of producing 12 V is also capable of damaging hardware.
Anything electrically connected to a shared UPDI/HV node must either:
tolerate the activation voltage
or:
be isolated from it
Imagine:
+---------- target AVR
|
12 V pulse ----------+---------- logic buffer
|
+---------- LED
|
+---------- sensor IC
If those branches are not designed for 12 V, HV recovery may damage them.
This is why production hardware may use:
- isolation;
- series resistance;
- transistor interfaces;
- removable jumpers;
- dedicated programming pads;
- carefully designed buffers.
Our finalized Nano programmer specifically avoids connecting the Nano GPIO pins directly to the target UPDI conductor.
The target-side UPDI line instead reaches:
TX transistor collector RX transistor through a resistor
while the Nano sees only its own 5 V logic domain.
Consequently an intentional older-style 12 V UPDI activation pulse does not appear directly on D5 or D6.
The optional external UPDI pull-up is also isolated from VTARGET through a series diode and is DNP by default.
That provides considerably better protection than a bare Nano GPIO connected through only a series resistor.
29. HV Activation Is a Pulse, Not a Programming Supply
High voltage is temporary.
Older shared-pin UPDI activation sequences use a pulse-like operation rather than continuous 12 V Flash programming.
A representative documented sequence uses a pulse on the order of:
100 µs to 1 ms
before the programming driver returns to a non-driving state.
Newer lower-voltage mechanisms have their own timing specifications.
Some document minimum HV durations around:
10 µs
with practical activation sequences recommending longer pulses.
Therefore our firmware will represent HV as:
target-specific operation
rather than:
digitalWrite(HV, HIGH); delay(arbitrary_value);
with one universal delay.
30. The Approximately 65 Millisecond Window
High-voltage activation includes another useful safety mechanism.
An electrostatic-discharge event can produce a voltage transient far above the normal supply.
Without further confirmation, such an event could accidentally resemble an HV activation pulse.
Applicable UPDI implementations therefore require a valid activation key shortly after the HV event.
A representative documented interval is approximately:
65 ms
Conceptually:
HV pulse
|
v
time ---------------+----------------------------------->
|<--------- ~65 ms --------->|
|
+---- establish UPDI
|
+---- send valid KEY
|
+---- continue required sequence
If the required key is not supplied within the permitted interval, the target can treat the event as invalid or accidental.
That is considerably more sophisticated than:
“Apply 12 V and the chip enters programming mode.”
31. HV Activation Can Be Temporary
High-voltage activation does not necessarily rewrite the configuration that made normal UPDI unavailable.
It may temporarily override the configured pin behavior.
Depending on the device implementation, the original function can return after events such as:
power-on reset programming exit other reset/state transitions
Therefore HV activation may restore temporary access without permanently sacrificing the application’s configured pin function.
If permanent ordinary UPDI availability is desired afterward, the relevant configuration may need to be changed deliberately.
32. The Special Problem of a UPDI Pin Configured as an Output
Suppose a shared UPDI/GPIO pin is currently being driven by application firmware as:
GPIO output LOW
and an external programmer suddenly applies:
12 V
to that same node.
The MCU output transistor may be trying to pull the line toward ground while the programmer attempts to raise it toward 12 V.
Possible consequences include:
- excessive current;
- pad stress;
- damaged external circuitry;
- disturbed target power;
- failed activation.
This is why applicable HV recovery procedures may involve RESET or target power sequencing.
The application should not be allowed to establish an opposing output state before the activation pulse is applied.
33. Safe Power-Toggle HV Entry
A safer shared-pin recovery strategy is conceptually:
1. Remove target power.
2. Ensure the programmer's target driver is released.
3. Restore target power.
4. Detect that VDD has risen.
5. Before application firmware actively drives the shared pin:
apply the correct HV activation pulse.
6. Remove HV.
7. Establish ordinary UPDI communication.
8. Send the required key within the allowed interval.
Target power control is therefore useful for more than convenience.
It can become part of safe and repeatable HV recovery.
Our finalized hardware reserves:
Nano D8 = TARGET_POWER_ENABLE
and includes an optional relay-controlled target-power stage.
The first experiments do not require that section to be populated, but the hardware and firmware architecture already reserve the capability.
That means automatic power-cycle recovery can be added without changing the Nano pin assignments later.
34. Why We Use an External Bench Supply for HV
Generating 12 V onboard would be entirely practical.
Possible circuits include:
- boost converter;
- charge pump;
- flyback converter;
- dedicated programming-voltage generator.
But that would obscure the subject.
Our purpose is to understand UPDI.
Therefore our experimental programmer uses:
bench supply
|
v
HV switching circuit
|
v
target activation node
The Arduino controls only:
when
and:
where
the external voltage is applied.
It does not generate that voltage itself.
This provides several advantages.
First:
different target families can use different HV settings
Second:
voltage and current are directly observable
Third:
we avoid adding a switching-converter project
Fourth:
a current-limited bench supply adds another layer of experimental protection
The final hardware also measures the external HV rail using Nano A1.
35. The Arduino Must Never See the HV Rail Directly
A safe conceptual arrangement looks like this:
CURRENT-LIMITED BENCH SUPPLY
|
HV INPUT
|
+------------------+
| HIGH-SIDE SWITCH |
+------------------+
|
series resistor
|
HV ROUTE / ARM
/ \
/ \
RESET-HV HV_OUT
The Nano controls that stage only through:
D7 = HV_ENABLE
A low-voltage NPN/PNP transistor arrangement isolates the Nano control signal from the high-voltage source.
The hardware defaults to HV OFF.
In addition, the normal UPDI data connection is also translated.
The Nano does not directly touch the target UPDI voltage:
TARGET DOMAIN
TARGET UPDI
|
+---------------+---------------+
| |
open-collector TX RX translator
| |
| |
Nano D6 -------+ +------- Nano D5
UPDI_TX UPDI_RX
NANO DOMAIN
This means the same target conductor can operate at:
lower target logic voltages normal 5 V logic
and, on applicable older devices, tolerate an intentional:
approximately 12 V UPDI activation pulse
without applying that voltage directly to the Nano GPIO pins.
The high-voltage output is also not permanently wired to RESET.
A physical route/arm selector allows the switched HV source to be directed appropriately for the target family or disconnected entirely.
That is deliberate.
Different UPDI generations use different activation destinations.
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 that an ATmega328P-class Arduino can successfully implement UPDI timing and communication.
Its traditional implementation commonly uses:
Arduino D6 / PD6
as a single bidirectional UPDI GPIO.
Our final article hardware deliberately departs from that electrical arrangement.
We retain D6 as the transmit-control pin:
D6 = UPDI_TX
but add:
D5 = UPDI_RX
for a separately translated receive path.
Two small-signal NPN transistors combine those internal signals into the target’s single physical UPDI conductor.
This gives us:
- voltage translation;
- easier RX/TX handling;
- better isolation;
- and much better protection from an older 12 V-on-UPDI activation event.
The basic software timing ideas remain very similar.
37. Our Final Nano UPDI Interface
A minimal same-voltage experiment can indeed be built as:
Nano D6 ---- 4.7 kΩ ---- target UPDI
That remains a useful teaching example because it explains why extremely simple Arduino UPDI programmers can work.
Our final reference hardware is intentionally more capable.
Transmit path
The transmitter uses an NPN transistor as an open-collector pull-down.
Conceptually:
Nano D6 / UPDI_TX
|
47 kΩ
|
base
QTX
2N3904
|
collector
|
+---------------- TARGET UPDI
|
emitter
|
GND
A base-emitter pull-down keeps QTX off while the Nano pin is floating during reset.
When D6 activates QTX:
TARGET UPDI → LOW
When D6 turns QTX off:
TARGET UPDI → released
The Nano never drives the target HIGH.
This is important.
The target’s own voltage domain determines the HIGH level.
Receive path
The receiver uses another NPN transistor.
Conceptually:
TARGET UPDI
|
47 kΩ
|
base
QRX
2N3904
|
emitter
|
GND
QRX collector
|
+---------------- Nano D5 / UPDI_RX
|
47 kΩ
|
+5 V
When target UPDI is HIGH:
QRX turns ON
and Nano D5 becomes:
LOW
When target UPDI is LOW:
QRX turns OFF
and D5 is pulled:
HIGH
The receiver is therefore electrically inverted.
Transmit is also logically inverted
For the TX transistor:
Nano D6 HIGH
|
v
QTX ON
|
v
target UPDI LOW
while:
Nano D6 LOW
|
v
QTX OFF
|
v
target UPDI released HIGH
Firmware therefore hides the transistor polarity behind logical physical-layer operations such as:
driveLow() releaseLine() readLine()
rather than allowing transistor polarity to leak into the rest of the protocol code.
Optional UPDI pull-up assistance
The target normally supplies the UPDI idle-HIGH behavior.
Our schematic nevertheless includes an optional external pull-up branch:
VTARGET | Schottky diode | 33 kΩ DNP | TARGET UPDI
The resistor is:
DNP — Do Not Populate by default.
It exists only as a tuning option.
If oscilloscope testing shows that a particular target/cable/baud combination benefits from stronger pull-up assistance, the resistor can be fitted.
The series diode allows the branch to source current from VTARGET during normal operation while greatly reducing reverse current from an intentional 12 V UPDI activation pulse back into VTARGET.
The final schematic therefore does not assume that the auxiliary pull-up is required.
Testing will decide that.
Voltage range
The transistor interface is intended to make the programmer usable over a much wider target-voltage range than a bare 5 V Nano GPIO.
We will specifically test it at representative target supplies including:
1.8 V 3.3 V 5.0 V
and at several UPDI communication speeds.
Until those tests are complete, we should describe this as:
designed for low-voltage target support
rather than claiming guaranteed operation at every voltage and baud-rate combination.
That is the difference between design intent and qualification.
38. Final Nano Pin Assignment
The finalized programmer assigns:
| Nano pin | Function |
|---|---|
| D2 | Activity indication |
| D3 | HV/status indication |
| D4 | TARGET_RESET_CTRL |
| D5 | UPDI_RX |
| D6 | UPDI_TX |
| D7 | HV_ENABLE |
| D8 | TARGET_POWER_ENABLE |
| A0 | VTARGET_SENSE |
| A1 | HV_SENSE |
Additional pins are available for optional:
SPI expansion I²C expansion
The important UPDI point is:
D6 = transmit D5 = receive
inside the programmer.
At the target connector those two signals become:
one UPDI conductor.
39. The Programmer Has Two Serial Links
Our Nano programmer participates in two completely different serial conversations.
The first is:
PC <---- USB serial ----> Arduino Nano
The second is:
Arduino Nano
|
D6 TX / D5 RX
|
UPDI translator
|
single-wire UPDI
|
target AVR
They are not the same protocol.
The PC-to-Nano link might use:
115200 baud 8N1
or another convenient host rate.
The target link might use:
UPDI bit timing 8E2 SYNCH BREAK ACK half-duplex transaction rules
Graphically:
+------------+
| PC |
| |
| host tool |
+-----+------+
|
| USB serial
| HOST PROTOCOL
|
+-----v------+
| Arduino |
| Nano |
| |
| D6 TX |
| D5 RX |
+-----+------+
|
| transistor translation
|
| one-wire UPDI
|
+-----v------+
| Target AVR |
+------------+
This distinction is essential.
40. Our Programmer Firmware Should Be Layered the Same Way
Rather than writing one enormous Arduino sketch, we 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 | +-- voltage_sense.h +-- voltage_sense.cpp | +-- hv_control.h +-- hv_control.cpp | +-- host_protocol.h +-- host_protocol.cpp | +-- tests/
Conceptually:
updi_phy
|
+-- drive target UPDI LOW through TX transistor
+-- release target UPDI
+-- read inverted RX state
+-- send bit
+-- receive bit
+-- send byte 8E2
+-- receive byte 8E2
+-- BREAK
updi_link
|
+-- SYNCH
+-- ACK
+-- recovery
+-- transaction timing
+-- turnaround
updi_commands
|
+-- LDS
+-- STS
+-- LD
+-- ST
+-- LDCS
+-- STCS
+-- REPEAT
+-- KEY
updi_nvm
|
+-- enter programming mode
+-- chip erase
+-- Flash erase
+-- Flash write
+-- EEPROM
+-- fuses
voltage_sense
|
+-- VTARGET
+-- HV input/output validation
hv_control
|
+-- HV switching
+-- routing
+-- timing
+-- safety interlocks
host_protocol
|
+-- PC/Nano communication
The new two-pin translator means the physical layer no longer has to repeatedly change one GPIO between:
INPUT
and:
OUTPUT
states.
Instead, transmit and receive hardware remain available independently.
The target line itself is still half-duplex.
That simplifies implementation without changing UPDI semantics.
41. Our First Development Milestones
We will not begin by attempting to upload a Blink sketch.
The project will progress in controlled stages.
Milestone 1
Nano generates accurate UPDI 8E2 timing.
Milestone 2
TX transistor produces the expected target-side waveform.
Milestone 3
RX transistor reliably returns the target line state.
Milestone 4
Nano generates robust BREAK.
Milestone 5
Nano sends SYNCH successfully.
Milestone 6
Nano reads a UPDI control/status register.
Milestone 7
Nano reads target identification/signature.
Milestone 8
Nano enters NVM programming mode.
Milestone 9
Nano reads Flash.
Milestone 10
Nano performs chip erase.
Milestone 11
Nano writes and verifies Flash.
Milestone 12
Nano reads/writes EEPROM.
Milestone 13
Fuse support with safeguards.
Milestone 14
VTARGET and HV measurement qualification.
Milestone 15
External-HV recovery.
Milestone 16
Host-side programming utility integration.
Milestone 17
Explore OCD/debug support.
Every destructive feature comes after read-only communications have been demonstrated.
That is safer and substantially 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
Applicable devices provide capabilities including:
- memory-mapped access to NVM, RAM, and I/O;
- program run/stop/reset control;
- hardware breakpoints;
- software/user-program breakpoints;
- PC observation;
- stack-pointer observation;
- status-register observation;
- register access;
- nonintrusive runtime monitoring features.
So conceptually:
single target UPDI wire
|
v
UPDI
|
+-------- NVM programming
|
+-------- memory access
|
+-------- 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 involves at least two major tasks:
communicate with the target's OCD machinery and present that functionality to a host debugger/IDE
We will therefore build programming first.
Only after the electrical 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 surprisingly understandable.
Electrically
At the target:
one bidirectional UPDI signal common ground optional VTARGET reference/power optional RESET
Our programmer internally implements that one bidirectional signal using:
separate TX and RX transistor paths
for level translation and protection.
That is an implementation detail of the programmer.
It does not change UPDI itself.
At the serial/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 interface-activation mechanism required by certain target pin arrangements.
Most importantly:
12 V is not universal.
Older shared-pin arrangements may use the 12 V class.
Dedicated-UPDI devices ordinarily do not require HV simply to make UPDI physically available.
Some newer devices use a lower target-specific activation voltage, frequently around:
VDD + 2 V
on a separate RESET pin.
Always consult the exact target documentation before applying high voltage.
44. Where We Go Next
In Part II we move from theory to actual hardware and firmware.
We will build the Arduino Nano UPDI interface from the ground up and examine:
- the complete Nano reference schematic;
- the four-pin target connector;
- why UPDI remains one external wire even though our programmer internally uses two GPIOs;
D6 = UPDI_TX;D5 = UPDI_RX;- the two-transistor level translator;
- open-collector target transmission;
- inverted receive logic;
- target-voltage translation;
- the optional DNP target-side pull-up;
- the Schottky isolation used with that optional pull-up;
- tolerance of the older 12 V-on-UPDI activation case;
A0 = VTARGET_SENSE;A1 = HV_SENSE;- the target-voltage ADC divider and input protection;
- the HV divider and its approximately 18 V comfortable measurement range;
D4 = TARGET_RESET_CTRL;D7 = HV_ENABLE;D8 = TARGET_POWER_ENABLE;- physical HV route/arm selection;
- why naïve level shifting can interfere with UPDI;
- waveform and rise-time testing;
- target operation at representative 1.8 V, 3.3 V, and 5 V supplies;
- UPDI timing;
- implementing 8E2 in software;
- generating even parity;
- generating BREAK correctly;
- sending
0x55SYNCH; - receiving target responses;
- turnaround timing;
- detecting parity and framing errors;
- implementing LDCS;
- implementing STCS;
- implementing LDS;
- implementing STS;
- implementing LD and ST;
- implementing REPEAT;
- implementing KEY;
- reading the System Information Block;
- obtaining target identification;
- building a simple host command console;
- and validating each layer before destructive programming is allowed.
Part III then builds the actual programmer:
- programming-mode entry;
- NVM keys;
- NVM-controller generations;
- Flash reads;
- chip erase;
- page erase/write;
- verification;
- EEPROM;
- fuses;
- USERROW;
- lock handling;
- recovery;
- Intel HEX;
- and the Python host utility.
Part IV covers high-voltage recovery in detail:
- old 12 V-class activation;
- newer RESET-HV activation;
- externally supplied bench HV;
- transistor switching;
- HV measurement;
- physical route/arm control;
- target power sequencing;
- pulse timing;
- the key-acceptance window;
- output-pin contention;
- device-family safety rules;
- and actual recovery procedures.
Part V examines UPDI debugging:
- OCD architecture;
- entering debug mode;
- halt and run control;
- reset;
- single stepping;
- PC/SP/SREG access;
- CPU register inspection;
- SRAM and peripheral inspection;
- hardware breakpoints;
- software breakpoints;
- GDB Remote Serial Protocol;
- the division of responsibility between Nano and PC;
- and the parts of the low-level OCD interface that require experimental or community-derived knowledge.
Finally, Part VI integrates the whole project into a practical reference:
- final system architecture;
- reference wiring;
- programmer operation;
- high-voltage operation;
- debugging workflow;
- automated testing;
- failure diagnosis;
- oscilloscope and analyzer procedures;
- host-software architecture;
- Git/test strategy;
- engineering notes;
- and a curated resource directory.
By that point we will not merely know how to use UPDI.