第 3 章 機能別制御方法 39
3.1.7 送受信処理
【送信動作】
送信バッファへのデータ書き込みのあと、
DTSDコマンドを発行することで、データを送信します。
DTSDコマンド発行のプログラム例をリスト6に示します。
送信完了後のHDLCコントローラの動作はMDSTコマンドで設定したTXEDの設定値によって異 なります。
送信データの結合
送信データは、送信バッファとDTSDコマンド内に設定できます。
DTSDコマンドへの設定は最大 8バイトです。
DTSDコマンドに送信データを設定した場合、送信フレームの先頭フラグのあとにDTSDに設定し
た送信データを送信し、その後送信バッファのデータを送信します。送信バッファチェイン
HDLCコントローラはDTSDコマンドの実行により、BUFAで指定するメモリアドレス上のデータ
とDTSDコマンド内に設定されたデータを送信します。1フレームのデータ長を16Kバイト以上とする場合、または送信バッファ内に設定したデータが複
数の領域に分割して格納されている場合のデータ送信時、送信バッファチェインによる送信がで きます。送信バッファチェインは、送信データを送信バッファに設定し、それぞれのデータに対応する送 信データアドレスを指定したDTSDコマンドを連続的に用意します。このとき、チェインにより最 終データとなるDSTDコマンド以外のDTSDコマンドのCBビットを1にセットします。
送信バッファチェインを行う場合、DTSDコマンドへの送信データ設定は、チェインの最初の
DTSDコマンドのみ可能です。
【受信動作】
HDLCコントローラはデータを受信すると、 DTRVステータスを報告します。
リスト7に受信データの取得例を示します。
受信データの分離
HDLCコントローラは、受信フレームのデータを受信バッファとDTRVステータスのデータ領域と
に分離して受信できます。DTRVへの受信データは、MDSTコマンドのSTBCパラメータで指定できます。
DTRVに格納される受信データは、受信フレームの先頭フラグ直後からMDSTコマンドのSTBCパ
ラメータで指定したバイト数となります。受信バッファのチェイン
HDLCコントローラは、受信したフレームがMDSTコマンドで設定したRXBS以上MAXD以下のサ
イズの場合、複数の受信バッファに分割して受信データを格納します。この場合、受信したデー タはDTRVステータスのBUFAを先頭アドレスとする受信バッファをチェインしてBCバイト分格 納されます。受信データの取り出し後、使用した受信バッファ・アドレス・テーブルを全て開放 してください。アドレスフィールド認識
HDLCコントローラは受信フレーム先頭フラグ直後のアドレス部のデータに対する認識機能があ
ります。アドレス認識可能なデータ数は、1バイトまたは2バイトで、
MDSTコマンドのAUTOパラメータ
で設定します。受信するアドレスはAFSTコマンドで設定します。
AFSTコマンドで指定されたアドレス以外のデータはエラーフレームとして扱われます。
エラーフレームの扱い
エラーフレームを受信した場合の動作は、
MDSTコマンドで設定したSAFパラメータによって異な
ります。SAFパラメータが’0’の場合、エラーフレームは破棄され、SAFパラメータが’1’の場合は、保存さ
れます。詳しくは『26ページ 2.7.3 MDSTコマンド』を参照してください。
エラーフレームには、次のようなものがあります。
エラーフレーム 意味
Abort Frame 7ビット以上の連続した’1’のフレーム
FCS Error Frame FCSでエラーとなったフレーム
Long Frame MDSTコマンドのRXBSで設定した受信バッファサイズを超えたフレーム
Short Frame MDSTコマンドのSHORTで設定したデータ数未満のフレーム
No Address AFSTコマンドで設定したアドレス以外のアドレスをもつフレーム
〈リスト6〉データ送信のサンプルプログラム
#include <stdio.h>
#include <dos.h>
#include "GETBAR.H"
#include "FBIUIO.H"
unsigned long BA; /* HDLC通信制御アドレス */
unsigned long DPRAM; /* メモリベースアドレス */
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
/* */
/* DTSDコマンド発行サブルーチン */
/* */
/* int dtsd(unsigned long cadr,char *s,int l,unsigned int ba); */
/* */
/* 入力パラメータ cadr ‑‑‑ コマンドアドレス */
/* s ‑‑‑‑‑‑ 送信データ */
/* l ‑‑‑‑‑‑ 送信データ長 */
/* ba ‑‑‑‑‑ 送信データバッファアドレス */
/* 出力パラメータ 0 ‑‑‑‑‑‑ 正常終了 */
/* 1 ‑‑‑‑‑‑ 異常終了 */
/* */
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
void dtsd(unsigned long cadr,char *s,int l,unsigned long ba) {
unsigned long adr,tba;
unsigned int i;
adr = DPRAM + cadr; /* コマンド書き込みアドレス */
tba = DPRAM + ba; /* 送信データ書き込みアドレス */
for (i = 0; i < l; i++){ /* 送信データをメモリにセット */
UioPokeByte(tba+i,*s++);
}
if (UioPeekByte(adr+0x1) < 0xfc) return 1; /* CMDSがFCh未満ならエラー */
/* DTSDコマンドの書き込み */
UioPokeByte(adr+0x2,0x00); /* CB,TXBC=0 */
UioPokeByte(adr+0x3,(unsigned char)(l & 0xff)); /* BC(L) */
UioPokeByte(adr+0x4,(unsigned char)((l>>8) & 0xff)); /* BC(H) */
UioPokeByte(adr+0x5,(unsigned char)(ba & 0xff)); /* BUFA(L) */
UioPokeByte(adr+0x6,(unsigned char)((ba>>8) & 0xff)); /* BUFA(M) */
UioPokeByte(adr+0x7,(unsigned char)((ba>>16) & 0xff)); /* BUFA(H) */
UioPokeByte(adr+0x8,0x00); /* TXDT */
UioPokeByte(adr+0x9,0x00); /* TXDT */
UioPokeByte(adr+0xa,0x00); /* TXDT */
UioPokeByte(adr+0xb,0x00); /* TXDT */
UioPokeByte(adr+0xc,0x00); /* TXDT */
UioPokeByte(adr+0xd,0x00); /* TXDT */
UioPokeByte(adr+0xe,0x00); /* TXDT */
UioPokeByte(adr+0xf,0x00); /* TXDT */
UioPokeByte(adr+0x0,0x31); /* CMDN */
UioPokeByte(adr+0x1,0x00); /* CMDS */
UioPokeByte(BA+0x0,0x01); /* CCRQ発行 */
return 0;
}
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
/* メイン処理 */
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
void main(void) {
unsigned int bus̲info;
PCI̲CONFIG PciData;
/* リソース取得 */
PciGetConfigRegEx(1,0x1147,4172,0x1147,0x0001,&bus̲info,&PciData);
BA = PciData.BaseAddresses[0];
DPRAM = PciData.BaseAddresses[1];
/* データ送信 */
dtsd(0x10UL,"0123456789ABCDEF",16,0x800);
}
〈リスト7〉受信データ取り出しのサンプルプログラム
#include <stdio.h>
#include <dos.h>
#include "GETBAR.H"
#include "FBIUIO.H"
unsigned long BA; /* HDLC通信制御アドレス */
unsigned long DPRAM; /* メモリベースアドレス */
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
/* */
/* 受信データ取りだしサブルーチン */
/* */
/* int getdata(unsigned char *s,unsigned char *d,int *l); */
/* */
/* 入力パラメータ sadr ‑‑‑‑‑‑‑ ステータスアドレス */
/* d ‑‑‑‑‑‑ 受信データ格納バッファ */
/* l ‑‑‑‑‑‑ 受信データ長格納バッファ */
/* badr ‑‑‑ 受信バッファアドレステーブル */
/* 出力パラメータ 0 ‑‑‑‑‑‑ 正常終了 */
/* 1 ‑‑‑‑‑‑ 異常終了(S(n)ステータスがDTRVでない) */
/* */
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
int getdata(unsigned long sadr,unsigned char *d,int *l,unsigned long badr) {
int i,cl;
unsigned long adr,da,ta;
unsigned char s[16];
adr = DPRAM + sadr; /* ステータス読み込みアドレス */
if (UioPeekByte(adr) != 0x31){ /* ステータスがDTRVでなければエラー */
return 1;
}
for (i = 0; i < 16; i++){ /* ステータス取りだし */
s[i] = UioPeekByte(adr+i);
}
UioPokeByte(adr,0xff); /* STSNをFFhにする */
da = (unsigned long)s[5] + /* 受信データ格納先アドレスを */
((unsigned long)s[6] << 8) + /* DTRVステータスから取り出す */
((unsigned long)s[7] << 16);
da = da + DPRAM; /* 受信データ読み出しアドレス */
ta = badr + DPRAM; /* 受信バッファテーブルアドレス */
*l = (int)s[3] + ((int)s[4] << 8); /* 受信データ長 */
cl = (int)s[2] & 0x07; /* ステータス内の受信データ長 */
for (i = 0; i < cl; i++){ /* ステータス内の受信データ取りだし */
*d++ = s[8+i];
}
for (i = 0; i < *l; i++){ /* 受信データりだし */
*d++ = UioPeekByte(da+i);
}
UioPokeByte(ta,0x00); /* 受信バッファテーブルのBRDYを00hにする*/
*l += cl;
return 0;
}
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
/* メイン処理 */
/* ‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑ */
void main(void) {
int rxsize;
unsigned int bus̲info;
PCI̲CONFIG PciData;
unsigned char rxdata[256];
/* リソース取得 */
PciGetConfigRegEx(1,0x1147,4172,0x1147,0x0001,&bus̲info,&PciData);
BA = PciData.BaseAddresses[0];
DPRAM = PciData.BaseAddresses[1];
/* 受信データ取り出し */
getdata(s,rxdata,&rxsize,0x400UL);
}