目次
バンチ電流モニターは509MHzで動作する8ビットのメモリーボードです。メモリー自体は20Mbもっていますが、高速更新・アクセスを実現するためアドレス空間を制限しています。
本デバイスサポートはバンチ電流モニターデータ更新と同時にリフレクティブメモリーへのアクセスもするようになっており、KEKB専用です。
- ブロック図

- 入射時は、入射トリガー(最大50Hz)をdelayしたもの[入射が終わった数ms後の信号]でバンチ電流モニターをストップします。蓄積時は入射トリガーの代わりに1Hzのトリガーに切り替わります。この部分は本ボードとは別システムです。
- ストップ信号によりVMEシステムに割り込みがかかりバンチ電流モニターを読みとり状態にして、データ転送を開始します。1バンチデータは8ビットですが、これをD32で一度に4個読みとります。時間節約のため常に先頭から5120までしか読みません。(メモリー自体は大容量メモリーボードシステムとの互換性のため20Mb積んでいます。また、先頭データがあまりにも古くなったりしないためにアドレス空間を1Mに制限しています)
- EPICS waveformへのデータ転送(バンチ電流に換算したFLOATデータ)と同時にshared memory boardへもバンチ電流データを書き込み(unsigned short)、shared memory boardのリング識別フラグ及び割り込みフラグを立てます。shared memory boardのデータを用いて入射器トリガータイミング制御を入射器側のIOCが行っています。
- データ転送終了後、バンチ電流モニターシステムをリセットし、次のストップトリガーに備えます。ロジックアナライザを用いた実測でストップ割り込みから5120データ転送終了まで(shared memory boardへの書き込み含む)約1.4msかかります(PPC750使用)。また、2ボード(HER用、LER用)同時に100Hzトリガーでの使用(実際はあり得ない)でも問題はありません。なお、EPICS waveform転送自体は低速で、ネットワークの負荷を考えても表示更新レートは高くできません。
- 制御室の写真
- メモリーボード内部の写真
- VMEファンクション
- アドレスはA32およびA24をサポートしますが、本デバイスサポートはA32(拡張)用です。
- AMコードは0x0D(拡張特権)と0x3D(標準特権)をサポートしますが、本デバイスサポートは0x0D用です。
- 本システム1台で4,194,304バイト空間を占有します。つまり、0x00400000ごとのアドレス設定となります。このうち下位0x00200000をデータメモリ用に、上位0x00200000をコントロール用に(とはいってもほんの4ロングワードのみ)使用します。基本的にFIRフィルターボードと同じ構造ですがアクセス方法は全く異なります。
バンチ電流モニターボードのアドレスマップは以下の通りです。
- 0x**000000
データメモリ(R/W)。本システムには20Mbのメモリーが乗っていますが、アドレスマップされているのは512kBのみです。さらに基本的にそのうち先頭の5120しか読みません。
- 0x**200000
コントロールレジスタ1。メモリーのstart/stop(ビット0)、カウンタークリア(ビット2)、動作(ビット3)等の機能があります。何種類かのビットパターンの組み合わせで動作します。
- 0x**200004
コントロールレジスタ2。データ転送方式の指定をします。特にD32のときは設定しないとまともに動きません。
- 0x**200008
ストップビット1。本デバイスサポートでは使用しません。意味はメモリーボードの解説に書いてあるのと同じです。
- 0x**20000A
ストップビット2。本デバイスサポートでは使用しません。意味はメモリーボードの解説に書いてあるのと同じです。
本デバイスサポートは、EPICS R313改訂版で開発したものです。EPICSそのものに対する説明、入門出家入道遁世については専門家に帰依するなり、コントロールグループのページをご参照なさるなり勝手になさってください。動作はPPC750のみで確認しています。
コードは以下の通りです。通常使用しない部分に関しては完全なテストは行っていません。
Advanet1522のアドレス
作者の違いにより、Advanet1522 shared memory関連のアドレス指定は特殊です。
#define R_MID (CARD1522 + 0x03) /* Node ID */
#define R_MINF1 (CARD1522 + 0x07) /* Memory Information 1 */
#define R_MINF2 (CARD1522 + 0x0B) /* Memory Information 2 */
#define R_SR (CARD1522 + 0x0F) /* Status */
#define R_CMD (CARD1522 + 0x13) /* Command */
#define R_HCNT (CARD1522 + 0x17) /* Hop Count Register */
#define R_IIVEC (CARD1522 + 0x1B) /* Internal Interrupt Vector */
#define R_IILEV (CARD1522 + 0x1F) /* Internal Interrupt Level */
#define R_EIVEC (CARD1522 + 0x23) /* External Interrupt Vector */
#define R_EILEV (CARD1522 + 0x27) /* External Interrupt Level */
#define R_TITID (CARD1522 + 0x2B) /* Transfer Interrupt Command ID */
#define R_TIINF (CARD1522 + 0x2F) /* Transfer Interrupt Information */
#define R_RIDTD (CARD1522 + 0x33) /* Receive Interrupt Command ID */
#define R_RIINF (CARD1522 + 0x37) /* Receive Interrupt Infromation */
#define R_MEM1 ((void*)(CARD1522 + 0x200))
/* Start addr. of network shared memory */
#define R_MEM2 ((void*)(CARD1522 + 0x2200))
初期化部
バンチ電流モニターと同時にshared memory ADVANET1522の初期化もします。
if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char *)Base_IO,(char **)&p) == ERROR)
{
logMsg("VmebcmL: cannot find extended address space\n");
return(ERROR);
}
/* これはバンチ電流モニター用アドレス割り振り */
cards[cardNum].card = p; /* Remember address of the board */
cards[cardNum].card->cntl2 = 0x40;
/* データ転送方式をD32-compressedにするおまじない */
cards[cardNum].card->cntl1 = 0x01;
/* とりあえずバンチ電流モニターをstop状態にする
初期化中に割り込みが入ると困るから */
scanIoInit(&(cards[cardNum].ioscanpvt));
/* 割り込みベクタ初期化 */
FASTLOCKINIT(&(cards[cardNum].lock));
FASTUNLOCK(&(cards[cardNum].lock)); /* Init the board lock */
/* ここからAdvanet 1522初期化ルーチン */
BASE1522=0x30000000; /* 完全に決めうち */
if (sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA, (char *)(int)BASE1522,
(char **)&CARD1522) == ERROR)
{
logMsg("devDvmesw: cannot find extended address space\n");
}
logMsg("R_MID=0x%x R_MEM1= 0x%x R_MEM2= 0x%x\n",R_MID,R_MEM1,R_MEM2);
*R_TITID=0xFF; /* reciever ID 3= Linac */
*R_MINF1=0x80; /* transfer enable */
configuration function
ボード数、A32アドレス、割り込みレベル、割り込みベクターの初期値を指定します。
int devVmebcmConfigS(ncards,a32base,intlevel,intvecbase)
int ncards;
long a32base;
int intlevel;
int intvecbase;
{
vmebcm_num_links = ncards;
Base_IO = a32base;
INT_LEVEL = intlevel;
INT_VEC_BASE = intvecbase;
logMsg("devVmebcm NumLink= %d BaseIO= %x IntLevel = %d IntVecBase =0x%x\n",vmebcm_num_links,Base_IO,INT_LEVEL,INT_VEC_BASE);
init_all(0);
}
BOの動作
割り込み処理ルーチン
単に割り込みをかけたボードに対してscanリクエストを出すだけ。
void bcm_isr(pwf)
struct waveformRecord *pwf;
{
unsigned char mode;
short cardN;
cardN = pwf->inp.value.vmeio.card;
scanIoRequest(cards[cardN].ioscanpvt);
return;
}
waveform初期化ルーチン
割り込みの初期化及びボードの初期化を行います。ここを通って初めてボードは動作可となります。
static long init_wf_record(pwf)
struct waveformRecord *pwf;
{
short cardNum;
cardNum = pwf->inp.value.vmeio.card;
if (intConnect(INUM_TO_IVEC(INT_VEC_BASE + cardNum),
(VOIDFUNCPTR)bcm_isr,
(int)pwf) != OK)
logMsg("devbcm: Interrupt connect failed for card %d\n",pwf->inp.value.vmeio.card);
logMsg("intConnect 0x%X\n",pwf);
cards[cardNum].card->cntl1 = 0x01;
sysIntEnable(INT_LEVEL+cardNum);
logMsg("bcm int set for int 0x%x\n",INT_LEVEL+cardNum);
cards[cardNum].card->cntl1 = 0x01;
cards[cardNum].card->cntl1 = 0x09;
cards[cardNum].card->cntl1 = 0xff0c;
return(0);
}
shared memory用データ合成ファンクション
8ビットデータ4つを合成して1つの32ビットデータを作るfunctionです。shared memoryへのアクセス回数をできるだけ減らすための工夫です。
static unsigned long bc_comb(unsigned char bc_o[], int i)
{
unsigned long a = 0;
a = ((unsigned long)(bc_o[i*4])<<24) | ((unsigned long)(bc_o[i*4+1])<<16) | ((unsigned long)(bc_o[i*4+2])<<8) | (unsigned long)(bc_o[i*4+3]);
return a;
}
waveform読みとり
はじめに(念のため)ボードを読みとり状態に再設定します(余り意味はないが...)
cards[cardN].card->cntl2 = 0x40;
cards[cardN].card->cntl1 = 0x01;
cards[cardN].card->cntl1 = 0x09;
charの配列bc_oにまずデータを入れます。メモリーの構造は大きくboardとcardに分かれており、隣同士もインターリーブ出力なので面倒です。あるアドレスをD32で読んだとき、
4 2 3 1
という形でデータが並んでいます。また、隣のアドレス(1 card先)は32個先のデータになります。1ボード先は4先のデータ(つまり今のデータの隣組)となります。これを正しく読むため、
for (j=0; j<8; j++)
{
for (i=0;i<160; i++)
{
a1=cards[cardN].card->board[j][i+MEM_OFFSET];
bc_o[j*4+i*32]= (unsigned char)(a1 & 0x000000ff);
bc_o[j*4+i*32+1] = (unsigned char)((a1 & 0x00ff0000)>>16);
bc_o[j*4+i*32+2] = (unsigned char)((a1 & 0x0000ff00)>>8);
bc_o[j*4+i*32+3] = (unsigned char)((a1 >>24));
}
}
LERのときは(card IDが0と決めうちしてある)waveformデータ用にbc_oを換算し、SMemLにバンチ電流データを書き込み、shared memoryの*R_TIINFに0xf0を(LERよ)と書き、*R_CMDを1にします。
if (cardN==0) /* for LER */
{
for (i=0; i<1280; i++)
{
for (j=0; j<4; j++)
{
f_thing[i*4+j]=cal_fac_bcm_L*bc_o[i*4+j];
}
ref_dat[i]=bc_comb(bc_o,i);
}
for (iad=0;iad<320;iad++){
write_smemek(SMemL,ref_dat,iad*4,nwd);
}
*R_TIINF = 0xf0;
*R_CMD=1; /* inform interrupt */
}
HERの時は換算計数がHER用になり、SMemHに書き、*R_TIINFが0x00となります。作業が終わったら、waveformの長さを書いておきます。
pwf->nord=5120;
このあと、ボードをリセットして次のトリガーに備えます。
cards[cardN].card->cntl1 = 0x01;
cards[cardN].card->cntl1 = 0x09;
cards[cardN].card->cntl1 = 0xff0c;
dbdファイル
dbdファイルの中で次のように定義します。
device(bo,VME_IO,devBoVmebcmS,"VMEBCMS")
device(mbbiDirect,VME_IO,devMbbiVmebcmS,"VMEBCMS")
device(waveform,VME_IO,devWfVmebcmS,"VMEBCMS")
初期化ファイルはdevVmeFIRCnfigで、ベースアドレスが0x20400000で2枚使うとすると、
devVmebcmConfigS(2,0x20400000,0x05,0xf1)
の様に指定します。
このデバイスサポートで使うデータベースをまとめると、以下の様になります。
DTYP | Record | Signal | Name | Function | Remarks
|
---|
VMEBCMS | waveform | 0 | ($USER):BUNCH | Bunch current data(5120) | このままでは表示等できないのでデータベースで分割する必要あり
|
Soft Channel | subarray | N/A | ($USER):FILL1 | Bunch current data(0-2559) | 速すぎるのでやはり使えない
|
Soft Channel | subarray | N/A | ($USER):FILL2 | Bunch current data(2560-5119) | 速すぎるのでやはり使えない
|
Soft Channel | waveform | N/A | ($USER):HALF1 | Bunch current data(0-2559) | 5秒更新
|
Soft Channel | waveform | N/A | ($USER):HALF2 | Bunch current data(2560-5119) | 5秒更新
|
Soft Channel | waveform | N/A | ($USER):BCM1 | Bunch current data(0-2559) | 60秒更新(記録用)
|
Soft Channel | waveform | N/A | ($USER):BCM1 | Bunch current data(2560-5119) | 60秒更新(記録用)
|
VMEBCMS | BO | 0 | ($USER):SYNC | ボードスタート | アクセスで起動
|
VMEBCMS | BO | 1 | ($USER):STOP | ボードストップ | アクセスで起動
|
現在ののスタートアップファイル(の関係部分)は次のようになります。
dbLoadDatabase("fbppcApp/Db/FBL_BCM.db")
dbLoadDatabase("fbppcApp/Db/FBH_BCM.db")
devVmebcmConfigS(2,0x20400000,0x05,0xf1)
iocInit
バンチ電流モニターボード用のEPICSデバイスサポートおよびデータベースについて紹介しました。この中のAdvanet 1522に関連する部分は菊谷氏によってかかれたものをこのデバイスサポートに移植したものです。
LERのバンチ電流モニター表示例
Makoto Tobiyama
7/Mar/2001
Return to FB Home Page...