DAQConfig¶
首先修改 StartDAQ.sh/StopDAQ.sh 两个文件,将文件内的 wuhongyi 替换成当前 LINUX 的用户名。然后修改 bbcaenvme 文件夹下 babies、init 文件夹内文件。
修改文件之前,我们需要先理解硬件地址与 GEO 编号。每个插件模块侧面都有四个拨盘,每个拨盘代表一个 16 进制位,例如,当四个拨盘从左到右分别为 1,2,3,4 时,表示其硬件地址为 0x1234。控制器与模块的通讯依靠该硬件地址来寻址,每个控制器下的模块地址应该具有唯一性。同时,我们可以通过软件对每个模块设置一个 GEO 编号,该模块输出数据中都会带有该 GEO 标记,方便我们对数据进行解码。GEO 编号范围为 0-31。
这里我们对硬件地址设置进行如下约定(当然以下约定不是强制要求,用户可以任意修改),
v7xx 模块硬件地址从 0x1000 开始,然后 0x1001,有多少个模块就依次往后设置。
MADC32 硬件地址从 0x2000 开始,然后 0x2001,有多少个模块就依次往后设置。
v1x90 硬件地址从 0x4000 开始,然后 0x4001,有多少个模块就依次往后设置。
v830 模块硬件地址从 0x5000 开始,然后 0x5001,有多少个模块就依次往后设置。
这里我们对 GEO 地址设置进行如下约定(当然以下约定不是强制要求,用户可以任意修改),
一般 v830 使用 1-2 个模块而已,因此 GEO 编号 30/31 我们预留给 v830。第一个 v830 的 GEO 为 30,第二个 v830 的 GEO 为 31。
实验中一般 v7xx 和 MADC32 模块使用较多,如果每种模块均不超过 10 个的话,我们默认 0-9 预留给 v7xx,10-19 预留给 MADC32。如果某种模块超过 10 个话,那么 v7xx 和 MADC32 的 GEO 按照 0-19 的编号依次往下进行分配。
实验中 v1x90 模块的使用数量一般不会超过 5 个,这里我们为 v1x90 预留 20-24,编号从 20 开始依次往后进行分配。
剩余的 GEO 编号 25-29 进行机动使用。
整个 DAQ 的程序配置中,需要在文件 babies/bbmodules.h 中进行硬件地址设置。然后还需对文件夹 init 内的文件进行硬件地址和 GEO 的设置。
babies/bbmodules.h¶
修改 ADCADDR、MADCADDR、V1x90ADDR、SCAADDR 使之与硬件地址匹配(可以多余设置,不可少设置)。其它不要修改。
这里我们按照之前的约定,V7xx 硬件地址从 0x1000 开始编号,用 ADC[x]ADDR 来表示不同模块。MADC32 硬件地址从 0x2000 开始编号,用 MADC[x]ADDR 来表示不同模块。V1x90 硬件地址从 0x4000 开始编号,用 V1x90ADDR[x] 来表示不同模块。 V830 硬件地址从 0x5000 开始编号,用 SCAADDR[x] 来表示不同模块。(其中 [x] 代表不同的数字)
如果您依照我们的约定来设置,则不需要修改本文件。
如果您使用控制器V1718,则需要注释以下代码。否则开启以下代码
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
#define V2718 //如果使用 V1718 则注释本行
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
如果您使用软件 busy 模式时,则开启以下代码行,如果您使用硬件 busy 模式时,则注释掉以下行代码。
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
#define SOFTWAREBUSY
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
如果您使用常规的busy模式,且需要多个机箱同步运行,则开启以下代码,否则注释掉
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
#define SOFTWAREBUSYMULTICRATE
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
选择合适的插件类型作为 INTERRUPT 源,以下4行代码仅能开启一个。选择的依据是系统中的模块在一个事件中,谁最后完成数据的 MEB 写入,这样能够避免有些模块已经开始读取数据,而一些模块数据还未转换结束。当有 v7xx 模块时,默认选择该类型模块,如果系统有 MADC32 时,需要考虑读取它之前是否完成数据的转换。
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
#define V7XXINTERRUPT
// #define SCAINTERRUPT
// #define MADC32INTERRUPT
// #define V1X90INTERRUPT
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
babies/start.c¶
根据文件内提示设置,有该类型插件则开启对应代码。其它不要修改。
V830
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
// 有 V830 插件
v830_clear_all(SCAADDR0);
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
用户需要修改以上代码段,如果您不使用 V830 模块,则注释掉以上区域的代码。
如果您使用一个 V830 模块,则添加代码:
v830_clear_all(SCAADDR0);
如果您使用两个 V830 模块,则添加代码:
v830_clear_all(SCAADDR0);
v830_clear_all(SCAADDR1);
V7xx
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
// 有 V7xx 插件
// 每个插件单独设置
v7xx_rst_counter(ADC0ADDR);
v7xx_rst_counter(ADC1ADDR);
v7xx_rst_counter(ADC2ADDR);
// v7xx_rst_counter(ADC3ADDR);
// v7xx_rst_counter(ADC4ADDR);
// v7xx_rst_counter(ADC5ADDR);
// v7xx_rst_counter(ADC6ADDR);
// v7xx_rst_counter(ADC7ADDR);
v7xx_clear(ADC0ADDR);
v7xx_clear(ADC1ADDR);
v7xx_clear(ADC2ADDR);
// v7xx_clear(ADC3ADDR);
// v7xx_clear(ADC4ADDR);
// v7xx_clear(ADC5ADDR);
// v7xx_clear(ADC6ADDR);
// v7xx_clear(ADC7ADDR);
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
用户需要修改以上代码段,如果您不使用 V7xx 模块,则注释掉以上区域的代码。
如果您使用一个 V7xx 模块,则添加代码:
v7xx_rst_counter(ADC0ADDR);
v7xx_clear(ADC0ADDR);
如果您使用两个 V7xx 模块,则添加代码:
v7xx_rst_counter(ADC0ADDR);
v7xx_rst_counter(ADC1ADDR);
v7xx_clear(ADC0ADDR);
v7xx_clear(ADC1ADDR);
使用更多 V7xx 则依次类推。
V1x90
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
// 有 V1190/V1290 插件
// 每个插件单独clear
// v1190_clear(V1x90ADDR0);
// v1290_clear(V1x90ADDR1);
v1190_clear(V1x90ADDR0);
v1190_clear(V1x90ADDR1);
// v1290_clear(V1x90ADDR0);
// v1290_clear(V1x90ADDR1);
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
用户需要修改以上代码段,如果您不使用 V1x90 模块,则注释掉以上区域的代码。
如果您只使用一个 V1190 模块,则添加代码:
v1190_clear(V1x90ADDR0);
如果您只使用两个 V1190 模块,则添加代码:
v1190_clear(V1x90ADDR0);
v1190_clear(V1x90ADDR1);
如果您使用一个 V1190,一个 V1290,则添加代码:
v1190_clear(V1x90ADDR0);
v1290_clear(V1x90ADDR1);
更多模块使用的组合,请以此类推。
MADC32
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
// 有 MADC32 插件
madc32_mclear(MSTMDCADDR);
madc32_mirq_level(MSTMDCADDR,0);
madc32_mreset_ctra_counters(MSTMDCADDR);
madc32_mfifo_reset(MSTMDCADDR);
madc32_mstart_acq(MSTMDCADDR);
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
用户需要修改以上代码段,如果您不使用 MADC32 模块,则注释掉以上区域的代码。如果您使用了 MADC32 模块,不管使用了多少个模块,只需要开启以上代码即可对所有的模块完成初始化。
babies/evt.c¶
根据文件内提示设置。其它不要修改。
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
// 软件BUSY模式下6036->0x1不需要以下清除,6036->0x3需要以下清除,6036->0x0需要以下清除
// 硬件BUSY模式下只能采用6036->0x3,需要以下清除
// 有 MADC32 插件
madc32_mclear(MSTMDCADDR);
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
用户需要修改以上代码段,如果您不使用 MADC32 模块,则注释掉以上区域的代码。如果您使用了 MADC32 模块,不管使用了多少个模块,只需要开启以上代码即可对所有的模块完成清除。
当然,在软件 busy 模式下,对每个模块的寄存器进行相应的寄存器配置,可以不用以上清除指令自动进行清除,此时每个事件能够节约 20 us 左右的时间,该方案建议对 DAQ 比较熟悉的用户使用。
当系统中有两个及以上模块时。采用 CBLT 方式读取数据,这是最高效的数据读取方式。但是当系统中只有一个模块时,则注释掉 CBLT 的数据读取,开启对应插件的读取。
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
// Read data
babies_init_segment(MKSEGID(0, 0, PLAQ, CBLT));
#ifdef V7XXINTERRUPT
v7xx_dmasegdata(MSTTDCADDR, 4000);
#endif
#ifdef SCAINTERRUPT
usleep(10);
v830_dmasegdata(MSTTDCADDR, 4000);
#endif
#ifdef V1X90INTERRUPT
v1190_dmasegdata(MSTTDCADDR, 4000);
#endif
#ifdef MADC32INTERRUPT
madc32_dmasegdata(MSTTDCADDR, 4000);
#endif
babies_end_segment();
// 插件
// babies_init_segment(MKSEGID(0, 0, PLAQ, V785));
// v7xx_dmasegdata(ADC0ADDR, 34);
// babies_end_segment();
// babies_init_segment(MKSEGID(0, 0, PLAQ, V830));
// v830_dmasegdata(SCAADDR0, 34);
// babies_end_segment();
// babies_init_segment(MKSEGID(0, 0, PLAQ, V1190));//V1290
// v1190_dmasegdata(V1x90ADDR0, 1000);
// babies_end_segment();
// babies_init_segment(MKSEGID(0, 0, PLAQ, MADC));
// madc32_dmasegdata(MADC0ADDR, 34);
// babies_end_segment();
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
babies/stop.c¶
根据文件内提示设置,有该类型插件则开启对应代码,开启对应类型 busy 代码。其它不要修改。
MADC32
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// 以下部分用户需要修改
// 有 MADC32 插件
madc32_mstop_acq(MSTMDCADDR);
// 以上部分用户需要修改
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
用户需要修改以上代码段,如果您不使用 MADC32 模块,则注释掉以上区域的代码。如果您使用了 MADC32 模块,不管使用了多少个模块,只需要开启以上代码即可对所有的模块发送结束采集指令。
cmdvme/cmdvme.c¶
如果使用控制器 V1718,则需要修改文件中以下代码。将 V2718 改为 V1718 即可。
enum board bd = V2718;
如果编译中出现以下类似的错误,
cmdvme.c:29:8: error: initialization of flexible array member in a nested context
29 | {WR, "-wr"},
| ^~~~~
cmdvme.c:29:8: note: (near initialization for ‘chkmode[0]’)
则代码修改如下
typedef struct {
enum mode md;
const char mdchar[3];//指定数组长度
}stchkmode;
init/daqinitrc.sh¶
修改该文件内对应脚本,使之与获取插件对应,用来初始化插件。
重点是修改 cblt.hh 文件,对启用的插件设置CBLT ADDR 为 0xbb,其中 MADC 还得设置 MCST ADDR 为 0xdd。还得设置每一个插件在 CBLT 中的顺序,first、mid、last。至少得两个插件才能组成CBLT.
init/daqinitrc.sh 文件包含以下内容:
#!/bin/sh
/bin/sh ./v830.sh
/bin/sh ./v7xx_all.sh
# /bin/sh ./v7xx_thres.sh
/bin/sh ./v1190_0.sh
/bin/sh ./v1190_1.sh
# /bin/sh ./v1290.sh
/bin/sh ./madcall.sh
# /bin/sh ./madc_thres.sh
/bin/sh ./cblt.sh
如果您使用了 V830 则开启以下代码,否则注释掉以下代码:
/bin/sh ./v830.sh
待补充