-
Patrick Robbe authoredPatrick Robbe authored
main_pcie40_klmbytestream.c 3.52 KiB
#include "pcie40_ecs.h"
#include "pcie40_b2slc.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct {
unsigned int chip_no;
unsigned int rpc_board;
__uint16_t thresh_values[48];
}KLMFPGAconfig;
typedef union {
char charval[2];
__uint16_t uint16val;
}uint16toChar;
int writeConfig(int fd, KLMFPGAconfig * config) {
const unsigned int lane_no = 8 + (*config).rpc_board;
const unsigned int chip_no = (*config).chip_no;
const __uint16_t sof = 0xF000; // start of frame pre-shifted
const __uint16_t eof = 0x0008;
const __uint16_t type_wr = 0x0200; // write command (1) pre-shifted
const __uint16_t type_ud = 0x0E00; // update command (7) pre-shifted
const size_t sof_eof_nbits = 4; // SOF/EOF bits
// const size_t lane_nbits = 5; // lane bits
const size_t chip_nbits = 4; // channel bits
const size_t rc_pkt_size = 3; // 16-bit words
// const unsigned int rpc_nbds = 13; // number of boards
// const unsigned int rpc_nfpga = 2; // number of FPGAs
const unsigned int rpc_nchan = 48; // number of channels per FPGA
const unsigned int rpc_naddr = rpc_nchan / 16 + rpc_nchan; // number of addresses/FPGA
// const size_t rpc_pkt_size = rpc_nbds * rpc_nfpga * rpc_naddr * rc_pkt_size; // total size
const unsigned int fpga_pkt_size = rpc_naddr * rc_pkt_size; // packet size per FPGA
const __uint16_t rpc_pulser[rpc_nchan / 16] = {0};
__uint16_t rpc_thresh[48] = {0} ;
// const __uint16_t (&rpc_thresh)[48] = config.thresh_values;
int ii = 0 ;
for ( ii = 0 ; ii < 48 ; ++ii ) rpc_thresh[ ii ] = (*config).thresh_values[ ii ] ;
__uint16_t fpga_word[48*3] = {0};
__uint16_t data, temp;
unsigned int idx = 0;
unsigned int addr = 0 ;
for (addr = 0; addr < rpc_naddr; addr++) {
if (addr <= 47)
data = rpc_thresh[addr];
else
data = rpc_pulser[addr - 48];
temp = chip_no | (lane_no << chip_nbits);
if (addr == rpc_naddr - 1)
temp = temp | sof | type_ud;
else
temp = temp | sof | type_wr;
fpga_word[idx] = temp;
temp = (addr << 4) | (data >> 12);
fpga_word[idx + 1] = temp;
temp = (data << sof_eof_nbits) | eof;
fpga_word[idx + 2] = temp;
idx = idx + 3;
}
__uint16_t word;
uint16toChar uch;
const size_t fpga_pkt_n_bytes = 2 * fpga_pkt_size;
char stream_data[fpga_pkt_n_bytes];
size_t i = 0 ;
for (i = 0; i < fpga_pkt_size; i++) {
word = fpga_word[i];
uch.uint16val = word;
stream_data[2 * i] = uch.charval[1];
stream_data[2 * i + 1] = uch.charval[0];
}
int ret = pcie40_writebytestream(0,fd,fpga_pkt_n_bytes,stream_data);
return ret;
}
int main(int argc, char *argv[]) {
ecs_open( 0 , 2 ) ;
KLMFPGAconfig config;
unsigned int thresh = strtoul(argv[1],0,16);
size_t i = 0 ;
for (i = 0; i < 48; i++)
config.thresh_values[i] = thresh;
printf( "Setting threshold value %d for all channels.\n" , thresh );
int b = 0 ;
int c = 0 ;
int hslb_id = 0 ;
int try_no = 0 ;
int ret;
for(b=0;b<13;b++){
for( c=0;c<2;c++){
config.chip_no = c;
config.rpc_board = b;
// Stream the config through HSLBs
for(hslb_id=0;hslb_id<4;hslb_id++){
for(try_no = 0; try_no < 3; try_no++){
ret = writeConfig(hslb_id, &config);
if(ret == 0)
break;
}
if(ret)
printf("Packet streaming failed for HSLB= %d, board= %d, chip= %d\n", hslb_id , b , c ) ;
else
printf( "Packet streamed successfully for HSLB= %d, board = %d ,chip= %d\n" , hslb_id , b , c ) ;
usleep(500);
}
}
}
ecs_close( 0 , 2 ) ;
return 0 ;
}