www.pudn.com > drivers.rar > dma_env.c


/** 
 * @file	dma_env.c 
 * 
 * Coding of the Riviera Generic Functions, 
 * except handle_message and handle_timer, which are 
 * in dma_handle_message.c and dma_handle_timer.c 
 * 
 * @author	 () 
 * @version 0.1 
 */ 
 
/* 
 * History: 
 * 
 *	Date       	Author					Modification 
 *	------------------------------------------------------------------- 
 *	7/2/2003	 ()		Create. 
 * 
 * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved 
 */ 
 
 
#include  
 
#include "inth/sys_inth.h" 
#include "dma/dma_cfg.h" 
#include "dma/dma_i.h" 
#include "dma/dma_env.h" 
#include "dma/sys_dma.h" 
 
extern T_DMA_CHANNEL_ARRAY dma_channel_array [];  
extern T_DMA_QUEUE_ARRAY   dma_queue_array   []; 
extern UINT8 dma_function_status []; 
 
 
/** 
 * Pointer on the structure gathering all the global variables 
 * used by DMA instance. 
 */ 
T_DMA_ENV_CTRL_BLK *dma_env_ctrl_blk_p = 0; 
 
#ifndef HISR_STACK_SHARING 
extern char dma_hisr_stack[DMA_HISR_STACK_SIZE]; 
extern char dma_secure_hisr_stack [DMA_SECURE_HISR_STACK_SIZE]; 
#endif 
 
/** 
 * Called by the RV manager to learn  
 * dma requirements in terms of memory, SWEs... 
 * 
 * @param	swe_info	Pointer to the structure to fill 
 *						containing infos related to the dma SWE. 
 * 
 * @return	RVM_OK 
 */ 
T_RVM_RETURN dma_get_info(T_RVM_INFO_SWE  * swe_info) 
{ 
	/* The SWE is a Type 3 SWE */ 
	swe_info->swe_type = RVM_SWE_TYPE_3; 
 
	/* Used for info */ 
	strncpy(swe_info->type_info.type3.swe_name, "DMA", RVM_NAME_MAX_LEN); 
	swe_info->type_info.type3.version =  
                   BUILD_VERSION_NUMBER(DMA_MAJOR,DMA_MINOR,DMA_BUILD); 
	/* 
	 * This is the real way to indentify a SWE. 
	 * Look in: 
	 * - rvm_use_id_list.h if the SWE is part of the standard SDK. 
	 * - rvm_ext_use_id_list.h for custom/under development SWEs. 
	 */ 
	swe_info->type_info.type3.swe_use_id = DMA_USE_ID; 
 
	/* Active SWE specific info */ 
	swe_info->type_info.type3.stack_pool_id = RVF_POOL_EXTERNAL_MEM; 
	swe_info->type_info.type3.stack_size    = DMA_STACK_SIZE; 
	swe_info->type_info.type3.priority      = DMA_TASK_PRIORITY; 
	/* End of specific */ 
 
	/* Memory bank info */ 
	swe_info->type_info.type3.nb_mem_bank = 1; 
	strncpy(swe_info->type_info.type3.mem_bank[0].bank_name, "DMA_PRIM", RVF_MAX_MB_LEN); 
	swe_info->type_info.type3.mem_bank[0].initial_params.pool_id   = RVF_POOL_EXTERNAL_MEM; 
	swe_info->type_info.type3.mem_bank[0].initial_params.size      = DMA_MB_PRIM_SIZE; 
	swe_info->type_info.type3.mem_bank[0].initial_params.watermark = DMA_MB_PRIM_WATERMARK; 
	 
	/*  
	 * Linked SWE info. 
	 * This SWE doesn't requires SWE to run 
	 */ 
	swe_info->type_info.type3.nb_linked_swe = 0; 
 
	/* Set the return path: NOT USED. */ 
	swe_info->type_info.type3.return_path.callback_func	= NULL; 
	swe_info->type_info.type3.return_path.addr_id		= 0; 
 
 
	/* Generic functions */ 
	swe_info->type_info.type3.set_info		= dma_set_info; 
	swe_info->type_info.type3.init			= dma_init; 
	swe_info->type_info.type3.stop			= dma_stop; 
	swe_info->type_info.type3.kill			= dma_kill; 
 
 
	/* Type 3 specific generic functions */ 
	swe_info->type_info.type3.start          = dma_start; 
	swe_info->type_info.type3.handle_message = dma_handle_message; 
	swe_info->type_info.type3.handle_timer   = dma_handle_timer; 
	/* End of specific */ 
 
	DMA_SEND_TRACE("DMA get_info has been done ",DMA_TRACE_LEVEL); 
 
	return RVM_OK; 
} 
 
 
/** 
 * Called by the RV manager to inform the dma SWE about  
 * addr_id, return path, mb_id and error function. 
 * 
 * It is called only once. 
 * 
 * @param	addr_id			Address ID of the DMA SWE. 
 *							Used to send messages to the SWE. 
 * @param	return_path		Return path array of the linked SWEs. 
 * @param	bk_id_table		Array of memory bank ids allocated to the SWE. 
 * @param	call_back_error_ft Callback function to call in case of unrecoverable error. 
 * @return	RVM_MEMORY_ERR ou RVM_OK. 
 */ 
