7
mirror of https://github.com/EEVengers/ThunderScope.git synced 2025-04-22 17:43:44 +00:00

Merge pull request from EEVengers/FPGA_DSP_PIPE_HOOKUP

Fpga dsp pipe hookup
This commit is contained in:
Aleksa Bjelogrlic 2021-03-25 13:04:28 -04:00 committed by GitHub
commit 1b57c317ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 634 additions and 91 deletions

View File

@ -22,7 +22,7 @@
#define USER_DEVICE_PATH "user"
#define C2H_0_DEVICE_PATH "c2h_0"
#define DATAMOVER_REG_OUT 0x00000 // bit 0: halt, bit 1: reset
#define DATAMOVER_REG_OUT 0x00000 // bit 0: !halt, bit 1: !reset
#define DATAMOVER_TRANSFER_COUNTER 0x00008 // A 32 bit value, low 16 is transfer counter, bit 31 error bit
#define BOARD_REG_OUT 0x10000 // A 32 bit value, bit 0:3: attenuation, bit 4:7: dc_cpl, bit 8: acq_en, bit 9: clk_oe, bit 10: fe_en, 21bits unused
#define BOARD_REG_IN 0x10008 // unused for now
@ -43,19 +43,55 @@
#define CLOCK_GEN_I2C_ADDRESS_READ 0b10110001 //IF WE COULD
enum ScopeCommand {
board_enable,
adc_enable,
adc_rest,
adc_power_down,
adc_active,
adc_cgain_cfg,
adc_btc_mode,
adc_chnum_clkdiv_init,
clk_enable,
init_board,
adc_enable_ramp_test,
dataMover_enable,
dataMover_halt,
dataMover_disable,
test_write
enable_channel,
disable_channel,
ac_couple,
dc_couple,
voltage_divison_set,
voltage_offset_set,
bandwidth_set,
test_write,
test_adc_data
};
struct VoltageDivSetParam {
int ch_num;
int voltage_div;
};
struct VoltageOffsetParam {
int ch_num;
double voltage;
};
struct BandwidthSetParam {
int ch_num;
int bw;
};
struct BoardState {
//general front end en
bool board_en;
//adc values
bool adc_en;
uint8_t num_ch_on;
bool ch_is_on[4];
uint8_t adc_chnum_clkdiv [4];
uint8_t adc_in_sel_12[4];
uint8_t adc_in_sel_34[4];
//pga's
uint8_t pga[4][4];
//dac
uint8_t dac[4][5];
//clock values
bool clk_en;
//Board Register Values
uint32_t board_reg_out; // A 32 bit value, bit 0:3: attenuation, bit 4:7: dc_cpl, bit 8: acq_en, bit 9: clk_oe, bit 10: fe_en, 21bits unused
uint32_t datamover_reg_out; // bit 0: !halt, bit 1: !reset, bit 4:6: channel
};
class PCIeLink {
@ -85,7 +121,6 @@ private:
char user_device[20] = USER_DEVICE_PATH; //write/read registers
char c2h_0_device[20] = C2H_0_DEVICE_PATH; //read memory
uint8_t dataMoverReg[1] = {0x00};
HANDLE user_handle;
char user_connection_string[261] = "";
HANDLE c2h_0_handle;
@ -93,6 +128,9 @@ private:
LARGE_INTEGER freq; //used for perforamnce testing
int64_t last_chunk_read;
//current state
BoardState currentBoardState;
std::atomic<bool> _run;
std::atomic<bool> _pause;
std::thread PCIeReadThread;
@ -106,9 +144,23 @@ private:
void _Read(HANDLE hPCIE, long long address, uint8_t* buff, int bytesToRead);
void _Write(HANDLE hPCIE, long long address, uint8_t* buff, int bytesToWrite);
void _Write32(HANDLE hPCIE, long long address, uint32_t val);
void _FIFO_WRITE(HANDLE hPCIE, uint8_t* data, uint8_t bytesToWrite);
void _Job();
//scope control stuff
int _ch_on(int ch_num);
int _ch_off(int ch_num);
int _dc_cpl(int ch_num);
int _ac_cpl(int ch_num);
int _vdiv_set(int ch_num, int vdiv);
int _voffset_set(int ch_num, double voffset);
int _bw_set(int ch_num, int bw);
int _adc_ch_cfg();
void _adc_power_down();
void _adc_active();
protected:
};

