The first tests were perfect ! The chip in MPSSE mode let you communicate via I2C just by calling a few DLL API calls. But soon I noticed that this mode had some drawbacks. In de specifications of the chip nothing is telling you that if you use the MPSSE mode the gpios of the ADBUS and ACBUS are not available ! As my OE and INT of the IO board were connected using these gpio pins, the design became useless. Of course I tried to write to FTDI support but they are not that fast in response. Here are some FTDI answers:
- Is the use of ADBUS4-7 totally free as GPIO when using the DLL FTCI2C with the FTDI 2232D device ?
- In case of no please write some additional design remarks in dedicated specifications to avoid confusion and bad design.
- In case of yes is it also free to use ACBUS as gpio together with I2C DLL ?
- Is it possible to have the source code of the I2C DLL ?
At last they attached the source code of the DLL which was a good thing. Nevertheless I wrote some final mail to point out my situation and what I really need for my design:
First of all thanks for your quick answer and attaching the source code. Bad news of course to hear that the GPIOs can not be combined together with the MPSSE mode. It's not quit clear to me if the behaviour comes from using the DLL or it's inherent on the MPSSE mode itself. (not checked the code in detail yet) But one thing that FTDI definitly must do is add some remark in the specification. The pdf as is now only shows following notes in the column MPSSE:
**Note 4 : MPSSE is Channel A only.
**Note 8 : SI/WU is not available in these modes.
This should be extended with a dedicated note like "GPIOs not available.." in case it's inherent on MPSSE mode and if the cause is due to the DLL in software this can be noted in the API pdf as such.
However my design issue remains and I want to find a solution. The purpose is to have 8 GPIOs available not at the same time when I need the I2C functionality. I want to poll on some eg xxBUS1 signal and act upon it when this is low with a I2C command. So it's important to have a statefull GPIO when using the I2C commands and returning to GPIO mode. Therefore maybe I can use channels A/B in some combination.
Can I use the device channel B in GPIO mode to poll and switch to MPSSE mode on channel A without losing the state on channel B ? What mode for B to use ?
I think the use of EEPROM is mandatory in such a A/B configuration ?
I hope you can point me in the right direction to solve my problems with the right design approach.
Still no answer. So maybe there's still a small change to combine the GPIOs with MPSSE I2C mode but I doubt it really. In the next blog I present some DLL calls I made to work with FTDI.
4 comments:
Your experience is great help to me since I'm now on similar situation as you. Very appreciate!
Regarding accessing GPIO, I guess it's probably DLL-inherent. In the command processor of MPSSE, there is...
Set Data Bits Low Byte
0x80,
0xValue,
0xDirection
This will setup the direction of the first 8 lines and force a value on the bits that are set as output. A
'1' in the Direction byte will make that bit an output.
Set Data Bits High Byte
0x82,
0xValue,
0xDirection
This will setup the direction of the high 4 lines and force a value on the bits that are set as output.
A '1' in the Direction byte will make that bit an output.
I guess this enables us to control ADBUS and ACBUS. But this feature is not implemented in DLL. Maybe already implemented ... but not documented ...
I found below in the FTCI2C.h...
03/06/08 kra Added two new functions ie I2C_SetGPIOs and I2C_GetGPIOs and two
structures ie FTC_INPUT_OUTPUT_PINS and FTC_LOW_HIGH_PINS and two
error constants FTC_NULL_INPUT_BUFFER_POINTER and FTC_NULL_INPUT_OUTPUT_BUFFER_POINTER to
control the output states ie high(true) or low(false) of the 4 general purpose higher
input/output ACBUS 0-3/GPIOH 0-3) pins
I'm not quite sure since I don't code .. For now, I'm just thinking.
Would it be possible for you to give me FTDI's DLL source?
If possible, together with your modification version.
Regards and thanks, Daewoong.
e-mail : easydsp@gmail.com
daewoong.chung@infineon.com
Daewoong,
I will send you to code this evening on following address:
daewoong.chung@infineon.com
I'm at work now and don't have it here with me.
And I can say that the Get/Set GPIO is not implemented in the I2C DLL.
Regards
-G
Guyvo/Daewoong,
The information published by both of you is really useful. Right now, I'm working with FTDI 2232D chip. I'm using DLP 2232M-G(I tried with DLP 2232PB also) as I2C master and connected to our I2C slave. I've installed the DLP software that came with CD supplied and I've copied ftci2c.dll(ftd2xx.dll came with the installation) into my C:\windows\system32 folder.
It is observed that I'm able to write to the I2C slave device properly whereas I2C read is not consistent. It returns invalid bytes most of the times. Irrespective of whether I2C_Read is returning correct bytes or not, I2C_Write/I2C_Read transactions will fail subsequantly with Status saying control bytes are not acknowledged.
Did you guys observed this kind of behavior at any point of time? Any pointer for me? I've sent a mail to FTDI without any response.
Please let me know what might be the problem.
The sample for the read is as follows:
/***************************************************************/
INT32 Vmc_I2C_Read(UINT8 slaveAddress, INT32 readCount, UINT8* readBuff)
{
DWORD DataReadType = 0;
DWORD dwNumDataBytesToRead = 0;
DWORD dwReadDataByteAddress = 0;
DWORD dwReadDataIndex = 0;
UINT8 WriteControlBuffer[4];
FTC_STATUS Status;
WriteControlBuffer[0] = 0xAF; //1 0 1 0 A2 A1 A0 1 - device address 7
dwReadDataByteAddress = 0;
DataReadType = BLOCK_READ_TYPE; //BLOCK_READ_TYPE; //
if (DataReadType == BYTE_READ_TYPE)
dwNumDataBytesToRead = 1;
else
dwNumDataBytesToRead = readCount;
do
{
printf("BEfore Read: ReadStatus = %d Readbytes= %02x %02x %02x %02x %02x %02x %02x %02x\n",(int)Status,readBuff[0],readBuff[1],readBuff[2],readBuff[3],readBuff[4],readBuff[5],readBuff[6],readBuff[7]);
Status = I2C_Read(ft_i2c_handle, WriteControlBuffer, 1, true, 20, DataReadType, &(readBuff[dwReadDataByteAddress]), dwNumDataBytesToRead);
printf("After Read: ReadStatus = %d Readbytes= %02x %02x %02x %02x %02x %02x %02x %02x\n",(int)Status,readBuff[0],readBuff[1],readBuff[2],readBuff[3],readBuff[4],readBuff[5],readBuff[6],readBuff[7]);
if(Status == FTC_SUCCESS)
dwReadDataByteAddress += dwNumDataBytesToRead;
}
while ((dwReadDataByteAddress < readCount) && (Status == FTC_SUCCESS));
//printf("slave address = %x, readdata = %x readcount = %d\n",slaveAddress,(UINT32)*readBuff,readCount);
return dwReadDataByteAddress;
}
/************************************************************************************/
Thank you very much in advance
When I checked something on my blog I saw you last comment. I don't know for sure but I never got this blog remark by email so I don't remember anymore if I anwsered you on this one could but I suppose it's already solved due to the long time in between ;-)
Post a Comment