汎用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をカスタマイズしてロジック生成したい人へ)