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

📄 es1371.cpp

📁 嵌入式操作系统wince5.0下的声卡驱动
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    case ES1371_DAC0 :
      // set the DAC0 DWORD frame count
      HwPagedIOWrite( ES1371_DAC0CTL_PAGE, 
                      ES1371_wDAC0FC_OFF, 
                      (ulDesiredBufferSize/4 - 1) & 0x0000ffff );  

      // Write DAC0 interrupt count - sample frames per half-buffer (n-1).
      HwRegRMW( ES1371_wDAC0IC_OFF, 0xffff, usInterruptCount );
//      WRITE_PORT_USHORT((PUSHORT)(m_pPciAddr + ES1371_wDAC0IC_OFF),
//                         (USHORT) (ulSamplesPerInt - 1) ) ;
      break;

    case ES1371_DAC1 :
      // set the DAC1 DWORD frame count
      HwPagedIOWrite( ES1371_DAC1CTL_PAGE, 
                      ES1371_wDAC1FC_OFF, 
                      (ulDesiredBufferSize/4 - 1) & 0x0000ffff );  

      // Write DAC1 interrupt count - sample frames per half-buffer (n-1).
      HwRegRMW( ES1371_wDAC1IC_OFF, 0xffff, usInterruptCount );
//      WRITE_PORT_USHORT((PUSHORT)(m_pPciAddr + ES1371_wDAC1IC_OFF),
//                         (USHORT) (ulSamplesPerInt - 1) ) ;
      break;

    case ES1371_ADC :
      // set the ADC DWORD frame count
      HwPagedIOWrite( ES1371_ADCCTL_PAGE, 
                      ES1371_wADCFC_OFF, 
                      (ulDesiredBufferSize/4 - 1) & 0x0000ffff );  

      // Write ADC interrupt count - sample frames per half-buffer (n-1).
      HwRegRMW( ES1371_wADCIC_OFF, 0xffff, usInterruptCount );
//      WRITE_PORT_USHORT((PUSHORT)(m_pPciAddr + ES1371_wADCIC_OFF),
//                         (USHORT) (ulSamplesPerInt - 1) ) ;
      break;
  }
  return ;  
}

//--------------------------------------------------------------------------
//
//  Name: StartDMAChannel
//
//  Description: Start a particular DMA channel running.
//
//  Parameters: UCHAR ucDMAChannel : Index of the DMA channel to start
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::StartDMAChannel( UCHAR ucDMAChannel )
{
  UCHAR ucIOVal;

  switch ( ucDMAChannel )
  {
    case ES1371_DAC0 :
      if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
      {
        // modify pause bit for DAC0
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC0PAUSE, ucIOVal );
      }
      else
      {
        // enable the DAC0 interrupt
        ucIOVal = ES1371_SERCTL_DAC0IE;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC0IE,
                  ucIOVal ); 

        // start DAC0
        ucIOVal = ES1371_DEVCTL_DAC0_EN;
        HwRegRMW( ES1371_bDEVCTL_OFF,
                  ES1371_DEVCTL_DAC0_EN,
                  ucIOVal ); 
      }

      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_RUNNING;
      break;

    case ES1371_DAC1 :
      if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
      {
        // modify pause bit for DAC1
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC1PAUSE, ucIOVal );
      }
      else
      {
        // enable the DAC1 interrupt
        ucIOVal = ES1371_SERCTL_DAC1IE;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC1IE,
                  ucIOVal ); 

        // start DAC1
        ucIOVal = ES1371_DEVCTL_DAC1_EN;
        HwRegRMW( ES1371_bDEVCTL_OFF,
                  ES1371_DEVCTL_DAC1_EN,
                  ucIOVal ); 
      }

      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_RUNNING;
      break;

    case ES1371_ADC :
      // enable the ADC interrupt
      ucIOVal = ES1371_SERCTL_ADCIE;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_ADCIE,
                ucIOVal ); 

      // start ADC
      ucIOVal = ES1371_DEVCTL_ADC_EN;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_ADC_EN,
                ucIOVal ); 

      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_RUNNING;
      break;
  }
  return;
}

