}
else {
ofpga[TIMING_IO] = 0x0000;
}
#if SYSCLK_INTERNAL
ofpga[TIMING_IO] |= 0x0100; // Force internal SysClock
printf("TIMING_IO: %x\n", ofpga[TIMING_IO]);
printf("TEST: %x\n", ofpga[PU0_REG_BASE + TEST]);
#endif
dprintf(DBG_FPGA, "TIMING_IO: %x\n", ofpga[TIMING_IO]);
ofpga[PU0_REG_BASE + CYCLE] = 0;
ofpga[PU1_REG_BASE + CYCLE] = 0;
ofpga[PU2_REG_BASE + CYCLE] = 0;
#ifdef ZAP
{
uint8_t data[2*1024*1024];
uint32_t p = 0;
printf("Clear memory\n");
memset(data, 0x55, sizeof(data));
ofpga[MEM_REG] = SDRAM_DATA_PU0;
for(p = 0; p < 1; p++){
ofpga[ADDR_REG] = p << 19;
fpgaWriteData64(data, 0, sizeof(data));
}
ofpga[MEM_REG] = SDRAM_DATA_PU1;
for(p = 0; p < 1; p++){
ofpga[ADDR_REG] = p << 19;
fpgaWriteData64(data, 0, sizeof(data));
}
ofpga[MEM_REG] = SDRAM_DATA_PU2;
for(p = 0; p < 1; p++){
ofpga[ADDR_REG] = p << 19;
fpgaWriteData64(data, 0, sizeof(data));
}
printf("Clear memory: Done\n");
}
#endif
#ifdef ZAP
{
BArray<UInt32> data;
BFile file;
BString fileName = "../datasrc/beam3-437000-8.psd";
int nb;
printf("Load Test Data\n");
if(err = file.open(fileName, "r")){
printf("Error: Opening file:\n");
}
data.resize(1024);
if((nb = file.read(&data[0], 1024 * sizeof(UInt32))) <= 0){
printf("Error: Reading file:\n");
}
data.resize(nb / sizeof(UInt32));
olock.unlock();
setTestData(PuChannel(1,1,1), 1, data);
olock.lock();
printf("Load Test Data: Done\n");
}
#endif
#ifdef ZAP
dprintf(DBG_FPGA, "Pupe::fpgaConfig: DumpState\n");
dumpState();
#endif
#ifdef ZAP
BIter i;
BList<NameValue> infoList;
fpgaGetInfo(infoList);
for(infoList.start(i); !infoList.isEnd(i); infoList.next(i)){
printf("%s: %s\n", infoList[i].name.retStr(), infoList[i].value.retStr());
}
#endif
dprintf(DBG_FPGA, "Pupe::fpgaConfig: End\n");
return err;
}
BError Pupe::fpgaReadData64(uint32_t fpgaOffset, void* toAddress, int nbytes){
BError err;
ADMXRC2_STATUS status;
uint32_t dmaMode;
dprintf(DBG_FPGA, "Pupe::fpgaReadData64\n");
dmaMode = ADMXRC2_BuildDMAModeWord(ocardInfo.BoardType,
ADMXRC2_IOWIDTH_64, 0,
ADMXRC2_DMAMODE_USEREADY |
ADMXRC2_DMAMODE_USEBTERM |
ADMXRC2_DMAMODE_BURSTENABLE);
dprintf(DBG_FPGA, "fpgaReadData64: Offset: 0x%x MEM_REG: 0x%x, ADDR_REG: 0x%x, MEM_RAO: 0x%x, MEM_RAS: 0x%x NBytes: %d\n", fpgaOffset, ofpga[MEM_REG], ofpga[ADDR_REG], ofpga[MEM_RAO], ofpga[MEM_RAS], nbytes);
ocontrol.odmaLock.lock();
status = ADMXRC2_DoDMA(ofpgaCard, odmabuf, 0, nbytes,
FPGA_DATA_ADDRESS + fpgaOffset, ADMXRC2_LOCALTOPCI, 0, dmaMode, 0, 0, 0);
ocontrol.odmaLock.unlock();
memcpy(toAddress, odmaBuffer, nbytes);
if(status){
err.set(ErrorFpga, getName() + "Fpga: DMA Error");
}
return err;
}
BError Pupe::fpgaReadData32(uint32_t fpgaOffset, void* toAddress, int nbytes){
BError err;
ADMXRC2_STATUS status;
uint32_t dmaMode;
dprintf(DBG_FPGA, "Pupe::fpgaReadData32\n");
dmaMode = ADMXRC2_BuildDMAModeWord(ocardInfo.BoardType,
ADMXRC2_IOWIDTH_32, 0,
ADMXRC2_DMAMODE_USEREADY |
ADMXRC2_DMAMODE_USEBTERM |
ADMXRC2_DMAMODE_BURSTENABLE);
ocontrol.odmaLock.lock();
status = ADMXRC2_DoDMA(ofpgaCard, odmabuf, 0, nbytes,
FPGA_DATA_ADDRESS + fpgaOffset, ADMXRC2_LOCALTOPCI, 0, dmaMode, 0, 0, 0);
ocontrol.odmaLock.unlock();
memcpy(toAddress, odmaBuffer, nbytes);
if(status){
err.set(ErrorFpga, getName() + "Fpga: DMA Error");
}
return err;
}
BError Pupe::fpgaWriteData64(void* fromAddress, uint32_t fpgaOffset, int nbytes){
BError err;
ADMXRC2_STATUS status;
uint32_t dmaMode;
dprintf(DBG_FPGA, "Pupe::fpgaWriteData64\n");
dmaMode = ADMXRC2_BuildDMAModeWord(ocardInfo.BoardType,
ADMXRC2_IOWIDTH_64, 0,
ADMXRC2_DMAMODE_USEREADY |
ADMXRC2_DMAMODE_USEBTERM |
ADMXRC2_DMAMODE_BURSTENABLE);
memcpy(odmaBuffer, fromAddress, nbytes);
ocontrol.odmaLock.lock();
status = ADMXRC2_DoDMA(ofpgaCard, odmabuf, 0, nbytes,
FPGA_DATA_ADDRESS + fpgaOffset, ADMXRC2_PCITOLOCAL, 0, dmaMode, 0, 0, 0);
ocontrol.odmaLock.unlock();
if(status){
err.set(ErrorFpga, getName() + "Fpga: DMA Error");
}
return err;
}
BError Pupe::fpgaCopyData(int pupeChan, uint32_t address, uint32_t nsamples, Data& data){
BError err;
uint32_t pageSize = 2*1024*1024;
uint32_t dataTablePage;
uint32_t dataTableOffset;
uint32_t ncopy;
uint32_t addressOut = 0;
dprintf(DBG_FPGA, "Pupe::fpgaCopyData: %d\n", pupeChan);
switch(pupeChan){
case 1: ofpga[MEM_REG] = SDRAM_DATA_PU0; break;
case 2: ofpga[MEM_REG] = SDRAM_DATA_PU1; break;
case 3: ofpga[MEM_REG] = SDRAM_DATA_PU2; break;
default: return err.set(ErrorFpga, "Incorrect puChannel");
}
while(nsamples){
dataTablePage = address >> 21; // 2MByte Region
dataTableOffset = address & 0x001FFFFF; // Offset
ncopy = nsamples * 8;
if(ncopy > (pageSize - dataTableOffset)){
ncopy = pageSize - dataTableOffset;
}
ofpga[ADDR_REG] = dataTablePage << 19;
#if DEBUG_DATA
printf("MEM_RAO: %d MEM_RAS: %d\n", ofpga[MEM_RAO], ofpga[MEM_RAS]);
printf("ReadData: Chan: %d Address: %x Page: %x Offset: %x NBytes: %d\n", pupeChan, address, dataTablePage, dataTableOffset, ncopy);
#endif
#if USE_DMA
if(err = fpgaReadData64(dataTableOffset, &data.dataValues[addressOut], ncopy)){
ofpga[MEM_REG] = SDRAM_BLOCKRAM;
return err;
}
#else
uint64_t* dataTable = (uint64_t*)&ofpga[FPGA_MEM];
memcpy_64(&data.dataValues[addressOut], &dataTable[dataTableOffset/8], ncopy);
#endif
dataTableOffset = 0;
address = sdramAddressByteAdd(address, ncopy);
addressOut += (ncopy / 8);
nsamples -= (ncopy / 8);
}
ofpga[MEM_REG] = SDRAM_BLOCKRAM;
dprintf(DBG_FPGA, "Pupe::fpgaCopyData: End\n");
return err;
}
void Pupe::fpgaClose(){
dprintf(DBG_FPGA, "Pupe::fpgaClose\n");
if(ofpgaCard){
// Stop interrupt thread
ointerruptThread.cancel();
ADMXRC2_CancelWaitForInterrupt(ofpgaCard);
ointerruptThread.waitForCompletion();
// Disable interrupts
ofpga[IER] = 0;
// Release DMA
if(odmabuf){
ADMXRC2_UnsetupDMA(ofpgaCard, odmabuf);
odmabuf = 0;
}
ofpga = 0;
// Close card
ADMXRC2_CloseCard(ofpgaCard);
}
}