ADVANCED TECHNIQUES FOR DESIGN ENGINEERS
space by examining the FT800 memory
map that is described in its datasheet.
All of the memory space we currently
need to navigate is laid out in Table 1. Our
job is to code a common set of calls that
exercise the FT800 by reading and writing
the registers and memory buffer areas
defined in Table 1.
The FTDI documentation divides these
reads and writes into three transaction
types: Memory Read; Memory Write;
and Command Write. The associated
transaction type commands are Host
Memory Read, Host Memory Write, and
Host Command Write.
■ Table 2. A 24-bit address is passed physically, but the FT800 only
utilized the least significant 22 address bits. This is a typical SPI read
with an extended address field.
Host Memory Read
CSlo;
dummybite = SPI2BUF; //clear BF
for(i=0;i<4;++i)
{
SPI2BUF = addrBuf[i];//send address
while(SPI2STATbits.SPIRBF == 0);
//wait until receive buff full
dummybite = SPI2BUF; //clear SPIRBF
while(SPI2STATbits.SPIBUSY == 1);
//all done?
}
Table 2 is the top to bottom description of a Host
Memory Read command. The FT800 acts as an SPI slave
device and requires the toggling of the SPI_SS_N signal.
We define the SPI_SS_N signal in the following manner:
#define CSlo LATGCLR = 0x0200;
//0000 0010 0000 0000
#define CShi LATGSET = 0x0200;
SPI2BUF = 0x00; //8 clocks out - 8 bits in
while(SPI2STATbits.SPIRBF == 0);
//wait until receive buff full
readBuf[0] = SPI2BUF; //read byte
while(SPI2STATbits.SPIBUSY == 1);
//all done?
CShi;
return(readBuf[0]);
The PIC32MX atomic operations are self-commenting.
We have declared the FTDI documented SPI_SS_N signal
as CS. According to Table 2, we must drop the CS line
logically low to begin a Host Memory Read command.
This is accomplished using CSlo. From the code, our CS
signal is generated on RG9.
The Host Memory Read command ends when CS is
forced logically high with the issuance of CShi. In the
meantime, the Host Memory Read command is no more
than a standard SPI read operation; the difference from a
standard SPI read being the extended 22-bit address field.
The first order of business is to adhere to the FT800’s
rule concerning data format. So, we must first convert the
24-bit address to Little Endian format. As you can see in
the code, we simply rotated the address information into
an array in such a manner as to transmit the address top
to bottom instead of bottom to top.
We now have a basis for our Host Memory Read
command code. Let’s start by coding a single byte read
command:
To save some code, the dummy byte is coded as part
of the Little Endian array. CS pin RG9 is driven logically
low and the SPI buffer full flag is cleared with a dummy
read of the SPI data buffer. As per Table 2, 24 bits of
address information is transferred to the FT800, followed
by the dummy byte of 0x00.
unsigned char rd8(unsigned int addr)
{
unsigned char i;
//convert address to Little Endian format
addrBuf[0] = 0x3F & (addr >> 16);
addrBuf[1] = addr >> 8;
addrBuf[2] = addr;
addrBuf[3] = 0x00; //dummy byte
SPI data travels on clock edges, so we need to clock
the FT800 eight times to enable the PIC32MX on the MX3
to clock in one byte of information. Once we have filled
the Master device’s SPI buffer, we end the Host Memory
Read command by forcing port pin RG9 logically high.
The clocked-in SPI data resides in the first slot of the
readBuf array. We simply return the byte of data as a
byproduct of the Host Memory Read function call.
Another look at Table 2 reveals that multiple bytes
can be read with a single Host Memory Read command.
Here is how we do that for two bytes:
unsigned short rd16(unsigned int addr)
{
unsigned char i;
unsigned short rdata16;
July 2014 55