汎用I/OはCPLDのピンを汎用ポートとして使うためのCPLDのロジックです。CPLDの書き込み用JEDファイルで提供されます。
汎用I/Oは汎用ファームウエアと組み合わせて使うことが出来ます。このときカメレオンUSBのアプリケーション開発は、カメレオンUSBのアタッチ基板の配線と、PCで動くソフトウエアの開発のみですむため、非常に簡単になります。
汎用I/Oのデメリットは、I/Oへの転送速度が遅い点です。転送速度が遅くても良い場合は、汎用I/O+汎用FWで開発されるのがベストです。また、汎用I/Oでとりあえず動作の確認を行い、その後高速化のためにCPLDのロジックや、FWの開発を行うような使い方も可能です。
汎用I/Oは11本(P0-PB)の8bitポートからなり、このうち8本(P0-P7)のポートは個別に入力・出力の切り替えが出来ます。残りのポート(P8-PB)は出力ポートとして使います。
各ポートのピン配置は下記の表のとおりです。

ポート コネクタ CPLD ポート コネクタ CPLD
P0_0 CN1-7 110 P6_0 CN3-17 25
P0_1 CN1-8 111 P6_1 CN3-18 26
P0_2 CN1-9 112 P6_2 CN3-19 27
P0_3 CN1-10 113 P6_3 CN3-20 28
P0_4 CN1-11 115 P6_4 CN3-21 30
P0_5 CN1-12 116 P6_5 CN3-22 31
P0_6 CN1-13 117 P6_6 CN3-23 32
P0_7 CN1-14 118 P6_7 CN3-24 33
P1_0 CN1-15 119 P7_0 CN2-4 61
P1_1 CN1-16 120 P7_1 CN2-5 64
P1_2 CN1-17 121 P7_2 CN2-6 66
P1_3 CN1-18 124 P7_3 CN2-7 68
P1_4 CN1-19 125 P7_4 CN2-8 69
P1_5 CN1-20 126 P7_5 CN2-9 70
P1_6 CN1-21 128 P7_6 CN2-10 71
P1_7 CN1-22 129 P7_7 CN2-11 74
P2_0 CN1-23 130 P8_0 CN2-12 75
P2_1 CN1-24 131 P8_1 CN2-13 76
P2_2 CN1-25 132 P8_2 CN2-14 77
P2_3 CN1-26 133 P8_3 CN2-15 78
P2_4 CN1-27 134 P8_4 CN2-16 79
P2_5 CN1-28 135 P8_5 CN2-17 80
P2_6 CN1-29 136 P8_6 CN2-18 81
P2_7 CN1-30 137 P8_7 CN2-19 82
P3_0 CN1-31 138 P9_0 CN2-20 83
P3_1 CN1-32 139 P9_1 CN2-21 85
P3_2 CN1-33 140 P9_2 CN2-22 86
P3_3 CN1-34 142 P9_3 CN2-23 87
P3_4 CN1-35 143 P9_4 CN2-24 88
P3_5 CN1-36 2 P9_5 CN2-25 91
P3_6 CN1-37 3 P9_6 CN2-26 92
P3_7 CN1-38 4 P9_7 CN2-27 93
P4_0 CN3-1 7 PA_0 CN2-28 94
P4_1 CN3-2 9 PA_1 CN2-29 95
P4_2 CN3-3 10 PA_2 CN2-30 96
P4_3 CN3-4 11 PA_3 CN2-31 97
P4_4 CN3-5 12 PA_4 CN2-32 98
P4_5 CN3-6 13 PA_5 CN2-33 100
P4_6 CN3-7 14 PA_6 CN2-34 101
P4_7 CN3-8 15 PA_7 CN2-35 102
P5_0 CN3-9 16 PB_0 CN2-36 103
P5_1 CN3-10 17 PB_1 CN2-37 104
P5_2 CN3-11 19 PB_2 CN2-38 105
P5_3 CN3-12 20 PB_3 CN2-39 106
P5_4 CN3-13 21 PB_4 CN2-40 107
P5_5 CN3-14 22 PB_5 CN3-25 34
P5_6 CN3-15 23 PB_6 CN3-26 35
P5_7 CN3-16 24 PB_7 CN3-27 38

汎用I/Oのレジスタマップ

レジスタ 内容
0x0 P0データ
0x1 P1データ
0x2 P2データ
0x3 P3データ
0x4 P4データ
0x5 P5データ
0x6 P6データ
0x7 P7データ
0x8 P8データ
0x9 P9データ
0xa PAデータ
0xb PBデータ
0xf P0-P7の入出力設定
0:入力 1:出力
デフォルト値 0x0

汎用ファームウエア・汎用I/O使用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <windows.h>
#include <stdio.h>

#include "cusb.h"
#include "gpfw.h"

extern u8 fw_bin[];
u8 buf[64];
HANDLE dh;

int main(int argc,char *argv[]){
 if(cusb_init(0,&dh,fw_bin,"GPFW","V100")){
  printf("Can't found Chameleon USB.\n");
  exit(-1);
 }
 //GPIOの初期化
 buf[0]=GPFW_DIR | 0x0f;
 buf[1]=GPFW_SET | 0x00;
 usb_bulk_write(&dh,GPFW_CPIPE,buf,2);
 //P0-P3,P6-P7:出力 P4-P5:入力
 buf[0]=GPFW_WRITE | 0x0f;
 buf[1]=0xcf;
 //P0に0xaaを出力
 buf[2]=GPFW_WRITE | 0x00;
 buf[3]=0xaa;
 //P1に0x55を出力
 buf[4]=GPFW_WRITE | 0x01;
 buf[5]=0x55;
 //P4からデータ入力
 buf[6]=GPFW_READ | 0x04;
 //P5からデータ入力
 buf[7]=GPFW_READ|0x05;
 //コマンドの転送
 usb_bulk_write(&dh,GPFW_CPIPE,buf,8);
 //ポート(P4,P5)データの読み込み
 usb_bulk_read(&dh,GPFW_RPIPE,buf,2);
 //ポートの表示
 printf("P4=%x,P5=%x\n",buf[0],buf[1]);
 usb_close(&dh);
}

