/**HEADER********************************************************************
* 
* Copyright (c) 2010 Avnet Japan Co.,Ltd (NIKE Borad Project.)
* All Rights Reserved
*
**************************************************************************
*
* $FileName: AD5546_mcf52xx.c$
* $Version : 0.1.0.0$
* $Date    : Jan-29-2010$
*
* Comments:
*
*
*END************************************************************************/
#include "mqx.h"
#include "bsp.h"
#include "io_prv.h"
#include "fio_prv.h"
#include "event.h"
//#include "timer.h"

#include "../AD5546.h"
#include "../AD5546_prv.h"

#include "AD5546_mcf52xx.h"
#include "AD5546_mcf52xx_prv.h"


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

#define	AD5546_MCF52XX_DMA_CH	1


#define	AD5546_SIGNAL_BPS_MAX	100000L
#define	AD5546_SIGNAL_BPS		 50000L

//#define AD_DATA_SIZE	300
#define AD_DATA_SIZE	((BSP_SIGNAL_DMA_TIME * AD5546_SIGNAL_BPS_MAX)/1000)



#define AD5546_TASK		10

#define BSP_DMA1_INT_LEVEL			(3)
#define BSP_DMA1_INT_SUBLEVEL       (1)


#define AD5546_MEM_MAXSIZE	5

#define E_OK	0
#define E_OBJ	-1


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

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


/* 宣言：AD5546_MEM_BUFFER */
typedef struct
{
	AD5546_MEM_DATA		mem;
	void 				*buffer;
}AD5546_MEM_BUFFER, *PAD5546_MEM_BUFFER;


/* 宣言：AD5546_MEM_BUFFER */
typedef struct
{
	uint_32	dma_isr_count;
	uint_32	dma_task_count;
	uint_32	dma_error_count;
	uint_32	dma_sp_count;
}AD5546_STATISTICS, *PAD5546_STATISTICS;


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

unsigned short	dac_dma_data_sp[AD_DATA_SIZE];

AD5546_STATISTICS	ad5546_statistics;

AD5546_MEM_BUFFER	ad5546_data[AD5546_MEM_MAXSIZE];
AD5546_MEM_BUFFER	*ad5546_mem_start;
AD5546_MEM_BUFFER	*ad5546_mem_end;

int_16	ad5546_mem_size;
int_16	ad5546_mem_size_max;

AD5546_MEM_BUFFER	*pad5546_mem_que;
AD5546_MEM_BUFFER	*pad5546_mem_isr;
AD5546_MEM_BUFFER	*pad5546_mem_free;

int_32	ad5546_bps_data;

uint_32	ad5546_dma_size;


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

void   AD5546_mem_init(void);
int_32 AD5546_mem_alloc(AD5546_MEM_BUFFER	**pSB);
void   AD5546_mem_free(AD5546_MEM_BUFFER	**ppSB);
int    AD5546_Set_queue(AD5546_MEM_BUFFER	*pnew_ad5546_mem);
int    AD5546_Get_queue(AD5546_MEM_BUFFER	**pget_ad5546_mem);