T_RVM_RETURN dma_set_info ( T_RVF_ADDR_ID	addr_id, 
							T_RV_RETURN_PATH return_path[],  
							T_RVF_MB_ID		bk_id_table[], 
							T_RVM_CB_FUNC	call_back_error_ft) 
{ 
	/* Memory bank status (red, yellow, green). */ 
	T_RVF_MB_STATUS mb_status; 
 
	DMA_SEND_TRACE("DMA set info called ",DMA_TRACE_LEVEL); 
	 
	/* Create instance gathering all the variable used by DMA instance */ 
	mb_status = rvf_get_buf(bk_id_table[0],  
							sizeof(T_DMA_ENV_CTRL_BLK), 
							(T_RVF_BUFFER **) & dma_env_ctrl_blk_p); 
	if (mb_status == RVF_RED) 
	{ 
		/* 
		 * The flag returned by rvf_get_buf is red, there is not enough 
		 * memory to allocate the buffer. 
		 * The environment will cancel the DMA instance creation. 
		 */ 
		DMA_SEND_TRACE("DMA Error to get memory ",DMA_TRACE_LEVEL); 
				 
		return RVM_MEMORY_ERR; 
	} 
	else if (mb_status == RVF_YELLOW) 
	{ 
		/* 
		 * The flag is yellow, there will soon be not enough memory anymore. 
		 */ 
		DMA_SEND_TRACE("DMA Getting short on memory ", DMA_TRACE_LEVEL); 
	} 
 
 
	/* Store the address ID. */ 
	dma_env_ctrl_blk_p->addr_id = addr_id; 
 
	/* Store the pointer to the error function. */ 
	dma_env_ctrl_blk_p->error_ft = call_back_error_ft; 
 
	/* 
	 * Store the mem bank id. 
	 * Memory bank ID (mb_id) can be retrieved later using rvf_get_mb_id function. 
	 */ 
	dma_env_ctrl_blk_p->prim_mb_id = bk_id_table[0]; 
 
	/* 
	 * return_path of linked SWE: 
	 * This is an efficient way to get the return path of the linked SWE in order 
	 * to immediately communicate with them. However since the address id is not 
	 * needed for SWE providing bridge functions as API, this is not always usefull. 
	 */ 
	/* return_path... */ 
 
	return RVM_OK; 
} 
 
 
/** 
 * Called by the RV manager to initialize the  
 * dma SWE before creating the task and calling dma_start.  
 * 
 * @return	RVM_OK 
 */ 
T_RVM_RETURN dma_init (void) 
{ 
#ifndef _WINDOWS   
  T_DMA_TYPE_GLOBAL_PARAMETER  dma_type_global_parameter; 
#endif //_WINDOWS 
 
  UINT8 n; 
 
	/* 
	 * Here the instance (dma_env_ctrl_blk_p) could be initialised. 
	 */ 
 
  DMA_SEND_TRACE ("DMA init ENTER", DMA_TRACE_LEVEL); 
 
  if (dma_env_ctrl_blk_p == 0) 
  { 
    DMA_SEND_TRACE("DMA Initialization is not yet done or failed", DMA_TRACE_LEVEL); 
  } 
 
#ifndef _WINDOWS 
  /* Fill the entire stack with the pattern 0xFE */ 
    #ifndef HISR_STACK_SHARING 
  	memset (dma_env_ctrl_blk_p->dma_hisr_stack, 0xFE, DMA_HISR_STACK_SIZE); 
  	memset (dma_env_ctrl_blk_p->dma_secure_hisr_stack, 0xFE,  
          DMA_SECURE_HISR_STACK_SIZE); 
    #else 
	memset (HISR_STACK_PRIO2, 0xFE, HISR_STACK_PRIO2_SIZE); 
    #endif 
   
  if (NU_SUCCESS != 
      NU_Create_HISR (&dma_env_ctrl_blk_p->dma_hisr, "DMA_HISR", dma_hisr, 2, 
    	#ifndef HISR_STACK_SHARING 
                  dma_env_ctrl_blk_p->dma_hisr_stack, DMA_HISR_STACK_SIZE)) 
    	#else 
		  HISR_STACK_PRIO2, 
	 	  HISR_STACK_PRIO2_SIZE)) 
    	#endif 
  { 
    DMA_SEND_TRACE ("DMA init HISR creation FAILED", DMA_TRACE_LEVEL); 
  } 
 
  if (NU_SUCCESS != 
      NU_Create_HISR (&dma_env_ctrl_blk_p->dma_secure_hisr, "DMA_SECURE_HISR",  
                      dma_secure_hisr, 2, 
    	#ifndef HISR_STACK_SHARING 
		      dma_env_ctrl_blk_p->dma_secure_hisr_stack,  
                      DMA_SECURE_HISR_STACK_SIZE)) 
    	#else 
		      HISR_STACK_PRIO2, 
	 	      HISR_STACK_PRIO2_SIZE)) 
    	#endif 
  { 
    DMA_SEND_TRACE ("DMA init secure HISR creation FAILED",  
                     DMA_TRACE_LEVEL); 
  } 
 
