You are here

C++ - FTDI BitBang-Mode

// Literatur:
//      Manuals vom Hersteller FTDI
 
// Library hinzufügen:               ftd2xx.lib
// Header-Datei inkludieren:         ftd2xx.h
// DLLs in Ausgabe-Ordner kopieren:  ftbusui.dll
//                                   ftcserco.dll
//                                   ftd2xx.dll
//                                   ftlang.dll
//                                   ftserui2.dll
 
/* Beispiel einer Ausgabe-Datei:
        date          time        value
        2012.11.21    13:06:24    0xf0
        2012.11.21    13:06:28    0xf1
        2012.11.21    13:06:28    0xf0
*/
 
#include <iostream>
#include <fstream>
#include <iomanip>
#include <conio.h>
#include <string>
#include <time.h>
#include <windows.h>
#include "ftd2xx.h"
 
using namespace std;
 
#define D0              0x01        // TXD (orange wire)
#define D1              0x02        // RXD (yellow wire)
#define D2              0x04        // RTS (green wire)
#define D3              0x08        // RTS (brown wire)
 
#define RESET_MODE      0x00
#define ASYNC_BIT_BANG  0x01
#define SYNC_BIT_BANG   0x04
 
 
int main(int argc, char **argv)
{
    FT_HANDLE handle;
    FT_STATUS status;
    DWORD nrDevices;
    DWORD bytesWritten;
    DWORD bytesRead;
    int devNr = 0;
    unsigned char latency = 0;
    unsigned char output = 0;
    unsigned char input = 0;
    int tmp = 0;
    time_t rawtime;
    struct tm* timeinfo;
 
 
    try
    {
        if ((argc == 2) && (strcmp(argv[1], "-list") == 0))
        {
            status = FT_ListDevices(&nrDevices, NULL, FT_LIST_NUMBER_ONLY);
            if(status != FT_OK)
                throw("Can't list connected devices!");
 
            cout << "Number devices connected: " << nrDevices << endl;
        }
        else if ((argc == 3) && (strcmp(argv[1], "-write") == 0))
        {
            devNr = atoi(argv[2]);
            status = FT_Open(devNr, &handle);
            if(status != FT_OK)
                throw("Can't open device!");
 
            // 0...input, 1...output
            FT_SetBitMode(handle, D0 | D1 | D2 | D3, ASYNC_BIT_BANG);
            if(status != FT_OK)
                throw("Can't set bit-mode!");
 
            // 9600 * 16
            FT_SetBaudRate(handle, FT_BAUD_9600);
            if(status != FT_OK)
                throw("Can't set baud rate!");
 
            cout << "End write mode with 0xff!" << endl;
 
            do
            {
                cout << "New value (x x x x D3 D2 D1 D0): ";
                cin >> hex >> tmp;
 
                if (tmp != 0xFF)
                {
                    output = (unsigned char)tmp & 0x0F;
                    FT_Write(handle, &output, 1, &bytesWritten);
                    if(status != FT_OK)
                        throw("Can't write to device!");
 
                    Sleep(100);
                }
            }
            while (tmp != 0xFF);
 
            FT_Close(handle);
            if(status != FT_OK)
                throw("Can't close device!");
        }
        else if ((argc == 4) && (strcmp(argv[1], "-read") == 0))
        {
            // open output file
            ofstream out(argv[3]);
            if(!out.is_open())
                throw("Can't open file!");
 
            // open FTDI device
            devNr = atoi(argv[2]);
            status = FT_Open(devNr, &handle);
            if(status != FT_OK)
                throw("Can't open device!");
 
            // 0...input, 1...output
            FT_SetBitMode(handle, 0, ASYNC_BIT_BANG);
            if(status != FT_OK)
                throw("Can't set bit-mode!");
 
            // 9600 * 16
            FT_SetBaudRate(handle, FT_BAUD_9600);
            if(status != FT_OK)
                throw("Can't set baud rate!");
 
            cout << "End read mode by unplugging the device!" << endl;
            out << "date\ttime\tvalue" << endl;
 
            do
            {
                // clear device buffers
                status = FT_Purge(handle, FT_PURGE_RX | FT_PURGE_TX);
                if(status != FT_OK)
                {
                    out.close();
                    cout << "File was written." << endl;
 
                    throw("Can't clear device buffers!");
                }
 
                // read all inputs
                status = FT_Read(handle, &input, 1, &bytesRead);
                if(status != FT_OK)
                {
                    out.close();
                    cout << "File was written." << endl;
 
                    throw("Can't read from device!");
                }
 
                // if something changed
                if (tmp != input)
                {
                    time(&rawtime);
                    timeinfo = localtime(&rawtime);
                    out << setfill('0');
                    out << setw(4);
                    out << timeinfo->tm_year + 1900 << ".";
                    out << setw(2);
                    out << timeinfo->tm_mon << ".";
                    out << setw(2);
                    out << timeinfo->tm_mday << "\t";
                    out << setw(2);
                    out << timeinfo->tm_hour << ":";
                    out << setw(2);
                    out << timeinfo->tm_min << ":";
                    out << setw(2);
                    out << timeinfo->tm_sec;
                    out << hex << "\t0x" << (int)input << dec << endl;
                }
                tmp = input;
            }
            while(true);
 
            FT_Close(handle);
            if(status != FT_OK)
                throw("Can't close device!");
 
            out.close();
        }
        else
        {
            cout << endl;
            cout << "  " << argv[0] << " -list" << endl;
            cout << "      ... lists some information" << endl;
            cout << endl;
            cout << "  " << argv[0] << " -write 0" << endl;
            cout << "      ... opens device 0 in output mode" << endl;
            cout << endl;
            cout << "  " << argv[0] << " -read 0 samples.txt" << endl;
            cout << "      ... opens device 0 in input mode" << endl;
            cout << "          and stores read data in samples.txt" << endl;
            cout << endl;
        }
    }
    catch(char const *error)
    {
        cout << "Error: " << error << endl;
    }
    catch(...)
    {
        cout << "Undefined Error!" << endl;
    }
 
    cout << "Press any key..." << endl;
    getch();
    return 0;
}