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

📄 lib_audio.c

📁 关于测试at91sam9260的各种驱动和功能的测试源代码。
💻 C
字号:
/*************************************** Copyright (c) *************************************************
*
*			            POLAR STAR
*				   北天星国际有限公司
*				   http://www.po-star.com
*
*文 件 名: lib_audio.c    
*
*编译环境:ADS1.2
*
********************************************************************************************************/


#include "main.h"
#include "lib_audio.h"


#define DELAY			 		100000

AT91PS_WaveHeaderDESC 	sdram_file = (AT91PS_WaveHeaderDESC)AT91C_ATMEL_WAVE;
AT91PS_SSC				pSSC = AT91C_BASE_SSC0;

//*----------------------------------------------------------------------------
//* \fn    AT91F_SPI_CfgSPI
//* \brief Config SPI for 1MHz on NPCS0
//*----------------------------------------------------------------------------
void AT91F_SPI1_CfgSPI(void)
{
	AT91F_PIO_CfgPeriph(
		AT91C_BASE_PIOB, // PIO controller base address
		((unsigned int) AT91C_PB1_SPI1_MOSI) |
		((unsigned int) AT91C_PB3_SPI1_NPCS0) |
		((unsigned int) AT91C_PB0_SPI1_MISO) |
		((unsigned int) AT91C_PB2_SPI1_SPCK), // Peripheral A
		0); // Peripheral B

	// Configure PMC by enabling SSC1 clock
	AT91F_SPI1_CfgPMC();

	// Reset the SPI
	AT91F_SPI_Reset(AT91C_BASE_SPI1);

    // Configure SPI in Master Mode   
	AT91F_SPI_CfgMode(AT91C_BASE_SPI1, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | (AT91C_SPI_PCS0_AUDIODAC << 16) );

	// Configure SPI NPCS03
	AT91F_SPI_CfgCs(AT91C_BASE_SPI1, 0, AT91C_SPI_BITS_16 | (AT91C_SPI_DLYBS & 0x100000) |
					((AT91C_MASTER_CLOCK_FOR_I2S / AT91C_SPI_CLK_AUDIODAC) << 8));

    // Enable the SPI
    AT91F_SPI_Enable(AT91C_BASE_SPI1);
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_SpiWrite
//* \brief Set the PDC registers for a transfer
//*----------------------------------------------------------------------------
void AT91F_SpiWrite (unsigned short *rx_buf, unsigned short *tx_buf, int size)
{ 	
	int i;

	for(i=0;i<size;i++)
	{
		AT91C_BASE_SPI1->SPI_TDR = *tx_buf++;
		while((AT91C_BASE_SPI1->SPI_SR & AT91C_SPI_RDRF) != AT91C_SPI_RDRF);
		*rx_buf++ = AT91C_BASE_SPI1->SPI_RDR;
	}
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_InitDrivers
//* \brief This function initializes AIC and SSC1 in I2S mode
//*----------------------------------------------------------------------------
void AT91F_InitDrivers()
{
	int tmp;
	
	// ======================= Init SPI and at73c213 DAC ==========================

	// Init PLLA to 11.289MHz x 8 = 90.316MHz
/*	AT91C_BASE_CKGR->CKGR_PLLAR = (1<<29) | AT91C_CKGR_OUTA_0 | AT91C_CKGR_PLLACOUNT |\
								(AT91C_CKGR_MULA & (548<<16)) | (AT91C_CKGR_DIVA & 112);		// 90.349 MHz
																							
	// Wait for PLL stabilization LOCK bit in PMC_SR 
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA) && (tmp++ < DELAY) );
*/
	// Init PCK0 to PLLA/8 = 11.289MHz
	AT91F_PIOC_CfgPMC();
	AT91F_PIO_CfgPeriph(AT91C_BASE_PIOC, 0, AT91C_PC1_PCK0);
//	AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, AT91C_PMC_PCK0);
	AT91F_PMC_EnablePCK(AT91C_BASE_PMC, 0, AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK_8);

	// Select PLLA/2 for MCK to be synchronous with SSC
	// bit clock will be 11.289MHz/8 = 1.411MHz
	// FS freq will be 11.289/256 = 44.097 kHz
/*	AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK_2;
	
	// Wait until Master Clock is established
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY) );

	// Reinit SDRAM
	AT91F_InitSDRAM(AT91C_MASTER_CLOCK_FOR_I2S);

	// Reinit DBGU
 	AT91F_Configure_DBGU (AT91C_MASTER_CLOCK_FOR_I2S);
*/
	// Configure SPI clock
	AT91F_SPI1_CfgSPI();
	
	// Configure DAC
	// Write @0x10 => 0x00
	// Write @0x10 => 0x03 (deassert the reset)
	// Write @0x00 => 0x30 (precharge + master on)
	// Delay 500 ms
	// Write @0x0C => 0x01 (precharge off + master on)
	// Write @0x00 => 0x3c (ONLNOL and ONLONOR set to 1)
	
	// Write/read each register
	{
	unsigned short txbuf[18] = {0x1000,0x1003,0x0030};
	unsigned short rxbuf[18];
	int tempo = 10000000;
	int i;
	
	for (i=0;i<16;i++) rxbuf[i] = 0x0;
	
	AT91F_SpiWrite(rxbuf,txbuf,3);
	while(tempo--);

	txbuf[0] = 0x0c01;
	txbuf[1] = 0x8cff;
	
	AT91F_SpiWrite(rxbuf,txbuf,1);

	txbuf[0] = 0x003c;
	txbuf[1] = 0x80ff;
	
	AT91F_SpiWrite(rxbuf,txbuf,1);


	txbuf[0] = 0x0a00;
	txbuf[1] = 0x8aff;
	
	AT91F_SpiWrite(rxbuf,txbuf,1);
	
	// Read all regs
	for (i=0;i<18;i++) rxbuf[i] = 0x0;
	for (i=0;i<18;i++) txbuf[i] = 0x80ff + (i<<8);
	AT91F_SpiWrite(rxbuf,txbuf,18);
	
	rxbuf[0] = txbuf[0];

	}
	
	// ======================= Init SSC in I2S mode ==========================
	// Configure SSC0 PIOs
	AT91F_PIO_CfgPeriph(
		AT91C_BASE_PIOB, // PIO controller base address
		((unsigned int) AT91C_PB16_TK0     ) |
		((unsigned int) AT91C_PB18_TD0     ) |
		((unsigned int) AT91C_PB17_TF0     ), // Peripheral A
		0); // Peripheral B

//	AT91F_SSC0_CfgPIO();

	// Configure PMC by enabling SSC0 clock
	AT91F_SSC0_CfgPMC();
	
	// Configure SSC in I2S mode
	AT91F_SSC_Configure (pSSC,    // \arg pointer to a SSC controller
						AT91C_MASTER_CLOCK_FOR_I2S, // \arg master clock
						AT91C_WAV_FILE_SAMPLING_FREQ*(AT91C_I2S_NB_BITS_BY_SLOT*AT91C_I2S_NB_SLOT_BY_FRAME), // \arg baudrate
						0,
						0,
						AT91C_I2S_ASY_MASTER_TX_SETTING(AT91C_I2S_NB_BITS_BY_SLOT, AT91C_I2S_NB_SLOT_BY_FRAME),
 						AT91C_I2S_ASY_TX_FRAME_SETTING(AT91C_I2S_NB_BITS_BY_SLOT, AT91C_I2S_NB_SLOT_BY_FRAME)
	);	// End of SSC_Configure function

	// Disable PDC Rx and Tx
	AT91F_PDC_DisableTx ((AT91PS_PDC) &(pSSC->SSC_RPR));
	AT91F_PDC_DisableRx ((AT91PS_PDC) &(pSSC->SSC_RPR));

	// Enable Transmit
	AT91F_SSC_EnableTx (pSSC);
	
	// Disable all interrupts
	AT91F_SSC_DisableIt (pSSC, 0xFFFFFFFF);
	
	// Configure AIC controller to handle SSC interrupts
	AT91F_AIC_ConfigureIt (
		AT91C_BASE_AIC,                        // AIC base address
		AT91C_ID_SSC0,                         // System peripheral ID
		AT91C_IRQ_LEVEL_I2S,               	   // Max priority
		AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL, 	   // Level sensitive
		AT91F_ASM_I2S_Init_Handler );

	// Enable SSC interrupt in AIC
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SSC0);
		
	// Enable Interrupt
	AT91F_SSC_EnableIt (pSSC, AT91C_SSC_TXSYN);
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_CloseDrivers
//* \brief This function Close SSC1 in I2S mode and the AIC
//*----------------------------------------------------------------------------
void AT91F_CloseDrivers()
{
	// Disable Interrupt
	AT91F_SSC_DisableIt (pSSC, 0xFFFFFFFF);	

	// Disable SSC interrupt in AIC
	AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_SSC0);

	// Disable Transmit
	AT91F_SSC_DisableTx (pSSC);
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_TestAudio
//* \brief 
//*----------------------------------------------------------------------------
int AT91F_TestAudio()
{
	volatile unsigned int dummy;
	char message[1];

	// Wait message is displayed
	for (dummy = 0; dummy < 5000000; dummy++);

	// Init I2S
	AT91F_InitDrivers();

    AT91F_DBGU_Printk("\n\r-I- Step 11. SSC/I2S Stereo Audio DAC\n\r");
    AT91F_DBGU_Printk("-I- Press a key to stop the test...\n\r");			
	message[0] = AT91F_Wait4KeyPressed();

	AT91F_CloseDrivers();
	
	AT91F_DBGU_Printk("\r\n");

 	return 0;
}

⌨️ 快捷键说明

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