Author Topic: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed  (Read 27672 times)

0 Members and 1 Guest are viewing this topic.

Offline free_electronTopic starter

  • Super Contributor
  • ***
  • Posts: 8547
  • Country: us
    • SiliconValleyGarage
Does anyone have a working example using the FTDI MPSSE-SPI library ( version 1.1 , which apparently is the most recent one although there is a 2.0 which is older and has completely different functions... go figure... ) in a .NET language (C# or VB).

That DLL is made using GCC and i cannot create a wrapper for .NET automatically since there is no manifest. GRRRRR !
FTDI doesn't have anything available ...

I managed to create the wrapper by hand (which is a pain as i need to marshall the code in. i'm not a coding guru. it took me 4 hours to figure out how to pass a fixed size string thru a structure... i gave up and simply created a structure with as many bytes in it as characters and i rebuild the string afterwards. .NET has marshalling tools specifically (p/invoke tool) for this but they don't work as it cannot retrieve the compilation manifest for the FTDI DLL)

It works apart from 1 thing : i cannot toggle the CS line. no idea why.

In short : all i need is the function prototypes for the MPSSE-SPI dll , the structure prototypes and a 5 line program

- open device index 1
- retrieve its information block in the information structure and give the serial number and description as strings. ( not 0 terminated strings, but .NET strings )
  i got the above working but it is UGLY. i need to know how to do the marshalling correctly. Google yielded tons of examples of people with the same problem and the answer is invariably use p/invok... if that can't help 'try all options until it works'. riiiight ...

- initialize it at 100Khz, active low CS at pin db3    <- is suspect trouble here in my code
- flunk 2 bytes out ( 0x55 and 0xaa for example ) <- or here
- close device

if i have this i can compare it with my code.
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #1 on: January 25, 2013, 10:56:32 am »
If all else fails you could go down one level and directly use FTDI's normal D2XX device driver DLL. For this one they have a C# wrapper. And a chip's MPSSE can be configured and programmed via D2XX, although that requires a bit of coding and fiddling with bits.

This way you wouldn't have to deal with the SPI lib, at the cost of having to code on a lower level.
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline free_electronTopic starter

  • Super Contributor
  • ***
  • Posts: 8547
  • Country: us
    • SiliconValleyGarage
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #2 on: January 25, 2013, 04:11:09 pm »
Well the point was to avoid all the bit thumping ... I'm pressed for time.
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline marshallh

  • Supporter
  • ****
  • Posts: 1462
  • Country: us
    • retroactive
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #3 on: January 25, 2013, 04:55:20 pm »
built the DLL with MSVC2008... embedded manifest

let me know if this does the trick
Verilog tips
BGA soldering intro

11:37 <@ktemkin> c4757p: marshall has transcended communications media
11:37 <@ktemkin> He speaks protocols directly.
 

Offline free_electronTopic starter

  • Super Contributor
  • ***
  • Posts: 8547
  • Country: us
    • SiliconValleyGarage
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #4 on: January 25, 2013, 09:08:10 pm »
ah that is the FTCspi . That's not the one i want... its the LibMPSSE one . it has both SPI and I2C on board and they don't release the source  to that one. the FTCspi is no longer supported... ( besides it is a kludge to work with. i spent 3 days futsing around with it....  the LibMPSSE is easier to work with apart from having no demo code for .NET

Thanks for the effort though...

I hacked it the hard way. I simply do not pass a structure, but a pointer to an array of bytes (for the DLL call it doesn't matter a pointer is a pointer as long as there is enough room to plunk its stuff.... i reconstruct the data by walking the array and picking the bytes i need. works like a charm.

FTDI is a weird company. I email them , call them. Nobody ever answers the phone. they are always 'unavailable'. Email response is slow takes 3 days to get an answer. I have one direct number and the voice message says 'i am out until january 3' .. it's january 25 for crying out loud ....

They have at lest 3 revisions of appnotes and none match the driver version. The appnotes are full of 'for explanation of this see document that' . It is one massive puzzle.

If someone wants it : here is the NET code: (VB, but easily portable to C#)
Code: [Select]
Structure ChannelConfig
        Dim clockrate As UInt32
        Dim latencytimer As Byte
        Dim ConfigOptions As UInt32
        Dim Pins As UInt32
        Dim Reserved As UInt16
End Structure
Dim ChannelConfiguration As ChannelConfig
Dim MPSSE_Status As UInt32
Dim MPSSE_Handle As UInt32

 Private Declare Function MPSSE_SPI_GetChannels Lib "libmpsse" Alias "SPI_GetNumChannels" (ByRef NumberOfChannels As UInt32) As UInt32
Private Declare Function MPSSE_SPI_GetChannelinfo Lib "libmpsse" Alias "SPI_GetChannelInfo" (ByVal Index As UInt32, ByRef DeviceInfo As DeviceInfoStructure) As UInt32
Private Declare Function MPSSE_SPI_OpenChannel Lib "libmpsse" Alias "SPI_OpenChannel" (ByVal Index As UInt32, ByRef SPI_ProbeHandle As UInt32) As UInt32
Private Declare Function MPSSE_SPI_InitChannel Lib "libmpsse" Alias "SPI_InitChannel" (ByVal SPI_ProbeHandle As UInt32, ByRef ChannelConfiguration As ChannelConfig) As UInt32
Private Declare Function MPSSE_SPI_CloseChannel Lib "libmpsse" Alias "SPI_Closechannel" (ByVal SPI_ProbeHandle As UInt32) As UInt32
Private Declare Function MPSSE_SPI_Read Lib "libmpsse" Alias "SPI_read" (ByVal SPI_ProbeHandle As UInt32, ByRef Readbuffer() As Byte, ByVal SizeToRead As UInt32, ByRef SizeRead As UInt32, ByVal TransferOptions As UInt32) As UInt32
Private Declare Function MPSEE_SPI_Write Lib "libmpsse" Alias "SPI_Write" (ByVal SPI_ProbeHandle As UInt32, ByVal Writebuffer() As Byte, ByVal SizeToWrite As UInt32, ByRef SizeWritten As UInt32, ByVal TransferOptions As UInt32) As UInt32
Private Declare Function MPSEE_SPI_ReadWrite Lib "libmpsse" Alias "SPI_ReadWrite" (ByVal SPI_ProbeHandle As UInt32, ByRef Readbuffer() As Byte, ByVal Writebuffer() As Byte, ByVal SizeTotransfer As UInt32, ByRef Sizetransferred As UInt32, ByVal TransferOptions As UInt32) As UInt32
Private Declare Function MPSEE_SPI_CheckBusy Lib "libmpsse" Alias "SPI_IsBusy" (ByVal SPI_ProbeHandle As UInt32, ByRef State As Byte) As UInt32
Private Declare Function MPSEE_SPI_ChangeCS Lib "libmpsse" Alias "SPI_ChangeCS" (ByVal SPI_ProbeHandle As UInt32, ByVal Options As UInt32) As UInt32
Private Declare Function MPSEE_SPI_GPIOWrite Lib "libmpsse" Alias "FT_WriteGPIO" (ByVal SPI_ProbeHandle As UInt32, ByVal Direction As Byte, ByVal Value As Byte) As UInt32
Private Declare Function MPSEE_SPI_GPIORead Lib "libmpsse" Alias "FT_WriteGPIO" (ByVal SPI_ProbeHandle As UInt32, ByRef Value As Byte) As UInt32

Private Declare Function MPSSE_I2C_GetChannels Lib "libmpsse" Alias "I2C_GetNumChannels" (ByRef NumberOfChannels As UInt32) As UInt32
Private Declare Function MPSSE_SPI_I2CChannelinfo Lib "libmpsse" Alias "I2C_GetChannelInfo" (ByVal Index As UInt32, ByRef DeviceInfo As DeviceInfoStructure) As UInt32

    Const Options_SPI_Mode0 As UInt32 = 0
    Const Options_SPI_Mode1 As UInt32 = 1
    Const Options_SPI_Mode2 As UInt32 = 2
    Const Options_SPI_Mode3 As UInt32 = 3
    Const Options_CS_DB3 As UInt32 = 0
    Const Options_CS_DB4 As UInt32 = 4
    Const Options_CS_DB5 As UInt32 = 8
    Const Options_CS_DB6 As UInt32 = 12
    Const Options_CS_DB7 As UInt32 = 16
    Const Options_CSmode_ActiveHigh As UInt32 = 0
    Const Options_CSmode_ActiveLow As UInt32 = 32
    Const TransferOptions_Inbits As UInt32 = 1
    Const TransferOptions_Inbytes As UInt32 = 0
    Const TransferOptions_CSAtStart As UInt32 = 2
    Const TransferOptions_CSAtStop As UInt32 = 4

as soon as i got the i2c prototypes in there as well i will release that too together with helper functions ( like 'giveme alist of available chips, their device nemaes and port handles' 'connect to this porthandle at this channel'

etc.

It really shouldn't be that hard to interface with these things if their damn documentation would be right and complete and if they would use the right compiler.
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline Rob

  • Newbie
  • Posts: 1
Hey free_electron,

I'm currently facing almost the same problems as you did. I try to use the I2C interface of a FT2232H via the libMPSSE in C# (Visual Studio 2008).
Stuff like I2C_GetNumChannels(), I2C_GetChannelInfo() works fine. But I can't use the I2C_DeviceWrite() function. When I call that one, the program always gets stuck.
I suppose the issue lies somewhere in my import of this function from the DLL. Did you finished your work on that and if so, can you give me a hint or maybe some code you wrote?
Here is my code, I currently use for the import.

        [DllImportAttribute("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        private static extern UInt32 I2C_DeviceWrite(UInt32 handle, UInt32 deviceAddress, UInt32 sizeToTransfer,
                                                   ref byte[] buffer, ref UInt32 sizeTransferred, UInt32 options);

Thanks in advance for your response,
Rob
 

Offline free_electronTopic starter

  • Super Contributor
  • ***
  • Posts: 8547
  • Country: us
    • SiliconValleyGarage
Its not your code. The DLL is flawed.

I have spi fully working now. Including the modes that they could not get glitch free. (Mode 1 and 3 od spi are not supported as it has glitches in the output... Some silicon bug.. I found a workaround and these modes are now also glitch free... )

I am working on i2c. I have not got it fully working yet.. It freezes once in a while.

The dll for spi and i2c is the same.

I created extra functions in the dll that let me manipulate the commnad stream into the mpssee.
It is just so annoying to have to use commnad line tools to edit that stupid code , compile it under mingw , lod it . I can't put breakpoints nor trace it... Shit like that should be prohibited.

I am also working on code that eliminates the dll altogether. That dll is compiled using a compiler under mingw.. They produce both a dll and a linux library. The problem is there is no manifest and the produced dll loads only on 32 bit. There is no way to call it from a 64 bit environment. So i am moving code into native visual studio domain. That solves all this misery.

I have built a set of functions i call packetbuilder. It uses a transmit and receive buffer that is exactly one usb frame long ( they have problems with multipacket streams. Byte 64 always gets corrupted...)

You throw in commands
Sendspistart
Sendspibyte
Sendi2cstart
Etc...
When you reach the maximum commnadlength the packet leaves. If your commnad is too short there is a closepacked command that forces a transmit.

The same with receive. There is something weierd with the function te request the number of received bytes. Sometimes it falsely reports one more than there really is and then it locks up.
The are obviously aware of these problems as the dll code dances around the real problem. They dont even 'pack' multiple commnads in a frame .

This gives really weird things like a start condition followed by a long time nothing and then a byte followed by a long time nothing ...
So there is no way you can race at full throttle on spi or i2c as you have random delays thrown in due to the usb transport only going out in bits and pieces as opposed to using full packet space.

I have a few days off bow. I will post the code i have so far on monday.
« Last Edit: May 02, 2013, 04:48:22 pm by free_electron »
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline DavidDLC

  • Frequent Contributor
  • **
  • Posts: 755
  • Country: us
I have used the class they provide: FTD2XX_NETclass.cs.

I have the I2C fully operational. It is a pain on the butt to work with those functions they have.

David.
 

Offline shine98

  • Newbie
  • Posts: 1
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #8 on: December 18, 2013, 09:50:38 am »
Hi free_electron,

could you attach your working spi-library so I can try so interface my SPI-Displays using VB.NET and my FT2232-Breakout.

Thanks and regards,
Jan
 

Offline luky315

  • Regular Contributor
  • *
  • Posts: 244
  • Country: at
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #9 on: January 02, 2014, 01:05:49 pm »
Same Problem here: Tried to use the FT4232 as SPI / I2C Master with Visual Studio 2013 but it is not working under 64bit Windows.
 

Offline free_electronTopic starter

  • Super Contributor
  • ***
  • Posts: 8547
  • Country: us
    • SiliconValleyGarage
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #10 on: January 02, 2014, 02:47:04 pm »
I know. That library is a pest.

I will try to clean out my code over the weekend, remove proprietary stuff and release the source.
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline helge

  • Regular Contributor
  • *
  • Posts: 73
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #11 on: January 12, 2014, 11:25:54 am »
Hello free_electron,

I gave the FT2232H a try and currently I'm stuck with the 32bit libmpsse.dll. Hope you can find the time to finish your lib. Any progress?

edit:

Here you can find a write-up on a little piece of code I wrote to be able to use libMPSSE with serial terminal programs like RealTerm and HTerm.
« Last Edit: January 15, 2014, 01:46:40 am by helge »
 

Offline dbendov

  • Newbie
  • Posts: 1
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #12 on: February 10, 2014, 09:17:01 pm »
hi there free electron,

I hahve just started looking into FTDI SPI dll when i crossed your post.

any chance you upload your solution? this will be great help for us...
 

Offline Digital Don

  • Newbie
  • Posts: 1
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #13 on: May 26, 2014, 04:21:26 pm »
I ran into a similar problem. Here is my code snippet that interfaces to the unmanaged libMPSSE.dll from C#. (If I knew how to upload a whole file, I could submit a full example program.)  Enjoy!

        // Derived from FT_DEVICE_LIST_INFO_NODE in ftd2xx.h
        // With help from Microsoft's P/Invoke Interop Assistant
        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
        public struct FT_DEVICE_LIST_INFO_NODE
        {
            public uint Flags;
            public uint Type;
            public uint ID;
            public uint LocId;

            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 16)]
            public string SerialNumber;

            [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 64)]
            public string Description;

          System.IntPtr ftHandle;
       }

        // Derived from ChannelConfig in libMPSSE_spi.h
        // With help from Microsoft's P/Invoke Interop Assistant
        [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
        public struct ChannelConfig
        {
            public uint ClockRate;
            public byte LatencyTimer;
            public uint configOptions;
            public uint Pin;
            public uint reserved;
        }

        [DllImport("libMPSSE.dll",  CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_GetNumChannels(out uint numChannels);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_GetChannelInfo(uint index, out FT_DEVICE_LIST_INFO_NODE chanInfo);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_OpenChannel(uint index, out System.IntPtr handle);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_InitChannel(System.IntPtr handle, ref ChannelConfig config);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_CloseChannel(System.IntPtr handle);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_Read(System.IntPtr handle, [MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint sizeToTransfer, ref uint sizeTransfered, uint options);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_Write(System.IntPtr handle, [MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint sizeToTransfer, ref uint sizeTransfered, uint options);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_ReadWrite(System.IntPtr handle, [MarshalAs(UnmanagedType.LPArray)] byte[] inBuffer, [MarshalAs(UnmanagedType.LPArray)] byte[] outBuffer, uint sizeToTransfer, ref uint sizeTransfered, uint options);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_IsBusy(System.IntPtr handle, out Boolean state);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern void Init_libMPSSE();

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern void Cleanup_libMPSSE();

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint SPI_ChangeCS(System.IntPtr handle, ChannelConfig config);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint FT_WriteGPIO(System.IntPtr handle, byte dir, byte value);

        [DllImport("libMPSSE.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern uint FT_ReadGPIO(System.IntPtr handle, out byte value);



 

Offline Cristalized

  • Newbie
  • Posts: 1
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #14 on: June 18, 2014, 07:08:59 pm »
I know. That library is a pest.

I will try to clean out my code over the weekend, remove proprietary stuff and release the source.

Hello,

I am using ft4232h and the library mpsse-spi.
I am facing some problem with the spi mode1 which is not working properly.
Surfing in internet I have found that you have already solved the problem.
Can you please explain how?

Did you finally release your source?

Thanks in advance
 

Offline cosminnci

  • Regular Contributor
  • *
  • Posts: 85
  • Country: ro
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #15 on: November 27, 2014, 07:54:04 am »

Hello,

I try to use MPSSE-I2C lib for sending 6 bytes over i2c, modified the example they offer for eeprom.
on win it sends ok for 5 loops then the i2c clock stays low, then after a few loops it recovers and does other 5 loops and so on.
the speed on the bus is great, but when it looses clock it looses the i2c commands as well.

same example on linux does 3 loops correctly, then it inserts 10 s delay between each loop.

so none of them work :(

any ideas what could cause the the i2c clock to stop at a regular interval?

@free_electron did you encounter this behavior?

thank you,
regards
Cosmin
 

Offline aave

  • Newbie
  • Posts: 1
  • Country: cy
Re: FTDI 2232H in MPSSE-SPI mode. Toil and Trouble. Example code needed
« Reply #16 on: May 18, 2018, 01:07:05 pm »
I know. That library is a pest.

I will try to clean out my code over the weekend, remove proprietary stuff and release the source.
Good day! You promised to share youre code. It will be great help for people, because libmpsse.dll is not working under Windows 7 x64. I like your decision, but don't know how exactly it realize. Can you help me, please?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf