/**HEADER********************************************************************
* 
* Copyright (c) 2010 Avnet Japan Co.,Ltd (NIKE Borad Project.)
* All Rights Reserved
*
**************************************************************************
*
* $FileName: AD7652_mcf52xx.c$
* $Version : 0.1.0.0$
* $Date    : Jan-29-2010$
*
* Comments:
*
*   The file contains functions to program queued serial peripheral
*   interface on Freescale Coldfire 52xx CPU
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "fio_prv.h"
#include "event.h"
//#include "timer.h"

//#include "../AD7652.h"
//#include "../AD7652_prv.h"
#include "AD7652.h"
#include "AD7652_prv.h"

#include "AD7652_mcf52xx.h"
#include "AD7652_mcf52xx_prv.h"


/* ------------------------------------------------------------------ 
   --- macro definition                                           --- 
   ------------------------------------------------------------------ */

#define	AD7652_MCF52XX_TASK_TEST	1


#define	AD7652_MCF52XX_DMA_CH	0

#define	AD7652_SIGNAL_BPS_MAX	100000L
#define	AD7652_SIGNAL_BPS		 50000L
//#define AD_DATA_SIZE	300
#define AD_DATA_SIZE	((BSP_SIGNAL_DMA_TIME * AD7652_SIGNAL_BPS_MAX)/1000)

#define AD7652_TASK		10

#define BSP_DMA0_INT_LEVEL			(3)
#define BSP_DMA0_INT_SUBLEVEL       (1)

//#define AD7652_ADC_DATA_SIZE		(AD_DATA_SIZE*2)
#define AD7652_MEM_MAXSIZE			5

#define E_OK	0
#define E_OBJ	-1

/* ------------------------------------------------------------------ 
   --- structure body definition                                  --- 
   ------------------------------------------------------------------ */

/* 宣言：AD7652_MEM_DATA */
typedef struct
{
	uint_16	data[AD_DATA_SIZE];
	uint_16	size;
}AD7652_MEM_DATA, *PAD7652_MEM_DATA;


/* 宣言：AD7652_MEM_BUFFER */
typedef struct
{
	AD7652_MEM_DATA		mem;
	void 				*buffer;
}AD7652_MEM_BUFFER, *PAD7652_MEM_BUFFER;


/* 宣言：AD7652_MEM_BUFFER */
typedef struct
{
	uint_32	dma_isr_count;
	uint_32	dma_task_count;
	uint_32	dma_error_count;
}AD7652_STATISTICS, *PAD7652_STATISTICS;

uint_32		ad7652_dma_size;


/* ------------------------------------------------------------------ 
   --- variable definition                                        --- 
   ------------------------------------------------------------------ */

unsigned short	dma_outdata[2][AD_DATA_SIZE];

AD7652_STATISTICS	ad7652_statistics;
AD7652_MEM_BUFFER	ad7652_data[AD7652_MEM_MAXSIZE];
AD7652_MEM_BUFFER	*ad7652_mem_start;
AD7652_MEM_BUFFER	*ad7652_mem_end;

int_16	ad7652_mem_size;
int_16	ad7652_mem_size_max;

AD7652_MEM_BUFFER	*pad7652_mem_que;

int_32	ad7652_bps_data;


AD7652_MEM_BUFFER	*pad7652_mem_dma_in;
AD7652_MEM_BUFFER	*pad7652_mem_dma_out;


/* ------------------------------------------------------------------ 
   --- prototype declaration                                      --- 
   ------------------------------------------------------------------ */

void *memcpy(void *dest, const void *source, _mem_size n);

extern uint_32 _mcf52xx_AD7652_init(IO_AD7652_DEVICE_STRUCT_PTR, char_ptr);
extern uint_32 _mcf52xx_AD7652_deinit(MCF52XX_AD7652_INIT_STRUCT_PTR, MCF52XX_AD7652_INFO_STRUCT_PTR);
extern int_32  _mcf52xx_AD7652_ioctl(MCF52XX_AD7652_INFO_STRUCT_PTR, uint_32, _mqx_uint_ptr);
extern int_32  _mcf52xx_AD7652_rx(IO_AD7652_DEVICE_STRUCT_PTR, uchar_ptr, _mqx_int);
extern int_32  _mcf52xx_AD7652_tx(IO_AD7652_DEVICE_STRUCT_PTR, uchar_ptr, _mqx_int);

