/********************************************************************\ Name: HV.cc Created by: Sebastian Commichau, November 2008 commichau@phys.ethz.ch Contents: Main class for HV supply \********************************************************************/ #include "HV.h" extern bool Verbose; // // Constructor // HVBoard::HVBoard(int DeviceNumber, char *DeviceName) { char Buffer[MAX_COM_SIZE]; struct termios tio; fTimeOut = 1; BoardNumber = DeviceNumber; BoardName = DeviceName; LastWrapCount = -1; // Open device snprintf(Buffer, MAX_COM_SIZE, "/dev/%s",DeviceName); if ((fDescriptor = open(Buffer, O_RDWR|O_NOCTTY|O_NDELAY)) == -1) { printf("Error: Could not open device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno)); return; } // Get current serial port settings if (tcgetattr(fDescriptor, &tio) == -1) { printf("Error: tcgetattr() failed on device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno)); return; } // Set baudrate and raw mode if (cfsetspeed(&tio, BAUDRATE) == -1) printf("Error: Could not set baud rate of device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno)); cfmakeraw(&tio); if (tcsetattr(fDescriptor, TCSANOW, &tio ) == -1) printf("Error: tcsetattr() failed on device #%d: %s (%d/%s)\n", DeviceNumber, DeviceName, errno, strerror(errno)); return; } // // Destructor // HVBoard::~HVBoard() { if(fDescriptor != -1) close(fDescriptor); } // Communicate: Write and read from HV Board until fTimeOut has been reached // // Returns: 0 error, 1 success, -1 fTimeOut exceeded int HVBoard::Communicate(unsigned char* wbuf, int Bytes) { unsigned char rbuf[RBUF_LEN]; int ret; fd_set SelectDescriptor; Status.BoardNumber = -1; // === Write data === ret = write(fDescriptor, wbuf, Bytes); if (ret == -1) { printf("Error: Could not write data (%d/%s)\n", errno, strerror(errno)); return 0; } else if (ret < Bytes) { printf("Error: Could write only %d of %d bytes\n", ret, Bytes); return 0; } if (Verbose) { printf(" %d byte(s) written: ", Bytes); for (int i=0; i>4) { printf("Warning: Wrap counter mismatch.\n"); } } LastWrapCount = (rbuf[0] & 0x70)>>4; // Print result in hexadecimal and binary representation if (Verbose) { printf(" %d byte(s) read: ", ret); for (int i=0; i=0; j--) { printf("%c", (rbuf[i] & 1<>4) & 7; Status.Reset = rbuf[2] & 128; Status.Acknowledge = !((rbuf[2] & 0x70) == 0x70); if (Verbose) { printf(" *** Board %d *** Current: %d\n" "Overcurrent bit: %s Wrap counter: %d Reset bit: %s Status: %s\n", Status.BoardNumber, Status.Current, Status.Overcurrent ? "set":"clear", Status.WrapCounter, Status.Reset==false ? "clear": "set", Status.Acknowledge ? "OK" : "No response"); } } // if (ret == 3) { // printf(" *** Board %d *** Current: %d\n" // "Overcurrent bit: %s Wrap counter: %d Reset bit: %s Status: %s\n", // rbuf[2]&0xf, rbuf[1]+(rbuf[0]&15)*256, // rbuf[0]&128 ? "set":"clear", (rbuf[0]>>4)&7, // (rbuf[2]&128)==0 ? "clear": "set", // (rbuf[2]&0x70)==0x70 ? "No response": "OK"); // } return 1; } // System reset of HV board int HVBoard::SystemReset() { unsigned char wbuf[] = {0,0,0}; return Communicate(wbuf, 3); } // Read channel status int HVBoard::ReadChannel(int Chain, int Channel) { unsigned char wbuf[] = {1<<5 | Chain<<1 | (Channel&16)>>4, Channel<<4, 0}; return Communicate(wbuf, 3); } // Global set int HVBoard::GlobalSet(int Voltage) { unsigned char wbuf[] = {1<<6 , Voltage>>8, Voltage}; return Communicate(wbuf, 3); } // Channel set int HVBoard::ChannelSet(int Chain, int Channel, int Voltage) { unsigned char wbuf[] = {3<<5 | Chain<<1 | (Channel&16)>>4, Channel<<4 | Voltage>>8, Voltage}; return Communicate(wbuf, 3); } // Synchronize board bool HVBoard::SynchBoard() { unsigned char wbuf = 0; int trial = 0, ret; while(++trial<=3) { if((ret = Communicate(&wbuf, 1)) == 1) return true; if (ret==0) break; } return false; }