View File

@ -39,6 +39,8 @@ public:
void setMathSign(bool newSign);
void getData();
void setFileName(int8_t newFile);
void hardWareCommand(int command, int channel, int val1, double val2);
void testADCData();
private:
// external queue

View File

@ -222,17 +222,7 @@ boost::lockfree::queue<buffer*, boost::lockfree::fixed_sized<false>> testerDataQ
void runPCIeTest() {
controller* troller = new controller(&testerDataQueue);
troller->controllerUnPause();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
/*FILE* fp = fopen("TestData.txt","w");
for(int i = 0; i < (1 << 23); i+= 8) {
fprintf(fp,"%X,%X,%X,%X,%X,%X,%X,%X\n",
buff[i],buff[i + 1],buff[i + 2],buff[i + 3],buff[i + 4],buff[i + 5],buff[i + 6],buff[i + 7]);
}
fclose(fp); */
troller->setWindowSize(1000);
troller->testADCData();
delete troller;
}

View File

@ -174,9 +174,7 @@ void PCIeLink::Read(uint8_t* buff) {
}
void PCIeLink::InitBoard() {
Write(board_enable,nullptr);
Write(clk_enable,nullptr);
Write(adc_enable,nullptr);
Write(init_board,nullptr);
Write(dataMover_enable,nullptr);
}
@ -204,18 +202,84 @@ void PCIeLink::Stop() {
*************************************************************/
void PCIeLink::Write(ScopeCommand command, void* val) {
switch(command) {
case board_enable:
case init_board:
INFO << "Enabling Board";
{
uint8_t en[] = {0x00, 0x00};
_Read(user_handle,BOARD_REG_OUT,en,2);
en[1] |= 0x01; //acq->on fe->off
_Write(user_handle,BOARD_REG_OUT,en,2);
currentBoardState.board_reg_out |= 0x0100; //acq->on fe->off
_Write32(user_handle,BOARD_REG_OUT,currentBoardState.board_reg_out);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
break;
case adc_enable:
INFO << "Enabling PLL";
{
uint16_t config_clk_gen[] = {
0x0010, 0x010B, 0x0233, 0x08B0,
0x0901, 0x1000, 0x1180, 0x1501,
0x1600, 0x1705, 0x1900, 0x1A32,
0x1B00, 0x1C00, 0x1D00, 0x1E00,
0x1F00, 0x2001, 0x210C, 0x2228,
0x2303, 0x2408, 0x2500, 0x2600,
0x2700, 0x2F00, 0x3000, 0x3110,
0x3200, 0x3300, 0x3400, 0x3500,
0x3800, 0x4802 }; //correct bytes to configure the clock gen
//write to the clock generator
for(int i = 0; i < 34; i++) {
uint8_t data[] = {I2C_BYTE_PLL, CLOCK_GEN_I2C_ADDRESS_WRITE, (uint8_t)((config_clk_gen[i] & 0xFF00) >> 8),(uint8_t)(config_clk_gen[i] & 0xFF)};
//printf("DataPacket: %X %X %X %X\n",data[0],data[1],data[2],data[3]);
_FIFO_WRITE(user_handle,data,4);
}
currentBoardState.board_reg_out |= 0x0200;
_Write32(user_handle,BOARD_REG_OUT,currentBoardState.board_reg_out);
}
INFO << "Enabling ADC";
{
//Reset ADC
uint8_t resetADC[] = {0xFD,0x00,0x00,0x01};
_FIFO_WRITE(user_handle,resetADC,4);
//Power Down ADC
_adc_power_down();
//Set Channel and Clock Div
uint8_t setChannelClock[] = {0xFD,0x31,0x00,0x01};
_FIFO_WRITE(user_handle,setChannelClock,4);
//invert channels
uint8_t channel_invert[] = {0xFD,0x24,0x00,0x7F};
_FIFO_WRITE(user_handle,channel_invert,4);
_ch_on(0);
//twos compliment mode TURN OFF
uint8_t setTwosComp[] = {0xFD,0x46,0x00,0x00};
_FIFO_WRITE(user_handle,setTwosComp,4);
//Course Gain On
uint8_t course_gain_on[] = {0xFD,0x33,0x00,0x00};
_FIFO_WRITE(user_handle,course_gain_on,4);
//Course Gain 4-CH set
uint8_t course_gain4[] = {0xFD,0x2A,0x99,0x99};
_FIFO_WRITE(user_handle,course_gain4,4);
//Course Gain 1-CH & 2-CH set
uint8_t course_gain12[] = {0xFD,0x2B,0x09,0x99};
_FIFO_WRITE(user_handle,course_gain12,4);
//Set adc into active mode
_adc_active();
}
INFO << "Enabling the front end";
{
currentBoardState.board_reg_out |= 0x0400; //fe->on
_Write32(user_handle,BOARD_REG_OUT,currentBoardState.board_reg_out);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
//enable the pga
for(int i = 0; i < 4; i++) {
_FIFO_WRITE(user_handle,currentBoardState.pga[i],sizeof(currentBoardState.pga[i]));
_FIFO_WRITE(user_handle,currentBoardState.dac[i],sizeof(currentBoardState.dac[i]));
}
}
break;
case adc_enable_ramp_test:
INFO << "Enabling ADC RAMP MODE";
{
//Reset ADC
uint8_t resetADC[] = {0xFD,0x00,0x00,0x01};
@ -244,31 +308,53 @@ void PCIeLink::Write(ScopeCommand command, void* val) {
_FIFO_WRITE(user_handle,adcActiveMode,4);
}
break;
case clk_enable:
INFO << "Enabling PLL";
case dataMover_enable:
INFO << "Enabling DataMover";
{
uint16_t config_clk_gen[] = {
0x0010, 0x010B, 0x0233, 0x08B0,
0x0901, 0x1000, 0x1180, 0x1501,
0x1600, 0x1705, 0x1900, 0x1A32,
0x1B00, 0x1C00, 0x1D00, 0x1E00,
0x1F00, 0x2001, 0x210C, 0x2228,
0x2303, 0x2408, 0x2500, 0x2600,
0x2700, 0x2F00, 0x3000, 0x3110,
0x3200, 0x3300, 0x3400, 0x3500,
0x3800, 0x4802 }; //correct bytes to configure the clock gen
//write to the clock generator
for(int i = 0; i < 34; i++) {
uint8_t data[] = {I2C_BYTE_PLL, CLOCK_GEN_I2C_ADDRESS_WRITE, (uint8_t)((config_clk_gen[i] & 0xFF00) >> 8),(uint8_t)(config_clk_gen[i] & 0xFF)};
//printf("DataPacket: %X %X %X %X\n",data[0],data[1],data[2],data[3]);
_FIFO_WRITE(user_handle,data,4);
}
uint8_t en[] = {0x00, 0x00};
_Read(user_handle,BOARD_REG_OUT,en,2);
en[1] |= 0x02; //clk->on
_Write(user_handle,BOARD_REG_OUT,en,2);
currentBoardState.datamover_reg_out |= 0x03;
_Write32(user_handle,DATAMOVER_REG_OUT,currentBoardState.datamover_reg_out);
}
break;
case dataMover_disable:
INFO << "Disabling DataMover";
{
currentBoardState.datamover_reg_out &= ~(0x01);
_Write32(user_handle,DATAMOVER_REG_OUT,currentBoardState.datamover_reg_out);
currentBoardState.datamover_reg_out &= ~(0x02);
_Write32(user_handle,DATAMOVER_REG_OUT,currentBoardState.datamover_reg_out);
}
break;
case enable_channel:
_ch_on(*((int*)val));
break;
case disable_channel:
_ch_off(*((int*)val));
break;
case ac_couple:
_ac_cpl(*((int*)val));
break;
case dc_couple:
_dc_cpl(*((int*)val));
break;
case voltage_divison_set:
{
VoltageDivSetParam* param = (VoltageDivSetParam*)val;
DEBUG << "Setting Channel " << param->ch_num << " Voltage Division To " << param->voltage_div;
_vdiv_set(param->ch_num,param->voltage_div);
}
break;
case voltage_offset_set:
{
VoltageOffsetParam* param = (VoltageOffsetParam*)val;
DEBUG << "Setting Channel " << param->ch_num << " DC Voltage Offset To " << param->voltage << "mV";
_voffset_set(param->ch_num,param->voltage);
}
break;
case bandwidth_set:
{
BandwidthSetParam* param = (BandwidthSetParam*)val;
DEBUG << "Setting Channel " << param->ch_num << " Bandwidth To: " << param->bw;
_bw_set(param->ch_num,param->bw);
}
break;
case test_write:
@ -293,20 +379,48 @@ void PCIeLink::Write(ScopeCommand command, void* val) {
printf("After writting 0 again, the read value is: %d\n",rxBuff[0]);
}
break;
case dataMover_enable:
INFO << "Enabling DataMover";
case test_adc_data:
{
dataMoverReg[0] |= 0x03;
_Write(user_handle,DATAMOVER_REG_OUT,dataMoverReg,1);
}
break;
case dataMover_disable:
INFO << "Disabling DataMover";
{
dataMoverReg[0] &= ~(0x01);
_Write(user_handle,DATAMOVER_REG_OUT,dataMoverReg,1);
dataMoverReg[0] &= ~(0x02);
_Write(user_handle,DATAMOVER_REG_OUT,dataMoverReg,1);
int num_buffers = 4;
uint8_t* preBuff = (uint8_t*)malloc(BUFFER_SIZE * sizeof(uint8_t));
int8_t **buffers = (int8_t**)malloc(num_buffers * sizeof(int8_t*));
for(int i = 0; i < num_buffers; i++) {
buffers[i] = (int8_t*)malloc(BUFFER_SIZE * sizeof(int8_t));
}
for(int i = 0; i < num_buffers; i++) {
Read(preBuff);
for(int q = 0; q < BUFFER_SIZE; q++) {
if(preBuff[i] & 0x80) {
//postive
buffers[i][q] = (int)(preBuff[q] & 0x7F);
} else {
//negative
buffers[i][q] = (-128 + ((int)(preBuff[q] & 0x7F)));
}
}
}
for(int i = 0; i < num_buffers; i++) {
char name[100];
sprintf(name,"ADC_DATA_FILE%d.csv",i);
FILE* file = fopen(name,"w");
for(int q = 0; q < BUFFER_SIZE;) {
fprintf(file,"%d,",buffers[i][q++]);
fprintf(file,"%d,",buffers[i][q++]);
fprintf(file,"%d,",buffers[i][q++]);
fprintf(file,"%d,",buffers[i][q++]);
fprintf(file,"%d,",buffers[i][q++]);
fprintf(file,"%d,",buffers[i][q++]);
fprintf(file,"%d,",buffers[i][q++]);
fprintf(file,"%d\n",buffers[i][q++]);
}
}
for(int i = 0; i < num_buffers; i++) {
free(buffers[i]);
}
free(buffers);
}
break;
default:
@ -399,7 +513,34 @@ void PCIeLink::_Write(HANDLE hPCIE, int64_t address, uint8_t* buff, int bytesToW
}
}
void PCIeLink::_Write32(HANDLE hPCIE, long long address, uint32_t val) {
if(hPCIE == INVALID_HANDLE_VALUE) {
ERROR << "INVALID HANDLE PASSED INTO PCIeLink::_Write(): " << hPCIE;
return;
}
LARGE_INTEGER offset;
offset.QuadPart = address;
// set file pointer to offset of target address within PCIe BAR
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hPCIE, offset, NULL, FILE_BEGIN)) {
ERROR << "Error setting file pointer for PCIeLink::_Write(), win32 error code: " << GetLastError();
}
// write from buffer to device
DWORD bytesWritten;
uint8_t bytes[4];
bytes[3] = (uint8_t)( (val & 0xFF000000) >> 24);
bytes[2] = (uint8_t)( (val & 0x00FF0000) >> 16);
bytes[1] = (uint8_t)( (val & 0x0000FF00) >> 8);
bytes[0] = (uint8_t)( (val & 0x000000FF));
if (!WriteFile(hPCIE, bytes, 4, &bytesWritten, NULL)) {
ERROR << "_Write() failed with Win32 error code: " << GetLastError();
}
}
void PCIeLink::_Job() {
uint8_t* preBuff = (uint8_t*)malloc(sizeof(uint8_t) * BUFFER_SIZE);
while(_run.load()) {
while(_pause.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(2));
@ -409,36 +550,111 @@ void PCIeLink::_Job() {
buff = bufferAllocator.allocate(1);
bufferAllocator.construct(buff);
//read from the PCIeLink
Read((uint8_t*)buff->data);
Read(preBuff);
for(int i = 0; i < BUFFER_SIZE; i++) {
if(preBuff[i] & 0x80) {
//postive
buff->data[i] = (int)(preBuff[i] & 0x7F);
} else {
//negative
buff->data[i] = (-128 + ((int)(preBuff[i] & 0x7F)));
}
}
//push to queue
outputQueue->push(buff);
}
free(preBuff);
}
PCIeLink::PCIeLink(boost::lockfree::queue<buffer*, boost::lockfree::fixed_sized<false>> *outputQueue) {
user_handle = INVALID_HANDLE_VALUE;
c2h_0_handle = INVALID_HANDLE_VALUE;
dataMoverReg[0] = 0x00;
last_chunk_read = -1;
_run = true;
_pause = true;
QueryPerformanceFrequency(&freq);
this->outputQueue = outputQueue;
//keep the read thread alive but paused
_run = true;
_pause = true;
//init board state vairable
currentBoardState.board_en = false;
currentBoardState.adc_en = false;
currentBoardState.clk_en = false;
currentBoardState.num_ch_on = 0;
//adc stuff
currentBoardState.adc_chnum_clkdiv[0] = 0xFD;
currentBoardState.adc_chnum_clkdiv[1] = 0x31;
currentBoardState.adc_chnum_clkdiv[2] = 0x00;
currentBoardState.adc_chnum_clkdiv[3] = 0x01;
currentBoardState.adc_in_sel_12[0] = 0xFD;
currentBoardState.adc_in_sel_12[1] = 0x3A;
currentBoardState.adc_in_sel_12[2] = 0x10;
currentBoardState.adc_in_sel_12[3] = 0x10;
currentBoardState.adc_in_sel_34[0] = 0xFD;
currentBoardState.adc_in_sel_34[1] = 0x3B;
currentBoardState.adc_in_sel_34[2] = 0x10;
currentBoardState.adc_in_sel_34[3] = 0x10;
for(int i = 0; i < 4; i++) {
currentBoardState.ch_is_on[i] = 0;
//init dac state
currentBoardState.dac[i][0] = 0xFF;
currentBoardState.dac[i][1] = 0xC2;
currentBoardState.dac[i][3] = 0x08;
currentBoardState.dac[i][4] = 0x00;
//init pga state
currentBoardState.pga[i][1] = 0x00;
currentBoardState.pga[i][2] = 0x04;
currentBoardState.pga[i][3] = 0x0A;
}
//init pga state address
currentBoardState.pga[0][0] = 0xFB;
currentBoardState.pga[1][0] = 0xFA;
currentBoardState.pga[2][0] = 0xF9;
currentBoardState.pga[3][0] = 0xF8;
currentBoardState.dac[0][2] = 0x40;
currentBoardState.dac[1][2] = 0x42;
currentBoardState.dac[2][2] = 0x44;
currentBoardState.dac[3][2] = 0x46;
//init register values
currentBoardState.datamover_reg_out = 0x00;
currentBoardState.board_reg_out = 0xFF; // FOR FUCKS SAKE CHANGE THIS!
//connect to the board and start the adc + read thread
Connect();
InitBoard();
PCIeReadThread = std::thread(&PCIeLink::_Job, this);
}
PCIeLink::~PCIeLink() {
if(user_handle != INVALID_HANDLE_VALUE)
CloseHandle(user_handle);
if(c2h_0_handle != INVALID_HANDLE_VALUE)
CloseHandle(c2h_0_handle);
//turn off the adc
INFO << "Powering down adc";
_adc_power_down();
//disable the front end and board power
INFO << "Turning Off Power To Front End";
currentBoardState.board_reg_out = 0;
_Write32(user_handle,BOARD_REG_OUT,currentBoardState.board_reg_out);
_pause.store(false);
_run.store(true);
_run.store(false);
DEBUG << "Waiting to join PCIeReadThread";
PCIeReadThread.join();
DEBUG << "Joined PCIeReadThread";
if(user_handle != INVALID_HANDLE_VALUE) {
CloseHandle(user_handle);
user_handle = INVALID_HANDLE_VALUE;
}
if(c2h_0_handle != INVALID_HANDLE_VALUE) {
CloseHandle(c2h_0_handle);
c2h_0_handle = INVALID_HANDLE_VALUE;
}
}
void PCIeLink::ClockTick1() {
@ -466,11 +682,224 @@ double PCIeLink::GetTimeDelta() {
}
/************************************************************************ SCOPE CONTROL STUFF ***********************************************/
int PCIeLink::_ch_on(int ch_num){
if (currentBoardState.ch_is_on[ch_num])
return 0; //Channel already on
currentBoardState.num_ch_on++;
currentBoardState.ch_is_on[ch_num] = true;
_adc_ch_cfg();
_FIFO_WRITE(user_handle,currentBoardState.dac[ch_num],sizeof(currentBoardState.dac[ch_num]));
_FIFO_WRITE(user_handle,currentBoardState.pga[ch_num],sizeof(currentBoardState.pga[ch_num]));
return 1;
}
int PCIeLink::_ch_off(int ch_num){
if (!currentBoardState.ch_is_on[ch_num])
return 0; //Channel already off
currentBoardState.num_ch_on--;
currentBoardState.ch_is_on[ch_num] = false;
_adc_ch_cfg();
return 1;
}
int PCIeLink::_dc_cpl(int ch_num){
if (ch_num == 0)
currentBoardState.board_reg_out |= (1 << 4);
else if (ch_num == 1)
currentBoardState.board_reg_out |= (1 << 5);
else if (ch_num == 2)
currentBoardState.board_reg_out |= (1 << 6);
else if (ch_num == 3)
currentBoardState.board_reg_out |= (1 << 7);
_Write32(user_handle,BOARD_REG_OUT,currentBoardState.board_reg_out);
return 1;
}
int PCIeLink::_ac_cpl(int ch_num){
if (ch_num == 0)
currentBoardState.board_reg_out &= ~(1 << 4);
else if (ch_num == 1)
currentBoardState.board_reg_out &= ~(1 << 5);
else if (ch_num == 2)
currentBoardState.board_reg_out &= ~(1 << 6);
else if (ch_num == 3)
currentBoardState.board_reg_out &= ~(1 << 7);
_Write32(user_handle,BOARD_REG_OUT,currentBoardState.board_reg_out);
return 1;
}
//expect vdiv in millivolts
int PCIeLink::_vdiv_set(int ch_num, int vdiv){
if (vdiv <= 100){ //Attenuator relay on for higher v/divs
if (ch_num == 0)
currentBoardState.board_reg_out |= (1 << 0);
else if (ch_num == 1)
currentBoardState.board_reg_out |= (1 << 1);
else if (ch_num == 2)
currentBoardState.board_reg_out |= (1 << 2);
else if (ch_num == 3)
currentBoardState.board_reg_out |= (1 << 3);
}
else{ //Attenuator relay off for lower v/divs
if (ch_num == 0)
currentBoardState.board_reg_out &= ~(1 << 0);
else if (ch_num == 1)
currentBoardState.board_reg_out &= ~(1 << 1);
else if (ch_num == 2)
currentBoardState.board_reg_out &= ~(1 << 2);
else if (ch_num == 3)
currentBoardState.board_reg_out &= ~(1 << 3);
}
if (vdiv == 10000 || vdiv == 100){
currentBoardState.pga[ch_num][3] &= 0xE0;
currentBoardState.pga[ch_num][3] |= 0x0A;
}
else if (vdiv == 5000 || vdiv == 50){
currentBoardState.pga[ch_num][3] &= 0xE0;
currentBoardState.pga[ch_num][3] |= 0x07;
}
else if (vdiv == 2000 || vdiv == 20){
currentBoardState.pga[ch_num][3] &= 0xE0;
currentBoardState.pga[ch_num][3] |= 0x03;
}
else if (vdiv == 1000 || vdiv == 10){
currentBoardState.pga[ch_num][3] &= 0xE0;
currentBoardState.pga[ch_num][3] |= 0x1A;
}
else if (vdiv == 500 || vdiv == 5){
currentBoardState.pga[ch_num][3] &= 0xE0;
currentBoardState.pga[ch_num][3] |= 0x17;
}
else if (vdiv == 200 || vdiv == 2){
currentBoardState.pga[ch_num][3] &= 0xE0;
currentBoardState.pga[ch_num][3] |= 0x13;
}
else if (vdiv == 1){
currentBoardState.pga[ch_num][3] &= 0xE0;
currentBoardState.pga[ch_num][3] |= 0x10;
}
_Write32(user_handle,BOARD_REG_OUT,currentBoardState.board_reg_out);
_FIFO_WRITE(user_handle,currentBoardState.pga[ch_num],sizeof(currentBoardState.pga[ch_num]));
return 1;
}
int PCIeLink::_voffset_set(int ch_num, double voffset){
unsigned int dac_value = (unsigned int)round((voffset + 0.5) * 4095);
currentBoardState.dac[ch_num][4] = (unsigned char)(0xFF & dac_value);
currentBoardState.dac[ch_num][3] = (unsigned char)(0x0F & (dac_value >> 8));
_FIFO_WRITE(user_handle,currentBoardState.dac[ch_num],sizeof(currentBoardState.dac[ch_num]));
return 1;
}
int PCIeLink::_bw_set(int ch_num, int bw){
if (bw == 20){
currentBoardState.pga[ch_num][3] &= 0x1F;
currentBoardState.pga[ch_num][3] |= 0x40;
}
else if (bw == 100){
currentBoardState.pga[ch_num][3] &= 0x1F;
currentBoardState.pga[ch_num][3] |= 0x80;
}
else if (bw == 200){
currentBoardState.pga[ch_num][3] &= 0x1F;
currentBoardState.pga[ch_num][3] |= 0xC0;
}
else if (bw == 350){
currentBoardState.pga[ch_num][3] &= 0x1F;
}
_FIFO_WRITE(user_handle,currentBoardState.pga[ch_num],sizeof(currentBoardState.pga[ch_num]));
return 1;
}
int PCIeLink::_adc_ch_cfg(){
unsigned char cmd_temp [4];
int i;
if (currentBoardState.num_ch_on == 0){
return 1;
}
else if (currentBoardState.num_ch_on == 1) {
currentBoardState.adc_chnum_clkdiv[3] = 0x01;
currentBoardState.adc_chnum_clkdiv[2] = 0x00;
for (i=0; !currentBoardState.ch_is_on[i]; i++); //Find channel that is on
currentBoardState.adc_in_sel_12[3] = (2 << i); //Set all 4 ADCs to sample that channel
currentBoardState.adc_in_sel_12[2] = (2 << i);
currentBoardState.adc_in_sel_34[3] = (2 << i);
currentBoardState.adc_in_sel_34[2] = (2 << i);
currentBoardState.datamover_reg_out &= ~(0xF0);
} else if (currentBoardState.num_ch_on == 2){
currentBoardState.adc_chnum_clkdiv[3] = 0x02;
currentBoardState.adc_chnum_clkdiv[2] = 0x01;
for (i=0; !currentBoardState.ch_is_on[i]; i++); //Find first on channel
currentBoardState.adc_in_sel_12[3] = (2 << i); //Set 2 ADCs to sample first channel
currentBoardState.adc_in_sel_12[2] = (2 << i);
for (; !currentBoardState.ch_is_on[i]; i++); //Find second on channel
currentBoardState.adc_in_sel_34[3] = (2 << i); //Set 2 ADCs to sample second channel
currentBoardState.adc_in_sel_34[2] = (2 << i);
currentBoardState.datamover_reg_out &= ~(0xF0);
currentBoardState.datamover_reg_out |= 0x10;
} else {
currentBoardState.adc_chnum_clkdiv[3] = 0x04;
currentBoardState.adc_chnum_clkdiv[2] = 0x02;
currentBoardState.adc_in_sel_12[3] = (2 << 0); //Set each ADC to sample one channel
currentBoardState.adc_in_sel_12[2] = (2 << 1);
currentBoardState.adc_in_sel_34[3] = (2 << 2);
currentBoardState.adc_in_sel_34[2] = (2 << 3);
currentBoardState.datamover_reg_out &= ~(0xF0);
currentBoardState.datamover_reg_out |= 0x30;
}
_adc_power_down();
_FIFO_WRITE(user_handle,currentBoardState.adc_chnum_clkdiv,sizeof(currentBoardState.adc_chnum_clkdiv));
_adc_active();
_FIFO_WRITE(user_handle,currentBoardState.adc_in_sel_12,sizeof(currentBoardState.adc_in_sel_12));
_FIFO_WRITE(user_handle,currentBoardState.adc_in_sel_34,sizeof(currentBoardState.adc_in_sel_34));
return 1;
}
void PCIeLink::_adc_power_down() {
uint8_t power_down_bytes[4] = {0xFD,0x0F,0x02,0x00};
_FIFO_WRITE(user_handle,power_down_bytes,sizeof(power_down_bytes));
}
void PCIeLink::_adc_active() {
uint8_t adc_active_bytes[4] = {0xFD,0x0F,0x00,0x00};
_FIFO_WRITE(user_handle,adc_active_bytes,sizeof(adc_active_bytes));
}

View File

@ -436,8 +436,8 @@ int Bridge::InitTxBridge() {
// pipe already exists...
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
1,
4096 * 16,
4096 * 16,
4096 * 4096 * 16,
4096 * 4096 * 16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
@ -503,8 +503,8 @@ int Bridge::InitRxBridge() {
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE |
PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
1,
4096 * 16,
4096 * 16,
4096 * 4096 * 16,
4096 * 4096 * 16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);

View File

@ -69,6 +69,7 @@ controller::~controller()
delete processorThread;
delete postProcessorThread;
delete bridgeThread;
delete pcieLinkThread;
DEBUG << "Controller Destroyed";
}
@ -408,7 +409,7 @@ void controller::controllerLoop()
}
//Sleep, but don't oversleep
std::this_thread::sleep_for(std::chrono::milliseconds(5));
std::this_thread::sleep_for(std::chrono::microseconds(250));
}
}
@ -815,3 +816,69 @@ void controller::setFileName(int8_t newFile)
free(inputFile);
inputFile = filename;
}
void controller::hardWareCommand(int command, int channel, int val1, double val2) {
ScopeCommand cmd = static_cast<ScopeCommand>(command);
switch(cmd) {
case init_board:
break;
case adc_enable_ramp_test:
break;
case dataMover_enable:
break;
case dataMover_disable:
break;
case test_write:
break;
case enable_channel:
pcieLinkThread->Write(cmd,(void*)&channel);
break;
case disable_channel:
pcieLinkThread->Write(cmd,(void*)&channel);
break;
case ac_couple:
pcieLinkThread->Write(cmd,(void*)&channel);
break;
case dc_couple:
pcieLinkThread->Write(cmd,(void*)&channel);
break;
case voltage_divison_set:
{
VoltageDivSetParam param;
param.ch_num = channel;
param.voltage_div = val1;
pcieLinkThread->Write(cmd,(void*)&param);
}
break;
case voltage_offset_set:
{
VoltageOffsetParam param;
param.ch_num = channel;
param.voltage = val2;
pcieLinkThread->Write(cmd,(void*)&param);
}
break;
case bandwidth_set:
{
BandwidthSetParam param;
param.ch_num = channel;
param.bw = val1;
pcieLinkThread->Write(cmd,(void*)&param);
}
break;
default:
break;
}
}
void controller::testADCData() {
pcieLinkThread->Write(test_adc_data,nullptr);
}

View File

@ -407,6 +407,9 @@ void runCli() {
parseThings = parseCli(line);
}
if(controllerThread != NULL)
delete controllerThread;
}
int main(int argc, char** args)
{