/********************************************************************
Name: DRS.cpp
Created by: Stefan Ritt, Matthias Schneebeli
Contents: Library functions for DRS mezzanine and USB boards
$Id: DRS.cpp 14602 2009-11-27 11:47:36Z ritt $
\********************************************************************/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <algorithm>
#include <sys/stat.h>
#include "strlcpy.h"
#ifdef _MSC_VER
#pragma warning(disable:4996)
# include <windows.h>
# include <direct.h>
#else
# include <unistd.h>
# include <sys/time.h>
inline void Sleep(useconds_t x)
{
usleep(x * 1000);
}
#endif
#ifdef _MSC_VER
#include <conio.h>
#define drs_kbhit() kbhit()
#else
#include <sys/ioctl.h>
int drs_kbhit()
{
int n;
ioctl(0, FIONREAD, &n);
return (n > 0);
}
static inline int getch()
{
return getchar();
}
#endif
#include <DRS.h>
#ifdef _MSC_VER
extern "C" {
#endif
#include <mxml.h>
#ifdef _MSC_VER
}
#endif
/*---- minimal FPGA firmvare version required for this library -----*/
const int REQUIRED_FIRMWARE_VERSION_DRS2 = 5268;
const int REQUIRED_FIRMWARE_VERSION_DRS3 = 6981;
const int REQUIRED_FIRMWARE_VERSION_DRS4 = 13191;
/*---- calibration methods to be stored in EEPROMs -----------------*/
#define VCALIB_METHOD 1
#define TCALIB_METHOD 1
/*---- VME addresses -----------------------------------------------*/
#ifdef HAVE_VME
/* assuming following DIP Switch settings:
SW1-1: 1 (off) use geographical addressing (1=left, 21=right)
SW1-2: 1 (off) \
SW1-3: 1 (off) > VME_WINSIZE = 8MB, subwindow = 1MB
SW1-4: 0 (on) /
SW1-5: 0 (on) reserverd
SW1-6: 0 (on) reserverd
SW1-7: 0 (on) reserverd
SW1-8: 0 (on) \
|
SW2-1: 0 (on) |
SW2-2: 0 (on) |
SW2-3: 0 (on) |
SW2-4: 0 (on) > VME_ADDR_OFFSET = 0
SW2-5: 0 (on) |
SW2-6: 0 (on) |
SW2-7: 0 (on) |
SW2-8: 0 (on) /
which gives
VME base address = SlotNo * VME_WINSIZE + VME_ADDR_OFFSET
= SlotNo * 0x80'0000
*/
#define GEVPC_BASE_ADDR 0x00000000
#define GEVPC_WINSIZE 0x800000
#define GEVPC_USER_FPGA (GEVPC_WINSIZE*2/8)
#define PMC1_OFFSET 0x00000
#define PMC2_OFFSET 0x80000
#define PMC_CTRL_OFFSET 0x00000 /* all registers 32 bit */
#define PMC_STATUS_OFFSET 0x10000
#define PMC_FIFO_OFFSET 0x20000
#define PMC_RAM_OFFSET 0x40000
#endif // HAVE_VME
/*---- USB addresses -----------------------------------------------*/
#define USB_TIMEOUT 1000 // one second
#ifdef HAVE_USB
#define USB_CTRL_OFFSET 0x00 /* all registers 32 bit */
#define USB_STATUS_OFFSET 0x40
#define USB_RAM_OFFSET 0x80
#define USB_CMD_IDENT 0 // Query identification
#define USB_CMD_ADDR 1 // Address cycle
#define USB_CMD_READ 2 // "VME" read <addr><size>
#define USB_CMD_WRITE 3 // "VME" write <addr><size>
#define USB_CMD_READ12 4 // 12-bit read <LSB><MSB>
#define USB_CMD_WRITE12 5 // 12-bit write <LSB><MSB>
#define USB2_CMD_READ 1
#define USB2_CMD_WRITE 2
#define USB2_CTRL_OFFSET 0x00000 /* all registers 32 bit */
#define USB2_STATUS_OFFSET 0x10000
#define USB2_FIFO_OFFSET 0x20000
#define USB2_RAM_OFFSET 0x40000
#endif // HAVE_USB
/*------------------------------------------------------------------*/
using namespace std;
#ifdef HAVE_USB
#define USB2_BUFFER_SIZE (1024*1024+10)
unsigned char static *usb2_buffer = NULL;
#endif
/*------------------------------------------------------------------*/
DRS::DRS()
: fNumberOfBoards(0)
#ifdef HAVE_VME
, fVmeInterface(0)
#endif
{
#ifdef HAVE_USB
MUSB_INTERFACE *usb_interface;
#endif
#if defined(HAVE_VME) || defined(HAVE_USB)
int index = 0, i = 0;
#endif
memset(fError, 0, sizeof(fError));
#ifdef HAVE_VME
unsigned short type, fw, magic, serial, temperature;
mvme_addr_t addr;
if (mvme_open(&fVmeInterface, 0) == MVME_SUCCESS) {
mvme_set_am(fVmeInterface, MVME_AM_A32);
mvme_set_dmode(fVmeInterface, MVME_DMODE_D16);
/* check all VME slave slots */
for (index = 2; index <= 21; index++) {
/* check PMC1 */
addr = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE; // VME board base address
addr += GEVPC_USER_FPGA; // UsrFPGA base address
addr += PMC1_OFFSET; // PMC1 offset
mvme_set_dmode(fVmeInterface, MVME_DMODE_D16);
i = mvme_read(fVmeInterface, &magic, addr + PMC_STATUS_OFFSET + REG_MAGIC, 2);
if (i == 2) {
if (magic != 0xC0DE) {
printf("Found old firmware, please upgrade immediately!\n");
fBoard[fNumberOfBoards] = new DRSBoard(fVmeInterface, addr, (index - 2) << 1);
fNumberOfBoards++;
} else {
/* read board type */
mvme_read(fVmeInterface, &type, addr + PMC_STATUS_OFFSET + REG_BOARD_TYPE, 2);
type &= 0xFF;
if (type == 2 || type == 3 || type == 4) { // DRS2 or DRS3 or DRS4
/* read firmware number */
mvme_read(fVmeInterface, &fw, addr + PMC_STATUS_OFFSET + REG_VERSION_FW, 2);
/* read serial number */
mvme_read(fVmeInterface, &serial, addr + PMC_STATUS_OFFSET + REG_SERIAL_BOARD, 2);
/* read temperature register to see if CMC card is present */
mvme_read(fVmeInterface, &temperature, addr + PMC_STATUS_OFFSET + REG_TEMPERATURE, 2);
/* LED blinking */
#if 0
do {
data = 0x00040000;
mvme_write(fVmeInterface, addr + PMC_CTRL_OFFSET + REG_CTRL, &data, sizeof(data));
mvme_write(fVmeInterface, addr + PMC2_OFFSET + PMC_CTRL_OFFSET + REG_CTRL, &data,
sizeof(data));
Sleep(500);
data = 0x00000000;
mvme_write(fVmeInterface, addr + PMC_CTRL_OFFSET + REG_CTRL, &data, sizeof(data));
mvme_write(fVmeInterface, addr + PMC2_OFFSET + PMC_CTRL_OFFSET + REG_CTRL, data,
sizeof(data));
Sleep(500);
} while (1);
#endif
if (temperature == 0xFFFF) {
printf("Found VME board in slot %d, fw %d, but no CMC board in upper slot\n", index, fw);
} else {
printf("Found DRS%d board %2d in upper VME slot %2d, serial #%d, firmware revision %d\n", type, fNumberOfBoards, index, serial, fw);
fBoard[fNumberOfBoards] = new DRSBoard(fVmeInterface, addr, (index - 2) << 1);
if (fBoard[fNumberOfBoards]->HasCorrectFirmware())
fNumberOfBoards++;
else
sprintf(fError, "Wrong firmware version: board has %d, required is %d\n",
fBoard[fNumberOfBoards]->GetFirmwareVersion(),
fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
}
}
}
}
/* check PMC2 */
addr = GEVPC_BASE_ADDR + index * GEVPC_WINSIZE; // VME board base address
addr += GEVPC_USER_FPGA; // UsrFPGA base address
addr += PMC2_OFFSET; // PMC2 offset
mvme_set_dmode(fVmeInterface, MVME_DMODE_D16);
i = mvme_read(fVmeInterface, &fw, addr + PMC_STATUS_OFFSET + REG_MAGIC, 2);
if (i == 2) {
if (magic != 0xC0DE) {
printf("Found old firmware, please upgrade immediately!\n");
fBoard[fNumberOfBoards] = new DRSBoard(fVmeInterface, addr, (index - 2) << 1 | 1);
fNumberOfBoards++;
} else {
/* read board type */
mvme_read(fVmeInterface, &type, addr + PMC_STATUS_OFFSET + REG_BOARD_TYPE, 2);
type &= 0xFF;
if (type == 2 || type == 3 || type == 4) { // DRS2 or DRS3 or DRS4
/* read firmware number */
mvme_read(fVmeInterface, &fw, addr + PMC_STATUS_OFFSET + REG_VERSION_FW, 2);
/* read serial number */
mvme_read(fVmeInterface, &serial, addr + PMC_STATUS_OFFSET + REG_SERIAL_BOARD, 2);
/* read temperature register to see if CMC card is present */
mvme_read(fVmeInterface, &temperature, addr + PMC_STATUS_OFFSET + REG_TEMPERATURE, 2);
if (temperature == 0xFFFF) {
printf("Found VME board in slot %d, fw %d, but no CMC board in lower slot\n", index, fw);
} else {
printf("Found DRS%d board %2d in lower VME slot %2d, serial #%d, firmware revision %d\n", type, fNumberOfBoards, index, serial, fw);
fBoard[fNumberOfBoards] = new DRSBoard(fVmeInterface, addr, ((index - 2) << 1) | 1);
if (fBoard[fNumberOfBoards]->HasCorrectFirmware())
fNumberOfBoards++;
else
sprintf(fError, "Wrong firmware version: board has %d, required is %d\n",
fBoard[fNumberOfBoards]->GetFirmwareVersion(),
fBoard[fNumberOfBoards]->GetRequiredFirmwareVersion());
}
}
}
}
}
} else
printf("Cannot access VME crate, check driver, power and connection\n");
#endif // HAVE_VME
#ifdef HAVE_USB
unsigned char buffer[512];
int found, one_found, usb_slot;
one_found = 0;
usb_slot = 0;
for (index = 0; index < 127; index++) {
found = 0;
/* check for USB-Mezzanine test board */
if (musb_open(&usb_interface, 0x10C4, 0x1175, index, 1, 0) == MUSB_SUCCESS) {
/* check ID */
buffer[0] = USB_CMD_IDENT;
musb_write(usb_interface, 2, buffer, 1, USB_TIMEOUT);
... 6480 more lines ...
|