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; n dma_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; n dma_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; }