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


/*/ * @file dma_inth.c 
 * 
 * DMA initialise and handle interrupt functions. 
 * 
 * @author   () 
 * @version 0.1 
 */ 
 
/* 
 * History: 
 * 
 *  Date        Author          Modification 
 *  ------------------------------------------------------------------- 
 *  6/17/2003  ()   Create. 
 * 
 * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved 
 */ 
 
#ifndef _DMA_INTH_H_ 
#include "dma/board/dma_inth.h" 
#endif 
 
 
#include "rv/rv_defined_swe.h" 
 
#if (L1_EXT_AUDIO_MGT == 1) 
  #include "dma/sys_dma.h" 
#endif 
 
#undef    DMA_DEBUG 
 
UINT8 dma_channel_number; 
UINT16 dma_it_status; 
 
extern T_DMA_CHANNEL_ARRAY dma_channel_array [DMA_MAX_NUMBER_OF_CHANNEL];  
extern UINT8 dma_function_status [DMA_MAX_NUMBER_OF_CHANNEL]; 
 
#ifdef RVM_CAMD_SWE 
#if CHIPSET != 15 
	extern void camd_stop_sensor_clock (void); 
#else 
	extern void camcore_disable(void); 
#endif 
#endif 
 
extern UINT8 dma_channel_number_tab[DMA_MAX_NUMBER_OF_CHANNEL]; 
extern UINT8 dma_it_status_tab[DMA_MAX_NUMBER_OF_CHANNEL]; 
extern UINT8 total_active_dma_channels; 
/*-----------------------------------------------------------------------*/ 
/* dma_hisr()                                                            */ 
/*                                                                       */ 
/* This function is called when an DMA interrupt is received.            */ 
/*-----------------------------------------------------------------------*/ 
 
