\chapter{The Hardware of the AVR 8-bit micro controllers}

\section{CPU and memory access}
You can find any thing at the chip of a AVR 8-bit micro-controller,
what is needed to run a digital computer.
You find a clock generator, registers, data storage (RAM), program storage (flash),
input registers and output registers.
The content of registers and data storage is loosed with every restart.
The content of the instruction memory (flash) and the often available additional
nonvolatile data storage (EEprom) is preserved for long time.
The figure~\ref{fig:block} shows a simplified block diagram of a
8-bit AVR micro-controller.

\begin{figure}[H]
\centering
\includegraphics[]{../FIG/avr_block.eps}
\caption{Simplified block diagram of a AVR mikrocontroller}
\label{fig:block}
\end{figure}

You can see at the diagram, that the CPU (Central Processor Unit) can
access easy the resisters R0-R31 and the RAM memory.
Also the access to the input and output resisters is easy possible.
But the access to the instruction memory (flash) is only possible
with a special controller and more complex.

Only the instruction engine can easy access the flash data for
the selected program address.
With the Load Immediate (LDI) instruction you can transfer parts of 
the instruction word to the upper registers (R16-R31).
Also with the instructions ADIW, ANDI, CPI, ORI, SBCI, SBIW and SUBI 
parts of the 16-bit instruction word are processed.

Usually after every instruction the program counter will be
increased by one word or two words, depending on the instruction length.
A exception to this rule for the normal operation is only
caused by the conditional or unconditional jump instructions
(RJMP, JMP, IJMP, RCALL, CALL, ICALL, RET, RETI).

Also a reset event or interrupt event can be the reason for
a discontinuity of the program counter increase.
A Reset will reset the whole processor and the program counter
will be set to a previous selected address.
A interrupt will set the program counter to a associated address.
Normally the start address for the reset event is set to 0.
For starting the boot-loader many AVR processors have special
configuration bits is fuses to select a different start address.

A random address to the instructing memory content is only possible
with the flash-controller.
For that access you must tell the controller the requested  byte address.
Afterward the requested byte can be read with a special instruction.

More complex is a write operation to the flash memory.
The write access is only possible for a total page of flash.
The flash page must be erased before any write access and
you must load load the total page data to the controller buffer storage
before you can select the write operation.
You can compare this method with printing a page with a stamp.
The stamp can be configured with replaceable letters before the next print.
So you can print any text.
But you need a empty sheet of paper and you must configure the whole
text for the page.
Only if all is prepared right, you can stamp a page.

Also the access to the nonvolatile data memory (EEprom) is only possible
with the special controller. The writing to the EEprom is more
simple compared to the flash memory access, but you need the
controller access too.
You can not use the EEprom and flash memory access together,
because some common parts of the controller is used.

\section{Input and Output function}

The CPU can access the external pins with IO-registers.
The IO-register are organized with Byte access, so that you
can select up to 8~pins with one IO register.
The figure~\ref{fig:port} shows the structure of a port pin circuit.

\begin{figure}[H]
\centering
\includegraphics[]{../FIG/port.eps}
\caption{Simplified circuit of every AVR Port pin}
\label{fig:port}
\end{figure}

Every pin is associated with one port bit and can be used as output pin (PORT)
or as input pin (PIN).
The 8~bits of the Data~Direction~Register (DDR) are used to select the mode of every port bit.
For every pin you will find a associated bit number in three different registers.
The DDR register is used to select the direction of the associated bits.
The PIN register shows the voltage level of the associated bits.
If the voltage is below the half operating voltage, the PIN bit is switched to 0 and
above the half operating voltage the PIN bit is switched to 1.
If the associated bit in the DDR register is set to 1,
the associated bit in the PORT register select the level of the output signal.
A 0 select a voltage level near to GND and a 1 select a voltage level near to the
operating voltage (VCC).
If the output mode for one bit is deselected with a 0 in the DDR register, a setting
of the corresponding bit in the PORT register enables a Pull-Up resistor.
But if the PUD bit in the MPU configuration register MCUPR is set,
all Pull-Up registers are deactivated.
All associated registers and bits of a group (8-bit) use always the
same code letter. For the second group this letter is a B.
The output port of this group has the name PORTB, the input port can
be accessed with the name PINB and the register for the data direction
has the name DDRB.
For the identification of a single bit a number between 0 and 7 will be appended.
For example the bit 0 of the input port B would be named PINB0.
This terminology is used in the Atmel documentation and is used also with
program languages.

\section{The start of AVR micro-controllers}

