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

📄 ac97.c

📁 基于ADSP-BF535 USB驱动应用程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	}


/*------------------------------------------------------------
*	InitSPORT0
*
*	Parameters:  
*		None
*
*	Globals Used:
*		None
*
*	Description:
*		Initializes SPORT0 for AC-Link
*
*	Returns:
*		Nothing.
*
*------------------------------------------------------------*/
void InitSPORT0 (void)
	{

		SPORT0_TX_CONFIG_REG = 0;
	  asm("ssync;");

		SPORT0_RX_CONFIG_REG = 0;
	  asm("ssync;");

		SPORT0_MCMC1_REG = 0;
	  asm("ssync;");

		SPORT0_IRQSTAT_RX_REG = kIRQSTAT_RX; //bits are cleared by writing 1s to this register
	  asm("ssync;");

		SPORT0_IRQSTAT_TX_REG = kIRQSTAT_TX; //bits are cleared by writing 1s to this register
	  asm("ssync;");

		// Set SPORT0 frame sync divisor rx

		SPORT0_RFSDIV_REG = 0x00ff;// AC'97 48Khz Frame Sync with 12.288Mhz Input Clock 
	  asm("ssync;");

		// Set SPORT0 frame sync divisor tx

    SPORT0_TFSDIV_REG = 0x00ff;// AC'97 48Khz Frame Sync with 12.288Mhz Input Clock 
	  asm("ssync;");

    SPORT0_RSCLKDIV_REG = 0x0005;	// AC'97 48Khz Frame Sync with 12.288Mhz Input Clock??? 
	  asm("ssync;");

		SPORT0_RX_CONFIG_REG = kRX_CFG;
	  asm("ssync;");

		SPORT0_TX_CONFIG_REG = kTX_CFG;
	  asm("ssync;");


		// Enable MCM Transmit and Receive Channels 
		SPORT0_MTCS0_REG = 0xFFFF;	   	// Select 16 Channels for TX out of possibly 128				    
	  asm("ssync;");

		SPORT0_MTCS1_REG = 0;
	  asm("ssync;");
		SPORT0_MTCS2_REG = 0;
	  asm("ssync;");
		SPORT0_MTCS3_REG = 0;
	  asm("ssync;");
		SPORT0_MTCS4_REG = 0;
	  asm("ssync;");
		SPORT0_MTCS5_REG = 0;
	  asm("ssync;");
		SPORT0_MTCS6_REG = 0;
	  asm("ssync;");
		SPORT0_MTCS7_REG = 0;
	  asm("ssync;");

		SPORT0_MRCS0_REG = 0xFFFF;	   	// Select 16 Channels for RX out of possibly 128				    
	  asm("ssync;");

		SPORT0_MRCS1_REG = 0;
	  asm("ssync;");
		SPORT0_MRCS2_REG = 0;
	  asm("ssync;");
		SPORT0_MRCS3_REG = 0;
	  asm("ssync;");
		SPORT0_MRCS4_REG = 0;
	  asm("ssync;");
		SPORT0_MRCS5_REG = 0;
	  asm("ssync;");
		SPORT0_MRCS6_REG = 0;
	  asm("ssync;");
		SPORT0_MRCS7_REG = 0;
	  asm("ssync;");
		
		// Set MCM Configuration Reg 1 

		SPORT0_MCMC1_REG = kMCMC1;
	  asm("ssync;");

		// Set MCM Configuration Reg 2 

		SPORT0_MCMC2_REG = kMCMC2;
	  asm("ssync;");

}