void dma_hisr (void) 
{ 
  /* used to determine the status of the interrupt */ 
  UINT16 dma_channel_status = DMA_OK; 
   
  /* used to send the status back to the originator */ 
  UINT8 dma_interrupt_status;        
 
  UINT8 n,dma_channel_index; 
 
  T_DMA_TYPE_CHANNEL_PARAMETER dma_ll_channel_info ; 
 
#ifdef DMA_DEBUG 
  DMA_HISR_SEND_TRACE ("DMA HISR called", DMA_TRACE_LEVEL);  
#endif 
 
  for(dma_channel_index=0;dma_channel_index=0)*/ 
            /*{*/ 
              if (dma_channel_array[dma_channel_number].bytes_to_be_transferred< 
                  dma_channel_array[dma_channel_number].buffer_size) 
              { 
                /* for the last part the frames might be modified */ 
                /* Write the number of frames to do */ 
                C_DMA_CFN_REG(dma_channel_number) =  
                   (dma_channel_array[dma_channel_number].bytes_to_be_transferred/ 
                  ((1<>= 1; 
  } 
 
  dma_channel_number = n; /* In fact this is not needed, but it is easier  
                             to read. dma_channel_number now holds the actual 
                             channel number 
                           */ 
 
  if (dma_channel_number == DMA_MAX_NUMBER_OF_CHANNEL) 
  { 
    /* This is an impossible situation. Return immediatly */ 
 
    /* UnMask interrupts */ 
    F_INTH_ENABLE_ONE_IT(C_INTH_2ND_INTH_IT) 
    F_INTH_ENABLE_ONE_IT(C_INTH_SEC_DMA_IT) 
    return; 
  } 
 
  /* Get the reason of the interrupt */ 
  dma_channel_status = DMA_GET_CHANNEL_IT_STATUS(dma_channel_number); 
 
  /* Check if notification is required, otherwise  
     skip this part. Determine the reason now  */ 
   
  if (dma_channel_array[dma_channel_number].dma_end_notification_bool  
                     == DMA_NOTIFICATION) 
  { 
    /* Find out the reason */ 
    if ((dma_channel_status & DMA_CICR_TOUT_IE_MASK) ==  
                              DMA_CICR_TOUT_IE_MASK) 
    { 
      if ((dma_channel_status & DMA_CICR_TOUT_SRC_NDEST_IE_MASK) ==  
                                DMA_CICR_TOUT_SRC_NDEST_IE_MASK) 
      { 
        dma_interrupt_status = DMA_TIMEOUT_SOURCE; 
      } 
      else 
      { 
        dma_interrupt_status = DMA_TIMEOUT_DESTINATION; 
      } 
    } 
    else 
    { 
      if ((dma_channel_status & DMA_CICR_DROP_IE_MASK) ==  
                                DMA_CICR_DROP_IE_MASK) 
      { 
        dma_interrupt_status = DMA_MISS_EVENT; 
      } 
      else 
      { 
        if ((dma_channel_status & DMA_CICR_HALF_BLOCK_IE_MASK) ==  
                                  DMA_CICR_HALF_BLOCK_IE_MASK) 
        { 
#ifdef DMA_DEBUG 
          DMA_HISR_SEND_TRACE ("DMA HISR half block interupt received", DMA_TRACE_LEVEL);  
#endif 
          if (dma_channel_array[dma_channel_number].double_buf_mode !=  
              DMA_NO_DOUBLE_BUF) 
          { 
            /* if the camera is working then the clock must be stopped as */ 
            /* soon as possible. it is restarted after copying the momory */ 
 
#if CHIPSET != 15 
						if (dma_channel_array[dma_channel_number].channel_info. 
                d_dma_channel_hw_synch == DMA_SYNC_DEVICE_NAND_FLASH) 
            { 
#ifdef RVM_CAMD_SWE 
              extern void camd_stop_sensor_clock (void); 
              /* Stop the camera sensor */ 
              camd_stop_sensor_clock (); 
#endif 
            } 
#else 
#ifdef RVM_CAMD_SWE 
						if (dma_channel_array[dma_channel_number].channel_info. 
                d_dma_channel_hw_synch == DMA_SYNC_DEVICE_CAM_THRESHOLD) 
            { 
              /* Stop the camera sensor */ 
              /*camd_stop_sensor_clock ();*/ 
							camcore_disable(); 
            } 
#endif 
#endif 
            /* Decrease the amount of bytes to be transferred */ 
            dma_channel_array[dma_channel_number].bytes_to_be_transferred -= 
                 dma_channel_array[dma_channel_number].buffer_size; 
 
            dma_interrupt_status = DMA_BUF1_READY; 
          } 
          else 
          { 
            /* Unmask interrupts */ 
            F_INTH_ENABLE_ONE_IT(C_INTH_2ND_INTH_IT) 
            F_INTH_ENABLE_ONE_IT(C_INTH_SEC_DMA_IT) 
            return; 
          } 
        } 
        else 
        if ((dma_channel_status & DMA_CICR_BLOCK_IE_MASK) ==  
                                  DMA_CICR_BLOCK_IE_MASK) 
        { 
          dma_interrupt_status = DMA_COMPLETED; 
 
          /* if the camera is working then the clock must be stopped as */ 
          /* soon as possible. it is restarted after copying the momory */ 
#if CHIPSET != 15 
						if (dma_channel_array[dma_channel_number].channel_info. 
                d_dma_channel_hw_synch == DMA_SYNC_DEVICE_NAND_FLASH) 
            { 
#ifdef RVM_CAMD_SWE 
              extern void camd_stop_sensor_clock (void); 
              /* Stop the camera sensor */ 
              camd_stop_sensor_clock (); 
#endif 
            } 
#else 
#ifdef RVM_CAMD_SWE 
						if (dma_channel_array[dma_channel_number].channel_info. 
                d_dma_channel_hw_synch == DMA_SYNC_DEVICE_CAM_THRESHOLD) 
            { 
              /* Stop the camera sensor */ 
              /*camd_stop_sensor_clock ();*/ 
							camcore_disable(); 
            } 
#endif 
#endif 
          if (dma_channel_array[dma_channel_number].double_buf_mode !=  
              DMA_NO_DOUBLE_BUF) 
          { 
            /* Check if for this channel double buffering is needed */ 
            if ((dma_channel_array[dma_channel_number].double_buf_mode ==  
                            DMA_DEST_XRAM) ||  
                (dma_channel_array[dma_channel_number].double_buf_mode ==  
                            DMA_DEST_DOUBLE_BUF)) 
            { 
              /* Change the offset in the source buffer if post incremental address mode is used */ 
              if (dma_channel_array[dma_channel_number].channel_info. 
                  d_dma_dst_channel_addr_mode == DMA_ADDR_MODE_POST_INC)  
              { 
                if (dma_channel_array[dma_channel_number].int_or_ext == DMA_INTERNAL) 
                { 
                  /* add offset to the destination adress */ 
                  dma_channel_array[dma_channel_number].channel_info.d_dma_channel_src_address+= 
                    dma_channel_array[dma_channel_number].buffer_size; 
                } 
              } 
            } 
            else 
            { 
              if ((dma_channel_array[dma_channel_number].double_buf_mode == DMA_SOURCE_DOUBLE_BUF) || 
                  (dma_channel_array[dma_channel_number].double_buf_mode == DMA_SOURCE_XRAM )) 
              { 
                /* Change the offset in the destination buffer if post incremental address mode is used */ 
                if (dma_channel_array[dma_channel_number].channel_info. 
                    d_dma_dst_channel_addr_mode == DMA_ADDR_MODE_POST_INC)  
                { 
                  if (dma_channel_array[dma_channel_number].int_or_ext == DMA_EXTERNAL) 
                  { 
                    /* add offset to the destination adress */ 
                    dma_channel_array[dma_channel_number].channel_info.d_dma_channel_dst_address+= 
                      dma_channel_array[dma_channel_number].buffer_size; 
                  } 
                } 
              } 
            } 
 
            /* Decrease the amount of bytes to be transferred */ 
            dma_channel_array[dma_channel_number].bytes_to_be_transferred -= 
                 dma_channel_array[dma_channel_number].buffer_size; 
 
            /*if (dma_channel_array[dma_channel_number].bytes_to_be_transferred>=0)*/ 
            /*{*/ 
              if (dma_channel_array[dma_channel_number].bytes_to_be_transferred< 
                  dma_channel_array[dma_channel_number].buffer_size) 
              { 
                /* for the last part the frames might be modified */ 
                /* Write the number of frames to do */ 
                C_DMA_CFN_REG(dma_channel_number) =  
                   (dma_channel_array[dma_channel_number].bytes_to_be_transferred/ 
                  ((1<dma_hisr)) 
  { 
     return FALSE; 
  } 
  return TRUE; 
} 
 
 
/*-----------------------------------------------------------------------*/ 
/* Activate_DMA_SECURE_HISR()                                            */ 
/*                                                                       */ 
/* This function is called from the interrupt handler to activate        */ 
/* the HISR associated to the DMA External Interrupt.                    */ 
/*                                                                       */ 
/*-----------------------------------------------------------------------*/ 
SYS_BOOL Activate_DMA_SECURE_HISR(void) 
{ 
  extern T_DMA_ENV_CTRL_BLK	*dma_env_ctrl_blk_p; 
 
  if(NU_SUCCESS != NU_Activate_HISR(&dma_env_ctrl_blk_p->dma_secure_hisr)) 
  { 
     return FALSE; 
  } 
  return(TRUE); 
} 
 
 
 
/*-----------------------------------------------------------------------*/ 
/* dma_secure_int_handler()                                              */ 
/*                                                                       */ 
/* This function is called when an secure interrupt occurs. It will      */ 
/* first check if the DMA module actually exist and if it is not         */ 
/* uninitialised. When it exists and is initialising, the interrupt High */ 
/* interrupt service routine is activated that will be called in time.   */ 
/*-----------------------------------------------------------------------*/ 
void dma_secure_int_handler(void) 
{ 
   
  extern T_DMA_ENV_CTRL_BLK	*dma_env_ctrl_blk_p; 
 
  /* Mask interrupts */ 
  F_INTH_DISABLE_ONE_IT(C_INTH_2ND_INTH_IT) 
  F_INTH_DISABLE_ONE_IT(C_INTH_SEC_DMA_IT) 
 
  /* If dma is not started, return immediately */ 
  if (dma_env_ctrl_blk_p == 0) 
  { 
    /* re-enable the interrupts */ 
    F_INTH_ENABLE_ONE_IT(C_INTH_2ND_INTH_IT) 
    F_INTH_ENABLE_ONE_IT(C_INTH_SEC_DMA_IT) 
    return; 
  } 
  else 
  { 
    if(Activate_DMA_SECURE_HISR() == FALSE) 
  	{ 
       DMA_SEND_TRACE ("DMA SECURE HISR activation FAILED", DMA_TRACE_LEVEL); 
       F_INTH_ENABLE_ONE_IT(C_INTH_2ND_INTH_IT) 
       F_INTH_ENABLE_ONE_IT(C_INTH_SEC_DMA_IT) 
	  } 
  } 
}