void *memcpy(void *dest, const void *source, _mem_size n);
extern uint_32 _mcf52xx_AD5546_init(IO_AD5546_DEVICE_STRUCT_PTR, char_ptr);
extern uint_32 _mcf52xx_AD5546_deinit(MCF52XX_AD5546_INIT_STRUCT_PTR, MCF52XX_AD5546_INFO_STRUCT_PTR);
extern int_32  _mcf52xx_AD5546_ioctl(MCF52XX_AD5546_INFO_STRUCT_PTR, uint_32, _mqx_uint_ptr);
extern int_32  _mcf52xx_AD5546_rx(IO_AD5546_DEVICE_STRUCT_PTR, uchar_ptr, _mqx_int);
extern int_32  _mcf52xx_AD5546_tx(IO_AD5546_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    _ad5546_int_isr(pointer parameter);

_mqx_int _bsp_AD5546_io_reset(void);
pointer  _bsp_get_gpio_base_address(void);
_mqx_int _bsp_AD5546_io_init( void );





/*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_AD5546_io_init( void )
{
	VMCF5225_GPIO_STRUCT_PTR	gpio_ptr;

	gpio_ptr = _bsp_get_gpio_base_address();

#define PORT_DAC_MSB			__BIT(0)
#define PORT_DAC_RESET			__BIT(2)

	/* PUC0,PUC2 GPIO Hi Set */
	GPIO_P_SET(UC, PORT_DAC_MSB);
//	GPIO_P_CLR(UC, PORT_DAC_MSB);
	GPIO_P_CLR(UC, PORT_DAC_RESET);

	/* PUC0,PUC2 GPIO OUTPUT */
	GPIO_DDR_OUT(UC, PORT_DAC_MSB);
	GPIO_DDR_OUT(UC, PORT_DAC_RESET);

	/* PUC0,PUC2 GPIO */
	gpio_ptr->PUCPAR = (gpio_ptr->PUCPAR&(~0x33))|0x00;

//	GPIO_P_CLR(UC, PORT_DAC_MSB);
	GPIO_P_SET(UC, PORT_DAC_MSB);


    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_AD5546_io_reset(void)
{
	VMCF5225_GPIO_STRUCT_PTR		gpio_ptr;
	TIME_STRUCT                     time;
	uint_32                         milliseconds;

	gpio_ptr = _bsp_get_gpio_base_address();

	/* PORT_ADC_CNV_ST,PORT_ADC_RESET Hi Set */
	GPIO_P_CLR(UC, PORT_DAC_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_SET(UC, PORT_DAC_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;
		}
	}

    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_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_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_i2c_vector
* Returned Value   : Vector number upon success, 0 upon failure
* Comments         :
*    This function returns desired interrupt vector number for specified I2C
*
*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_AD5546_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_AD5546_install(char_ptr identifier, pointer init_data_ptr)
{
	return _io_AD5546_install(identifier,
		(uint_32 (_CODE_PTR_)(pointer, char_ptr))_mcf52xx_AD5546_init,
		(uint_32 (_CODE_PTR_)(pointer, pointer))_mcf52xx_AD5546_deinit,
		(int_32 (_CODE_PTR_)(pointer, char_ptr, _mqx_int))_mcf52xx_AD5546_rx,
		(int_32 (_CODE_PTR_)(pointer, char_ptr, _mqx_int))_mcf52xx_AD5546_tx,
		(int_32 (_CODE_PTR_)(pointer, uint_32, _mqx_uint_ptr))_mcf52xx_AD5546_ioctl,
		init_data_ptr);
}


/************************************************************************
 *
 * 関数名	()
 *
 * 機能		
 * 引数		
 * 戻値		エラーコード
 *
 ***********************************************************************/
void AD5546_mem_init(void)
{
	int i;

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

	ad5546_data[AD5546_MEM_MAXSIZE-1].buffer  = (void *)0;
	ad5546_mem_start 	= (AD5546_MEM_BUFFER*)&ad5546_data[0];
	ad5546_mem_end 		= (AD5546_MEM_BUFFER*)&ad5546_data[(AD5546_MEM_MAXSIZE-1)];

	ad5546_mem_size = 0;
//	ad5546_mem_size_max = 0;

	pad5546_mem_que = (AD5546_MEM_BUFFER*)0;
}



/************************************************************************
 *
 * 関数名	()
 *
 * 機能		
 * 引数		
 * 戻値		エラーコード
 *
 ***********************************************************************/
int_32 AD5546_mem_alloc(AD5546_MEM_BUFFER	**pSB)
{
	AD5546_MEM_BUFFER *pad5546_temp;

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

	pad5546_temp = ad5546_mem_start;
	//*pSB  = (AD5546_MEM_BUFFER*)ad5546_mem_start;
	ad5546_mem_start = (AD5546_MEM_BUFFER*)ad5546_mem_start->buffer;
	ad5546_mem_size++;

	pad5546_temp->buffer = 0;
	*pSB  = (AD5546_MEM_BUFFER*)pad5546_temp;

	return E_OK;
}


/************************************************************************
 *
 * 関数名	()
 *
 * 機能		
 * 引数		
 * 戻値		エラーコード
 *
 ***********************************************************************/
void AD5546_mem_free(AD5546_MEM_BUFFER	**ppSB)
{
	volatile AD5546_MEM_BUFFER	*pSB;

	pSB = (AD5546_MEM_BUFFER*)*ppSB;

	ad5546_mem_end->buffer = (void*)pSB;
	ad5546_mem_end = (AD5546_MEM_BUFFER*)pSB;
	ad5546_mem_end->buffer = 0;
	ad5546_mem_size--;
}



/************************************************************************
 *
 * 関数名	()
 *
 * 機能		
 * 引数		
 * 戻値		エラーコード
 *
 ***********************************************************************/
int AD5546_Set_queue(AD5546_MEM_BUFFER	*pnew_ad5546_mem)
{
	AD5546_MEM_BUFFER	*pWmem;

	if (pad5546_mem_que == 0){
		pad5546_mem_que = pnew_ad5546_mem;
	}
	else{
		pWmem = pad5546_mem_que;
		while(1){
			if (pWmem->buffer == 0){
				pWmem->buffer = (void*)pnew_ad5546_mem;
				break;
			}
			pWmem = (AD5546_MEM_BUFFER*)pWmem->buffer;
		}
	}

	return E_OK;
}




/************************************************************************
 *
 * 関数名	()
 *
 * 機能		
 * 引数		
 * 戻値		エラーコード
 *
 ***********************************************************************/
int AD5546_Get_queue(AD5546_MEM_BUFFER	**pget_ad5546_mem)
{
	if (pad5546_mem_que == 0){
		return E_OBJ;
	}

	*pget_ad5546_mem  = pad5546_mem_que;

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

	return E_OK;
}




/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_AD5546_init  
* Input Value      : 
   [IN] the initialization information for the device being opened 	: IO_AD5546_DEVICE_STRUCT_PTR  io_dev_ptr,
   [OUT] the address to store device specific information 			: pointer _PTR_                 io_info_ptr_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_AD5546_init(IO_AD5546_DEVICE_STRUCT_PTR io_dev_ptr, char_ptr open_name_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;
	MCF52XX_AD5546_INFO_STRUCT_PTR	io_info_ptr;
	uint_32	div;
	uint_32	result = QSPI_OK;
	_task_id	created_task;
	MCF52XX_AD5546_INIT_STRUCT_PTR	init_io_dev_ptr;
	uint_32 status;

	init_io_dev_ptr = io_dev_ptr->DEV_INIT_DATA_PTR;

	ad5546_bps_data = AD5546_SIGNAL_BPS;

	ad5546_dma_size = (BSP_SIGNAL_DMA_TIME * ad5546_bps_data)/1000;
	printf("AD5546：dma size = %d \n",ad5546_dma_size);


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

#if 0
	created_task = _task_create(0, 0, (uint_32)&AD5546_task_template);
	if (created_task == MQX_NULL_TASK_ID) {
		printf("\nRx task: task creation failed.");
	}
	printf("AD5546_task: task creation. %x \n",created_task);
#endif

	/* QSPI board specific initialization */
	//   _bsp_qspi_initialize(0);
	/* Initialize internal data */
	io_info_ptr = (MCF52XX_AD5546_INFO_STRUCT _PTR_)_mem_alloc_system_zero((uint_32)sizeof(MCF52XX_AD5546_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;

	ad5546_statistics.dma_isr_count = 0;
	ad5546_statistics.dma_task_count = 0;
	ad5546_statistics.dma_error_count = 0;
	ad5546_statistics.dma_sp_count = 0;

	{
		int i;

		for(i=0;i<AD_DATA_SIZE;i++){
//			dac_dma_data0[i] = 0x0000 + i;
			dac_dma_data_sp[i] = 0x8000;
		}
	}


	_bsp_AD5546_io_init();

	_bsp_AD5546_io_reset();

	/* AD5546_mem初期化 */
	AD5546_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_DMA1);
	io_info_ptr->OLD_ISR_EXCEPTION_HANDLER = _int_get_exception_handler(MCF5225_INT_DMA1);
	io_info_ptr->OLD_ISR = _int_install_isr(MCF5225_INT_DMA1, _ad5546_int_isr, io_dev_ptr);

	status = _mcf52xx_int_init((PSP_INTERRUPT_TABLE_INDEX)MCF5225_INT_DMA1, BSP_DMA1_INT_LEVEL, BSP_DMA1_INT_SUBLEVEL, TRUE);
	if (status == MQX_OK) {
	 	printf("AD5546 _mcf52xx_int_init OK\n");
	}


	return (result);
}

/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_AD5546_deinit  
* Input Value      :
   [IN] the initialization information for the device being opened	: MCF52XX_AD5546_INIT_STRUCT_PTR     int_io_dev_ptr,
   [IN] the address of the device specific information				: MCF52XX_AD5546_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_AD5546_deinit(MCF52XX_AD5546_INIT_STRUCT_PTR int_io_dev_ptr, MCF52XX_AD5546_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(AD5546_MCF52XX_DMA_CH);
	dmatim_ptr = _bsp_get_dmatim_base_address(AD5546_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_AD5546_ioctl
* Input Value      : 
      [IN] the address of the device specific information 	: MCF52XX_AD5546_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_AD5546_ioctl(MCF52XX_AD5546_INFO_STRUCT_PTR io_info_ptr, uint_32 cmd, uint_32_ptr param_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;
	static AD5546_MEM_BUFFER		*pad5546_mem;
	int_32                            *pint;

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

	switch (cmd) {
		case IO_IOCTL_AD5546_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/ad5546_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 = (scm_ptr->DMAREQC & (~0x00f0))|0x0050;

			if (AD5546_Get_queue(&pad5546_mem) != E_OK){
				ad5546_statistics.dma_sp_count++;
				pad5546_mem_isr = (AD5546_MEM_BUFFER*)&dac_dma_data_sp[0];
			}
			else{
				pad5546_mem_isr = (AD5546_MEM_BUFFER*)pad5546_mem;
			}

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

//			dma_ptr->BCR =  MCF5225_DMA_BCR_BCR((AD_DATA_SIZE*2));
			dma_ptr->BCR =  MCF5225_DMA_BCR_BCR((ad5546_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_SSIZE(MCF5225_DMA_DCR_SSIZE_WORD))|(MCF5225_DMA_DCR_SINC)|(MCF5225_DMA_DCR_BWC(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_AD5546_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_AD5546_SET_BPS:
			pint = (int_32*)param_ptr;
			ad5546_bps_data = *pint;

			ad5546_dma_size = (BSP_SIGNAL_DMA_TIME * ad5546_bps_data)/1000;
			printf("AD5546：dma size = %d \n",ad5546_dma_size);
			break;

		case IO_IOCTL_AD5546_GET_BPS:
			pint = (int_32*)param_ptr;
			*pint = ad5546_bps_data;
			break;

		default:
			break;
	}

	return(result);
}



/*FUNCTION****************************************************************
* 
* Function Name    :_mcf52xx_AD5546_rx
* Input Value      : 
      [IN] The address of the device specific information 	: IO_AD5546_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_AD5546_rx(IO_AD5546_DEVICE_STRUCT_PTR int_io_dev_ptr, uchar_ptr buffer, int_32 size)
{
	MCF52XX_AD5546_INFO_STRUCT_PTR    io_info_ptr;
	VMCF5225_DMA_STRUCT_PTR			dma_ptr;
	VMCF5225_DMA_TIMER_STRUCT_PTR	dmatim_ptr;
	TIME_STRUCT                     time;
	uint_16_ptr                     buf_ptr = NULL;
	_mqx_int                        i, num, length = size;
	uint_32                         milliseconds;
	static AD5546_MEM_BUFFER		*pad5546_mem;

	dma_ptr = _bsp_get_dma_base_address(AD5546_MCF52XX_DMA_CH);
	dmatim_ptr = _bsp_get_dmatim_base_address(AD5546_MCF52XX_DMA_CH);

	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;

	return AD5546_MEM_MAXSIZE;
}


/*FUNCTION****************************************************************
* 
* Function Name    : _mcf52xx_AD5546_tx
* Input Value      :
      [IN] The address of the device specific information	: IO_AD5546_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_AD5546_tx(IO_AD5546_DEVICE_STRUCT_PTR int_io_dev_ptr, uchar_ptr buffer, int_32 size)
{
	MCF52XX_AD5546_INFO_STRUCT_PTR    io_info_ptr;
	VMCF5225_DMA_STRUCT_PTR			dma_ptr;
	VMCF5225_DMA_TIMER_STRUCT_PTR	dmatim_ptr;
	static AD5546_MEM_BUFFER		*pad5546_mem;
	int_32                          i;
	uint_16 *u16_buffer;


	dma_ptr = _bsp_get_dma_base_address(AD5546_MCF52XX_DMA_CH);
	dmatim_ptr = _bsp_get_dmatim_base_address(AD5546_MCF52XX_DMA_CH);

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

	ad5546_statistics.dma_task_count++;

	if (AD5546_mem_alloc(&pad5546_mem) != E_OK){
		ad5546_statistics.dma_error_count++;
	}
	else{
		u16_buffer = (uint_16 *)buffer;

		for(i=0;i<(ad5546_dma_size);i++){
			pad5546_mem->mem.data[i] = (u16_buffer[i]^0x8000);
		}

		pad5546_mem->mem.size = (ad5546_dma_size*2);
		AD5546_Set_queue(pad5546_mem);
	}

	io_info_ptr->TX_PACKETS++;

	return size;
}




/*FUNCTION****************************************************************
*
* Function Name    : _ad5546_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 _ad5546_int_isr(pointer parameter)
{
	static VMCF5225_DMA_STRUCT_PTR		dma_ptr;
	static AD5546_MEM_BUFFER	*pad5546_mem;

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

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

	pad5546_mem_free =(AD5546_MEM_BUFFER*)pad5546_mem_isr;

	if (AD5546_Get_queue(&pad5546_mem) != E_OK){
		ad5546_statistics.dma_sp_count++;
		pad5546_mem_isr = (AD5546_MEM_BUFFER*)dac_dma_data_sp;
	}
	else{
		pad5546_mem_isr = (AD5546_MEM_BUFFER*)pad5546_mem;
	}

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

	/* DMA Destination address register	 */
	dma_ptr->DAR = (unsigned long)0x80000010L;

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

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

	if ((uint_32)dac_dma_data_sp != (uint_32)pad5546_mem_free){
		AD5546_mem_free(&pad5546_mem_free);
	}

	ad5546_statistics.dma_isr_count++;
}


/* EOF */