pointer  _bsp_get_qspi_base_address(uint_8);
pointer  _bsp_get_dma_base_address(uint_8);
pointer  _bsp_get_dmatim_base_address(uint_8);
pointer  _bsp_get_scm_base_address(uint_8 dev_num);

uint_32  _bsp_get_dma_vector(uint_8);
void     _ad7652_int_isr(pointer parameter);
_mqx_int _bsp_AD7652_io_init( uint_8 dev_num );
pointer  _bsp_get_gpio_base_address(void);
_mqx_int _bsp_AD7652_io_reset(void);

void AD7652_mem_init(void);
int_32 AD7652_mem_alloc(AD7652_MEM_BUFFER	**pSB);
void AD7652_mem_free(AD7652_MEM_BUFFER	**ppSB);
int AD7652_Set_queue(AD7652_MEM_BUFFER	*pnew_ad7652_mem);
int AD7652_Get_queue(AD7652_MEM_BUFFER	**pget_ad7652_mem);



/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_gpio_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding GPIO
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_gpio_base_address(void)
{
	return (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->GPIO);
}



/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _bsp_AD7652_io_init
* Returned Value   : 0 for success, -1 for failure
* Comments         :
*    This function performs BSP-specific initialization related to AD7652 GPIO
*
*END*----------------------------------------------------------------------*/
_mqx_int _bsp_AD7652_io_init( uint_8 dev_num )
{
	VMCF5225_GPIO_STRUCT_PTR	gpio_ptr;

	gpio_ptr = _bsp_get_gpio_base_address();

	/* PTA0,PTA1,PTA3 GPIO Hi Set */
	GPIO_P_SET(TA, PORT_ADC_CNV_ST);
	GPIO_P_SET(TA, PORT_ADC_PD);
	GPIO_P_SET(TA, PORT_ADC_RESET);

	GPIO_DDR_IN(NQ, PORT_ADC_BUSY);

	/* PTA0,PTA1,PTA3 GPIO OUTPUT */
	GPIO_DDR_OUT(TA, PORT_ADC_CNV_ST);
	GPIO_DDR_OUT(TA, PORT_ADC_PD);
	GPIO_DDR_OUT(TA, PORT_ADC_RESET);

	/* PTA0,PTA1,PTA3 GPIO */
	gpio_ptr->PTAPAR = (gpio_ptr->PTAPAR&(~0xcf))|0x00;

	/* PN1 GPIO */
	gpio_ptr->PNQPAR = (gpio_ptr->PNQPAR&(~0x000c))|0x0000;

    return 0;
}




/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _bsp_AD7652_io_init
* Returned Value   : 0 for success, -1 for failure
* Comments         :
*    This function performs BSP-specific initialization related to MiniFLEXBUS
*
*END*----------------------------------------------------------------------*/
_mqx_int _bsp_AD7652_io_reset(void)
{
	VMCF5225_GPIO_STRUCT_PTR		gpio_ptr;
	TIME_STRUCT                     time;
	uint_32                         milliseconds;

	gpio_ptr = _bsp_get_gpio_base_address();

	/* PORT_ADC_PD Low Set */
	GPIO_P_CLR(TA, PORT_ADC_PD);

	/* PORT_ADC_CNV_ST,PORT_ADC_RESET Hi Set */
	GPIO_P_SET(TA, PORT_ADC_CNV_ST);
	GPIO_P_SET(TA, PORT_ADC_RESET);

	/* 2ms WAIT */
	_time_get(&time);
	milliseconds = time.MILLISECONDS;
	while (1) {
		_time_get(&time);
		if (time.MILLISECONDS < milliseconds){
			time.MILLISECONDS += 1000;
		}

		if ((time.MILLISECONDS - milliseconds) >= 2) {
			break;
		}
	}

	/* PORT_ADC_RESET Low Set */
	GPIO_P_CLR(TA, PORT_ADC_RESET);

	/* 2ms WAIT */
	_time_get(&time);
	milliseconds = time.MILLISECONDS;
	while (1) {
		_time_get(&time);
		if (time.MILLISECONDS < milliseconds){
			time.MILLISECONDS += 1000;
		}

		if ((time.MILLISECONDS - milliseconds) >= 5) {
			break;
		}
	}

	/* PORT_ADC_CNV_ST Low Set */
	GPIO_P_CLR(TA, PORT_ADC_CNV_ST);

    return 0;
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_i2c_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding I2C
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_qspi_base_address(uint_8 dev_num)
{
	if (dev_num > 0){
		return NULL;
	}

	return (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->QSPI);
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_dma_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding DMA
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_dma_base_address(uint_8 dev_num)
{
	if (dev_num > 3){
		return NULL;
	}

	return (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->DMA[dev_num]);
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_dmatim_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding DMA_TIMER
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_dmatim_base_address(uint_8 dev_num)
{
	if (dev_num > 3){
		return NULL;
	}

	return (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->DMA_TIMER[dev_num]);
}


/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_scm_base_address
* Returned Value   : Address upon success, NULL upon failure
* Comments         :
*    This function returns the base register address of the corresponding SCM
*
*END*----------------------------------------------------------------------*/
pointer _bsp_get_scm_base_address(uint_8 dev_num)
{
	if (dev_num > 0){
		return NULL;
	}

	return (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->SCM);
}




/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _bsp_get_dma_vector
* Returned Value   : Vector number upon success, 0 upon failure
* Comments         :
*    This function returns desired interrupt vector number for specified DMA
*
*END*----------------------------------------------------------------------*/
uint_32 _bsp_get_dma_vector(uint_8 dev_num)
{
    if (dev_num > 0){
       return 0;
	}

	return MCF5225_INT_QSPI;
}



/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : _mcf52xx_AD7652_install
* Input Value      : 
      [IN] A string that identifies the device for fopen: char_ptr identifier,
      [IN] The I/O init data pointer					: pointer init_data_ptr

* Returned Value   : uint_32 a task error code or MQX_OK
* Comments         :
*    Install an QSPI device.
*
*END*----------------------------------------------------------------------*/
uint_32 _mcf52xx_AD7652_install(char_ptr identifier, pointer init_data_ptr)
{
	return _io_AD7652_install(identifier,
		(uint_32 (_CODE_PTR_)(pointer, char_ptr))_mcf52xx_AD7652_init,
		(uint_32 (_CODE_PTR_)(pointer, pointer))_mcf52xx_AD7652_deinit,
		(int_32 (_CODE_PTR_)(pointer, char_ptr, _mqx_int))_mcf52xx_AD7652_rx,
		(int_32 (_CODE_PTR_)(pointer, char_ptr, _mqx_int))_mcf52xx_AD7652_tx,
		(int_32 (_CODE_PTR_)(pointer, uint_32, _mqx_uint_ptr))_mcf52xx_AD7652_ioctl,
		init_data_ptr);
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : AD7652_mem_init
* Returned Value   : none
* Comments         :
*
*END*----------------------------------------------------------------------*/

void AD7652_mem_init(void)
{
	int i;

	for (i = 0 ;i < (AD7652_MEM_MAXSIZE-1) ; i++){
		ad7652_data[i].buffer  = (void *)&ad7652_data[i+1];
	}

	ad7652_data[AD7652_MEM_MAXSIZE-1].buffer  = (void *)0;
	ad7652_mem_start 	= (AD7652_MEM_BUFFER*)&ad7652_data[0];
	ad7652_mem_end 		= (AD7652_MEM_BUFFER*)&ad7652_data[(AD7652_MEM_MAXSIZE-1)];

	ad7652_mem_size = 0;
	pad7652_mem_que = (AD7652_MEM_BUFFER*)0;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : AD7652_mem_alloc
* Returned Value   : エラーコード
* Comments         :
*
*END*----------------------------------------------------------------------*/

int_32 AD7652_mem_alloc(AD7652_MEM_BUFFER	**pSB)
{
	AD7652_MEM_BUFFER *pad7652_temp;

	if (ad7652_mem_start->buffer == 0){
		/* Memory Busy */
		return E_OBJ;
	}

	pad7652_temp = ad7652_mem_start;
	//*pSB  = (AD7652_MEM_BUFFER*)ad7652_mem_start;
	ad7652_mem_start = (AD7652_MEM_BUFFER*)ad7652_mem_start->buffer;
	ad7652_mem_size++;

	pad7652_temp->buffer = 0;
	*pSB  = (AD7652_MEM_BUFFER*)pad7652_temp;

	return E_OK;
}



/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : AD7652_mem_free
* Returned Value   : none
* Comments         :
*
*END*----------------------------------------------------------------------*/

void AD7652_mem_free(AD7652_MEM_BUFFER	**ppSB)
{
	volatile AD7652_MEM_BUFFER	*pSB;

	pSB = (AD7652_MEM_BUFFER*)*ppSB;

	ad7652_mem_end->buffer = (void*)pSB;
	ad7652_mem_end = (AD7652_MEM_BUFFER*)pSB;
	ad7652_mem_end->buffer = 0;
	ad7652_mem_size--;
}


/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : AD7652_Set_queue
* Returned Value   : none
* Comments         :
*
*END*----------------------------------------------------------------------*/

int AD7652_Set_queue(AD7652_MEM_BUFFER	*pnew_ad7652_mem)
{
	AD7652_MEM_BUFFER	*pWmem;

	if (pad7652_mem_que == 0){
		pad7652_mem_que = pnew_ad7652_mem;
	}
	else{
		pWmem = pad7652_mem_que;
		while(1){
			if (pWmem->buffer == 0){
				pWmem->buffer = (void*)pnew_ad7652_mem;
				break;
			}
			pWmem = (AD7652_MEM_BUFFER*)pWmem->buffer;
		}
	}

	return E_OK;
}



/*FUNCTION*-------------------------------------------------------------------
* 
* Function Name    : AD7652_Get_queue
* Returned Value   : エラーコード
* Comments         :
*
*END*----------------------------------------------------------------------*/

int AD7652_Get_queue(AD7652_MEM_BUFFER	**pget_ad7652_mem)
{
	if (pad7652_mem_que == 0){
		return E_OBJ;
	}

	*pget_ad7652_mem  = pad7652_mem_que;

	if (pad7652_mem_que->buffer == 0){
		pad7652_mem_que = 0;
	}
	else{
		pad7652_mem_que = pad7652_mem_que->buffer;
	}

	return E_OK;
}





/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_AD7652_init  
* Input Value      : 
   [IN] the initialization information for the device being opened 	: IO_AD7652_DEVICE_STRUCT_PTR  io_dev_ptr,
   [IN] the rest of the name of the device opened 					: char_ptr                      open_name_ptr

* Returned Value   : uint_32 a QSPI error code or QSPI_OK
* Comments         :
*    This function initializes the QSPI module 
*
*END*********************************************************************/
uint_32 _mcf52xx_AD7652_init(IO_AD7652_DEVICE_STRUCT_PTR io_dev_ptr, char_ptr open_name_ptr)
{
	VMCF5225_DMA_STRUCT_PTR			dma_ptr;
	VMCF5225_DMA_TIMER_STRUCT_PTR	dmatim_ptr;
	VMCF5225_SCM_STRUCT_PTR			scm_ptr;
	MCF52XX_AD7652_INFO_STRUCT_PTR	io_info_ptr;
//	uint_32	div;
	uint_32	result = QSPI_OK;

	MCF52XX_AD7652_INIT_STRUCT_PTR	init_io_dev_ptr;
	uint_32 status;

	init_io_dev_ptr = io_dev_ptr->DEV_INIT_DATA_PTR;

//	ad7652_bps_data = 50000L;
	ad7652_bps_data = AD7652_SIGNAL_BPS;

	ad7652_dma_size = (BSP_SIGNAL_DMA_TIME * ad7652_bps_data)/1000;

	printf("AD7652：dma size = %d \n",ad7652_dma_size);


	dma_ptr = _bsp_get_dma_base_address(AD7652_MCF52XX_DMA_CH);
	dmatim_ptr = _bsp_get_dmatim_base_address(AD7652_MCF52XX_DMA_CH);
	scm_ptr = _bsp_get_scm_base_address(0);

	/* QSPI board specific initialization */
	//   _bsp_qspi_initialize(0);
	/* Initialize internal data */
	io_info_ptr = (MCF52XX_AD7652_INFO_STRUCT _PTR_)_mem_alloc_system_zero((uint_32)sizeof(MCF52XX_AD7652_INFO_STRUCT));

#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
	if (io_info_ptr == NULL) {
		return(MQX_OUT_OF_MEMORY);
	}
#endif

//	*io_info_ptr_ptr = io_info_ptr;
	io_dev_ptr->DEV_INFO_PTR = io_info_ptr;

	io_info_ptr->INIT       = *init_io_dev_ptr;
	io_info_ptr->INT_BITS   = 0;
	io_info_ptr->BUFFER     = NULL;
	io_info_ptr->INTERRUPTS = 0;
	io_info_ptr->RX_PACKETS = 0;
	io_info_ptr->TX_PACKETS = 0;
	io_info_ptr->TX_ABORT   = 0;
	io_info_ptr->DEV_CALLBACK = 0;

	ad7652_statistics.dma_isr_count = 0;
	ad7652_statistics.dma_task_count = 0;
	ad7652_statistics.dma_error_count = 0;

	{
		int i;

		for(i=0;i<AD_DATA_SIZE;i++){
			dma_outdata[0][i] = 0;
			dma_outdata[1][i] = 0;
		}
	}

	/* AD7652 IO INIT */
	_bsp_AD7652_io_init(0);

	/* AD7652 IO Reset */
	_bsp_AD7652_io_reset();

	pad7652_mem_dma_in = 0;
	pad7652_mem_dma_out = 0;

	/* AD7652_mem初期化 */
	AD7652_mem_init();

	/* DMA初期設定 */

	// DMA Source address register
	dma_ptr->SAR = 0;
	// DMA Destination address register	
	dma_ptr->DAR = 0;
	// DMA status register
	dma_ptr->BCR = 0;

	// DMA control register
	dma_ptr->DCR = (MCF5225_DMA_DCR_DSIZE(MCF5225_DMA_DCR_DSIZE_WORD))|(MCF5225_DMA_DCR_DINC)|
					(MCF5225_DMA_DCR_SSIZE(MCF5225_DMA_DCR_SSIZE_WORD))|(MCF5225_DMA_DCR_BWC(0));


	/* 割り込み設定 */
	io_info_ptr = io_dev_ptr->DEV_INFO_PTR;
	io_info_ptr->OLD_ISR_DATA = _int_get_isr_data(MCF5225_INT_DMA0);
	io_info_ptr->OLD_ISR_EXCEPTION_HANDLER = _int_get_exception_handler(MCF5225_INT_DMA0);
	io_info_ptr->OLD_ISR = _int_install_isr(MCF5225_INT_DMA0, _ad7652_int_isr, io_dev_ptr);

	status = _mcf52xx_int_init((PSP_INTERRUPT_TABLE_INDEX)MCF5225_INT_DMA0, BSP_DMA0_INT_LEVEL, BSP_DMA0_INT_SUBLEVEL, TRUE);
	if (status == MQX_OK) {
	 	printf("AD7652 _mcf52xx_int_init OK\n");
	}

	return (result);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_AD7652_deinit  
* Input Value      :
   [IN] the initialization information for the device being opened	: MCF52XX_AD7652_INIT_STRUCT_PTR     int_io_dev_ptr,
   [IN] the address of the device specific information				: MCF52XX_AD7652_INFO_STRUCT_PTR     io_info_ptr

* Returned Value   : uint_32 a QSPI error code or QSPI_OK
* Comments         :
*    This function de-initializes the QSPI module 
*
*END*********************************************************************/
uint_32 _mcf52xx_AD7652_deinit(MCF52XX_AD7652_INIT_STRUCT_PTR int_io_dev_ptr, MCF52XX_AD7652_INFO_STRUCT_PTR io_info_ptr)
{
	//VMCF52XX_QSPI_STRUCT_PTR	qspi_ptr;
	VMCF5225_DMA_STRUCT_PTR	dma_ptr;
	VMCF5225_DMA_TIMER_STRUCT_PTR	dmatim_ptr;
	TIME_STRUCT	time;
	uint_32	milliseconds;

	//qspi_ptr = _bsp_get_qspi_base_address(0);
	dma_ptr = _bsp_get_dma_base_address(AD7652_MCF52XX_DMA_CH);
	dmatim_ptr = _bsp_get_dmatim_base_address(AD7652_MCF52XX_DMA_CH);

#if 0
	/* wait while qspi is busy */
	qspi_ptr->QWR |= QSPI_QWR_HALT;

	/* Disable the QSPI */
	qspi_ptr->QMR |= QSPI_QMR_DOHIE;
#endif

	return (QSPI_OK);
}



/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_AD7652_ioctl
* Input Value      : 
      [IN] the address of the device specific information 	: MCF52XX_AD7652_INFO_STRUCT_PTR io_info_ptr,
      [IN] The command to perform							: uint_32 cmd,
      [IN] Parameters for the command						: uint_32_ptr param_ptr

* Returned Value   : QSPI_OK or a QSPI error code.
* Comments         : 
*    This function performs miscellaneous services for
*    the QSPI I/O device.  
*
*END*********************************************************************/
int_32 _mcf52xx_AD7652_ioctl(MCF52XX_AD7652_INFO_STRUCT_PTR io_info_ptr, uint_32 cmd, uint_32_ptr param_ptr)
{
	//VMCF52XX_QSPI_STRUCT_PTR 		qspi_ptr;
	VMCF5225_DMA_STRUCT_PTR			dma_ptr;
	VMCF5225_DMA_TIMER_STRUCT_PTR	dmatim_ptr;
	VMCF5225_SCM_STRUCT_PTR			scm_ptr;
	volatile uint_32         tstatus;
	volatile uint_32         tmp_cs;
	volatile uint_32         state_lev;
	_mqx_int                 i;
	uint_32                  result = QSPI_OK;
	int_32                            *pint;

	//qspi_ptr = _bsp_get_qspi_base_address(0);
	dma_ptr = _bsp_get_dma_base_address(AD7652_MCF52XX_DMA_CH);
	dmatim_ptr = _bsp_get_dmatim_base_address(AD7652_MCF52XX_DMA_CH);
	scm_ptr = _bsp_get_scm_base_address(0);

	switch (cmd) {
		case IO_IOCTL_AD7652_START:

			/* リセット処理 */
			dmatim_ptr->DTMR = dmatim_ptr->DTMR | MCF5225_DTIM_DTMR_RST;
			dmatim_ptr->DTMR = dmatim_ptr->DTMR & (~MCF5225_DTIM_DTMR_RST);

			// DMA Timer Reset
			dmatim_ptr->DTMR = (MCF5225_DTIM_DTMR_PS(0))|(MCF5225_DTIM_DTMR_CE_NONE)|
				(MCF5225_DTIM_DTMR_ORRI)|(MCF5225_DTIM_DTMR_FRR)|(MCF5225_DTIM_DTMR_CLK_DIV1);

			dmatim_ptr->DTXTMR = (MCF5225_DTIM_DTXMR_DMAEN);
			dmatim_ptr->DTER = MCF5225_DTIM_DTER_REF;
//			dmatim_ptr->DTRR = MCF5225_DTIM_DTRR_REF((800L*2L)); 
//			dmatim_ptr->DTRR = MCF5225_DTIM_DTRR_REF((BSP_SYSTEM_CLOCK/50000L)); 
			dmatim_ptr->DTRR = MCF5225_DTIM_DTRR_REF((BSP_SYSTEM_CLOCK/ad7652_bps_data)); 

			dmatim_ptr->DTCN = MCF5225_DTIM_DTCN_CNT(0);

			/* BCR[DONE] reset  */
			dma_ptr->BCR =  dma_ptr->BCR|MCF5225_DMA_BCR_DSR(MCF5225_DMA_DSR_DONE);
			scm_ptr->DMAREQC = 0x4;

			if (AD7652_mem_alloc(&pad7652_mem_dma_in) != E_OK){
				ad7652_statistics.dma_error_count++;
				pad7652_mem_dma_in = 0 ;
			}

			/* DMA Source address register */
			dma_ptr->SAR = (unsigned long)0x80000000L;
			//dma_ptr->DAR = (unsigned long)&dma_outdata[0][0];

			if (pad7652_mem_dma_in != 0){
				/* DMA Destination address register	 */
				dma_ptr->DAR = (unsigned long)&pad7652_mem_dma_in->mem.data[0];
			}
			else{
				/* DMA Destination address register	 */
				dma_ptr->DAR = (unsigned long)&dma_outdata[0][0];
			}

//			dma_ptr->BCR =  MCF5225_DMA_BCR_BCR((AD_DATA_SIZE*2));
			dma_ptr->BCR =  MCF5225_DMA_BCR_BCR((ad7652_dma_size*2));

			dma_ptr->DCR = (MCF5225_DMA_DCR_INT)|(MCF5225_DMA_DCR_CS)|(MCF5225_DMA_DCR_DSIZE(MCF5225_DMA_DCR_DSIZE_WORD))|
								(MCF5225_DMA_DCR_DINC)|(MCF5225_DMA_DCR_SSIZE(MCF5225_DMA_DCR_SSIZE_WORD))|(MCF5225_DMA_DCR_BWC(0));

			//DMA_buffer_select = 0;

			dma_ptr->DCR = 	dma_ptr->DCR |MCF5225_DMA_DCR_EEXT;

			/* Timer Enable */
			dmatim_ptr->DTMR = dmatim_ptr->DTMR | MCF5225_DTIM_DTMR_RST;
			break;

		case IO_IOCTL_AD7652_STOP:
			/* Timer Disable */
			dmatim_ptr->DTMR = dmatim_ptr->DTMR & (~MCF5225_DTIM_DTMR_RST);

			/* DMA STOP */
			dma_ptr->DCR = 	dma_ptr->DCR & (~MCF5225_DMA_DCR_EEXT);
			dma_ptr->BCR =  dma_ptr->BCR|MCF5225_DMA_BCR_DSR(MCF5225_DMA_DSR_DONE);
			break;

		case IO_IOCTL_AD7652_SET_CALLBACK:
			io_info_ptr->DEV_CALLBACK = (void (_CODE_PTR_)(void))param_ptr;

			//printf("IO_IOCTL_AD7652_SET_CALLBACK %x \n", (uint_32)io_info_ptr->DEV_CALLBACK);
			break;

		case IO_IOCTL_AD7652_SET_BPS:
			pint = (int_32*)param_ptr;
			ad7652_bps_data = *pint;

			ad7652_dma_size = (BSP_SIGNAL_DMA_TIME * ad7652_bps_data)/1000;
			printf("AD7652:dma size = %d \n",ad7652_dma_size);
			break;

		case IO_IOCTL_AD7652_GET_BPS:
			pint = (int_32*)param_ptr;
			*pint = ad7652_bps_data;
			break;

		default:
			break;
	}

	return(result);
}

/*FUNCTION****************************************************************
* 
* Function Name    :_mcf52xx_AD7652_rx
* Input Value      : 
      [IN] The address of the device specific information 	: IO_AD7652_DEVICE_STRUCT_PTR int_io_dev_ptr
      [IN] The array characters are to be read from 		: uchar_ptr buffer
      [IN] Number of char's to receive						: int_32 size

* Returned Value   : Returns the number of bytes received or QSPI error   
* Comments         : 
*   Reads the data into provided array.
*
*END*********************************************************************/
int_32 _mcf52xx_AD7652_rx(IO_AD7652_DEVICE_STRUCT_PTR int_io_dev_ptr, uchar_ptr buffer, int_32 size)
{
	MCF52XX_AD7652_INFO_STRUCT_PTR    	io_info_ptr;
	TIME_STRUCT                     	time;
	uint_16_ptr                     	buf_ptr = NULL;
	_mqx_int                        	i, num, length = size;
	uint_32                         	milliseconds;
	static AD7652_MEM_BUFFER			*pad7652_mem;


	io_info_ptr  = int_io_dev_ptr->DEV_INFO_PTR;

	io_info_ptr->BYTE_COUNT = size;
	io_info_ptr->RX_BUF_LEN = io_info_ptr->TOTAL_SIZE;

	ad7652_statistics.dma_task_count++;

	AD7652_Get_queue(&pad7652_mem);
//	memcpy(buffer, &pad7652_mem->mem.data[0], (AD_DATA_SIZE*2));
	memcpy(buffer, &pad7652_mem->mem.data[0], (ad7652_dma_size*2));

	AD7652_mem_free(&pad7652_mem);
	io_info_ptr->RX_PACKETS++;

//	return (AD_DATA_SIZE*2);
	return (ad7652_dma_size*2);
}


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_AD7652_tx
* Input Value      :
      [IN] The address of the device specific information	: IO_AD7652_DEVICE_STRUCT_PTR int_io_dev_ptr,
      [IN] The array characters are to be read from			: uchar_ptr	buffer,
      [IN] Number of char's to transmit 					: int_32	size

* Returned Value   : return number of byte transmitted or QSPI error code
* Comments         : 
*   Writes the provided data buffer and loops until transmission complete
*
*END*********************************************************************/
int_32 _mcf52xx_AD7652_tx(IO_AD7652_DEVICE_STRUCT_PTR int_io_dev_ptr, uchar_ptr buffer, int_32 size)
{
	MCF52XX_AD7652_INFO_STRUCT_PTR    io_info_ptr;
	TIME_STRUCT                     time;
	boolean                         flag = FALSE;
	_mqx_int                        num, i, length = size;
	uint_32                         milliseconds;
	volatile uint_16                buf_ptr = 0;

	io_info_ptr  = int_io_dev_ptr->DEV_INFO_PTR;
	io_info_ptr->TOTAL_SIZE = size;

	io_info_ptr->TX_PACKETS++;

	return size;
}


/*FUNCTION****************************************************************
*
* Function Name    : _ad7652_int_isr
* Input Value      :
      [IN] the address of the device specific information	: pointer parameter

* Returned Value   : none
* Comments         :
*   interrupt handler for the DMA I/O interrupts.
*
*************************************************************************/

void _ad7652_int_isr(pointer parameter)
{
	static VMCF5225_DMA_STRUCT_PTR		dma_ptr;
	MCF52XX_AD7652_INFO_STRUCT_PTR io_info_ptr;
	IO_AD7652_DEVICE_STRUCT_PTR io_dev_ptr;

	//int	Now_DMA_buffer_select;

	io_dev_ptr = (IO_AD7652_DEVICE_STRUCT_PTR)parameter;
   	io_info_ptr = io_dev_ptr->DEV_INFO_PTR;

	dma_ptr = (pointer)&(((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->DMA[0]);

	dma_ptr->BCR = dma_ptr->BCR | MCF5225_DMA_BCR_DSR(MCF5225_DMA_DSR_DONE);
	dma_ptr->DCR = dma_ptr->DCR & (~MCF5225_DMA_DCR_EEXT);

	pad7652_mem_dma_out = pad7652_mem_dma_in;

	if (AD7652_mem_alloc(&pad7652_mem_dma_in) != E_OK){
		ad7652_statistics.dma_error_count++;
		pad7652_mem_dma_in = 0 ;
	}

	/* DMA Source address register */
	dma_ptr->SAR = (unsigned long)0x80000000L;

	if (pad7652_mem_dma_in != 0){
		/* DMA Destination address register	 */
		dma_ptr->DAR = (unsigned long)&pad7652_mem_dma_in->mem.data[0];
	}
	else{
		/* DMA Destination address register	 */
		dma_ptr->DAR = (unsigned long)&dma_outdata[0][0];
	}

	/* DMA status register */
//	dma_ptr->BCR =  MCF5225_DMA_BCR_BCR((AD_DATA_SIZE*2));
	dma_ptr->BCR =  MCF5225_DMA_BCR_BCR((ad7652_dma_size*2));

	dma_ptr->DCR = dma_ptr->DCR | MCF5225_DMA_DCR_EEXT;

	if (pad7652_mem_dma_out != 0){
		pad7652_mem_dma_out->mem.size = (ad7652_dma_size*2);
		AD7652_Set_queue(pad7652_mem_dma_out);
		if (io_info_ptr->DEV_CALLBACK != 0){
			(*io_info_ptr->DEV_CALLBACK)();
		}
	}

	ad7652_statistics.dma_isr_count++;
}



/* EOF */