libftdi Archives

Subject: RE: MPSSE examples?

From: "Michael Plante" <michael.plante@xxxxxxxxx>
To: <libftdi@xxxxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 30 Aug 2009 12:48:41 -0500
>> >> AN108 is not exactly easy to understand. I read it and I wonders if
that's
>> >> enough or if there is more available.
>>
>> It is enough for SPI & (MPSSE) bit-bang, and presumably enough for JTAG.
>> I2C is kinda tough (with the ack bit reversing direction mid-byte,
>> particularly), and so I haven't tried it.  In order to use AN108
effectively
>> for SPI, you need a timing diagram for the chip you're talking to so you
know
>> clock polarity and how clock idles.  The FTDI chip is the SPI master.
One thing
>> that I couldn't find in the docs, but figured by trial and error, is
which bit
>> of the bit-bang mode corresponds to which pin.  If you need info on that,
I can post it.
>>
>> I need to leave, but maybe in a few hours (when I get back) I'll post a
piece of
>> code to do a simple SPI write.

Ok, so this is extracted from a slightly more sophisticated piece of code,
so I hope I haven't left anything crucial out.  This writes the buffer
pchDataOut, which is nBytes long.  It tells the chip to discard bytes sent
back by the slave, rather than making them available via ftdi_read_data()
after the fact.  I have removed error checking, among other things.
uchClkFlags should be either a member variable or global, as it is set once
and left.  I set it to 0x01 for my app, but every slave chip will be
different; check the timing diagrams on your datasheet.  Also, my slave does
not have a chip-select line.

bool spi_bytes_out(ftdi_context *pFtdiC, unsigned nBytes,
                   unsigned char const *pchDataOut,
                   unsigned char uchClkFlags) {
  unsigned char achBuf[MAX_TRANSMIT+3];       // may need to adjust size
here.
  achBuf[0]=0x10 | uchClkFlags;               // write (0x10)
  achBuf[1]=(unsigned char)((nBytes-1)&0xFF); // low byte of length
  achBuf[2]=(unsigned char)((nBytes-1)>>8);   // high byte of length

  memcpy(achBuf+3,pchDataOut,nBytes);

  ftdi_write_data(pFtdiC, achBuf, nBytes+3);

  return true; // Would ordinarily check for errors!
}

Reading is more complicated, and the error checking is significantly more
intertwined in my code, so I'm not posting that, but you would modify 0x10
to the appropriate command and keep calling ftdi_read_data trying to get
your results, eventually timing out, if necessary.  Note that a SPI
peripheral will always send and receive simultaneously (same # of bytes you
sent, as it's synchronous), but it may be "don't cares", in which case the
above makes sense to use.

HTH,
Michael



--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   

Current Thread