#define make16(varhigh,varlow) (((unsigned
short)varhigh & 0xFF)* 0x100) \
+ ((unsigned short)varlow & 0x00FF)
unsigned int rd32(unsigned int addr)
{
unsigned char i;
unsigned int rdata32;
//convert address to Little Endian format
addrBuf[0] = 0x3F & (addr >> 16);
addrBuf[1] = addr >> 8;
addrBuf[2] = addr;
addrBuf[3] = 0x00; //dummy byte
■ Screenshot 1. This is an
MPLAB X debug window
shot of the results of
executing the rd32 function
against the FT800's
REG_FREQUENCY register.
//convert address to Little Endian format
addrBuf[0] = 0x3F & (addr >> 16);
addrBuf[1] = addr >> 8;
addrBuf[2] = addr;
addrBuf[3] = 0x00; //dummy byte
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?
}
for(i=0;i<2;++i)
{
SPI2BUF = 0x00;
//8 clocks out - 8 bits in
while(SPI2STATbits.SPIRBF == 0);
//wait until receive buff full
readBuf[i] = SPI2BUF; //read byte
while(SPI2STATbits.SPIBUSY == 1);
//all done?
}
CShi;
rdata16 = make16(readBuf[1],readBuf[0]);
return(rdata16);
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?
}
for(i=0;i<4;++i)
{
SPI2BUF = 0x00;
//8 clocks out - 8 bits in
while(SPI2STATbits.SPIRBF == 0);
//wait until receive buff full
readBuf[i] = SPI2BUF; //read byte
while(SPI2STATbits.SPIBUSY == 1);
//all done?
}
CShi;
rdata32 = make32(readBuf[3],readBuf[2],
readBuf[1],readBuf[0]);
return(rdata32);
}
Instead of two bytes, four bytes are transferred from
the FT800. The make32 macro merges the four bytes into
a 32-bit integer:
#define make32(var1,var2,var3,var4) \
((unsigned int)var1<<24)+((unsigned
int)var2<<16)+ \
((unsigned int)var3<<8)+((unsigned
int)var4)
Note that we are not simply reading two bytes from
the FT800. We are actually reading a 16-bit integer value.
The pair of bytes obtained from the FT800 is converted to
an integer using the make16 macro:
Again, we use the make32 macro to convert the
received Little Endian value to Big Endian. Let’s read the
32-bit REG_FREQUENCY register which holds the default
Big Endian value of 0x02DC6C00. As you can see in
Screenshot 1, the REG_FREQUENCY data came to the
PIC32MX SPI portal in the sequence of 0x00, 0x6C,
Another look at the position of the variables in the
make16 macro reveals that the make16 macro is being
used to convert the incoming Little Endian formatted data
to Big Endian format.
0xDC, 0x02. The scratch32 variable value is the result of
the execution of the make32 macro within the rd32
function. Now that we can read, let’s learn to write.
Host Memory Write
There will be times that we’ll need to transfer a 32-bit
value from the FT800. The mechanics are exactly the
same as the eight-bit and 16-bit reads we have previously
discussed. With that, the 32-bit Host Memory Read
command code looks like this:
Table 3 looks just like Table 2 with the exception of
Write versus Read, and a read/write bit. The FT800 does
not use the two most significant address bits, as its
memory space is limited to 4 MB. In that these bits are
always part of the data transfer, it’s only logical to put
56 July 2014