⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lh7a400_dma_driver.c

📁 sharp flash blob 的烧写代码
💻 C
字号:
/*********************************************************************** 
 * $Workfile:   LH7A400_DMA_driver.c  $ 
 * $Revision:   1.0  $ 
 * $Author:   SuryanG  $ 
 * $Date:   Sep 10 2002 14:55:20  $ 
 * 
 * Project: LH7A400
 * 
 * Description: 
 *   This file contains function definitions for the LH7A400 DMA 
 *   controller driver
 *   
 *   ! ! !  P R E L I M I N A R Y ! ! !
 * 
 * Revision History: 
 * $Log:   //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/DMA/Drivers/LH7A400_DMA_driver.c-arc  $ 
 * 
 *    Rev 1.0   Sep 10 2002 14:55:20   SuryanG
 * Initial revision.
 * 
 * 
 * 
 *********************************************************************** 
 * 
 *  Copyright (c) 2002 Sharp Microelectronics of the Americas 
 * 
 *  All rights reserved 
 * 
 *  SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION 
 *  OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE, 
 *  AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 *  SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE. 
 * 
 *  SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 *  FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 *  SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE 
 *  FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS. 
 * 
 **********************************************************************/ 
#include "LH7A400_dma_driver.h"
#include "SMA_priority_driver.h"
#include "LH7A400_csc_driver.h"
#include "LH7A400_int_driver.h"
#include "LH7A400_cp15_driver.h"

#define DMAINTR_PRIORITY      (21) /* make sure this doesn't conflict 
                                      with other priorities (how?) */

#define N_DMA_INT_SOURCES     (10)
#define N_DMA_CHANNELS        (10)

#define DMA_AAC_OFFSET        (4)

static void (*dma_int_handlers[N_DMA_INT_SOURCES+1])(void);

static INT_8 dma_priorities[N_DMA_INT_SOURCES + 1];
static INT_8 dma_priority_encode0[_BIT(8)];
static INT_8 dma_priority_encode1[_BIT(N_DMA_INT_SOURCES - 8)];
static UNS_32 dma_int_status;

static PRIORITY_DATA prio =
{
   N_DMA_INT_SOURCES,
   dma_priorities,
   dma_priority_encode0,
   dma_priority_encode1,
   0,
   0,
   dma_int_handlers
};

static UNS_32 initialized = 0;

static DMACHANNELREGS *dmach;

/***********************************************************************
 *
 * Function: dma_null_handler
 *
 * Purpose:
 *  Disable the interrupt source if it is unhandled.
 *
 * Processing:
 *  This function is called by the DMA interrupt handler if the
 *  DMA has an active, unmasked, unhandled interrupt. It
 *  disables the unhandled interrupt.
 *
 * Parameters: none
 *
 * Outputs: nothing
 *
 * Returns: nothing
 *
 * Notes: None
 *
 **********************************************************************/
static void dma_null_handler(void)
{
   INT_32 i;
   
   for(i = 0; i < N_DMA_INT_SOURCES; i++)
   {
      if(dma_int_status & _BIT(i))
      {
         dma_interrupt_disable((INT_8)i);
      }
   }
}


/***********************************************************************
 *
 * Function: dma_irq_handler
 *
 * Purpose:
 *  Dispatches the appropriate dma handler
 *
 * Processing:
 *  call the MAKE_DISPATCHER macro
 *
 * Parameters: none
 *
 * Outputs: nothing
 *
 * Returns: nothing
 *
 * Notes: None
 *
 **********************************************************************/
static void dma_irq_handler(void)
{
   MAKE_DISPATCHER16( (dma_int_status = DMAC->dma_global_int),
                       dma_int_handlers,
                       dma_priority_encode)
}

/***********************************************************************
 *
 * Function: dma_install_int_handler
 *
 * Purpose:
 *  Install an interrupt handler function that will be called by the
 *  DMA interrupt handler function
 *
 * Processing:
 *  Use priority_driver functions
 *
 * Parameters:
 *  source:   The number for the interrupt source. can be one of
 *              DMAC_USBTXINT_BIT
 *              DMAC_USBRXINT_BIT
 *              DMAC_MMCTXINT_BIT
 *              DMAC_MMCRXINT_BIT
 *              DMAC_AACRX0INT_BIT
 *              DMAC_AACTX0INT_BIT
 *              DMAC_AACRX1INT_BIT
 *              DMAC_AACTX1INT_BIT
 *              DMAC_AACRX2INT_BIT
 *              DMAC_AACTX2INT_BIT
 *  priority: The priority number for the source. 
 *            0 <= priority < N_DMA_INT_SOURCES
 *  hp:       A pointer to the handler function.
 *
 * Outputs: Arrays in the prio structure set up for the handler
 *
 * Returns: 
 *  priority if successful, N_DMA_INT_SOURCES if not.
 *
 * Notes: None
 *
 **********************************************************************/
INT_8 dma_install_int_handler(INT_8 source, 
                              INT_8 priority, 
                              void (*hp)(void))
{
   return priority_install_handler(&prio, source, priority, hp,
                                   dma_null_handler);
}

