/**************************************************************
$Workfile:   tstdapi.c  $
***************************************************************
**
** FIRMWARE, Copyright (C) 2000-2002
** Ikanos Communications, Fremont, CA
** All rights reserved.
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of
** Ikanos Communication
**
$Revision: 1.1 $
$Date: 2006/10/16 04:34:51 $
***************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "ipos.h"
#include "dapi.h"
#include "apilocal.h"
#include "bmeconfig.h"

extern int jagReadBlock(U32 id, U32 dst,U32 src,int nBytes);
extern int jagWriteBlock(U32 id, U32 dst,U32 src,int nBytes);

#define MAX_DMA_BUF_SIZE 0x2000
#define u32 U32

extern tBmeStruct  	BmeStruct[];	  		 /* BME objects for direct API */

//extern HWAPI_RET_VAL bmePioWrite_diag (tBmeStruct *bmeStruct, UINT32 destAddr, BYTE *dataPtr);
//extern HWAPI_RET_VAL bmePioRead_diag (tBmeStruct *bmeStruct, UINT32 srcAddr, BYTE *dataPtr);

BYTE DmaArray[MAX_DMA_BUF_SIZE];

void testPIOWrite (int BmeNum, unsigned long addr, unsigned long data)
{
	bmePioWrite (&BmeStruct[BmeNum], addr, (BYTE *)&data);
}

int testPIORead (int BmeNum, unsigned long addr)
{
	HWAPI_RET_VAL retVal;
	UINT32 data = 0;	

	/* PIO read from DMA_SAR reg */		
	retVal = bmePioRead (&BmeStruct[BmeNum],  addr, (BYTE *)&data);
	printf("\nRead data 0x%08lx, dest 0x%08lx\n",data,addr);	

  return retVal;

}

int testPIORead1 (int BmeNum, unsigned long addr)
{
	HWAPI_RET_VAL retVal;
	UINT32 data = 0;	

	/* PIO read from DMA_SAR reg */		
	retVal = bmePioRead (&BmeStruct[BmeNum],  addr, (BYTE *)&data);
	return data;
}


void tpw (int BmeNum, unsigned long addr, unsigned long data)
{
	ipos_api_bme	*pApiBme;

  pApiBme=(ipos_api_bme *) iposGetBmeHandle(BmeNum);
  if(iposSemTake(pApiBme->semBme, IPOS_WAIT_FOREVER) == OS_SUCCESS)
  {
    testPIOWrite(BmeNum, addr, data);
    iposSemGive(pApiBme->semBme);			/* read BME successful, release the bme Lock */
  }
}

void tpr (int BmeNum, unsigned long addr)
{
	ipos_api_bme	*pApiBme;

  pApiBme=(ipos_api_bme *) iposGetBmeHandle(BmeNum);
  if(iposSemTake(pApiBme->semBme, IPOS_WAIT_FOREVER) == OS_SUCCESS)
  {
    testPIORead(BmeNum, addr);
    iposSemGive(pApiBme->semBme);			/* read BME successful, release the bme Lock */
  }
}

/****************************************************************************/
U32 eiuPioRead (int BmeNum, unsigned long addr) 
{
  U32           uiEiuRegData = 0xffff;

#if 0
  bmePioRead_diag (&BmeStruct[BmeNum],  addr, (BYTE *)&uiEiuRegData);
#else

  ipos_api_bme	*pApiBme;
  
  pApiBme=(ipos_api_bme *) iposGetBmeHandle(BmeNum);

  if(iposSemTake(pApiBme->semBme, IPOS_WAIT_FOREVER) == OS_SUCCESS)
  {
    bmePioRead (&BmeStruct[BmeNum],  addr, (BYTE *)&uiEiuRegData);
    iposSemGive(pApiBme->semBme);			/* read BME successful, release the bme Lock */
  }
#endif

  return uiEiuRegData;
}
/****************************************************************************/
U32 eiuPioWrite (int BmeNum, unsigned long addr, unsigned long data)
{

#if 0
  bmePioWrite_diag (&BmeStruct[BmeNum], addr, (BYTE *)&data);
#else
	
  ipos_api_bme	*pApiBme;

  pApiBme=(ipos_api_bme *) iposGetBmeHandle(BmeNum);
  if(iposSemTake(pApiBme->semBme, IPOS_WAIT_FOREVER) == OS_SUCCESS)
  {
    bmePioWrite (&BmeStruct[BmeNum], addr, (BYTE *)&data);
    iposSemGive(pApiBme->semBme);			/* read BME successful, release the bme Lock */
  }
#endif

  return 0;
}
/****************************************************************************/

