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

📄 sadma.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/*----------------------------------------------------------------------
 * Copyright (C) 1999 Intel Corp.
 *
 * This file contains the SA11x0 control object. This object provides
 * initialization and control objects for the SA1100 and SA1110 CPUs.
 *
 * The current implementaiton is a partial object with a number of
 * functions still made available as procedures. This will be removed
 * as the object is completed.
 *
 */

#include <windows.h>
#include <types.h>
#include "sa11x0.h"
#include "macros.h"

void usWait(unsigned usVal);
void msWait(unsigned msVal);

/*----------------------------------------------------------------------
 * Local storage
 */
static volatile struct dmareg * dmaP;

/*----------------------------------------------------------------------
 * Table 11-6
 * This table is the DMA channel setup for each source. It is in the
 * order of the DMA source identifiers in sa11x0.h.
 */
static unsigned dmaTab[] = {
  0 | (1 << 2) | (0 << 3) | (0 << 4) | (0x80000AU << 8), /* UDC_Xmit */
  1 | (1 << 2) | (0 << 3) | (1 << 4) | (0x80000AU << 8), /* UDC_Rcv */
  0 | (0 << 2) | (0 << 3) | (2 << 4) | (0x80801EU << 8), /* SDLC_Xmit */
  1 | (0 << 2) | (0 << 3) | (3 << 4) | (0x80801EU << 8), /* SDLC_Rcv */
  0 | (0 << 2) | (0 << 3) | (4 << 4) | (0x804005U << 8), /* UART1_Xmit */
  1 | (0 << 2) | (0 << 3) | (5 << 4) | (0x804005U << 8), /* UART1_Rcv */
  0 | (0 << 2) | (0 << 3) | (6 << 4) | (0x81001BU << 8), /* UART2_Xmit */
  1 | (0 << 2) | (0 << 3) | (7 << 4) | (0x81001BU << 8), /* UART2_Rcv */
  0 | (1 << 2) | (0 << 3) | (6 << 4) | (0x80C005U << 8), /* HSSP_Xmit */
  1 | (1 << 2) | (0 << 3) | (7 << 4) | (0x80C005U << 8), /* HSSP_Rcv */
  0 | (0 << 2) | (0 << 3) | (8 << 4) | (0x814005U << 8), /* UART3_Xmit */
  1 | (0 << 2) | (0 << 3) | (9 << 4) | (0x814005U << 8), /* UART3_Rcv */
  0 | (0 << 2) | (1 << 3) |(10 << 4) | (0x818002U << 8), /* MCP_AudioXmit */
  1 | (0 << 2) | (1 << 3) |(11 << 4) | (0x818002U << 8), /* MCP_AudioRcv */
  0 | (0 << 2) | (1 << 3) |(12 << 4) | (0x818003U << 8), /* MCP_TelecomXmit */
  1 | (0 << 2) | (1 << 3) |(13 << 4) | (0x818003U << 8), /* MCP_TelecomRcv */
  0 | (0 << 2) | (1 << 3) |(14 << 4) | (0x81C01BU << 8), /* SSP_Xmit */
  1 | (0 << 2) | (1 << 3) |(15 << 4) | (0x81C01BU << 8)  /* SSP_Rcv */
};

/*----------------------------------------------------------------------
 * Allocate a DMA channel and return a pointer to the channel
 */
void * SA_AllocateDMA(volatile struct dmareg *ddaP, int source, int endian)
{
  int i;

  
if (source > SA11x0_SSP_Rcv)
    return NULL;

  for (i=0; i < SA11x0_NumDMA; i++) {
    if (ddaP->dmaChannels[i].ddar.da == 0) {
      RETAILMSG(1,(TEXT("DMAlib ddaP=0x%x, Channel=0%d \r\n\n"),
  	ddaP,i));
      *(unsigned*)&ddaP->dmaChannels[i].ddar = dmaTab[source] | (endian << 1);
      IOW_REG_BITSET(struct dcsrBits,&ddaP->dmaChannels[i].ddcsrSet,run,1);
      return (void*)&ddaP->dmaChannels[i].ddar;
    }
  }
  return NULL;
}
/*----------------------------------------------------------------------
 * Start a DMA transfer on the channel
 */
void SA_InitiateDMA(volatile struct dmachannel * ddaP)
{
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,ie,1);
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,run,1);
}


/*----------------------------------------------------------------------
 * Release a previously allocated DMA channel
 */
void SA_ReleaseDMA(volatile struct dmachannel * ddaP)
{
  
  int retryCount;

  /* May need to sync with running DMA
   */
  IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrClr,run,1);
  retryCount = 100;
  while((ddaP->ddcsrSts.run) && (--retryCount > 0))
    usWait(10);
  *(unsigned*)&ddaP->ddar = 0;
  IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrClr,ie,1);
}

/*----------------------------------------------------------------------
 * Start a DMA transfer on the channel
 */
void SA_StartDMA(volatile struct dmachannel * p, void * ba, int len, int ie)
{
  volatile struct dmachannel * ddaP = (struct dmachannel *)p;
  IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrClr,run,1);
  if ((ddaP->ddcsrSts.biu && ddaP->ddcsrSts.strtb) ||
      (!ddaP->ddcsrSts.biu && !ddaP->ddcsrSts.strta)) {
    ddaP->dbsa = (unsigned)ba;
    IOW_REG_FIELD(struct dbtBits,&ddaP->dbta,tc,len);
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,ie,ie);
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,strta,1);
  }
  else {
    ddaP->dbsb = (unsigned)ba;
    IOW_REG_FIELD(struct dbtBits,&ddaP->dbtb,tc,len);
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,ie,ie);
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,strtb,1);
  }
  IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,run,1);
}

