MPSSE SPI プログラムの抜粋です

//---------------------------------------------------------------------------

void __fastcall TForm2::Button_UploadClick(TObject *Sender)
{
    DWORD startTime, diffTime;
    String str;

    if(gbFileOpen)
    {
        startTime = timeGetTime();

        if(CheckBox_BulkErase->Checked == TRUE){
            AttachReport("BULK ERASE...");
            SPI_BulkErase();
            while(1){
                if(Timer_MemInProcessCheck->Enabled == FALSE){
                    break;
                }
                Application->ProcessMessages();
            }
        }else{
            AttachReport("SECTOR ERASE...");
            SPI_FileSizeSectorErase();
        }

        AttachReport("OK");

        AddReport("FILE UP LOAD...");

        if(File_UpLoad() == 0){
            AttachReport("OK");
        }else{
            AddReport("File upload failure");
            return;
        }

        Sleep(300);

        AddReport("VERIFY...");
        if(CheckBox_Verify->Checked == TRUE){
            if(File_Verify() == 0){
                AttachReport("OK");
            }else{
                AttachReport("NG");
            }
        }else{
            AttachReport("SKIP");
        }

        AddReport("");

        diffTime = timeGetTime() - startTime;
        AddReport(str.sprintf("Elapsed Time: %d ms", diffTime));
    }
    else
    {
        AddReport("File is not opened");
        return;
    }

}
//---------------------------------------------------------------------------

void __fastcall TForm2::SPI_BulkErase()
{
    BYTE *outBuffer;
    int buffCount = 0;
    BYTE retStatus;

    outBuffer = new BYTE[16];

    SPI_WriteEnable();
    if( !(SPI_ReadStatus()&MEMORY_WRITE_ENABLED)) return;

    //CS LOW
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = 0; //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    //Command
    outBuffer[buffCount++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    outBuffer[buffCount++] = 0x00;
    outBuffer[buffCount++] = 0x00;
    outBuffer[buffCount++] = 0xC7;

    //CS HIGH
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = PORT_SPI_CS;       //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    FT_Write(ftHandle, outBuffer, buffCount, &dwByteWritten);

    Timer_MemInProcessCheck->Enabled = TRUE;

    delete []outBuffer;

    return;
}
//---------------------------------------------------------------------------

int __fastcall TForm2::File_UpLoad()
{
    DWORD remainFileSize;
    int pagePos = 0;
    String str;

    remainFileSize = dwUpFileSize;

    ProgressBar1->Position = 0;
    ProgressBar1->Max = remainFileSize;

    while(remainFileSize >= MEMORY_BYTE_PER_PAGE){
        SPI_WriteEnable();
        SPI_PageProgram(pagePos*0x100, (BYTE*)(buffUpData+(pagePos*0x100)), MEMORY_BYTE_PER_PAGE);

        remainFileSize -= MEMORY_BYTE_PER_PAGE;
        pagePos++;
        ProgressBar1->StepBy(MEMORY_BYTE_PER_PAGE);

        //
        // Status Check
        //
        for(int numTry=0;;numTry++){
            if( !(SPI_ReadStatus()&MEMORY_IN_PROCESS)){
            break;
            }
            
            if(numTry > MEMORY_STATUS_CHECK_TRY){
                AddReport("TRY STATUS CHECK OVERFLOWED");
                return -1;
            }
        }
    }

    if(remainFileSize > 0){
        SPI_WriteEnable();
        SPI_PageProgram(pagePos*0x100, (BYTE*)(buffUpData+(pagePos*0x100)), remainFileSize);
    }

    ProgressBar1->Position = ProgressBar1->Max;

    return 0;
}

//---------------------------------------------------------------------------
int __fastcall TForm2::File_Verify()
{
    int ret;
    int currentPos = 0;
    DWORD readBlock = 0x8000;
    DWORD remainFileSize;
    BYTE *verifyBuff;

    verifyBuff = new BYTE[dwUpFileSize];
    remainFileSize = dwUpFileSize;

    ProgressBar1->Position = 0;
    ProgressBar1->Max = remainFileSize;

    while(remainFileSize >= readBlock){
        SPI_ReadDataBytes(readBlock*currentPos, verifyBuff+(readBlock*currentPos), readBlock);

        remainFileSize -= readBlock;
        currentPos++;
        ProgressBar1->StepBy(readBlock);
    }

    if(remainFileSize > 0){
        SPI_ReadDataBytes(readBlock*currentPos, verifyBuff+(readBlock*currentPos), remainFileSize);
    }

    ProgressBar1->Position = ProgressBar1->Max;

    ret = memcmp(buffUpData, verifyBuff, dwUpFileSize);

    delete []verifyBuff;
    
    return ret;
}
//---------------------------------------------------------------------------

void __fastcall TForm2::SPI_SectorErase(DWORD address)
{
    BYTE *outBuffer;
    int buffCount = 0;
    DWORD writeSize;
    BYTE address23To16, address15To8, address7To0;

    address23To16 = (BYTE)(address>>8*2);
    address23To16 &= 0x1F;
    address15To8  = (BYTE)(address>>8*1);
    address7To0   = (BYTE)(address>>8*0);

    outBuffer = new BYTE[16];

    //CS LOW
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = 0; //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    //Command + Address
    outBuffer[buffCount++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    outBuffer[buffCount++] = 0x03;
    outBuffer[buffCount++] = 0x00;
    outBuffer[buffCount++] = 0xD8;
    outBuffer[buffCount++] = address23To16;
    outBuffer[buffCount++] = address15To8;
    outBuffer[buffCount++] = address7To0;

    //CS HIGH
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = PORT_SPI_CS;       //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    FT_Write(ftHandle, outBuffer, buffCount, &dwByteWritten);

    delete []outBuffer;

    return;
}

//---------------------------------------------------------------------------

void __fastcall TForm2::SPI_PageProgram(DWORD address, BYTE *data, int size)
{
    BYTE *outBuffer;
    int buffCount = 0;
    DWORD writeSize;
    BYTE writeSizeHigh, writeSizeLow;
    BYTE address23To16, address15To8, address7To0;

    address23To16 = (BYTE)(address>>8*2);
    address23To16 &= 0x1F;
    address15To8  = (BYTE)(address>>8*1);
    address7To0   = (BYTE)(address>>8*0);

    if(size > MEMORY_BYTE_PER_PAGE) return;

    writeSize = (DWORD)(size-1 +1+3); //+1 for Command, +3 for Address
    writeSizeHigh = (BYTE)(writeSize>>8*1);
    writeSizeLow = (BYTE)(writeSize>>8*0);

    outBuffer = new BYTE[writeSize + 16]; //+6 for CS command

    //CS LOW
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = 0; //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    //Command + Address
    outBuffer[buffCount++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    outBuffer[buffCount++] = writeSizeLow;
    outBuffer[buffCount++] = writeSizeHigh;
    outBuffer[buffCount++] = 0x02;
    outBuffer[buffCount++] = address23To16;
    outBuffer[buffCount++] = address15To8;
    outBuffer[buffCount++] = address7To0;

    for(int i=0; i<size; i++){
        outBuffer[buffCount++] = data[i];
    }

    //CS HIGH
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = PORT_SPI_CS;       //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    FT_Write(ftHandle, outBuffer, buffCount, &dwByteWritten);

    delete []outBuffer;

    return;
}

//---------------------------------------------------------------------------
BYTE __fastcall TForm2::SPI_ReadStatus()
{
    BYTE *outBuffer;
    int buffCount = 0;
    BYTE retStatus;

    outBuffer = new BYTE[16];

    //CS LOW
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = 0; //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    //Command
    outBuffer[buffCount++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    outBuffer[buffCount++] = 0x00;
    outBuffer[buffCount++] = 0x00;
    outBuffer[buffCount++] = 0x05;

    //Read
    outBuffer[buffCount++] = MSB_RISING_EDGE_CLOCK_BYTE_IN;
    outBuffer[buffCount++] = 0x00;
    outBuffer[buffCount++] = 0x00;
    outBuffer[buffCount++] = 0x87;  //Send Immediate

    //CS HIGH
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = PORT_SPI_CS;       //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    FT_Write(ftHandle, outBuffer, buffCount, &dwByteWritten);
    FT_Read(ftHandle, &retStatus, 1, &dwByteRead);

    delete []outBuffer;

    return retStatus;
}

//---------------------------------------------------------------------------
void __fastcall TForm2::SPI_ReadDataBytes(DWORD address, BYTE *data, int size)
{
    BYTE *outBuffer;
    int buffCount = 0;
    DWORD readSize;
    BYTE readSizeHigh, readSizeLow;
    BYTE address23To16, address15To8, address7To0;
    DWORD dwEventDWord, dwTxBytes, dwRxBytes;
    String str, str_temp;

    address23To16 = (BYTE)(address>>8*2);
    address23To16 &= 0x1F;
    address15To8  = (BYTE)(address>>8*1);
    address7To0   = (BYTE)(address>>8*0);

    if(size <0) return;

    readSize = (DWORD)(size-1);
    readSizeHigh = (BYTE)(readSize>>8*1);
    readSizeLow = (BYTE)(readSize>>8*0);

    outBuffer = new BYTE[16];

    //CS LOW
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = 0; //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    //Command + Address
    outBuffer[buffCount++] = MSB_FALLING_EDGE_CLOCK_BYTE_OUT;
    outBuffer[buffCount++] = 0x03;      //-_
    outBuffer[buffCount++] = 0x00;      //-  4 BYTE
    outBuffer[buffCount++] = 0x03;      //COMMAND
    outBuffer[buffCount++] = address23To16;
    outBuffer[buffCount++] = address15To8;
    outBuffer[buffCount++] = address7To0;

    //Read
    outBuffer[buffCount++] = MSB_RISING_EDGE_CLOCK_BYTE_IN;
    outBuffer[buffCount++] = readSizeLow;
    outBuffer[buffCount++] = readSizeHigh;
    outBuffer[buffCount++] = 0x87;  //Send Immediate

    //CS HIGH
    outBuffer[buffCount++] = SET_DATA_BITS_LOW_BYTE;
    outBuffer[buffCount++] = PORT_SPI_CS;       //Value
    outBuffer[buffCount++] = SPI_DEF_DIRECTION; //DIrection

    FT_Write(ftHandle, outBuffer, buffCount, &dwByteWritten);
    Sleep(10);
    FT_GetStatus(ftHandle, &dwRxBytes, &dwTxBytes, &dwEventDWord);

    if(dwRxBytes > 0){
        FT_Read(ftHandle, data, size, &dwByteRead);
    }

    delete []outBuffer;

    return;
}