//--------------------------------------------------------------------------
//
//  Name: StopDMAChannel
//
//  Description: Stop a particular DMA channel.
//
//  Parameters: UCHAR ucDMAChannel : Index of the DMA channel to stop
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::StopDMAChannel( UCHAR ucDMAChannel )
{
  UCHAR ucIOVal;
  ULONG ulFrameCount = 0;

  switch ( ucDMAChannel )
  {
    case ES1371_DAC0 :
      // Stop DAC0
      ucIOVal = 0;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_DAC0_EN, ucIOVal );

      // disable the DAC0 interrupt
      ucIOVal = 0;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC0IE, ucIOVal );

      if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
      {
        // modify pause bit for DAC0
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC0PAUSE, ucIOVal );
      }

      // Clear out the Current Frame count register
      ulFrameCount = HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0FC_OFF); 
      HwPagedIOWrite( ES1371_DAC0CTL_PAGE, 
                      ES1371_wDAC0FC_OFF,
                      ulFrameCount & 0x0000ffff ); 

      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_STOPPED;
      break;

    case ES1371_DAC1 :
      // Stop DAC1
      ucIOVal = 0;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_DAC1_EN, ucIOVal);

      // disable the DAC1 interrupt
      ucIOVal = 0;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC1IE, ucIOVal);

      if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
      {
        // modify pause bit for DAC0
        ucIOVal = 0;
        HwRegRMW( ES1371_bSERCTL_OFF,
                  ES1371_SERCTL_DAC1PAUSE, ucIOVal );
      }

      // Clear out the Current Frame count register
      ulFrameCount = HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1FC_OFF); 
      HwPagedIOWrite( ES1371_DAC1CTL_PAGE, 
                      ES1371_wDAC1FC_OFF,
                      ulFrameCount & 0x0000ffff ); 

      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_STOPPED;
      break;

    case ES1371_ADC :
      // Stop ADC
      ucIOVal = 0;
      HwRegRMW( ES1371_bDEVCTL_OFF,
                ES1371_DEVCTL_ADC_EN, ucIOVal);

      // disable the ADC interrupt
      ucIOVal = 0;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_ADCIE, ucIOVal);

      // Clear out the Current Frame count register
      ulFrameCount = HwPagedIORead( ES1371_ADCCTL_PAGE, ES1371_wADCFC_OFF); 
      HwPagedIOWrite( ES1371_ADCCTL_PAGE, 
                      ES1371_wADCFC_OFF,
                      ulFrameCount & 0x0000ffff ); 

      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_STOPPED;
      break;
  }
  return;
}

//--------------------------------------------------------------------------
//
//  Name: PauseDMAChannel
//
//  Description: Pause a particular DMA channel.
//
//  Parameters: UCHAR ucDMAChannel : Index of the DMA channel to pause
//
//  Returns: none   
//
//  Note:
//
//--------------------------------------------------------------------------
void
CES1371::PauseDMAChannel( UCHAR ucDMAChannel )
{
  UCHAR ucIOVal;

  switch ( ucDMAChannel )
  {
    case ES1371_DAC0 :
      // wait until interrupt count is non-zero
//      while ( !HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0CIC_OFF)); 

      // modify pause bit for DAC0
      ucIOVal = ES1371_SERCTL_DAC0PAUSE;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC0PAUSE, ucIOVal );
      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_PAUSED;
      break;

    case ES1371_DAC1 :
      // wait until interrupt count is non-zero
//      while ( !HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1CIC_OFF)); 

      // modify pause bit for DAC1
      ucIOVal = ES1371_SERCTL_DAC1PAUSE;
      HwRegRMW( ES1371_bSERCTL_OFF,
                ES1371_SERCTL_DAC1PAUSE, ucIOVal);
      // save the state
      m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_PAUSED;
      break;

    case ES1371_ADC :
      break;
  }
  return;
}

//--------------------------------------------------------------------------
//
//  Name: GetDMAPosition
//
//  Description: reads the current position of a DMA channel.
//
//  Parameters: UCHAR ucDMAChannel : Index of the DMA channel
//
//  Returns: ULONG current DMA position in bytes  
//
//  Note: This function returns the DMA position NOT the sample play
//        cursor.  It appears that this will be used for buffer filling.
//
//--------------------------------------------------------------------------
ULONG
CES1371::GetDMAPosition( UCHAR ucDMAChannel )
{
  ULONG ulCurrentPos = 0;

  switch ( ucDMAChannel )
  {
    case ES1371_DAC0 :
      // read the Frame register
      ulCurrentPos = HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0FC_OFF); 
      // the current frame count is in the upper WORD
      ulCurrentPos >>= 16;

      // multiply the DWORD count by 4 to get a BYTE count to return
      ulCurrentPos *= 4;
      break;

    case ES1371_DAC1 :
      // read the Frame register
      ulCurrentPos = HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1FC_OFF); 
      // the current frame count is in the upper WORD
      ulCurrentPos >>= 16;

      // multiply the DWORD count by 4 to get a BYTE count to return
      ulCurrentPos *= 4;
      break;

    case ES1371_ADC :
      // read the Frame register
      ulCurrentPos = HwPagedIORead( ES1371_ADCCTL_PAGE, ES1371_wADCFC_OFF); 
      // the current frame count is in the upper WORD
      ulCurrentPos >>= 16;

      // multiply the DWORD count by 4 to get a BYTE count to return
      ulCurrentPos *= 4;
      break;
  }
  return ulCurrentPos;
}