/*----------------------------------------------------------------------
 * Return the channel number of a channel
 */
int SA_GetChannelDMA(volatile struct dmachannel * p)
{
  return ((char*)p - (char*)dmaP->dmaChannels) / sizeof(struct dmachannel);
}

/*----------------------------------------------------------------------
 * Check to see if DMA is complete
 */
int SA_CheckDMA(volatile struct dmachannel * p)
{
  volatile struct dmachannel * ddaP = (struct dmachannel *)p;
  int rc = 0;

  if (ddaP->ddcsrSts.donea)
    rc |= (1 << 0);
  if (ddaP->ddcsrSts.doneb)
    rc |= (1 << 1);

  return rc;
}

/*----------------------------------------------------------------------
 * Pause the DMA channel
 */
void SA_PauseDMA(volatile struct dmachannel * p)
{
  volatile struct dmachannel * ddaP = (struct dmachannel *)p;
  do {
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrClr,run,1);
  } while (ddaP->ddcsrSts.run);
}

/*----------------------------------------------------------------------
 * Resume the DMA channel
 */
void SA_ResumeDMA(volatile struct dmachannel * p)
{
  volatile struct dmachannel * ddaP = (struct dmachannel *)p;
  IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,run,1);
}

/*----------------------------------------------------------------------
 * Start a DMA transfer on the channel
 */
void SA_PumpDMA(volatile struct dmachannel * ddaP, ULONG ba, int len, int use_b)
{
    if (use_b) {
        ddaP->dbsb = ba;
        IOW_REG_FIELD(struct dbtBits,&ddaP->dbtb,tc,len);
        IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,strtb,1);
    }
    else {
        ddaP->dbsa = ba;
        IOW_REG_FIELD(struct dbtBits,&ddaP->dbta,tc,len);
        IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,strta,1);
    }
}


/*----------------------------------------------------------------------
 * Return the current DMA pointer.
 */
int SA_GetDMABuffer(volatile struct dmachannel * p)
{
  volatile struct dmachannel * ddaP = (struct dmachannel *)p;
  int whichBuf = ddaP->ddcsrSts.biu;

  if (whichBuf)
    return ddaP->dbsb;
  else
    return ddaP->dbsa;
}

/*----------------------------------------------------------------------
 * Set the current DMA pointer
 */
int SA_SetDMABuffer(volatile struct dmachannel * p, int buf, void * ba)
{
  volatile struct dmachannel * ddaP = (struct dmachannel *)p;
  int rc = 0;
  int whichBuf = ddaP->ddcsrSts.biu;
  int howMany;

  if (whichBuf) {
    /* STRTB must be clear before update will be allowed
     */
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrClr,strtb,1);
    howMany = (unsigned)ba - (unsigned)ddaP->dbsb;
    ddaP->dbsb = (unsigned)ba;
    rc = ddaP->dbtb.tc-howMany;
    IOW_REG_FIELD(struct dbtBits,&ddaP->dbtb,tc,rc);
    if (rc > 0) {
      IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,strtb,1);
    }
  }
  else {
    /* STRTA must be clear before update will be allowed
     */
    IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrClr,strta,1);
    howMany = (unsigned)ba - (unsigned)ddaP->dbsa;
    ddaP->dbsa = (unsigned)ba;
    rc = ddaP->dbta.tc-howMany;
    IOW_REG_FIELD(struct dbtBits,&ddaP->dbta,tc,rc);
    if (rc > 0) {
      IOW_REG_BITSET(struct dcsrBits,&ddaP->ddcsrSet,strta,1);
    }
  }
  return rc;
}

/*----------------------------------------------------------------------
 * Clear the DMA interrupt
 */
void SA_ClearDMA(volatile struct dmachannel * p, int buf)
{
  volatile struct dmachannel * ddaP = (struct dmachannel *)p;
  struct dcsrBits ddcsr;

  *(unsigned*)&ddcsr = 0;
  if (buf) {
    ddcsr.doneb = 1;
    IOW_REG_SET(struct dcsrBits,&ddaP->ddcsrClr,*(unsigned*)&ddcsr);
  }
  else {
    ddcsr.donea = 1;
    IOW_REG_SET(struct dcsrBits,&ddaP->ddcsrClr,*(unsigned*)&ddcsr);
  }
}
/*----------------------------------------------------------------------
 * Stop DMA transfer on the channel
 */
void SA_StopDMA(volatile struct dmachannel * ddaP)
{ struct dcsrBits ddcsr;

    *(unsigned*)&ddcsr = 0;        
    ddcsr.ie = 1;
    ddcsr.run = 1;
    ddcsr.strta = 1;
    ddcsr.strtb = 1;
    IOW_REG_SET(struct dcsrBits,&ddaP->ddcsrClr,*(unsigned*)&ddcsr);
}


/*----------------------------------------------------------------------
 * DMA control object. Eventually the procedures above will form the
 * body of this object.
 */
void SA11x0_DMA_Init( volatile struct dmareg  *pdmaP)
{
  int i;
  dmaP=pdmaP;
  for (i=0; i < SA11x0_NumDMA; i++)
    SA_ReleaseDMA(&dmaP->dmaChannels[i]);
}

⌨️ 快捷键说明

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