void doDmaRead (int bmeNum, UINT32 srcAddr, UINT32 codeLen,
                BYTE * BmeCodeArrayPtr, int destFifoFlag)
{

#ifdef CPE_30
#if (_BYTE_ORDER == _LITTLE_ENDIAN)
	unsigned int	idx, lenData;
	unsigned int	*pData;
#endif
#endif

//	Bme[bmeNum].FifoFlag=destFifoFlag;

#ifdef CPE_30
   //jagReadBlock(bmeNum,(U32)BmeCodeArrayPtr,srcAddr,codeLen);
   bmePioBulkRead (&BmeStruct[bmeNum], srcAddr, BmeCodeArrayPtr, codeLen);


#if (_BYTE_ORDER == _LITTLE_ENDIAN)
	pData = (unsigned int*)BmeCodeArrayPtr;
	if ( codeLen & 0x03 )	lenData = codeLen/4 + 1;
	else	lenData = codeLen/4;
	for(idx=0; idx<lenData; idx++)	{
		*pData = htonl(*pData);
		pData++;
	}
#endif //#if (_BYTE_ORDER == _LITTLE_ENDIAN)
#else
{
	BYTE bDmaStatus = 0;
	int iCount = 0;
	UINT32 data = 0;
	/* initiate data transfer from memory to HIC_FIFO */
	bmeTrMemory (&BmeStruct[bmeNum], srcAddr,codeLen);

	/* poll for DMA_DONE bit / DW_H status bit to set */
	bmePioRead (&BmeStruct[bmeNum], DMA_CCR(0, DMA_CH_15), (BYTE *)&data);

  while (1)
	{
		/* poll for DW_H status bit to be set */
		bDmaStatus = bmeRdStatus (&BmeStruct[bmeNum]);

		/* check if it is DMA_WRITE_DONE interrupt */
		if (bDmaStatus & DW_H_DMA_WRITE_DONE)
		{
			BmeStruct[bmeNum].dataLen = codeLen;
			/* read data from HIC_FIFO */
			bmeRdMemory (&BmeStruct[bmeNum], BmeCodeArrayPtr);
			break;
		}
		else
		{
			if (iCount < 0x20)
			{
				iCount++;
				iposTaskDelay(1);	
			}
			else
			{
				printf ("\nDMA status : 0x%x failure", bDmaStatus);
				break;
			}
			
		}	
		}	
	}
#endif
}

#define MAX_DMA_SIZE 256
void dmaRead (int bmeNum, UINT32 srcAddr, BYTE  * destAddr, UINT32 size)
{
  int i=0;
  int loop=0;
  int size2;
  int index=0;
  ipos_api_bme	*pApiBme;


  pApiBme=(ipos_api_bme *) iposGetBmeHandle(bmeNum);
  loop = (int)((size-1) / MAX_DMA_SIZE) + 1;

	for (i = 0; i < loop; i++)
	{
		if (i == (loop - 1))
      size2 = size - ((loop - 1) * MAX_DMA_SIZE);
		else
      size2 = MAX_DMA_SIZE;

    if(iposSemTake(pApiBme->semBme, IPOS_WAIT_FOREVER) == OS_SUCCESS)
    {
      doDmaRead(bmeNum, srcAddr, size2, &destAddr[index], 0);
      iposSemGive(pApiBme->semBme);			/* read BME successful, release the bme Lock */
    }
		srcAddr += MAX_DMA_SIZE;
		index += MAX_DMA_SIZE;
	}
}

void rdm( int bmeNum, u32 addr, u32 len)
{
	if ((bmeNum < 1) || (bmeNum > IPOS_MAX_BME) || (len > MAX_DMA_BUF_SIZE))
	{
		printf("\ntry again....rdm BmeNum, SrcAddr, Len\n"); 
	}
	else
	{
		dmaRead (bmeNum, addr, DmaArray, len);
		printf("Done at 0x%x\n", (unsigned int) DmaArray);
	}
}
#if 0
int debugPIORead (int BmeNum, unsigned long addr)
{
	HWAPI_RET_VAL retVal;
	UINT32 data = 0;	

	BmeStruct[BmeNum].BMEbaseAddr = 0x08000000;	
	BmeStruct[BmeNum].BmeNum=BmeNum;

	/* PIO read from DMA_SAR reg */		
	retVal = bmePioRead (&BmeStruct[BmeNum],  addr, (BYTE *)&data);
//	printf("\nRead data 0x%08lx, dest 0x%08lx\n",data,addr);	

	return data;
}
#endif
void loadPattern(char *str, int dataLen, unsigned int bme_addr)
{
    FILE    *fp;
    FILE    *fout;
    char    filename[200];
    char    *data;
    int     i;
    short   *tmp;
    char    fileout[] = "/tgtsvr/data.txt";
    char    s1[200];
#ifndef CPE_30
    int     s2;
#endif

    sprintf(filename, "/tgtsvr/%s", str);

    printf("reading %s size %d", filename, dataLen);
    fp =fopen(filename, "r");

    if(fp == NULL)
    {
        printf("Cannot open %s", filename);
        return;
    }

    data = (char *)malloc(dataLen*sizeof(char));
        
    tmp = (short *)data;

    if((fout = fopen(fileout, "w"))==NULL)
    {
        printf("cannot open %s 0x%lx", fileout, (UINT32)fout);
    }

    for(i=0;i<dataLen/2;i++)
    {
        fgets(s1, 100, fp);
        tmp[i] = atoi(s1);
        //if(fout!=NULL)
         //   fprintf(fout, "%d", tmp[i]);
    }

    printf("tot data read = %d", i);
#ifdef CPE_30
    //jagWriteBlock(1, bme_addr, (U32)data, dataLen);
#else
    for(i=0;i<dataLen/2;i+=2)
    {
        s2 = (tmp[i]<<16)|tmp[i+1];
        tpw(1, bme_addr, s2);
        bme_addr+=4;
    }
#endif
    fclose(fp);
    if(fout!=NULL)
        fclose(fout);
    free(data);
}

