Project

General

Profile

Memcpy data transfer error from FPGA address space to CME... » fpga_interface.cpp

Michele Canepa, 01/21/2014 03:23 AM

 
/*************************************************************
* FPGA INTERFACE.CPP
* AUTHOR: Michele Canepa
* Description: Interface to data in fpga buffers.
*************************************************************/
#include <stdio.h>
#include <cstdio>
#include <string.h>
#include <std.h>
#include <math.h>
#include <clk.h>
// DSP/BIOS LINK Headers
#include <dsplink.h>
#include <failure.h>
#include <notify.h>
#include <bcache.h>
//Critical Link Headers
#include "core/DspFirmware.h"
#include "core/DspIntDispatch.h"
#include "core/DspFpgaGpio.h"
#include "core/DspQDMA.h"
//Custom Headers
#include "arm_interface.h"
#include "fpga_config.h"
#include "fpga_interface.h"

//#define DMA
// FILEID is used by SET_FAILURE_REASON macro.

using namespace MityDSP;

/*************************************************************
FPGA Initialization Routine
*************************************************************/
void fpga_init_tsk()
{

int r1 = tcDspInterruptDispatch::set_hw_interrupt_level(1,10);

tcDspFirmware::set_firmware_base((void*)FPGA_BASE_ADDR);

tcDspFpgaGpio *EofNew = new tcDspFpgaGpio((void*)0x66000080);
int num_channels = 4;
int rconf,isrconf = -1;
for (int i = 0; i< num_channels*2;i++){
rconf=EofNew->ConfigurePin(0,i,false,0,true,false);
isrconf= EofNew->SetISRCallback(0,i,EOFISR,NULL);
}
}


/*************************************************************
End of Frame Interrupt Routine
*************************************************************/

void EOFISR(tcGpio *apThis, unsigned int Bank, unsigned int Offset, void *apUser)
{
// Calculate Channel Number and whether the buffer is ping or pong.
int Ping = Offset % 2;
int ChannelNumber = ((Offset - Ping) >>1 );
//Don't care
int idMeas = 0;
//Pointer to fpga data.
unsigned short *DataStart;
//Depth of the Ping+Pong Buffers
int frameDepth = 1024;
int k,j=0;
Uint32 infoToArm = 0;

if (measureConfigurations.measConfs[idMeas].resolution == 16)
{
//Data buffers are contiguous.
DataStart = (unsigned short *)(MEM_CH0 + (ChannelNumber* CHANNEL_OFFSET*sizeof(unsigned short)) + (Ping*frameDepth/2)*sizeof(unsigned short));

// DMA is not tested yet...
#ifdef DMA

BCACHE_wbInvAll();
tcDspQDMA::GetInstance()->BlockTransfer(NULL,
(void*)DataStart,
(void*)measureBlocks.measureBlock[ChannelNumber][0].block,
frameDepth/4,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_PRI_HIGH);
#else
// This is the call that copies wrong.
//memcpy(measureBlocks.measureBlock[ChannelNumber][0].block,DataStart,frameDepth);

// This call is a temporary workaround
#pragma MUST_ITERATE(512,512)
for (k=0;k<512;k++){
do{
*((unsigned short *)measureBlocks.measureBlock[ChannelNumber][0].block +k)=*(DataStart +k);
}while(*((unsigned short *)measureBlocks.measureBlock[ChannelNumber][0].block +k)!=*(DataStart +k));
}

BCACHE_wbInvAll();
#endif

}

//Now I notify to ARM Channel and Measure ID.
idMeas = idMeas << 16;
infoToArm = ChannelNumber | idMeas;
NOTIFY_notify(ID_GPP,0,5,infoToArm);
}

(3-3/3)