With the factory set configuration of the AVR micro-controller a first
pass over of the minimal operating voltage will cause a reset
of the processor.
All IO-register are set to predefined values and after waiting some
time to stabilize the operating voltage the instruction unit is
started with the flash address 0.
Normally all pins are set to input mode.
Beside this reason for a reset event there exist three other reasons for a reset of
the processor.
The reason for the reset event is saved in the MCU status register (MCUSR) with
four bits.

\begin{table}[H]
  \begin{center}
    \begin{tabular}{| c | c |}
    \hline
              Name of Flag & Reason for the Reset \\
    \hline
    \hline
              PORF & Power-on Reset \\
                   & This Reset is caused by switching on the operating voltage.\\
                   & This reason can not be deactivated.\\
    \hline
              BORF & Brown-out Reset \\
                   & This reason can only occur, if the function \\
                   & is selected with the BODLEVEL bits of a Fuse \\
                   & and no Brown-out Interrupt is selected.\\
    \hline
              EXTRF & External Reset \\
                    & is caused by a 0 level at the Reset Pin, \\
                    & if the fuse  RSTDISBL is not activated. \\
    \hline
              WDRF & Watchdog Reset \\
		   & can only be set, if the corresponding Interrupt \\
		   & is not enabled. \\
    \hline
    \end{tabular}
  \end{center}
  \caption{Different Reset reasons in the MCUSR register}
  \label{tab:resets}
\end{table}

By setting the right configuration bits in the fuses of the AVR micro-controller
you can select another start address as the  usual 0.
The figure~\ref{fig:pages} shows the options for a ATmega168.
This processor has a total instruction memory (flash) capacity of 16384~Byte.
The instruction interpreter of the micro-controller can access a 16-bit
parallel instruction code of the flash memory.
So the largest program counter is only 8190 for optiboot!
It can not be 8192 because the counting begin with 0,
but it is one word less because the last word of the
flash memory is used to hold the version number of optiboot.

\begin{figure}[H]
\centering
\includegraphics[width=12cm]{../FIG/boot_pages.eps}
\caption{The different Start-Options for the ATmega168}
\label{fig:pages}
\end{figure}


The ATmega168 can select a boot-loader size of 256~bytes (BOOTSZ=3),
512~Bytes (BOOTSZ=2), 1024~Bytes (BOOTSZ=1) and 2048~Bytes (BOOTSZ=0).
The application program would like to use as many program space as
possible, so the boot-loader space should be as low as possible.
The boot-loader code is placed at the highest starting address possible.
The activating of Lock-bits of the AVR micro-controller can protect
the boot-loader area against overwrite.
Once activated Lock-bits can only be reset with a total erase of the
AVR memories.

For this processor, also for the Mega48 and Mega88, the control bits
for the boot-loader start are located in the extended fuse (efuse).
This is also true for the BOOTRST fuse, which can be used to switch
the start address from 0 to the boot-loader start.
For most other AVR micro-controller, also for the ATmega328, the same
control bits are located in the high fuse (hfuse).
The table~\ref{tab:bootsz} shows the memory sizes of different
AVR-micro-controllers and additionally the options for the Boot-loader area. 
The boot-loader options are located in the same bit numbers,
whatever fuse is selected, the high or extended fuse.

\begin{table}[H]
  \begin{center}
    \begin{tabular}{| c | c | c | c | c | c | c | c | c | c |}
    \hline
             Processor & Flash & EEprom & RAM & UART & Boot   & \multicolumn{4}{ c| }{BOOTSZ} \\
              Type      & size & size  & size &    & Config & \multicolumn{4}{ c| }{} \\
                       &       &        &     &      & Fuse   &   =3 &   =2 &   =1&   =0 \\
    \hline
    \hline
              ATmega48  & 4K    & 256  & 512  &  1   & Ext.  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATtiny84  & 8K    & 512  & 512  &  -   &  -    &  \multicolumn{4}{ c| }{(N x 64)} \\
    \hline
              ATmega8   & 8K    & 512  & 1K   &  1   & High  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega88  & 8K    & 512  & 1K   &  1   & Ext.  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega16  & 16K   & 512  & 1K   &  1   & High  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega168 & 16K   & 512  & 1K   &  1   & Ext.  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega164 & 16K   & 512  & 1K   &  1   & High  & 256  & 512 & 1K  & 2K  \\
    \hline
              ATmega32  & 32K   & 1K   & 2K   &  1   & High  & 512  & 1K  & 2K  & 4K  \\
    \hline
              ATmega328 & 32K   & 1K   & 2K   &  1   & High  & 512  & 1K  & 2K  & 4K  \\
    \hline
              ATmega324 & 32K   & 1K   & 2K   &  2   & High  & 512  & 1K  & 2K  & 4K  \\
    \hline
              ATmega644 & 64K   & 2K   & 4K   &  2   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
              ATmega640 & 64K   & 4K   & 8K   &  4   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
             ATmega1284 & 128K  & 4K   & 16K  &  2   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
             ATmega1280 & 128K  & 4K   & 8K   &  4   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
             ATmega2560 & 262K  & 4K   & 8K   &  4   & High  & 1K   & 2K  & 4K  & 8K  \\
    \hline
    \end{tabular}
  \end{center}
  \caption{Boot-loader configurations for different micro-controllers}
  \label{tab:bootsz}