/***********************************************************************
 *
 * Function: dma_remove_int_handler
 *
 * Purpose:
 *  Install an interrupt handler function that will be called by the
 *  DMA interrupt handler function
 *
 * Processing:
 *  Use priority_driver functions
 *
 * Parameters: The number for the interrupt source. can be one of
 *              DMAC_USBTXINT_BIT
 *              DMAC_USBRXINT_BIT
 *              DMAC_MMCTXINT_BIT
 *              DMAC_MMCRXINT_BIT
 *              DMAC_AACRX0INT_BIT
 *              DMAC_AACTX0INT_BIT
 *              DMAC_AACRX1INT_BIT
 *              DMAC_AACTX1INT_BIT
 *              DMAC_AACRX2INT_BIT
 *              DMAC_AACTX2INT_BIT
 *
 * Outputs: None
 *
 * Returns: 
 *  priority if successful, N_DMA_INT_SOURCES if not.
 *
 * Notes: None
 *
 **********************************************************************/
INT_8 dma_remove_int_handler(INT_8 source) 
{
   return priority_remove_handler(&prio, 
                                  priority_get_priority(&prio, source),
                                  dma_null_handler);
}

/***********************************************************************
 *
 * Function: dma_init
 *
 * Purpose:
 *  
 *
 * Processing:
 *  
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: 
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 dma_init(void)
{
   INT_32 retval, i;
   
   if(!initialized)
   {   
      int_init_irq_handler(0);
      retval = int_install_irq_handler(INTC_DMAINTR_BIT,
                                       DMAINTR_PRIORITY,
                                       dma_irq_handler);
      if(retval == INTC_N_IRQ_HANDLERS)
      {
         return (_ERROR);
      }                        
      priority_init_driver(&prio, dma_null_handler);
      int_enable_interrupt(INTC_DMAINTR);

      /* set up pointer to dma channel registers structure */
      dmach = &(DMAC->usbrx);
      
      /* disable all dma channels */
      for (i = 0; i < N_DMA_CHANNELS; i++)
      {
         csc_disable_dma((dma_channel_t) i);
      }

      initialized = 1;
   }
   return (_NO_ERROR);
}


/***********************************************************************
 *
 * Function: dma_interrupt_enable
 *
 * Purpose:
 *  
 *
 * Processing:
 *  
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: 
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 dma_interrupt_enable(INT_8 ch)
{
   if(ch < 0 || ch > (N_DMA_INT_SOURCES - 1)) 
   {
      return (_ERROR);
   }

   if (ch > DMA_MMC_TX)
   {
      ch += DMA_AAC_OFFSET;
   }

    dmach[ch].control |= DMAC_STALL | DMAC_NFB | DMAC_CHERROR;

    return(_NO_ERROR);
}


/***********************************************************************
 *
 * Function: dma_interrupt_disable
 *
 * Purpose:
 *  
 *
 * Processing:
 *  
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: 
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 dma_interrupt_disable(INT_8 ch)
{
   if(ch < 0 || ch > (N_DMA_INT_SOURCES - 1)) 
   {
      return (_ERROR);
   }

   if (ch > DMA_MMC_TX)
   {
      ch += DMA_AAC_OFFSET;
   }

    dmach[ch].control &= ~(DMAC_STALL | DMAC_NFB | DMAC_CHERROR);
    
    return(_NO_ERROR);
}


/***********************************************************************
 *
 * Function: dma_start
 *
 * Purpose:
 *  
 *
 * Processing:
 *  
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: 
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 dma_start(INT_8 ch,
                 UNS_32 start_addr,
                 UNS_32 nbytes)
{
   UNS_32 base0, base1, maxcnt0, maxcnt1;
   
   if (ch < 0 || ch > (N_DMA_INT_SOURCES - 1))
   {
      return (_ERROR);
   }
   
   if (ch > DMA_MMC_TX)
   {
      ch += DMA_AAC_OFFSET;
   }
   
   base0 = LH7A400_cp15_map_virtual_to_physical((void *)start_addr);
 
   if (nbytes > USHRT_MAX)
   {
      maxcnt0 = USHRT_MAX;
      maxcnt1 = nbytes - USHRT_MAX;
      
      base1 = LH7A400_cp15_map_virtual_to_physical((void *)
                              (start_addr + (sizeof(UNS_32)*USHRT_MAX)));
   }
   else
   {
      maxcnt0 = nbytes;
      maxcnt1 = 0;
      base1 = 0;
   }
   
   dma_interrupt_enable(ch - DMA_AAC_OFFSET);
   
   dmach[ch].maxcnt0 = maxcnt0;
   
   dmach[ch].control |= DMAC_ENABLE;
   
   dmach[ch].base0 = base0;

   return(_NO_ERROR);
}


/***********************************************************************
 *
 * Function: dma_next_buffer
 *
 * Purpose:
 *  
 *
 * Processing:
 *  
 * Parameters: None
 *
 * Outputs: None
 *
 * Returns: 
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 dma_next_buffer(INT_8 ch, 
                       UNS_32 base1,
                       UNS_16 maxcnt1)
{
   if (ch < 0 || ch > (N_DMA_INT_SOURCES - 1)) 
   {
      return (_ERROR);
   }
   if (ch > DMA_MMC_TX)
   {
      ch += DMA_AAC_OFFSET;
   }

   dmach[ch].maxcnt1 = maxcnt1;
    
   /* enable DMA channel before writing to the base address register */
   dmach[ch].control |= DMAC_ENABLE;
   
   dmach[ch].base1 = LH7A400_cp15_map_virtual_to_physical((void *)base1);
   
    return(_NO_ERROR);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -