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

📄 wavepdd.c

📁 基于wince 操作系统的开发的i2s驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    //
    //  Grab a spinlock
    //
    InitializeCriticalSection(&WaveDevice->CriticalSection);

    if(!InitializePlatform(WaveDevice)) {
        DEBUGMSG(ZONE_PDD,(L"Failed to Initialize platform registers\r\n"));
        goto ErrorReturn;
    }

    if(!InitializeDMA(WaveDevice)) {
        DEBUGMSG(ZONE_PDD,(L"Failed to Initialize DMA\r\n"));
        goto ErrorReturn;
    }
    
    if(!InitializeInterrupt(WaveDevice)) {
        DEBUGMSG(ZONE_PDD,(L"Failed to Initialize Interrupt\r\n"));
        goto ErrorReturn;
    }

    WaveOutResource = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
                                 sizeof(*WaveOutResource));

    if(WaveOutResource==NULL) {
        DEBUGMSG(ZONE_PDD,(L"Failed to allocate Out Resouece\r\n"));
        goto ErrorReturn;
    }

    WaveOutResource->WaveDirection=WAPI_OUT;
    WaveOutResource->DmaBufferSize=WaveDevice->DmaBufferSize;
    WaveOutResource->DMAChannel=WaveDevice->DMAChannelOutput;
    WaveOutResource->pI2S=WaveDevice->pI2S;
	WaveOutResource->CriticalSection=WaveDevice->CriticalSection;


    WaveInResource = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
                                sizeof(*WaveInResource));

    if(WaveInResource==NULL) {
        DEBUGMSG(ZONE_PDD,(L"Failed to allocate Out Resource\r\n"));
        goto ErrorReturn;
    }

    WaveInResource->WaveDirection=WAPI_IN;
    WaveInResource->DmaBufferSize=WaveDevice->DmaBufferSize;
    WaveInResource->DMAChannel=WaveDevice->DMAChannelInput;
    WaveInResource->pI2S=WaveDevice->pI2S;
	WaveInResource->CriticalSection=WaveDevice->CriticalSection;

    
    DEBUGMSG(ZONE_PDD,(L"-PDD_AudioInitialize\r\n"));
    return TRUE;
ErrorReturn:
    DEBUGMSG(ZONE_PDD,(L"-PDD_AudioInitialize failed\r\n"));
    return FALSE;
}

VOID
PDD_AudioDeinitialize (
    VOID
    )
{

    DEBUGMSG(ZONE_PDD, (TEXT("+Audio PDD_AudioDeinitialize.\r\n")));

    // FIXME FIXME  need to free used resources
    
    if (WaveDevice != NULL) {
        LocalFree(WaveDevice);
        WaveDevice = NULL;
    }
    DEBUGMSG(ZONE_PDD, (TEXT("-Audio PDD_AudioDeinitialize.\r\n")));

    return;
}

VOID 
PDD_AudioPowerHandler (
    BOOL PowerDown
    )
{
    if(PowerDown==TRUE) {

        
		ShutdownDma(WaveInResource);
		ShutdownDma(WaveOutResource);

    	WaveInResource->DmaRunning = FALSE;
    	WaveOutResource->DmaRunning = FALSE;
        
        // Halt the I2S
		WRITE_REGISTER_ULONG((PULONG)&WaveDevice->pI2S->psc.ctl,0);

    } else {
		WaveDevice->InPowerHandler=TRUE;
        InitializeRegisters(WaveDevice->pI2S);
        
        WaveInResource->DmaRunning = FALSE;
        WaveOutResource->DmaRunning = FALSE;
		WaveDevice->InPowerHandler=FALSE;
    }
    

    return;
}


MMRESULT
PDD_WaveProc(
    IN WAPI_INOUT ApiDirection,
    IN ULONG Code,
    IN OUT ULONG Param1,
    IN OUT ULONG Param2
    )

/*++

Routine Description:

    This routine is called to access various other functions in the driver
    It's similar to an I/O control in standard streams drivers.

Arguments:

    ApiDirection - Direction (input or output).

    Code - Code specifying which function to call.

    Param1 - Parameter 1.  Its usage is dependent on which function is called.

    Param2 - Parameter 2.  Its usage is dependent on which function is called.

Return Value:

    None.

--*/

