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

📄 hwctxt.cpp

📁 基于WINCE 的音频驱动源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	g_pIOPregs = (volatile S3C2440A_IOPORT_REG*)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (!g_pIOPregs)
	{
		DEBUGMSG(1, (TEXT("IOPreg: VirtualAlloc failed!\r\n")));
		return(FALSE);
	}
	if (!VirtualCopy((PVOID)g_pIOPregs, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
	{
		DEBUGMSG(1, (TEXT("IOPreg: VirtualCopy failed!\r\n")));
		return(FALSE);
	}

	g_pDMAregs = (volatile S3C2440A_DMA_REG*)VirtualAlloc(0, sizeof(S3C2440A_DMA_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (!g_pDMAregs)
	{
		DEBUGMSG(1, (TEXT("DMAreg: VirtualAlloc failed!\r\n")));
		return(FALSE);
	}
	if (!VirtualCopy((PVOID)g_pDMAregs, (PVOID)(S3C2440A_BASE_REG_PA_DMA >> 8), sizeof(S3C2440A_DMA_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
	{
		DEBUGMSG(1, (TEXT("DMAreg: VirtualCopy failed!\r\n")));
		return(FALSE);
	}

	s2440INT = (volatile S3C2440A_INTR_REG*)VirtualAlloc(0, sizeof(S3C2440A_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (!g_pDMAregs)
	{
		DEBUGMSG(1, (TEXT("INTreg: VirtualAlloc failed!\r\n")));
		return(FALSE);
	}
	if (!VirtualCopy((PVOID)s2440INT, (PVOID)(S3C2440A_BASE_REG_PA_INTR >> 8), sizeof(S3C2440A_INTR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
	{
		DEBUGMSG(1, (TEXT("INTreg: VirtualCopy failed!\r\n")));
		return(FALSE);
	}

	g_pCLKPWRreg = (volatile S3C2440A_CLKPWR_REG*)VirtualAlloc(0, sizeof(S3C2440A_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (!g_pCLKPWRreg)
	{
		DEBUGMSG(1, (TEXT("DMAreg: VirtualAlloc failed!\r\n")));
		return(FALSE);
	}
	if (!VirtualCopy((PVOID)g_pCLKPWRreg, (PVOID)(S3C2440A_BASE_REG_PA_CLOCK_POWER >> 8), sizeof(S3C2440A_CLKPWR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
	{
		DEBUGMSG(1, (TEXT("DMAreg: VirtualCopy failed!\r\n")));
		return(FALSE);
	}
   
    PowerUp();

	return(TRUE);
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		Deinit()

Description:	Deinitializest the hardware: disables DMA channel(s), 
				clears any pending interrupts, powers down the audio
				codec chip, etc.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::Deinit()
{
	//----- 1. Disable the input/output channels -----
//	AUDIO_IN_DMA_DISABLE();
	AUDIO_OUT_DMA_DISABLE();

	//----- 2. Disable/clear DMA input/output interrupts -----
	AUDIO_IN_CLEAR_INTERRUPTS();
	AUDIO_OUT_CLEAR_INTERRUPTS();

	//----- 3. Turn the audio hardware off -----
    AudioMute(DMA_CH_OUT | DMA_CH_MIC, TRUE);

    //----- 4. Unmap the control registers and DMA buffers -----
    UnmapRegisters();
	UnmapDMABuffers();

    return TRUE;
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		UnmapRegisters()

Description:	Unmaps the config registers used by both the SPI and
				I2S controllers.

Notes:			The SPI and I2S controllers both use the GPIO config
				registers, so these MUST be deinitialized LAST.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::UnmapRegisters()
{
	return TRUE;
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		MapDMABuffers()

Description:	Maps the DMA buffers used for audio input/output
				on the I2S bus.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::MapDMABuffers()
{
    PBYTE pVirtDMABufferAddr = NULL;
    DMA_ADAPTER_OBJECT Adapter;


    memset(&Adapter, 0, sizeof(DMA_ADAPTER_OBJECT));
    Adapter.InterfaceType = Internal;
    Adapter.ObjectSize = sizeof(DMA_ADAPTER_OBJECT);

    // Allocate a block of virtual memory (physically contiguous) for the DMA buffers.
    //
    pVirtDMABufferAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter, (AUDIO_DMA_PAGE_SIZE * 4), &g_PhysDMABufferAddr, FALSE);
    if (pVirtDMABufferAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("WAVEDEV.DLL:HardwareContext::MapDMABuffers() - Failed to allocate DMA buffer.\r\n")));
        return(FALSE);
    }

    // Setup the DMA page pointers.
    // NOTE: Currently, input and output each have two DMA pages: these pages are used in a round-robin
    // fashion so that the OS can read/write one buffer while the audio codec chip read/writes the other buffer.
    //
    m_Output_pbDMA_PAGES[0] = pVirtDMABufferAddr;
    m_Output_pbDMA_PAGES[1] = pVirtDMABufferAddr + AUDIO_DMA_PAGE_SIZE;
    m_Input_pbDMA_PAGES[0]  = pVirtDMABufferAddr + (2 * AUDIO_DMA_PAGE_SIZE);
    m_Input_pbDMA_PAGES[1]  = pVirtDMABufferAddr + (3 * AUDIO_DMA_PAGE_SIZE);

    return(TRUE);
	
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		UnmapDMABuffers()

Description:	Unmaps the DMA buffers used for audio input/output
				on the I2S bus.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::UnmapDMABuffers()
{
	if(m_Output_pbDMA_PAGES[0])
	{
		VirtualFree((PVOID)m_Output_pbDMA_PAGES[0], 0, MEM_RELEASE);
	}

	return TRUE;
}

BOOL HardwareContext::Codec_channel()
{

    UCHAR status = UDA1341_STATUS_B | UDA1341_STATUS_IGS; //enable 6dB mic boost
    // which parts to turn on?
    if (m_InputDMARunning) {
        status |= UDA1341_STATUS_PWR_ADC; // turn on ADC
    }
    if (m_OutputDMARunning) {
        status |= UDA1341_STATUS_PWR_DAC; // turn on DAC
    }

    //****** Port B Initialize *****
    g_pIOPregs->GPBDAT |= L3M|L3C;	//start condition : L3M=H, L3C=H
    g_pIOPregs->GPBUP  |= 0x1c;	//pull-up disable
    g_pIOPregs->GPBCON = ((g_pIOPregs->GPBCON & 0x3ffc0f) | 0x000150);
	

	WriteL3Addr(UDA1341_ADDR_STATUS);
    WriteL3Data(status, 0);

    return(TRUE);
}

MMRESULT HardwareContext::SetOutputGain (DWORD dwGain)
{
    m_dwOutputGain = dwGain & 0xffff; // save off so we can return this from GetGain - but only MONO
    // convert 16-bit gain to 5-bit attenuation
    UCHAR ucGain;
    if (m_dwOutputGain == 0) {
        ucGain = 0x3F; // mute: set maximum attenuation
    }
    else {
        ucGain = (UCHAR) ((0xffff - m_dwOutputGain) >> 11); // codec supports 64dB attenuation, we'll only use 32
    }
    ASSERT((ucGain & 0xC0) == 0); // bits 6,7 clear indicate DATA0 in Volume mode.

    WriteL3Addr(UDA1341_ADDR_DATA0);
    WriteL3Data(ucGain, 0); 

    return MMSYSERR_NOERROR;
}

MMRESULT HardwareContext::SetOutputMute (BOOL fMute)
{
    m_fOutputMute = fMute;

    WriteL3Addr(UDA1341_ADDR_DATA0);
    WriteL3Data(fMute ? 0x84 : 0x80, 0); // DATA0: 0x80 + fMute << 2

    return MMSYSERR_NOERROR;
}

BOOL HardwareContext::GetOutputMute (void)
{
    return m_fOutputMute;
}

DWORD HardwareContext::GetOutputGain (void)
{
    return m_dwOutputGain;
}

BOOL HardwareContext::GetInputMute (void)
{
    return m_fInputMute;
}

MMRESULT HardwareContext::SetInputMute (BOOL fMute)
{
    m_fInputMute = fMute;
    return m_InputDeviceContext.SetGain(fMute ? 0: m_dwInputGain);
}

DWORD HardwareContext::GetInputGain (void)
{
    return m_dwInputGain;
}

MMRESULT HardwareContext::SetInputGain (DWORD dwGain)
{
    m_dwInputGain = dwGain;
    if (! m_fInputMute) {
        m_InputDeviceContext.SetGain(dwGain);
    }
    return MMSYSERR_NOERROR;
}


/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		InitCodec()

Description:	Initializes the audio codec chip.

Notes:			The audio codec chip is intialized for output mode
				but powered down.  To conserve battery life, the chip
				is only powered up when the user starts playing a 
				file.

				Specifically, the powerup/powerdown logic is done 
				in the AudioMute() function.  If either of the 
				audio channels are unmuted, then the chip is powered
				up; otherwise the chip is powered own.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::InitCodec()
{
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("+++InitCodec\n")));

    //****** Port B Initialize *****
    g_pIOPregs->GPBDAT |= L3M|L3C;	//start condition : L3M=H, L3C=H
    g_pIOPregs->GPBUP  |= 0x1c;	//pull-up disable
    g_pIOPregs->GPBCON = ((g_pIOPregs->GPBCON & 0x3ffc0f) | 0x000150);
	

    // Reset codec internal registers by toggling the status register reset bit
    WriteL3Addr(UDA1341_ADDR_STATUS);
    WriteL3Data(UDA1341_STATUS_RESET | UDA1341_STATUS_CLK384,0);

    WriteL3Addr(UDA1341_ADDR_STATUS);
    WriteL3Data(UDA1341_STATUS_CLK384,0);

    // set default gain, power state
    WriteL3Addr(UDA1341_ADDR_STATUS);
    WriteL3Data(UDA1341_STATUS_B | UDA1341_STATUS_IGS | UDA1341_STATUS_PWR_DAC,0);

    // extended address:
	WriteL3Addr(UDA1341_ADDR_DATA0);
	WriteL3Data(0xC2,0);       //11000,010  : DATA0, Extended addr(010) 
	WriteL3Data(0xef,0);       //111,011,11 : DATA0, MS=+9dB, MixerMode=both(1) 

    // disable AGC
	WriteL3Addr(UDA1341_ADDR_DATA0);
	WriteL3Data(0xC4,0);       //11000,100  : DATA0, Extended addr(100) 
	WriteL3Data(0xe0,0);       //111,000,00 : DATA0, AGC=Off, IG[0,1]=0

	WriteL3Addr(UDA1341_ADDR_DATA0);
	WriteL3Data(0xC4,0);       //11000,101  : DATA0, Extended addr(101) 
	WriteL3Data(0xe8,0);       //111,01000 : DATA0, IG[6:2]=01000

	return(TRUE);
}



/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:		InitOutputDMA()

Description:	Initializes the DMA channel for output.

Notes:			DMA Channel 2 is used for transmitting output sound
				data from system memory to the I2S controller.

Returns:		Boolean indicating success
-------------------------------------------------------------------*/
BOOL HardwareContext::InitOutputDMA()
{
	
	//----- 1. Initialize the DMA channel for output mode and use the first output DMA buffer -----
    if (!g_PhysDMABufferAddr.LowPart)
    {
        DEBUGMSG(TRUE, (TEXT("ERROR:HardwareContext::InitOutputDMA: Invalid DMA buffer physical address.\r\n")));
        return(FALSE);
    }
    g_pDMAregs->DISRC2	= (int)(g_PhysDMABufferAddr.LowPart); 
    g_pDMAregs->DISRCC2 &= ~(SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);				// Source is system bus, increment addr

    //----- 2. Initialize the DMA channel to send data over the I2S bus -----
    g_pDMAregs->DIDST2	= (int)(S3C2440A_BASE_REG_PA_IISBUS+0x10); 
    g_pDMAregs->DIDSTC2 |= (DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS);	// Dest is  periperal bus, fixed addr

	//----- 3. Configure the DMA channel's transfer characteristics: handshake, sync PCLK, interrupt, -----
	//		   single tx, single service, I2SSDO, I2S request, no auto-reload, half-word, tx count
	g_pDMAregs->DCON2	= (  HANDSHAKE_MODE | GENERATE_INTERRUPT | I2SSDO_DMA2 | DMA_TRIGGERED_BY_HARDWARE 
                           | TRANSFER_HALF_WORD | (AUDIO_DMA_PAGE_SIZE / 2) );
	
	//----- 4. Reset the playback pointers -----
	AUDIO_RESET_PLAYBACK_POINTER();
	
	DEBUGMSG(ZONE_FUNCTION,(TEXT("---InitOutputDMA\n")));

	return TRUE;
}


⌨️ 快捷键说明

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