#endif 
 
  /* At start up all the channels are free */ 
  for (n=0; ndma_queue_index = DMA_QUEUE_INDEX_MIN; 
 
#ifndef _WINDOWS 
 
  /* Configuration items */ 
 
#ifdef DMA_EMULATOR_SUSPEND_ENABLE  
    /* enable free mode of dma */ 
    F_DMA_SUSPEND_MODE_EMULATION_FREE_ENABLE;     
#endif 
#ifdef DMA_EMULATOR_SUSPEND_DISABLE 
    /*disable free mode of the dma */ 
    F_DMA_SUSPEND_MODE_EMULATION_FREE_DISABLE; 
#endif 
 
 
#ifdef DMA_POWERSAVE_ENABLE 
  dma_type_global_parameter.d_dma_global_auto_gate = C_DMA_AUTO_GATE_ON; 
#endif 
#ifdef DMA_POWERSAVE_DISABLE 
  dma_type_global_parameter.d_dma_global_auto_gate = C_DMA_AUTO_GATE_OFF; 
#endif 
 
 
#ifdef DMA_DSP_PRIO_DMA 
dma_type_global_parameter.d_dma_global_api_prio    = C_DMA_API_PRIO_DMA; 
#endif 
#ifdef DMA_DSP_PRIO_ARM 
  dma_type_global_parameter.d_dma_global_api_prio  = C_DMA_API_PRIO_ARM; 
#endif 
 
 
#ifdef DMA_RHEA_PRIO_DMA 
  dma_type_global_parameter.d_dma_global_rhea_prio = C_DMA_RHEA_PRIO_DMA; 
#endif 
#ifdef DMA_RHEA_PRIO_ARM 
  dma_type_global_parameter.d_dma_global_rhea_prio = C_DMA_RHEA_PRIO_ARM; 
#endif 
 
 
#ifdef DMA_IMIF_PRIO_CPU_0 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_0; 
#endif 
#ifdef DMA_IMIF_PRIO_CPU_1 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_1; 
#endif 
#ifdef DMA_IMIF_PRIO_CPU_2 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_2; 
#endif 
#ifdef DMA_IMIF_PRIO_CPU_3 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_3; 
#endif 
#ifdef DMA_IMIF_PRIO_CPU_4 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_4; 
#endif 
#ifdef DMA_IMIF_PRIO_CPU_5 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_5; 
#endif 
#ifdef DMA_IMIF_PRIO_CPU_6 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_6; 
#endif 
#ifdef DMA_IMIF_PRIO_CPU_7 
  dma_type_global_parameter.d_dma_global_imif_prio = C_DMA_IMIF_PRIO_CPU_7; 
#endif 
 
#ifdef DMA_AUTOGATING_ON  
  dma_type_global_parameter.d_dma_global_auto_gate = C_DMA_AUTO_GATE_ON; 
#endif 
 
#ifdef DMA_AUTOGATING_OFF  
  dma_type_global_parameter.d_dma_global_auto_gate = C_DMA_AUTO_GATE_OFF; 
#endif 
 
  /* Make the settings actual */ 
/*  f_dma_global_parameter_set (&dma_type_global_parameter); 
 
  for (n=DMA_ZERO; ndma_hisr)) 
    { 
      DMA_SEND_TRACE ("DMA stop HISR deletion FAILED", DMA_TRACE_LEVEL); 
    } 
  else 
    { 
      DMA_SEND_TRACE ("DMA stop HISR deleted", DMA_TRACE_LEVEL); 
    } 
 
  if (NU_SUCCESS != NU_Delete_HISR (&dma_env_ctrl_blk_p->dma_secure_hisr)) 
    { 
      DMA_SEND_TRACE ("DMA stop secure HISR deletion FAILED", DMA_TRACE_LEVEL); 
    } 
  else 
    { 
      DMA_SEND_TRACE ("DMA stop secure HISR deleted", DMA_TRACE_LEVEL); 
    } 
 
#endif 
  DMA_SEND_TRACE ("DMA stop LEAVE", DMA_TRACE_LEVEL); 
  
	return RVM_OK; 
} 
 
 
/** 
 * Called by the RV manager to kill the dma SWE, 
 * after the dma_stop function has been called. 
 * 
 * @return	RVM_OK 
 */ 
T_RVM_RETURN dma_kill (void) 
{ 
	/* 
	 * Here we cannot send messages anymore. We only free the last 
	 * used resources, like the control block buffer. 
	 */ 
	DMA_SEND_TRACE("DMA kill called", DMA_TRACE_LEVEL); 
 
	rvf_free_buf(dma_env_ctrl_blk_p); 
 
	return RVM_OK; 
}