/*------------------------------------------------------------
*	InitSPORT0DMA
*
*	Parameters:  
*		pTxBuffer - pointer to a 16byte buffer to hold transmit frame
*		pRxBuffer - pointer to a 16bite buffer to hold the receive frame
*
*	Globals Used:
*		None
*
*	Description:
*		Sets up the SPORT0 DMA to use AC-Link
*
*	Returns:
*		Nothing
*
*------------------------------------------------------------*/
void InitSPORT0DMA (void *pTxBuffer, void *pRxBuffer)
	{
		// set autobuffer mode
		SPORT0_CONFIG_DMA_TX_REG = kTxDAUTO;
	  asm("ssync;"); 


		SPORT0_START_ADDR_LO_TX_REG = LOWORD ((ULONG)pTxBuffer);
	  asm("ssync;"); 
		SPORT0_START_ADDR_HI_TX_REG = HIWORD ((ULONG)pTxBuffer);
	  asm("ssync;"); 


		SPORT0_COUNT_TX_REG = FRAME_BUFFER_LEN >> 1;
	  asm("ssync;"); 

		// SPORT0 DMA AUTOBUFFER RX 

		// set autobuffer mode
		SPORT0_CONFIG_DMA_RX_REG = ZET(bRxDAUTO,1);
	  asm("ssync;"); 

		SPORT0_START_ADDR_LO_RX_REG = LOWORD ((ULONG)pRxBuffer);
	  asm("ssync;"); 

		SPORT0_START_ADDR_HI_RX_REG = HIWORD ((ULONG)pRxBuffer);
	  asm("ssync;"); 

		SPORT0_COUNT_RX_REG = FRAME_BUFFER_LEN >> 1;
	  asm("ssync;"); 


		// ENABLE SPORT0 DMA and DIRECTION IN DMA CONFIGURATION REGISTER 

		// Enable and configure TX DMA 
		SPORT0_CONFIG_DMA_TX_REG = kTX_DMA_CFG;
	  asm("ssync;"); 

		// Enable and configure RX DMA
		SPORT0_CONFIG_DMA_RX_REG = kRX_DMA_CFG;		
	  asm("ssync;"); 

	}


/*------------------------------------------------------------
*	InitCodec
*
*	Parameters:  
*
*	Globals Used:
*		gpTxBuffer, gpRxBuffer, gInitCodecRegs, gCodecInitResults
*
*	Description:
*		This routine initializes the AC97 codec from the gInitCodecRegs
*		array, and stores the register values read back in gCodecInitResults
*
*	Returns:
*		Nothing
*
*------------------------------------------------------------*/
void InitCodec (void)
	{
		USHORT regVal, currentReg, interruptCount;

		//Enable SPORT0 RX
		SPORT0_RX_CONFIG_REG |= ZET (bRxRSPEN, 1);
		asm ("ssync;");

		//Enable SPORT0 TX
		SPORT0_TX_CONFIG_REG |= ZET (bTxTSPEN, 1);		// Enable SPORT0 TX 
		asm ("ssync;");


		// idle and ssync will put the processor
		// in "idle state". The processor remains here until a peripheral or
		// external device such as a SPORT or the RTC generates an interrupt
		// that requires servicing.

	 	asm ("idle;");    		// Wait a few RX interrupts to ensure 
	 	asm ("ssync;");    		// SPORT is up and running 
	 	asm ("idle;");    		// Wait a few RX interrupts to ensure 
	 	asm ("ssync;");    		// SPORT is up and running 

		//Wait for the codec to be ready
		while (!(gpRxBuffer[0] & ZET(bCodecRdy, 1)))
			{
				asm ("idle;");
				asm ("ssync;");
			}


		//Now initialize all the registers
		gpTxBuffer[oTagPhase >> 1] = kVldFrm; //Don't say we've got anything until we've placed the data
		for (currentReg = 0; currentReg < CODEC_REG_INIT_COUNT; currentReg++)
			{
				gpTxBuffer[oCmdAddrSlot >> 1] = gInitCodecRegs[currentReg * 2];
				asm ("ssync;");
				gpTxBuffer[oCmdDataSlot >> 1] = gInitCodecRegs[(currentReg * 2)+1];
				asm ("ssync;");
				//Now it's safe to say we've got address and data
				gpTxBuffer[oTagPhase >> 1] = kVldFrm|kVldCmd|kVldAddr; //we've got commands coming in
				asm ("ssync;");
				asm ("idle;");
				asm ("ssync;");
				asm ("idle;");
				asm ("ssync;");
				asm ("idle;");
				asm ("ssync;");
				asm ("idle;");
				asm ("ssync;");
				interruptCount = gInterruptCount;

				//Wait for at least one interrupt to be received
				while (interruptCount == gInterruptCount)
					{
						asm ("idle;");
						asm ("ssync;");
					}

				gpTxBuffer[oTagPhase >> 1] = kVldFrm; //Don't say we've got anything until we've placed the data
			}

		//Now read the values back...
		gpTxBuffer[oTagPhase >> 1] = kVldFrm; //Don't say we've got anything until we've placed the data
		for (currentReg = 0; currentReg < CODEC_REG_INIT_COUNT; currentReg++)
			{
				gpTxBuffer[oCmdAddrSlot >> 1] = gInitCodecRegs[currentReg * 2] | kAddrRead; //signal read request
				asm ("ssync;");

				//Now it's safe to say we've got address 
				gpTxBuffer[oTagPhase >> 1] = kVldFrm|kVldCmd; //we've got commands coming in
				asm ("ssync;");

				interruptCount = gInterruptCount;
				//Wait for at least one interrupt to be received
				while (interruptCount == gInterruptCount)
					{
						asm ("idle;");
						asm ("ssync;");
					}

				//Now wait for the data
				while ((!gpRxBuffer[0] & ZET(bCodecRdy, 1)) || (gpRxBuffer[oStatusAddrSlot>>1] != gInitCodecRegs[currentReg * 2]))
					{
						asm ("idle;");
						asm ("ssync;");
					}
				//It's here
				gCodecInitResults[currentReg] = gpRxBuffer[oStatusDataSlot >> 1];

				gpTxBuffer[oTagPhase >> 1] = kVldFrm; //Don't say we've got anything until we've placed the data
			}

		//That's all folks!
		return;

	}



