Serial Flash and SPI
Most Embedded systems need non-volatile memory. Non-Volatile memory is used
to save software program, user configuration settings etc.
Non-Volatile: data is preserved even without power supply.
Flash Memory is enhanced version of EEPROM
(Electrically erasable and programmable Read only memeory).
Flash Memories consume less power with currents as low as microamps in standby and millamps
in active modes.
Types of EEPROMS
There are two types of Flash memories available based on the layout and interfacing.
NOR flash (Parallel EEPROM) and NAND flash (Serial EEPROM).
As the names suggest NOR flash is accessed with a parallel interface and
NAND is accessed over a serial interface.
Hence Serial flash would have simpler hardware when compared to their counterparts in
Parallel flash. At the same, the overall performance would be slower than that of the Parallel flash, considering
that only one bit is transferred at a time. But, the writes are generally faster to the serial flash
than the parallel flash.
Interfacing EEPROMS
Parallel flash in the system, would be referenced
as additional memory. In other words, in a microcontroller, the processor would treat it
as its own memory space. Using C, the location in the parallel flash could be accessed by
pointers.
Serial flash cannot be accessed in the same way.
In order to access serial flash, they must be interfaced to the chip (microcontroller)
in a specific fashion.
There are different technologies used to interface a serial EEPROM.
Serial EEPROM
Synchronous Communications:
Serial EEPROM works on synchronous interface. That means both the chip (communicating
with the serial EEPROM) and the serial EEPROM use a common clock. The clock is usually
defined by the master (chip).
Voltage and Capacity
Serial Flashes are available in different ranges of voltages and capacity. For smaller capacity (256K) of Flashes,
the flash is divided into integral multiple of blocks. As the capacity increases (for medium and large flashes of
more than 1M capability), the flash memory would be quantified into different ranges,
Bytes, Pages and Sectors. Each page would consist so many (for example
256, 512) bytes.
Interfacing Serial EEPROM
The following are
three of those types (of my knowledge). Microwire, SPI (Serial Peripheral interface) and
I2C (called I square C). The following describes the SPI. For more information on
interfacing serial flash with the other technologies refer to the following article by
Jan Axelson published in Circuit Cellar. http://www.lvr.com/files/seeprom.pdf.
SPI
Introduction
SPI (Serial Peripheral Interface) is the full-duplex, synchronous serial data mechanism
that is used to communicate among different chips on IC.
SPI follows Master-Slave concept. During a data transfer, the system that controls
the data flow would act as Master and the other one called the Slave.
Signals
SPI works on four signals. Two signals for read and write, a clock signal and a chip select
signal. The names of these signals differ for master and slave.
MOSI (Master out slave in) on Master is connected to SI(Serial In) on slave
MISO (Master In Slave Out) on Master is connected to SO (Serial Out) on slave
SCLK (Master clock) is connected to the slave clock.
CS(Chip select on the master) can contain upto 4 slaves. 4 SPI slaves could be connected
over the Chip select signal.
Clock
Depending on Clock Polarity and clock phase for receiving and transmiting data, SPI operates in
four modes. SPI mode 0 to 3. SPI device's data sheets would specify the operating modes
supported by the devices. For example most of the atmel flash memories support SPI mode 0 and 3.
In breif, the mode specifies which edge controls the data transfer.
Clocks for different modes are as shown in the figure. The timing diagrams are not to scale and
they are used to explain the modes.
As shown in the figure,
SPI Mode 0: Data is shifted on rising edge and shifted out on falling edge. Initial clock level is low.
SPI Mode 1: Data is shifted on falling edge and shifted out on rising edge. Initial clock level is low.
SPI Mode 2: Data is shifted on rising edge and shifted out on falling edge. Initial clock level is high.
SPI Mode 3: Data is shifted on falling edge and shifted out on rising edge. Initial clock level is high.
Algorithms for data transfer
Algorithms for data transfers could be developed easily without spending lot of time,
if the following things are kept in mind.
1. Flash memory provides internal buffers for data transfers.
2. Algorithms would be different for programming a whole page or programming individual bytes.
Serial flash gives the flexibility to program byte wise. Auto Erase operation is provided.
That means when ever the flash is programmed, an erase operation need not be given explicitly.
3. Make sure the mappings are taken care. The flash considers that every page starts from
location that is an integral multiple of 2 power 10.
For Example consider the flash with 528 bytes per page. The second page should start from
529th byte onwards (which is true physically). But when writing the commands to the flash
first page would start at 0, second page would start at 1024, third page would start at 2048
and so on. So to access 530th byte (which is the 2 byte of the 2 page), the location that
would be specified to flash in command would be 1026(1024+2).
Programming serial Flash by emulating SPI over parallel port
Parallel Port
There are so many documents on the web that provide the information about parallel port
and its programming. Here, I will just discuss emulating SPI over parallel port. For more
information on parallel port refer to the follwoing links.
Parallel port has 25(DB25) pins. Out of the 25 pins
8 pins are tied to data
4 pins are tied to control
5 pins are tied to Status
and 8 pins are connected to ground.
There are three registers assigned for the LPT1 (Windows 98/95).
The registers can be checked out by going into
settings->Control Panel->System->Device Manager->Ports (COM and LPT)->LPT1->Properties->Resoureces.
In general the base address assigned for parallel port is 378h.
Base +0 (0x378)woule be data register
Base +1 (0x379) is status register
Base +2 (0x37a) is control register.
By default, the parallel port is configured as bi-directional. The configuration could
be changed, if required, so that the parallel port can be configured as only output. The
5th bit in the control register corresponds to this configuration.
Try this.
At Dos Prompt
C:> debug
i 0x37a
EC
That says the fifth bit in the control register is set to 1. The configuration could be
set to "only output" by setting that bit to 0.
SPI Over Parallel Port
The following explanation considers c language development.
In order to communicate with Serial EEPROM over SPI, 4 signals are required. MOSI, MISO,
SCLK, CS. Out of which three are inputs(MOSI, SCLK, CS) to the Serial flash and one
output(MISO).
Select three data pins (bits in the data register) for the three inputs and
one status pin (Output).
For modes 0 and 3 data would be shifted in on rising edge and out on falling edge. Reverse
is the case with modes 1 and 2. Only one case would be considered here.. say modes 0 and 3.
ON every clock cycle a bit would be shifted in on rising edge and a bit would be shifted
out on falling edge. This means a byte is read and written in 8 clock cycles.
In windows 98/DOS, the parallel port could be accessed directly over 0x378. But this is not
the case with windows NT. Instead, VC++ provides the api necessary to access and manipulate
on ports. Emulate the signals using macros or functions.
Example
Consider MOSI as Data0 pin. Bit 0 in data register.
#define MOSI(state) /
U8 Temp; /
Temp = *(0x378); /
Temp &= FE; /
Temp |= state; /
All the inputs follow the same pattern. The output should be considered differently though.
The output should be inverted once it is read.
Once all the signals are emulated, a byte transfer could be considered as follows
Note: Flash is accessed only when the chip select is set to low.
READ SPI_BYTE_TRANSFER(BYTE)
{
SPI_CS(0); /* Set the chip select to low */
SPI_CLK(0);
for(i=0; i<8; i++)
delay;
SPI_CLK(1); /* Rising Edge */
SPI_MOSI((BYTE >> 1) & (0x01));
delay
SPI_CLK(0);
ReadBit = SPI_MISO();
READ |= (ReadBit << i);
return READ;
}