//--------------------------------------------------------------------------
//
//  Name: GetInterruptSource
//
//  Description: returns the source of the current interrupt
//
//  Parameters: none
//
//  Returns: UCHAR LONG current DMA position in bytes  
//
//--------------------------------------------------------------------------
UCHAR
CES1371::GetInterruptSource( void )
{
    ULONG intstat;
    UCHAR intsrc;

    intstat = READ_PORT_ULONG( (PULONG)(m_pPciAddr + ES1371_dSTATUS_OFF) ); 

    // If we get all f's back we can't see the hardware
    if ( 0xffffffff == intstat )
      return ES1371_INT_NONE;

    if ( !( ES1371_INTSTAT_PENDING & intstat ))
      return ES1371_INT_NONE;

    intsrc = (UCHAR)(intstat) & ES1371_INT_MASK;

    return intsrc;
}

//--------------------------------------------------------------------------
//
//  Name: AckDMAInterrupt
//
//  Description: clean up a (set of) interrupt(s) 
//
//  Parameters: UCHAR ucIntSrc : a bit mask interrupts to ack
//
//  Returns: none  
//
//--------------------------------------------------------------------------
void
CES1371::AckDMAInterrupt( UCHAR ucIntSrc )
{
    UCHAR ackmask = 0;

    if ( ES1371_INT_ADC & ucIntSrc )
       ackmask |= ES1371_SERCTL_ADCIE ;

    if ( ES1371_INT_DAC0 & ucIntSrc )
       ackmask |= ES1371_SERCTL_DAC0IE ;

    if ( ES1371_INT_DAC1 & ucIntSrc )
       ackmask |= ES1371_SERCTL_DAC1IE ;

    // now ack the interrupts - first set the IEs to 0
    HwRegRMW( ES1371_bSERCTL_OFF, ackmask, 0x00);

    // then set the IEs back to 1
    HwRegRMW( ES1371_bSERCTL_OFF, ackmask, ackmask);
}
   

//--------------------------------------------------------------------------
//
//  Name: JoystickEnable
//
//  Description: Enable or disable the joystick port IO range 
//
//  Parameters: 
//     ULONG ulIOPort : The starting IO address to use or 0 to disable
//
//  Returns: none  
//
//--------------------------------------------------------------------------
void
CES1371::JoystickEnable( ULONG ulIOPort )
{
    UCHAR joyio = 0;

    if ( ( 0x00000200 == ulIOPort ) ||
         ( 0x00000208 == ulIOPort ) ||
         ( 0x00000210 == ulIOPort ) ||
         ( 0x00000218 == ulIOPort ) )
    {
         // move the two useful bits to the correct position
         joyio = UCHAR( ulIOPort >> 3 ) ;

         // set the two bits that control the joystick io range
         HwRegRMW( ES1371_bJOYCTL_OFF, 0x03, joyio );

         // enable the joystick port
         joyio = ES1371_DEVCTL_JSTICK_EN ;
         HwRegRMW( ES1371_bDEVCTL_OFF, ES1371_DEVCTL_JSTICK_EN, joyio );
    }
    else // disable
    {
         // disable the joystick port
         joyio = 0;
         HwRegRMW( ES1371_bDEVCTL_OFF, ES1371_DEVCTL_JSTICK_EN, joyio );
    }     
}
   

/*****************************************************************************
 * SynchronizedPagedIO()
 *****************************************************************************
 * Do paged IO syncronized with the ISR.
 */
NTSTATUS
SynchronizedPagedIO
(
    IN      PINTERRUPTSYNC  InterruptSync,
    IN      PVOID           syncIOContext
)
{
    PSYNCIOCONTEXT context;

    context = (PSYNCIOCONTEXT)syncIOContext;
    ASSERT(context->pHardware);
    ASSERT(context->ulPage);
    ASSERT(context->ulIOAddress);

    NTSTATUS ntStatus = STATUS_SUCCESS;

	// write the page register if needed
    if ( context->pHardware->m_ulDRegs[ES1371_bMEMPAGE_OFF/4] != context->ulPage )
    {
        WRITE_PORT_UCHAR(context->pHardware->m_pPciAddr + ES1371_bMEMPAGE_OFF, 
                         UCHAR(context->ulPage) & 0x0f );
        // save in the regs array
        context->pHardware->m_ulDRegs[ES1371_bMEMPAGE_OFF/4] = context->ulPage;
    }

    // read or write the data
    if ( context->fRead )
    {
        *(context->pulData) = 
            READ_PORT_ULONG( 
               PULONG(context->pHardware->m_pPciAddr + context->ulIOAddress) );
    }
    else // write
    {
        WRITE_PORT_ULONG( 
               PULONG(context->pHardware->m_pPciAddr + context->ulIOAddress),
               *(context->pulData) );
    }

    return ntStatus;
}

⌨️ 快捷键说明

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