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

📄 hwctxt.cpp

📁 s3c2443的Wavedev代码,觉对好用.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		// Load B
		BytesTransferred += TransferInputBuffer(IN_BUFFER_B);
		break;
	}

	// If it was our interrupt, but we weren't able to transfer any bytes
	// (e.g. no empty buffers ready to be filled)
	// Then stop the input DMA
	if (BytesTransferred==0)
	{
		//RETAILMSG(1,(TEXT("+++ NO BYTES transferred by DMA\r\n")));
		StopInputDMA();
	}
	return BytesTransferred;
}


void HardwareContext::InterruptThread()
{
	ULONG InputTransferred, OutputTransferred;
	BOOL dmaInterruptSource = 0;

	// Fast way to access embedded pointers in wave headers in other processes.
	SetProcPermissions((DWORD)-1);
	
RETAILMSG(DBG_AUDIO,(TEXT("InterruptThread... wait event\n")));
	while(TRUE)
	{
		RETAILMSG(DBG_AUDIO,(TEXT("Wait event\n")));
		RETAILMSG(DBG_AUDIO,(TEXT(" INTMSK[0x%x]\n"),s2443INT->INTMSK));
		
		WaitForSingleObject(m_hAudioInterrupt, INFINITE);
		RETAILMSG(DBG_AUDIO,(TEXT("INTMSK: 0x%x\n"),s2443INT->INTMSK));
		g_ForCount++;
		dmaInterruptSource = 0;
		//----- 1. Grab the lock -----
		Lock();

		__try
		{
			RETAILMSG(DBG_AUDIO,(TEXT("try\n")));

			//----- 3. Determine the interrupt source (input DMA operation or output DMA operation?) -----
			//----- NOTE:	Often, platforms use two separate DMA channels for input/output operations but
			//				have the OAL return SYSINTR_AUDIO as the interrupt source.  If this is the case,
			//				then the interrupt source (input or output DMA channel) must be determined in
			//				this step.
			// charlie, determine the interrupt source

			/*
			RETAILMSG(1,(TEXT("INTMSK: 0x%x\n"),s2443INT->INTMSK));
			RETAILMSG(1,(TEXT("INTPND: 0x%x\n"),s2443INT->INTPND));
			RETAILMSG(1,(TEXT("SUBSRCPND: 0x%x\n"),s2443INT->SUBSRCPND));
			RETAILMSG(1,(TEXT("INTSUBMSK: 0x%x\n"),s2443INT->INTSUBMSK));*/
			if( s2443INT->INTSUBMSK & (1<< IRQ_SUB_DMA1))
			{
				delay_count = 0;
				dmaInterruptSource |= DMA_CH_MIC;								// Input DMA is supported...
				// For determine the interrupt source
				//----- 2. Acknowledge the DMA interrupt -----
				//RETAILMSG(1,(TEXT("MIC-------------------\n")));
				
				
				InterruptDone(m_dwSysintrInput);
			}
			
			if( s2443INT->INTSUBMSK & (1<< IRQ_SUB_DMA2)){
				dmaInterruptSource |= DMA_CH_OUT;								// Output DMA is supported...
				// For determine the interrupt source
				//----- 2. Acknowledge the DMA interrupt -----
				InterruptDone(m_dwSysintrOutput);
			}

			//----- 4. Handle any interrupts on the input source -----
			//		   NOTE: The InterruptDone() call below automatically clears the interrupt.
			if((dmaInterruptSource == DMA_CH_MIC))
			{
				//----- Determine which buffer just completed the DMA transfer -----
				if(m_InputDMAStatus & DMA_BIU)
				{
					m_InputDMAStatus &= ~DMA_STRTB;							// Buffer B just completed...
					m_InputDMAStatus |= DMA_DONEB;

					m_InputDMAStatus &= ~DMA_BIU;							// Buffer A is in use
#if DMA_FLAG					
					SELECT_AUDIO_DMA_INPUT_BUFFER_B();
#else					
					SELECT_AUDIO_DMA_INPUT_BUFFER_A();
#endif					
					//RETAILMSG(1,(TEXT("try2-MIC_B(%x)\n"), m_InputDMAStatus));
				}else
				{
					m_InputDMAStatus &= ~DMA_STRTA;							// Buffer A just completed...
					m_InputDMAStatus |= DMA_DONEA;

					m_InputDMAStatus |= DMA_BIU;							// Buffer B is in use
#if DMA_FLAG
					SELECT_AUDIO_DMA_INPUT_BUFFER_A();
#else										
					SELECT_AUDIO_DMA_INPUT_BUFFER_B();
#endif					
					//RETAILMSG(1,(TEXT("try2_A(%x)\n"), m_InputDMAStatus));
				}

#if !DMA_FLAG		
				//----- 5. Schedule the next DMA transfer -----
				AUDIO_IN_DMA_ENABLE();
#endif				
				
				//----- 6. Retrieve the next chunk of recorded data from the non-playing buffer -----
				InputTransferred = TransferInputBuffers(m_InputDMAStatus);			
			}
			else
			{
				//----- 7. Handle any interrupts on the output source -----
				//		   NOTE: The InterruptDone() call below automatically clears the interrupt.

				//----- Determine which buffer just completed the DMA transfer -----
				if(m_OutputDMAStatus & DMA_BIU)
				{
					m_OutputDMAStatus &= ~DMA_STRTB;						// Buffer A just completed...
					m_OutputDMAStatus |= DMA_DONEB;

					m_OutputDMAStatus &= ~DMA_BIU;							// Buffer B is in use

					// Wait for start DMA.
					delay_count = 0;
					while((g_pDMAregs->DSTAT2&0xfffff)==0){
	        				if( delay_count++ > DELAY_COUNT )	break;
					}

#if DMA_FLAG		
					SELECT_AUDIO_DMA_OUTPUT_BUFFER_B();		// charlie. B => A
#else				
					SELECT_AUDIO_DMA_OUTPUT_BUFFER_A();		// charlie. B => A	
#endif					
				RETAILMSG(DBG_AUDIO,(_T("try-DMA_BIU-B(%x)\n"), m_OutputDMAStatus));

				}else
				{
					m_OutputDMAStatus &= ~DMA_STRTA;						// Buffer B just completed...
					m_OutputDMAStatus |= DMA_DONEA;

					m_OutputDMAStatus |= DMA_BIU;							// Buffer A is in use


					// Wait for start DMA.
					delay_count = 0;
					while((g_pDMAregs->DSTAT2&0xfffff)==0){
	        				if( delay_count++ > DELAY_COUNT )	break;
					}
					
#if DMA_FLAG					
					SELECT_AUDIO_DMA_OUTPUT_BUFFER_A();		// charlie. B => A
#else				
					SELECT_AUDIO_DMA_OUTPUT_BUFFER_B();		// charlie. B => A	
#endif					
				}

//				SET_AUDIO_DMA_OUTPUT_DCON();
//				AUDIO_OUT_DMA_ENABLE();

#if !DMA_FLAG
				//----- 8. Schedule the next DMA transfer -----
				AUDIO_OUT_DMA_ENABLE();
#endif
				RETAILMSG(DBG_AUDIO,(_T("try-!DMA_BIU-A(%x)\n"), m_OutputDMAStatus));

				//----- 9. Fill the non-playing buffer with the next chunk of audio data to play -----
				OutputTransferred = TransferOutputBuffers(m_OutputDMAStatus);
			}

		}
		__except(EXCEPTION_EXECUTE_HANDLER) 
		{
			RETAILMSG(DBG_AUDIO, (TEXT("WAVDEV2.DLL:InterruptThread() - EXCEPTION: %d"), GetExceptionCode()));
		}

		//----- 10. Unlock ----- 
		Unlock();
	}  
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		AudioMute()

Description:	Mutes/unmutes the specified audio channel.

Notes:			If both audio channels are MUTED, then the chip 
				is powered down to conserve battery life.  
				Alternatively, if either audio channel is unMUTED, 
				the chip is powered up.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::AudioMute(DWORD channel, BOOL bMute)
{
	#if 0
	static DWORD dwActiveChannel = 0;
	{
		if(bMute)
		{
			_WrL3Addr(0x14);
			_WrL3Data(0xa4,0);
		}
		else
		{
			_WrL3Addr(0x14);
			_WrL3Data(0xa0,0);
		}
	}			
	#endif
	return(TRUE);
	
}


void CallInterruptThread(HardwareContext *pHWContext)
{
	pHWContext->InterruptThread();
}

DWORD HardwareContext::Open(void)
{
	DWORD mmErr = MMSYSERR_NOERROR;

	// Don't allow play when not on, if there is a power constraint upon us.
	if ( D0 != m_Dx )
	{
		// Tell the Power Manager we need to power up.
		// If there is a power constraint then fail.
		RETAILMSG(DBG_WAV, (TEXT("[A_HW] Open : DevicePowerNotify - D0\r\n")));

		DWORD dwErr = DevicePowerNotify(_T("WAV1:"), D0, POWER_NAME);
		if ( ERROR_SUCCESS !=  dwErr )
		{
			RETAILMSG(DBG_WAV, (TEXT("WAVEDEV::Open:DevicePowerNotify ERROR1: %u\r\n"), dwErr ));
			dwErr = DevicePowerNotify(_T("WAV1:"), D0, POWER_NAME);
			mmErr = MMSYSERR_ERROR;
		}
	}

	return mmErr;
}

DWORD HardwareContext::Close(void)
{
	DWORD mmErr = MMSYSERR_NOERROR;
	DWORD dwErr;

	if (bInputClose==TRUE) bIsRecording = FALSE;
	else bIsPlaying = FALSE;
	// we are done so inform Power Manager to power us down
	if(bIsPlaying==FALSE && bIsRecording==FALSE)
	{
		bClosing = TRUE;
    		if ( D4 != m_Dx )
		{
    			RETAILMSG(DBG_WAV, (TEXT("[A_HW] Close : DevicePowerNotify - D4\r\n")));
    			dwErr = DevicePowerNotify(_T("WAV1:"), (_CEDEVICE_POWER_STATE)D4, POWER_NAME);	

			if ( ERROR_SUCCESS !=  dwErr )
			{
				RETAILMSG(DBG_WAV, (TEXT("WAVEDEV::Close:DevicePowerNofify ERROR1: %u\r\n"), dwErr));
				dwErr = DevicePowerNotify(_T("WAV1:"), (_CEDEVICE_POWER_STATE)D4, POWER_NAME);	
				mmErr = MMSYSERR_ERROR;
			}
		}
	}

	if(bInputClose==TRUE && m_InputDMARunning==TRUE)	
	{
		RETAILMSG(1, (TEXT("[A_HW] Close : StopInputDMA Exception!\r\n")));
		StopInputDMA();

	}
	bInputClose=FALSE;

	return mmErr;
}

void HardwareContext::CodecPowerDown()
{
	if(!bIdlePwrDown)
	{
		RETAILMSG(DBG_WAV,(TEXT("[A_HW] CodecPowerDown : Done\r\n")));	
	}
	else
		RETAILMSG(DBG_WAV,(TEXT("[A_HW] CodecPowerDown : Already Off\r\n")));	
}

BOOL 
HardwareContext::IOControl(DWORD  dwOpenData, 
    DWORD  dwCode,
    PBYTE  pBufIn,
    DWORD  dwLenIn,
    PBYTE  pBufOut,
    DWORD  dwLenOut,
    PDWORD pdwActualOut)
{
    DWORD dwErr = ERROR_SUCCESS;    
    BOOL  bRc = TRUE;
	WCHAR wPState[20];
	DWORD dFlag;

    
    switch (dwCode) {
        //
        // Power Management
        //
    case IOCTL_POWER_QUERY:
            if(pBufOut != NULL && dwLenIn == sizeof(CEDEVICE_POWER_STATE))
            {
                // return a good status on any valid query, since we are always ready to
                // change power states.
                bRc = FALSE;
                __try
                {
                    CEDEVICE_POWER_STATE NewDx = *(PCEDEVICE_POWER_STATE) pBufOut;
                    if(VALID_DX(NewDx))
                    {
                        // this is a valid Dx state so return a good status
                        bRc = TRUE;
                    }
                    RETAILMSG(1, (L"%s: IOCTL_POWER_QUERY %u %s\r\n", TEXT("AUDIO"), 
						NewDx, bRc == TRUE ? L"succeeded" : L"failed"));
                }
                __except(EXCEPTION_EXECUTE_HANDLER)
                {
                    RETAILMSG(1, (L"%s: exception in ioctl2\r\n"));
                    bRc=FALSE;
                }
            }
            break;
        case IOCTL_POWER_CAPABILITIES: 
        {
            PPOWER_CAPABILITIES ppc;
            
            if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(POWER_CAPABILITIES)) ) {
                bRc = FALSE;
                dwErr = ERROR_INVALID_PARAMETER;
                break;
            }
            
            ppc = (PPOWER_CAPABILITIES)pBufOut;
            
            memset(ppc, 0, sizeof(POWER_CAPABILITIES));

            // support D0, D4
            ppc->DeviceDx = DX_MASK(D0)|DX_MASK(D4);

			DEBUGMSG(ZONE_FUNCTION, (TEXT("WAVE: IOCTL_POWER_CAPABILITIES = 0x%x\r\n"), ppc->DeviceDx));
			RETAILMSG(DBG_WAV,(TEXT("WAVDEV::IOCTL_POWER_CAPABILITIES\r\n")));
			
            
            *pdwActualOut = sizeof(POWER_CAPABILITIES);
            
        } break;
        
     	case IOCTL_POWER_SET:
			
			CEDEVICE_POWER_STATE NewDx;

			if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) )
			{
				bRc = FALSE;
				dwErr = ERROR_INVALID_PARAMETER;
				break;
			}

			NewDx = *(PCEDEVICE_POWER_STATE)pBufOut;

			RETAILMSG(1, (TEXT("[A_HW] IOControl(IOCTL_POWER_SET) : D%u => D%u \r\n"), m_Dx, NewDx));

			if ( VALID_DX(NewDx) )
			{
				// grab the CS since the normal Xxx_PowerXxx can not.
				Lock();
				switch ( NewDx )
				{
					case D0:
						if (m_Dx != D0)
						{
						    	m_Dx = D0;

						    	// Codec Power On, if Off
							if (bIdlePwrDown == TRUE)				// When Codec is off,
							{
								RETAILMSG(1, (TEXT("[A_HW] IOControl : Turning Codec On\r\n")));


								/*g_pCLKPWRreg->CLKSRC = g_pCLKPWRreg->CLKSRC & ~(0x3<<14); //clock from Divided EPLL
								g_pIISregs->IISMOD = g_pIISregs->IISMOD & ~(0x3<<10) | (0x01<<10);	//clock from EPLL*/
								g_pIISregs->IISMOD = g_pIISregs->IISMOD & ~(0x3<<10);	// PCLK
								//g_pCLKPWRreg->CLKCON |= IIS_INTERNAL_CLOCK_ENABLE;		



								InitCodec();

								bIdlePwrDown = FALSE;				// Then, Codec is on
							}

						    	dwErr = GetSystemPowerState(wPState, 20, &dFlag);
						    	RETAILMSG(1, (TEXT("[A_HW] IOControl : System Power State - %s \r\n"),wPState));

							//bPowerSet = TRUE;		// for logo test (unattended mode)
						}
						break;

					default:
						if (m_Dx != (_CEDEVICE_POWER_STATE)D4)
						{
							m_Dx = (_CEDEVICE_POWER_STATE)D4;

							dwErr = GetSystemPowerState(wPState, 20, &dFlag);
						    	RETAILMSG(1, (TEXT("[A_HW] IOControl : System Power State - %s \r\n"),wPState));
							AudioMute((DMA_CH_OUT | DMA_CH_MIC), TRUE);
							
							if(m_OutputDMARunning && !bClosing && (_tcscmp(wPState, _T("unattended")) != 0))
							{
								bDoingSuspend = TRUE;
								RETAILMSG(1, (TEXT("[A_HW] IOControl : going into Suspend state\r\n")));
							}

							bClosing = FALSE;
							//bPowerSet = FALSE;		// for logo test (unattended mode)
						}
						break;
				}

				// return our state
				*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;

				Unlock();

				*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
			}
			else
			{
				bRc = FALSE;
				dwErr = ERROR_INVALID_PARAMETER;
			}

			break;

		case IOCTL_POWER_GET:
			if ( !pdwActualOut || !pBufOut || (dwLenOut < sizeof(CEDEVICE_POWER_STATE)) )
			{
				bRc = FALSE;
				dwErr = ERROR_INVALID_PARAMETER;
				break;
			}

			*(PCEDEVICE_POWER_STATE)pBufOut = m_Dx;

			RETAILMSG(1, (TEXT("WAVEDEV: IOCTL_POWER_GET: D%u \r\n"), m_Dx));

			*pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
			break;
            
        default:
            bRc = FALSE;
            dwErr = ERROR_INVALID_FUNCTION;
            DEBUGMSG (ZONE_FUNCTION, (TEXT(" Unsupported ioctl 0x%X\r\n"), dwCode));
            break;            
    }
    
    if ( !bRc ) {
        SetLastError(dwErr);
    }
    
    return(bRc);
}

⌨️ 快捷键说明

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