{
    MMRESULT ReturnValue;

        
    DEBUGMSG(ZONE_PDD, (TEXT("+Audio PDD_WaveProc.\r\n")));

    ReturnValue = MMSYSERR_NOERROR;

    switch(Code) {

    case WPDM_CLOSE:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_CLOSE(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_IN) {

            ReturnValue = WaveClose(WaveInResource);
        }
        else {

            ReturnValue = WaveClose(WaveOutResource);
        }

        break;

    case WPDM_CONTINUE:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_CONTINUE(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_IN) {
            WaveInContinue(WaveInResource,
                           (PWAVEHDR)Param1);
        }
        else  {
            WaveOutContinue(WaveOutResource,
                            (PWAVEHDR)Param1);
        }

        break;

    case WPDM_GETDEVCAPS:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_GETDEVCAPS(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        ReturnValue = WaveGetDeviceCapabilities(ApiDirection,
                                                (PVOID)Param1,
                                                (UINT)Param2);
        break;

    case WPDM_OPEN:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_OPEN(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_IN) {

            ReturnValue = WaveOpen((LPWAVEFORMATEX)Param1,
                                   (BOOL)Param2,
                                   WaveInResource);
        }
        else {

            ReturnValue = WaveOpen((LPWAVEFORMATEX)Param1,
                                   (BOOL)Param2,
                                   WaveOutResource);
        }

        break;

    case WPDM_STANDBY:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_STANDBY(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_IN) {

            WaveStandby(WaveInResource);
        }
        else {

            WaveStandby(WaveOutResource);
        }
        
        
        break;

    case WPDM_START:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_START(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        
        if (ApiDirection == WAPI_IN) {
            WaveInStart(WaveInResource,
                        (PWAVEHDR)Param1);
        }
        else {
            WaveOutStart(WaveOutResource,
                         (PWAVEHDR)Param1);
        }

        break;

    case WPDM_STOP:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_STOP(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_IN) {
            WaveInStop(WaveInResource);
        }
        else {

            WaveOutEndOfData(WaveOutResource);
        }

        break;

    case WPDM_PAUSE:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_PAUSE(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_OUT) {

            //
            // Call end of data to halt transfer.
            //

            WaveOutEndOfData(WaveOutResource);
        }
        else {

            ReturnValue = MMSYSERR_NOTSUPPORTED;
        }

        break;

    case WPDM_ENDOFDATA:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_ENDOFDATA(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_OUT) {

            WaveOutEndOfData(WaveOutResource);
        }
        else {

            ReturnValue = MMSYSERR_NOTSUPPORTED;
        }

        break;

    case WPDM_RESTART:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_RESTART(%s).\r\n"),
                 DIR_STR(ApiDirection)));

        if (ApiDirection == WAPI_OUT) {

            //
            // Call start to continue in stream where we left off.
            //

            WaveOutStart(WaveOutResource,
                         (PWAVEHDR)Param1);
        }
        else  {

            ReturnValue = MMSYSERR_NOTSUPPORTED;
        }

        break;

    case WPDM_GETVOLUME:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: WPDM_GETVOLUME.\r\n")));

        ReturnValue = GetOutputVolume(WaveDevice,
                                      (PULONG)Param1);


        break;

    case WPDM_SETVOLUME:


        ReturnValue = SetOutputVolume(WaveDevice,
                                      Param1);

        break;

    default:

        DEBUGMSG(ZONE_PDD, (
                 TEXT("   PDD_WaveProc: Unknown code %u.\r\n"),
                      Code));
        ReturnValue = MMSYSERR_NOTSUPPORTED;
        break;
    }
    DEBUGMSG(ZONE_PDD, (TEXT("-Audio PDD_WaveProc.\r\n")));

    return ReturnValue;
}

AUDIO_STATE 
PDD_AudioGetInterruptType(
    VOID
    )
{
    AUDIO_STATE PendingInterrupts;
	ULONG Mask;

    PendingInterrupts = 0;
    DEBUGMSG(ZONE_PDD, (TEXT("+Audio PDD_AudioGetInterruptType.\r\n")));

    //
    // For each of input and output, read the DMA status registers to see if
    // there is a pending interrupt.  Depending on whether or not there is a
    // pending interrupt and if there is more data to play/record, various
    // flags are ORed into the audio state to be returned to the MDD.
    //
	Mask = HalCheckForDMAInterrupt(WaveDevice->DMAChannelInput);

	if( Mask )
	{
		if( WaveInResource->MoreData )
		{
			DEBUGMSG(DMA_VERBOSE_DEBUG, (
                     TEXT("PDD_AudioGetInterruptType: %s more data.\r\n"),
                     DIR_STR(WAPI_IN)));

			PendingInterrupts |= AUDIO_STATE_IN_RECORDING;

		}
		else
		{
			DEBUGMSG(ZONE_PDD, (
                     TEXT("PDD_AudioGetInterruptType: %s stopped.\r\n"),
                     DIR_STR(WAPI_IN)));

			PendingInterrupts |= AUDIO_STATE_IN_STOPPED;
            SetEvent(hAudioInterrupt);
		}
		HalAckDMAInterrupt(WaveDevice->DMAChannelInput,Mask);
        goto ReturnWaveStatus;
	}
    
    //
    // Wave output.
    //
	Mask = HalCheckForDMAInterrupt(WaveDevice->DMAChannelOutput);
    if (Mask)
	{
		if (WaveOutResource->MoreData) 
        {
		    PendingInterrupts |=  AUDIO_STATE_OUT_PLAYING;
	    }
	    else 
	    {
		    PendingInterrupts |=  AUDIO_STATE_OUT_STOPPED;
	    }
		HalAckDMAInterrupt(WaveDevice->DMAChannelOutput,Mask);
    }

ReturnWaveStatus:
    DEBUGMSG(ZONE_PDD, (TEXT("-Audio PDD_AudioGetInterruptType.\r\n")));
    return PendingInterrupts;
}

⌨️ 快捷键说明

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