Created by: gwideman, Mar 25, 2014 10:19 pm
Revised by: gwideman, Apr 7, 2015 9:19 pm (10 revisions)

Overview

This article gathers notes on programming Arduinos and AVR devices via the scheme called "In System Programming", or ISP.
This revolves around programming a target device using its SPI (Serial Peripheral Interface) pins.
(The target device might or might not actually be in a system. Programming while in a system will only be feasible if whatever else is connected to these pins doesn't disrupt the ISP signals from/to the programmer, and doesn't cause any other harmful side effects.)

In-System Programming (ISP)

Common ISP programmers mostly seem to involve the following:
Programming software on host PC/Mac/Linux <--> USB <--> Programmer AVR/Arduino <--> ISP signals <--> Target AVR device.

Required software

To make this work, there are a number of software components:
  • The Programmer AVR/Arduino has to be running an appropriate sketch
  • The host may need a driver to talk to the USB interface on the programmer
  • The host has to be running programming software, which includes configuration settings that will work with this particular combination of programmer hardware and its programming sketch
  • Host programming software communicates with the programmer AVR/Arduinousing some protocol.
    • A common protocol (is it the only one?) is ATMEL's protocol for their programmers, notably AVRISP and STK500. Described here:

ISP signals and standard connector

ISP signals include SPI (Serial Peripheral Interface Bus: MOSI, MISO, Clk), plus Reset, and Ground/Power.
ISP specifies a couple of standard connectors that many target boards offer for programming their AVRs "in system", and are standard on programmers from Atmel and others. The connectors are 0.1"-pitch headers with either 6 pins or 10 pins, the latter adding 4 ground pins. These connectors are not required, but they are convenient.
ISP Signal
Direction
6-pin
10-pin
Comment
GND
n/a
6
3,4,6,8,10

V+targ
From target
2
2
Positive supply voltage FROM TARGET. 1. Implies host doesn't power target via this cable. 2. Intended for target to power output buffer on programmer (or at least communicate the signal voltage preferred.)
SPI MOSI
Programmer to Target
4
1
Data
SPI MISO
Target to programmer
1
9
Data
SPI SCLK
Programmer to Target
3
7
Serial clock, from programmer to target
RESET#
Programmer to Target
5
5
Must be controlled by programmer. Low for programming operation.
XTAL1
Programmer to target
n/a
n/a
Target device may be set to run from its internal clock, or it may already be wired to an external crystal. If these are not available (or the fuses are set to defeat them), then the programmer could supply a clock signal to the target's XTAL1 input. This can rescue some AVRs with mistaken fuse settings. See Adafruit'sStandalone AVR ISP Programmer Shield Kit

Notes

  • SPI signals change direction according to whether a device is a master or slave. Thus master MOSI connects to slave MOSI etc. (MOSI = "Master Out, Slave In"). Some programming setups involves connecting one AVR more or less directly another of the same model, in which case it's conspicuous that the same SPI pins on each device are connected together.
  • A programmer device could implement the SPI part of the interface via general I/O pins (non-SPI-specific ones), using code to create the SPI signals -- so called "bit-bang" interfaces. Also there are rudimentary programmers that use PC parallel or serial port pins to implement (slow) SPI and ISP. There is little motivation to do this nowadays.
  • ATmega docs note that the target AVR's pins used for SPI during programming are not necessarily the same pins that are capable of SPI during normal use. Docs show a table that implies this consistent association instead:
Signal
Pin
MOSI
PB3
MISO
PB4
SCK
PB5

ISP connections to Arduino

Arduinos have one or two ISP connectors, labeled "ICSP". One ICSP is for programming the main ATmega, primarily for installing a bootloader. A second ICSP connector appears on some Arduinos (such as Uno) to program the second AVR that serves as the USB-to-serial device (instead of an FTDI chip).
The wiring for these ICSP sockets on a Uno R3 demonstrates representative ways to program an AVR from another AVR using the ISP method.


ICSP
ATmega16U2

ATmega328

ISP Signal
Direction
6-pin
pin
func

pin
func
Comment
GND
n/a
6






V+targ
From target
2





Allows programmer to use this voltage to drive/receive the SPI signals at appropriate voltages
SPI MOSI
Programmer to Target
4
16
MOSI

17
MOSI

SPI MISO
Target to programmer
1
17
MISO

18
MISO

SPI SCLK
Programmer to Target
3
15
SCLK

19
SCLK

RESET#
Programmer to Target
5
24
Reset#

1
Reset#
16U2: Reset also driven by Diode Resistor from +5V (Power-on reset)
328: Reset also driven by Diode Resistor from +5, and also by Capacitor from 16U2 (for programming main AVR via bootloader. )

ISP Programmer variants

To further understand the variations in features, wiring, and software support, following are some common ISP programmer variants.

From Arduino ISP Tutorial

Link to tutorial
This tutorial on the official Arduino site appears to be the origin of keyword "ArduinoISP".
The tutorial uses one Arduino to program an ATmega168 AVR installed on a breadboard. (ATmega168 and 328 have same pinouts.)
Prog Ard pin
Prog 328 pin
Prog AVR func
Targ 168 pin
(DIP)
Targ Func
Direction
Comment
D10
16
SS/PB2
1
Reset#/PC6


