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

📄 hwctxt.cpp

📁 smdk2440A的WINCE5.0的BSP
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        break;
    case DMA_DONEA|DMA_DONEB:
        // Load A, then B
        BytesTransferred = TransferInputBuffer(IN_BUFFER_A);
		BytesTransferred += TransferInputBuffer(IN_BUFFER_B);
		break;
        // fall through
    case DMA_DONEB|DMA_BIU: // This should never happen!
    case DMA_DONEB:
        // 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)
    {
        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);

	DWORD	dwCause;					

	dTimeoutval1 = INFINITE;

    while(TRUE)
    {
		dwCause = WaitForSingleObject(m_hAudioInterrupt, dTimeoutval1);
		
		if(dwCause == WAIT_OBJECT_0)
		{
			dmaInterruptSource = 0;
			dTimeoutval1 = 4000;
			//----- 1. Grab the lock -----
			Lock();

			if (IsPlaying) 
			{
				RETAILMSG(1,(_T("IsPlaying = TRUE\r\n")));
				StartOutputDMA();
				IsPlaying = 0;
			}
	
			__try
			{

				//----- 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.

				if( s2440INT->INTMSK & (1 << IRQ_DMA1) ){
					dmaInterruptSource |= DMA_CH_MIC;								// Input DMA is supported...
			    	//----- 2. Acknowledge the DMA interrupt -----
			    	InterruptDone(m_dwSysintrInput);
				}
			
				if( s2440INT->INTMSK & (1 << IRQ_DMA2) ){
					dmaInterruptSource |= DMA_CH_OUT;								// Output DMA is supported...
			    	//----- 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) != 0)
				{
					//----- 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
						SELECT_AUDIO_DMA_INPUT_BUFFER_B();
						DEBUGMSG(ZONE_FUNCTION,(TEXT("1\n")));
					}else
					{
						m_InputDMAStatus &= ~DMA_STRTA;							// Buffer A just completed...
						m_InputDMAStatus |= DMA_DONEA;

						m_InputDMAStatus |= DMA_BIU;							// Buffer B is in use
						SELECT_AUDIO_DMA_INPUT_BUFFER_A();
						DEBUGMSG(ZONE_FUNCTION,(TEXT("2\n")));
					}
				
					//----- 6. Retrieve the next chunk of recorded data from the non-playing buffer -----
					InputTransferred = TransferInputBuffers(m_InputDMAStatus);			
				}

				//----- 7. Handle any interrupts on the output source -----
				//		   NOTE: The InterruptDone() call below automatically clears the interrupt.
				if ((dmaInterruptSource & DMA_CH_OUT) != 0)
				{	
					if (m_OutputDMARunning == FALSE && bIdlePwrDown==FALSE)			// to prevent the Hopper failure (XXXXXXX..) + Sus/Resume Problem
					{
						RETAILMSG(DBG_WAV, (TEXT("[A_HW] InterruptThread : Interrupt after DMA ended!")));
						StopOutputDMA();
					}
					else if (m_OutputDMARunning == FALSE)
					{
						RETAILMSG(DBG_WAV, (TEXT("[A_HW] InterruptThread : What the fuck!\r\n")));
					}
					else
					{
						//----- 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
					
							delay_count = 0;
							while((g_pDMAregs->DSTAT2&0xfffff)==0);//{
	        				//if( delay_count++ > DELAY_COUNT )	break;
	        				//} 						
							SELECT_AUDIO_DMA_OUTPUT_BUFFER_B();		// charlie. B => A
						}else
						{
							m_OutputDMAStatus &= ~DMA_STRTA;						// Buffer B just completed...
							m_OutputDMAStatus |= DMA_DONEA;

							m_OutputDMAStatus |= DMA_BIU;							// Buffer A is in use
			
							delay_count = 0;			
							while((g_pDMAregs->DSTAT2&0xfffff)==0);//{
	        				//if( delay_count++ > DELAY_COUNT )	break;
	        				//}						
							SELECT_AUDIO_DMA_OUTPUT_BUFFER_A();		// charlie. B => A
						}
					//----- 9. Fill the non-playing buffer with the next chunk of audio data to play -----
					OutputTransferred = TransferOutputBuffers(m_OutputDMAStatus);			
					}
				}

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

		//----- 10. Give up the lock ----- 
		Unlock();
	}
	else if (dwCause == WAIT_TIMEOUT && !m_OutputDMARunning && !m_InputDMARunning)// && m_Dx == D4)		// 5 sec timeout event occurred
		{
			Lock();

			RETAILMSG(DBG_WAV, (TEXT("[A_HW] InterruptThread Timeout : %d msec\r\n"), dTimeoutval1));
			CodecPowerDown();

			dTimeoutval1 = INFINITE;				// reset timeout until DMA interrupt occurs
			bIdlePwrDown = TRUE;					// Codec is off
			RETAILMSG(DBG_WAV, (TEXT("[A_HW] InterruptThread : bIdlePwrDown = TRUE\r\n")));

			Unlock();
		}
		else
		{
			RETAILMSG(1, (TEXT("[A_HW] InterruptThread : Exit %d, Cause %d\r\n"),GetLastError(),dwCause));
		}
	}	  
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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)
{
	static DWORD dwActiveChannel = 0;
	
	//if(!m_InputDMARunning && !m_OutputDMARunning)
	{
		if(bMute)
		{
			WriteL3Addr(0x14);
			WriteL3Data(0xa4,0);
		}
		else
		{
			WriteL3Addr(0x14);
			WriteL3Data(0xa0,0);
		}
	}			
	
	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_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->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 + -