/*------------------------------------------------------------
*	AC97_ISR
*
*	Parameters:  
*		r0x, r1x, r2x
*
*	Globals Used:
*		
*
*	Description:
*		The ISR to handle SPORT0 DMA Tx and Rx interrupts. 
*
*	Returns:
*		Nothing
*
*
*------------------------------------------------------------*/
EX_INTERRUPT_HANDLER  (AC97_ISR)
	{
		//USHORT rxStat;

		//rxStat = SPORT0_IRQSTAT_RX_REG;
		//asm ("ssync;");
		//txStat = SPORT0_IRQSTAT_TX_REG;
		//asm ("ssync;");
		// Clear RX and TX Interrupts 
		// (cleared by writing 1s to them)
		//rxStat = SPORT0_IRQSTAT_RX_REG;
		SPORT0_IRQSTAT_RX_REG = kIRQSTAT_RX;
		asm ("ssync;");
		//SPORT0_IRQSTAT_TX_REG = txStat;
		//asm ("ssync;");

		//if (((FRAME_BUFFER_LEN >> 1) - SPORT0_COUNT_RX_REG) == 0)
		if ((FRAME_BUFFER_LEN >> 1) == SPORT0_COUNT_RX_REG)
		//if (rxStat & ZET(bRxCOMPL,1))
			{
				gInterruptCount++;
		
				if (gCurrentAC97State == AC97_STATE_PLAY_DATA)
					{
						//ToDo: Fetch data from the supplier,
						//and put it into the TxBuffer
						//
						//gpTxBuffer[oTagPhase >> 1] = kVldFrm; //Don't say we've got anything until we've placed the data
						gpTxBuffer[oLeft >> 1] = *(PUSHORT)(&gDataBuffer[gDataBufferTail]);
						gDataBufferTail += 2;
						//if (gDataBufferTail >= MAX_DATA_BUFFER_SIZE)
						//	gDataBufferTail = (gDataBufferTail - MAX_DATA_BUFFER_SIZE);
						gpTxBuffer[oRght >> 1] = *(PUSHORT)(&gDataBuffer[gDataBufferTail]);
						//gpTxBuffer[oTagPhase >> 1] = kVldFrm | kVldLeft | kVldRight;
						gDataBufferTail += 2;
						if (gDataBufferTail >= MAX_DATA_BUFFER_SIZE)
							gDataBufferTail = (gDataBufferTail - MAX_DATA_BUFFER_SIZE);

					}
			}

	}




/*----------------------------------------------------------------------------------
* $Log: ac97.c,v $
* Revision 1.5  2003/01/16 23:54:39  Devendra
* - The volume registers were not being set properly.
*
* Revision 1.4  2003/01/16 19:01:09  Devendra
* Changed "exported" function names to include AC97 prefix.
* Added routine to set volume and mute registers.
* Change the code af SPORT0 ISR to make it consume lesser DSP cycles.
*
* Revision 1.3  2003/01/15 01:33:20  Devendra
* - Changed code reset sequence to light all the LEDs on Eagle-35 after the codec has been reset.
*
* Revision 1.2  2003/01/13 19:57:53  Devendra
* Changed the priorities of interrupts - now SPORT0 is ivg7, USB is ivg8
* Other fixes with interrupt handling.
* Removed divides (used for modulo add)  from the ISR
*
*
*---------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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