D11
17
MOSI/PB3
17
MOSI/PB3
Programmer to Target

D12
18
MISO/PB4
18
MISO/PB4
Target to programmer

D13
19
SCKL/PB5
19
SCLK/PB5
Programmer to Target

Gnd


8, 22
Gnd


+5V


7, 20?
+5V


Sketch to run on the programmer Arduino: Randall Bohn: mega-isp

Adafruit USBtinyISP AVR Programmer Kit

Product Schematic Tutorial
This programmer uses an ATtiny2313 to interface from USB to ISP, and has 74AHC125 3-state buffers between the the 2313's SPI I/O and the SPI connectors. This allows the programmer to run on 5V from the USB cable, but allow the target to supply 3.3V or 5V to the buffers so that the programmer will work with a target that runs at 3.3V or 5V.
ATtiny pin
ATtiny func
Signal
Direction
6-pin
10-pin
Comment


GND
n/a
6
3,4,6,8,10



V+targ
n/a
2
2

17
MOSI
SPI MOSI
Programmer to Target
4
1

18
MISO
SPI MISO
Target to programmer
1
9

19
SCLK
SPI SCLK
Programmer to Target
3
7

16
PB4
RESET#
Programmer to Target
5
5

8
PD4
BUFFEN (Bar?)
Internal



12
PB0
LED1
Red, programming



9
PD5
LED2
Green, USB good



  • Windows USBtinyISP driver, using libusb
    • But some confusion which driver to use for Win64.
  • Sketch for the programmer AVR: Download from Adafruit via the tutorial or product page
  • Programming software: avrdude, AVRStudio, WinAVR?
Notes:
  1. Evidently, the USBtinyISP can't support AVRs with more than 128k of flash memory According to this article, for larger amounts of memory, a different protocol is required, which USBtinyISP and similar don't understand.
  2. Looks to me like 2313-based programmers use a USB library that only runs USB in one of the slow modes. This may or may not be a limitation, but seems funky.

Adafruit Standalone AVR ISP Programmer Shield Kit

Product
Uses Protoshield: Tutorial Product Schematic
Prog Ard pin
Prog 328 pin
Prog AVR func
Targ 328 pin
Targ Func
Direction
Comment
D9
15
OC1/PB1
9
XTAL1
Prog to Targ
PWM output can create clock for Target if needed
D10
16
SS/PB2
1
Reset#


D11
17
MOSI
17
MOSI
Programmer to Target

D12
18
MISO
18
MISO
Target to programmer

D13
19
SCKL
19
SCLK
Programmer to Target

D8
Red LED1




"Error"
A0
Green LED2




"Programming"
A3
Piezo beeper




"Problem"
Gnd


Gnd



+5V


+5V



Note: The Protoshield also has pads for an ICSP header. The Protoshield PCB connects this to headers such that this ICSP socket parallels the ICSP socket for the host Arduino. In the Protoshield's normal use, this allows ISP-reprogramming the host Arduino without removing the Protoshield.
I think this kit is intended to be used in two different ways:
  • "ArduinoISP" mode: Host controls burning a bootloader (or really any code) to an AVR.
  • "Stand-alone programmer": Uses revised Optiboot code: Host loads code onto the programmer Arduino, which can then autonomously program any number of target AVRs.
See also my forum thread regarding this kit.

Instructables How to program an AVR with another Arduino

Article
Prog Ard pin
Prog 328 pin
Prog 328 Func
Targ 328 pin
Targ Func
Comment
D7
13
PD7

Green LED
Prog
D8
14
PB0

Red LED
Err
D9
15
OC1/PB1

Blue LED
HB = Heartbeat
D10
16
SS/PB2
1
Reset#

D11
17
MOSI
17
MOSI

D12
18
MISO
18
MISO

D13
19
SCKL
19
SCLK

Gnd


Gnd


+5V


+5V


Sketch for the programmer Arduino: Randall Bohn's: mega-isp

Other ISP programmers

Just noting them here:
  • Atmel AVRISP mkII: $38? 1.8V to 5V. Presumably fast?
  • Pololu USB AVR Programmer: $20. 5V only -- probably could be adapted to 3.3V by adding a circuit like Adafruit's. Claims to be able to program <128k AVRs. Also includes serial as well, so may be usable for bootloader-based programming also. See other page on Bootloader-facilitated programming.
  • Sparkfun USB SPI programmers:
    • Pocket AVR Programmer $15 10-pin + 6 pin cable. ATtiny2313 based. Programmer itself runs on 3.3V. Buffered with 74AC125, like Adafruit's, but comments claim the result isn't 3.3V safe. Comments suggest this product or its software are a mess.
    • SPI Shortcut $25 Just a USB to SPI interface, not particularly ISP.
    • Tiny AVR Programmer $20 Specifically for 8-pin ATtinies -- has 8-pin socket, no ISP cable
    • STK500 Compatible USB Programmer $48 Not clear the point of this, since it's more expensive than Atmel's official AVRISP.