I2Cをアクセスしてみたいなぁってことで次のような仕様で数日かけてI2Cに特化したものを書いていこうと予定しています。
いまは未完成です。
#include "ftd2xx.h" を取り込んで アクセスする格好です。
何らかのラッパーが必要なのでこんなヘッダーを考えました。
いままでLINUXつかってたのですが、LINUXマシンがぶっ壊れたので、しかたなくMINIPCを購入しました。
CORI9 8コア 16スレッド 32GBメモリ搭載です。
I2Cというものだけど10Mhzでも動作できたらいいよねって話でつくっています。 スレーブのデバイスが遅いとむりですけどね。
相手がFPGAだったりすると、マジ10MhzでI2Cって動作しますから。ーーーー
JIG的で 相手がきちんとACKかえしてくれるならいいですが、いい加減な設計のFPGAのIPではACK返してこないインチキが存在します。そんな輩と通信するために // I2C Ignore Mode をつくりました。 ACK無視で動作できるようにしました。
GPIOとしても動作するし、ハードのシリアライザでI2Cにもアクセスする感じです。
タイプはカッコつけて 選べるようにしたいのですが実際はI2C特化です。 ^^;
いまは、ちょっとあれこれしたいなっておもったところで無駄なものがあります。
メンバー関数も一貫性がないのでこれからちょっと直していきます。
本体はまだ書いていません。
#ifndef FTDISPIWRAPPER_H
#define FTDISPIWRAPPER_H
#include <windows.h>
#include "ftd2xx.h"
#include <cstdint>
#include <string>
#include <vector>
// I2C Ignore Mode
#define NORMAL_OPERATION 0x00
#define IGNORE_SLAVE_ADDRESS_NACK 0x01
#define IGNORE_DATA_NACK 0x02
#define INTERACTIVE_MODE 0x04
class FT232HFifo {
public:
FT232HFifo(DWORD freq = 0);
~FT232HFifo();
FT_STATUS Write(uint8_t slaveAddress, uint64_t deviceAddress, const std::vector<uint8_t>* data, uint8_t deviceAddressSize = 1, uint8_t ignoreMode = NORMAL_OPERATION);
FT_STATUS Read (uint8_t slaveAddress, uint64_t deviceAddress, std::vector<uint8_t>* data, uint8_t deviceAddressSize = 1, uint8_t ignoreMode = NORMAL_OPERATION);
FT_STATUS command(std::vector<int16_t>& buffer, std::vector<uint8_t>* buf); // 最初の1バイトはコマンド あとはパラメータ
bool is_open();
FT_STATUS openDevice(int type = 0);
void ReadBytes(std::vector<uint8_t>* data);
bool I2CReadbytes(uint8_t bUnitID, uint8_t bDeviceAddr, uint32_t ustargaddress, std::vector<uint8_t>& result);
bool I2CWritebytes(uint8_t bUnitID, uint8_t bDeviceAddr, uint32_t ustargaddress, std::vector<uint8_t>& result);
private:
int m_type; // 0: 名前, 1: 強制GPIO, 2: 強制I2C
std::vector<std::string> descript{"GPIO_Driver", "SPI Driver","I2C_Driver"};
bool m_isOpenDevice;
FT_STATUS init();
FT_STATUS simpleByteWrite(UCHAR* D0_D7, UCHAR* C0_C7);
void closeDevice();
FT_STATUS openDeviceByDescription(std::string Description);
FT_HANDLE ftHandle = NULL;
std::vector<FT_DEVICE_LIST_INFO_NODE> UpdateDeviceList(); // デバイスリストを更新するメソッド
int getFt232HMydeviceDeviceIndex(std::string discription = "Single RS232-HS");
std::vector<FT_DEVICE_LIST_INFO_NODE> deviceList; // デバイスリストを保持するベクター
FT_DEVICE_LIST_INFO_NODE m_Selecteddevice;
void AddToBuffer(bool address, std::vector<UCHAR>& buffer, UCHAR value);
FT_STATUS read_sub_setCommand(std::vector<int8_t>* rbuffer, int8_t command); // 最初の1バイトはコマンド あとはパラメータ
FT_STATUS read_1char(std::vector<int8_t>* rbuffer);
bool read(std::vector<uint8_t>* rbuffer, int8_t command); // 最初の1バイトはコマンド あとはパラメータ
FT_STATUS setCLDCTLPins(std::vector<int8_t>* sequencebuff, int8_t cmd);
FT_STATUS FTDI_MPSSESetup(DWORD frequency = 10000000);
BYTE FTDI_FlushReadBUffer();
BYTE FTDI_GPIOCheck();
DWORD m_frequency;
DWORD m_loopCount;
const BYTE PORT_SCLK = 0x01;
const BYTE PORT_DO = 0x02;
const BYTE PORT_DI = 0x04;
const BYTE PORT_ALERT = 0x20; // ADBUS5
const BYTE PORT_THERM = 0x80; // ADBUS7
const BYTE MSB_FALLING_EDGE_CLOCK_BYTE_OUT = 0x11;
const BYTE MSB_RISING_EDGE_CLOCK_BYTE_OUT = 0x10;
const BYTE MSB_RISING_EDGE_CLOCK_BIT_IN = 0x22;
const BYTE MSB_RISING_EDGE_CLOCK_BYTE_IN = 0x20;
const BYTE MSB_FALLING_EDGE_CLOCK_BYTE_IN = 0x24;
const BYTE SET_DATA_BITS_LOW_BYTE = 0x80;
const BYTE READ_DATA_BITS_LOW_BYTE = 0x81;
const bool TEMP_MODE_LOCAL = false;
const bool TEMP_MODE_REMOTE = true;
};
#endif // FTDISPIWRAPPER_H
#include <iostream>
#include "ftdispiwrapper.h" //何らかのラッパーです。
using namespace std;
FT232HFifo * m_FT232HFifo=nullptr;
int main()
{
m_FT232HFifo= new FT232HFifo( 10000000);//5Mはきれいに5Mhz 10はきれいに10Mhz 1M 1M
m_FT232HFifo->openDevice(2);
bool ftStatus=m_FT232HFifo->is_open();
if (!ftStatus ){
std::cout<<ftStatus<<"アプリケーションを終了させる"<<std::endl; // メッセージボックスを表示
return -1;
}
cout << "Hello World!I2C で今回初期化終了" << endl;
std::vector<uint8_t> data={1,2,3,4};
m_FT232HFifo->Write(0x41, 0x030201, &data,3,INTERACTIVE_MODE);
m_FT232HFifo->Read(0x41, 0x030201, &data,8,INTERACTIVE_MODE|IGNORE_SLAVE_ADDRESS_NACK);
return 0;
}
つづく