\end{table}

By the way the boot-loader will work for the first time,
even if the BOOTRST fuse bit is not activated.
In this case the reset vector is still set to address 0, where
usually the application program is located.
Because for the first time no application program is loaded,
the CPU execute the instructions in the cleared flash memory
until it reach the boot-loader code.
For the ATmega168 this are less than 8000 instructions,
which executes the CPU in less than 1~ms with a 8~MHz clock.
But if any application program was loaded, the Reset will
start the application program, if the BOOTRST bit is not activated (still set).
The boot-loader program can no longer work, because it is
not addressed by the reset.


\section{Writing to the AVR memories}

The AVR micro-controllers know three different nonvolatile memories.
The most important is the instruction memory, the so called Flash memory.

In addition there are some configuration bits, which can be used to
select some features of the processor.
This configuration bits are organized in some bytes, the lfuse (low fuse),
the hfuse (high fuse), the efuse (extended fuse), the lock byte and the calibration byte.
The calibration byte is used to calibrate the frequency of the internal RC oscillator.
The lock byte can be used to restrict the access to the memories.
Once  activated lock bits can not be reset by rewriting the lock byte.
The only way to deactivate the lock bits is a complete clear of all memories.
Note, that the lock function will be activated by clearing the appropriate bits
(write to 0).
With the complete clear of all Memories the lock bits will be set to 1 (full access).
The layout of the configuration bits to the different fuse bytes differ for
the several AVR processor models and should be read in the specific data sheet.
You can select the way of clock generation, the delay of start and a
monitoring of operating voltage with the fuses.

Most AVR micro-controllers are also equipped with a nonvolatile data memory, the EEprom.
This memory type has no special function for the processor.
It is just a way for a application program so save data for the next
program start.


\subsection{Parallel programming}
All three nonvolatile memory types can be written or read with different technique.
Usually the parallel programming method is rare used for writing the nonvolatile memories.
Sometimes this method is the only way to reactivate processors, which can not
accessed with other methods.
For example you can not use the serial programming, if the fuse bit for the
Reset pin usage is deactivated (RSTDISBL=0).
The voltage at the reset pit is raised to higher voltage level (12V) for this parallel
programming method. Therefore this method is also called HV-programming.

\subsection{serial download with ISP}

The normal way to program any non volatile memory is the serial programming.
The Atmel documentation call this method also serial download.
For that way a SPI (Serial Parallel Interface) interface is used.
The SPI interface is build with three signals, MOSI, MISO and SCK.
Additionally the Reset pin of the AVR processor must hold to 0V to force
this special download mode.
Together with two additional power signals GND and VCC (about 2.7 to 5V) this
four signals build a ISP (In System Programming) interface, which is often
integrated at many boards.
The figure~\ref{fig:ISP} shows the layout of two usual plugs, which are
often integrated at boards with AVR micro-controllers.

\begin{figure}[H]
\centering
\includegraphics[width=12cm]{../FIG/ISP.eps}
\caption{Two different types of ISP Plugs}
\label{fig:ISP}
\end{figure}

The 10-pin version of the ISP-plug can additionally support a clock signal OSC
for feed-in a clock signal to the AVR micro-controller.
One of this two plug versions are usually required to program a boot-loader in
the flash memory of a AVR micro-controller. The program data
for the flash memory are usually created with a PC.
To transfer the program data to the AVR micro-controller a ISP programmer
is required, which use often a USB interface to the host computer side.
But the host computer can also use a serial or parallel interface to
connect a ISP programmer.
The USB interface has the advantage, that the power (5V or 3.3V) for
the micro-controller can be taken easy from the interface.
You can choose some types of specific ISP programmers at the electronic market,
the manufactor of the controllers offer the Atmel AVR-ISP MK2 programmer for example.
But you can also use a Arduino UNO or a similar Arduino with
a special program for the connected ISP interface.
I use a DIAMAX ALL-AVR, which is equipped with both plug types
and has some additional features.

\subsection{Self programming with serial interface}

