2
\$\begingroup\$

I would like to read an EEPROM Memory (SPI Flash Winbond) using an FTDI USB/SPI bridge (FT4222H). I developed a c++ application that connects to the FTDI and reads data from the memory(and using the FTDI library). I am using the continuous mode read because it's much faster than the buffer read. The problem is that the FTDI transfer limit is 64Kbytes and the total memory is 256MBytes so I have to read 64Kbyte in a loop of 4096 times and then save it in a file. The problem is that each time you have to send the OpCode of reading memory followed by 7 Dummy Bytes, which I lost each time 8Bytes in each 64Kbyte.

I tried to read less then 64Kbye (for example 60Kbyte +8Byte) but I realize that the data was corrupted and is not properly read. Also, I tried to fix the starting reading page in each 60Kbyte but the same, the data was corrupted.

Does anyone have an Idea about that or he reads data through an FT4222 bridge?

And Thank you very much :)

Here the code bellow:

uint8* FTDIQuodSendRecieve(uint8 *Tx, uint16 *byteToread){

uint8 R[80535];
uint8 *Rx=R;
uint16 sizeTransfered;
uint32 sizeOfRead;
ft4222Status = FT4222_SPIMaster_MultiReadWrite(ftHandle, Rx, Tx, 1, 6, *byteToread, &sizeOfRead);

if((ft4222Status!=FT4222_OK) )
{
    // single read write failed
    std::cout <<"single read write failed "<<ft4222Status;
    return 0;
}
return Rx;
}




int ftdiQuadConfig(){

ft4222Status = FT4222_SetClock(ftHandle, SYS_CLK_60);
if (FT4222_OK != ft4222Status){

    // set clock failed
    std::cout<< "set clock failed";
    return 0;
}

ft4222Status = FT4222_SPIMaster_Init(ftHandle, SPI_IO_QUAD, CLK_DIV_2, CLK_IDLE_LOW, CLK_LEADING, 0x01);
if (FT4222_OK != ft4222Status){

    std::cout<< "spi master init failed";
    return 0;
}
return 1;
}


void saveFile(QTextStream *outStream,uint8 *Rx){

for (unsigned int i=7; i<32772; i++){ // all data was shefted with 8 bytes 

   if ((i-7)%2048 ==0){
       *outStream << "\nPage "<< Page++ <<": ";
   }

   *outStream <<hex<< Rx[i]<<" ";
}
*outStream << "\n";
}

void continiousRead(QTextStream *outStream){



QElapsedTimer timer, total;
uint8 Tx[4];  
uint8 Tx1[65535];
uint8 Rx= new uint8 [65535];
uint16 bytestoRead=3;


/*Memory reset*/
Tx[0]=0xFF;Tx[1]=0xB0;Tx[2]=0x00;    
ft4222Status = FT4222_SPIMaster_SingleReadWrite(ftHandle, Rx, Tx, 3, &bytestoRead, true);
FtdiError(ft4222Status);

/*Set page data Read*/
bytestoRead=4;
Tx[0]=0x13;Tx[1]=0x00;Tx[2]=0x00;Tx[3]=0x00;
ft4222Status = FT4222_SPIMaster_SingleReadWrite(ftHandle, Rx, Tx, 4, &bytestoRead, true);
FtdiError(ft4222Status);

/*Set continous Read*/
bytestoRead=3;
Tx[0]=0x01;Tx[1]=0xB0;Tx[2]=0x00;
ft4222Status = FT4222_SPIMaster_SingleReadWrite(ftHandle, Rx, Tx, 3, &bytestoRead, true);
FtdiError(ft4222Status);

/*Verify continous Read*/
bytestoRead=5;
Tx[0]=0x0f;Tx[1]=0xB0;
Rx= FTDISingleSendRecieve(Tx, &bytestoRead);
std::cout <<  std::hex <<Rx[3]<<"\n";

/*Set FTDI to Quad Mode*/
ftdiQuadConfig();


Tx1[0]=0xec; Tx1[1]=0x00;Tx1[2]=0x00;Tx1[3]=0x00; bytestoRead=32775;//32775 =32Kb +8Byte

/*If Continious Mode Then start reading */
if (Rx[3]==0x00){


    
    total.start();
    for (unsigned int i=0; i<8192 ;i++){

        timer.start();
        Rx= FTDIQuodSendRecieve(Tx1, &bytestoRead);
        std::cout << "64Kbyte took " << timer.elapsed() << " milliseconds\n";
        saveFile(outStream, Rx);

    }
}
else {

    std::cout<< "\n\nERROR Continious read not fixed";
}
std::cout << "64Kbyte *10 Time is: " << total.elapsed() << " milliseconds\n";
}
\$\endgroup\$
  • \$\begingroup\$ Sounds like you need to debug your program, but at present you don't really have a specifically answerable question. Try putting a known pattern in flash, and do smaller reads to test your scheme. You might use a cheap USB based logic analyzer as a cross-check. Higher performance implementations of this goal would use a USB-capable MCU, keep the actual flash operations between the MCU firmware and the flash chip and merely use the USB to send back the results, either in a custom way or by implementing USB mass storage to give a raw block device. \$\endgroup\$ – Chris Stratton Sep 30 at 16:01
  • 1
    \$\begingroup\$ If 64kB is too much, why read almost 64kB and then 8 bytes? Why not then just use 32kb blocks to begin with? \$\endgroup\$ – Justme Sep 30 at 16:15
  • \$\begingroup\$ @Justme Yeah I reduce the reading from 64Kb to (60Kb +8byte) block. \$\endgroup\$ – mohamed bousselmi Oct 1 at 5:26
  • \$\begingroup\$ @ChrisStratton Thank you very much for your response :) I already debug my program and I get missing data too, I cannot go debugging inside FTDI-reading-function cause it's a DLL library. \$\endgroup\$ – mohamed bousselmi Oct 1 at 5:47
  • \$\begingroup\$ @ChrisStratton I tried continuous read with micro-controller and I get all the memory without missing data( the micro-controller doesn't use the FTDI-library and it's directly connected to spi port). I am thinking that the problem cames from the FTDI library cause the function itself puts the chip select High and low automatically while just coping one 64Kbyte block (tested with an oscilloscope) which I think misses some data while reading (cause in continuous mode the chip select must be low in all reading process not block by block). \$\endgroup\$ – mohamed bousselmi Oct 1 at 5:47
0
\$\begingroup\$

Solved: Just I have to set a start reading page before each 32Kbyte read. and the problem will be solved, normally in continuous mode, the address will be automatically updated but I think it has a delay in the chip select(I still don't know from where) that's why I get a missing data in each first page in each 32Kb reading.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.