このサンプルは、P0-P3を出力ポート、P4-P7を入力ポートに定義して、P0に0xaa、P1に0x55を出力して、P4、P5の入力ポートを読み出してコンソールに表示するサンプルプログラムです。このソース以外にカメレオンUSBのcusb.c、cusb.h、汎用ファームウエアのgpfw.cをリンクする必要があります。また、CPLD書き込みプログラム「cusbwr.exe」を使って、このページでダウンロード出来るgpio.jedをCPLDにプログラムする必要があります。

簡単にプログラムの解説を行います。
5行目でインクルードしているファイルは、汎用ファームウエアのための定義ファイルです。GPFW_xxxの定義がされています。
7行目のfw_binはgpfw.cの、汎用FWのバイナリへのポインタです。
12行目で汎用FWをEZ-USBにダウンロードさせます。引数の"GPFW","V100"は「汎用FW」で「バージョン1.00」の意味ですが、EZ-USBにすでに同じバージョンの汎用FWがダウンロードされているかをこの引数で調べます。
17行目はEZ-USBの持つ4本のI/Oポート(詳しくは汎用FWのページを参照)を出力に設定します。汎用I/Oでは4本のI/Oポートを使ってCPLDのポートを選択します。
18行目はとりあえずこのポートを0にセットしておきます。これは別にしなくても問題はありません。
19行目で2バイト汎用FWのコマンド用パイプを使って上記コマンドの2バイト分を転送します。EZ-USBはこの2バイトを受信するとコマンドを解釈して実行します。
21、22行目でCPLDのポートの方向を設定します。0x0fでORしているのは、CPLDのポート方向指定レジスタが0x0fにマッピングされているからです。このように、対象のレジスタ番号をORして指定します。
24、25行目でポート0のレジスタに0xaaの書き込みを指示します。
30行目はポート4に対して読み込みを指示します。この読み込んだデータはデータ読み込みようパイプ(GPFW_RPIPE)を使って読み込まれます。(36行目)
34行目でコマンドをEZ-USBに転送します。


汎用I/Oとは関係ないのですが、汎用FWのバースト転送機能を紹介しておきます。このバースト転送は高速にUSBでデータをやりとりするための方法で、1Mbyte/Sec程度の速度が出せます。汎用I/Oではポートに出力する値を1バイト、EZ-USBのデータバス+FWRを使ってCPLDに書き込みます。バースト転送はこれを1バイトではなく、連続して任意のバイト数転送します。このためメモリのようなデバイスをCPLDに接続して、アドレスバスを転送の毎にインクリメントといったロジックをCPLDに組み込む必要があります。(ロジアナではこのような方法を行っています。)

#include <windows.h>
#include <stdio.h>

#include "cusb.h"
#include "gpfw.h"

extern u8 fw_bin[];
u8 buf[1024*1024];
HANDLE dh;

int main(int argc,char *argv[]){
 s32 i;
 u8 cmd[16];
 if(cusb_init(0,&dh,fw_bin,"GPFW","V100")){
  printf("Can't found Chameleon USB.\n");
  exit(-1);
 }
 //EZ-USBの初期化
 cmd[0]=GPFW_DIR | 0x0f;
 cmd[1]=GPFW_SET | 0x00;
 usb_bulk_write(&dh,GPFW_CPIPE,cmd,2);
 //バースト読み込み(1024*1024byte)
 cmd[0]=GPFW_BREAD | 0x02;
 cmd[1]=(1024*1024) & 0x3f;
 cmd[2]=(1024*1024) >> 6;
 cmd[3]=(1024*1024) >> 14;
 usb_bulk_write(&dh,GPFW_CPIPE,cmd,4);
 usb_bulk_read(&dh,CPF_RPIPE,buf,1024*1024);
 //データ反転
 for(i=0;i<1024*1024;i++){
  buf[i] ^= 0xff;
 }
 //バースト書き込み(1024*1024byte)
 cmd[0]=GPFW_BWRITE | 0x03;
 cmd[1]=(1024*1024) & 0x3f;
 cmd[2]=(1024*1024) >> 6;
 cmd[3]=(1024*1024) >> 14;
 usb_bulk_write(&dh,GPFW_CPIPE,cmd,4);
 usb_bulk_write(&dh,GPFW_WPIPE,buf,1024*1024);
 usb_close(&dh);
}

このサンプルはカメレオンUSBから1Mbyteのデータを受け取り、データを反転して、1Mbyteのデータを返すサンプルです。
読み込むときにはGPFW_BREAD | 0x02のように0x02をEZ-USBのポートからCPLDに出力して、これからデータを受信することを明示させています。これはあくまでも例ですが、このようにEZ-USBのポートをコマンドのような形に使うことができます。


ダウンロード

汎用I/O gpio.jed (cusbwr.exeを使ってCPLDに書き込みます。)
汎用I/O WebPack用  (汎用I/Oをカスタマイズしてロジック生成したい人へ)