Because the AVR processor can write flash and EEprom memories with special instructions,
you can write a little program to the flash memory with one of the two programming methods,
which receive data from a serial interface and can write this data to
the flash or EEprom memory.
Exactly this is the feature of the boot-loader optiboot.
Setting of fuses or lock bytes is often not possible with this method and
is not supported by the boot-loader.
You must set the fuses and the lock byte with one of the other methods.
The STK500 Communication Protocol from Atmel is used for the serial data transfer.
Because up-to-date computers often has no more any serial interfaces, 
a USB - serial converter like the FTDI chip of Future Technology Devices International Ltd
is used. A module with this chip is for example a UM232R.

The Chips PL2303 from Prolific Technology Inc. and CP2102 from Silicon Laboratories Inc. 
satisfy the same purpose.
Also a suitable programmed ATmega16U2 can be used for the same function.
All of these chips have a selectable Baud-rate and a TTL level for the serial signals.
You have to add level converter to get real RS232 signals.
But the AVR micro-controllers don't need RS232 signal level.
One of these chips is integrated at any Arduino board with USB interface.
For a fast answer the serial interface should also connect the DTR signal of
the converter with a serial 100nF capacitor to the Reset input pin of
the AVR processor. The figure~\ref{fig:UM232} shows a  typical way of connection.

\begin{figure}[H]
\centering
\includegraphics[width=12cm]{../FIG/UM232.eps}
\caption{Connection of a USB-serial converter to the micro-controller}
\label{fig:UM232}
\end{figure}

You should select the right power voltage for the USB - serial converter.
Most modules can select a 3.3V or a 5V signal level with a jumper.
If you have a Arduino UNO with a ATmega328p at a socket, you can remove the
ATmega328p and use the board as USB - serial converter.
So you can transfer program data to another AVR processor with a already
installed boot-loader. If you frequently use this serial interface,
a separate USB - serial interface make sense.

You can select with the Arduino development tool Sketch with the menu entry ''Tools - serial Port''
a detected serial port. Then you can open a monitor window with the menu entry ''Tools - Serial Monitor'',
which can show you the serial output of your AVR micro-controller at the screen.
The Baud rate of the serial interface can be selected at the monitor window.
Both 1~nF capacitors at the RX-inputs removes spikes from the serial signals.
The test of the software UART program was only successfull with a little capacitor
at the RX input of the AVR processor. The probe of a scope was sufficient as ''filter'' for the spikes.
The hardware UART tolerates the spikes without any filter and runs proper
with or without the capacitor. 

The running Serial Monitor of the Arduino Sketch can disturb the program download with the
serial interface, if the same USB - serial module is used for download and the monitor program.
But you can insert a additional USB - serial module to the host computer and connect
only the RX-Signal to the TX-Port of the AVR micro-controller.
This second serial input listen to the output of the AVR without any problems
for the serial communication of the program download, if you select
this second interface with the Serial Monitor tool.

\subsection{Diagnostic Tools}
At the Linux operating system you can install a tool with the strange name jpnevulator, which
can monitor two serial inputs at the same time.
Any received data are shown in a hexadecimal format and with the option -a also as ASCII characters.
With the option --timing-print the system time of the serial data packets are shown.
To prevent any affect to the data communication, you should select two
separate USB - serial modules for this monitoring.
You should connect the serial input (RX) of one module to the TX signal and the 
serial input of the other module to the RX signal of the AVR micro-controller.
Together with the module for the program download there are three USB - serial modules
connected to the PC.
Of course all three modules must be set to the same baud rate (stty ... -F /dev/ttyUSB1).
The full command line with the start of the protocol can be look like:
\begin{verbatim}
jpnevulator -a --timing-print --read --tty "/dev/ttyUSB1" --tty "/dev/ttyUSB2"
2016-05-29 11:05:06.589614: /dev/ttyUSB0
30 20                                           0
2016-05-29 11:05:06.589722: /dev/ttyUSB1
14 10                                           ..
2016-05-29 11:05:06.593593: /dev/ttyUSB0
41 81 20                                        A.
2016-05-29 11:05:06.594581: /dev/ttyUSB1
14 74 10                                        .t.
2016-05-29 11:05:06.597583: /dev/ttyUSB0
41 82 20                                        A.
2016-05-29 11:05:06.598574: /dev/ttyUSB1
14 02 10                                        ...
2016-05-29 11:05:06.601586: /dev/ttyUSB0
42 86 00 00 01 01 01 01 03 FF FF FF FF 00 80 04 B...............
00 00 00 80 00 20                               .....
2016-05-29 11:05:06.603608: /dev/ttyUSB1
14 10                                           ..
2016-05-29 11:05:06.605639: /dev/ttyUSB0
45 05 04 D7 C2 00 20                            E.....
2016-05-29 11:05:06.606576: /dev/ttyUSB1
14 10                                           ..
...
\end{verbatim}
