i2s_sample_master.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 262 行

C
262
字号
/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2005 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  ML67Q4051/ML67Q4061 series                         */
/*     Module Name  :  ML67Q4051/ML67Q4061 i2s sample program (Master)    */
/*     File   Name  :  i2s_sample_master.c                                */
/*     Revision     :  01.00                                              */
/*     Date         :  05/09/2005                                         */
/*                                                                        */
/**************************************************************************/
#include   "ml674061.h"
#include   "common.h"
#include   "irq.h"

#ifdef __IAR__
#include "intrinsics.h"
#endif

/* constants */
#define BUFF_SIZE		0x400
#define PORTSEL3_I2S	0x1540
#define	REF_FREQ_32K	0x250C3308	/* 32kHz */
#define	AUDIO_CLK_8192M	0x00190101	/* 8.192MHz */

/* functions */
int  main(void);				/* Main routine */
void init_i2s(void);			/* Initialize I2S */
void dmac_data_send(UWORD *);	/* I2S send process */
void reg_irq_handler(void);		/* Registration of IRQ Handler */
void dmacCH0_handler(void);		/* DMAC CH0 interrupt handler */
void setup_dmac(void);			/* setup dmac */
void wait_dmaend(void);			/* Waiting for DMA data transfer finishing */

/* global variables */
unsigned long I2S_SendData1[BUFF_SIZE];	/* Send buffer1 */
unsigned long I2S_SendData2[BUFF_SIZE];	/* Send buffer2 */
UBYTE led_pt;							/* LED pattern */
UHWORD err_status;						/* Error status */
volatile UHWORD end_flag;				/* Flag for Program end */

enum err_num {			/* Error number */
	NO_ERR, 			/* No error */
	DATA_SEND_ERR,		/* Data sending error */
	DATA_RECEIV_ERR		/* Data receiving error */
};

/******************************************************************/
/*  Entry point                                                   */
/*  Function : main (Master)                                      */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  0                                           */
/******************************************************************/
int main(void)
{
	UWORD  *tp = I2S_SendData1;
	
	init_irq();					/* initialize irq */
	reg_irq_handler();			/* register IRQ handlers */
	
	init_led();                 /* initialize led */
	led_on(LED_START_PATTERN);  /* light led start pattern */

	led_pt = LED_NORMAL_END_PATTERN;

	init_i2s();					/* initialize i2s */
	setup_dmac();				/* setup DMAC */
	
	#ifdef __IAR__                          /* Enable interrupts */
        __enable_interrupt();
        #else
        irq_en();
        #endif
	
	end_flag = 0;
	led_pt = LED_NORMAL_END_PATTERN;
	
	dmac_data_send(tp);			/* DMAC data transfer */
	set_wbit(I2SCONO, I2SCONO_TSET_ISRUN);	/* transmitter start */
	wait_dmaend();				/* Waiting for DMA data transfer finishing */

	if(err_status==NO_ERR)
	{
		end_flag = 0;
		tp = I2S_SendData2;
		dmac_data_send(tp);
		wait_dmaend();			/* Waiting for DMA data transfer finishing */
	}
	
	clr_wbit(I2SCONO, (UWORD)I2SCONO_TSET_ISRUN);	/* transmitter stop */
    #ifdef __IAR__
      __disable_interrupt();                            /* Disable Irqs */
    #else
    irq_dis();
    #endif
	led_on(led_pt);				/* turn on lower square LED */
	
	return 0;
}

/******************************************************************/
/*  Initialize I2S                                                */
/*  Function : init_i2s (Master)                                  */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void init_i2s(void)
{
	UHWORD  i;
	UWORD get_data, set_data;
	
	put_wvalue(PLL1, REF_FREQ_32K);		/* reference frequency 32kHz */
	put_wvalue(PLL2, AUDIO_CLK_8192M);	/* audio Clock 8.192MHz */
	
	get_data = get_wvalue(CLKCNT);
	set_data = ((get_data & 0xFFFFCFFF) | 0x00032000);
	put_wvalue(CLKCNT, set_data);		/* PLLB Output */
	
	/***********************************************************
	    Setup of I2S
	    I2SCON0_TSET_ISSCKF		32FS
	    I2SCONO_TSET_ISBIT		16bit
	    I2SCONO_TSET_AFO		I2S
	***********************************************************/
	put_wvalue(I2SCONO, 0x40);
	
	put_wvalue(I2SAFRO, 0x3E);	/* almost full threshold 62 */
	put_wvalue(I2SAERO, 0x20);	/* almost empty 32 */
	
	clr_wbit(I2SCLKO, (UWORD)I2SCLKO_TSET_ISMST);	/* master mode */
	set_wbit(I2SCLKO, I2SCLKO_TSET_ISCLR);	/* FIFO clear */
	
	set_wbit(PORTSEL3, PORTSEL3_I2S);	/* selection of a secondary function */
	set_wbit(LSICNT, 0x00000001);		/* SD Output */
	
	/***********************************************************
	    Clear send_buffer and err_status
	***********************************************************/
	for(i=0; i<BUFF_SIZE; i++)
	{
		I2S_SendData1[i] = i;
		I2S_SendData2[i] = i + (UWORD)0xF000;
	}
	I2S_SendData2[BUFF_SIZE-1] = 0;
	I2S_SendData2[BUFF_SIZE-2] = 0;

	err_status = NO_ERR;
	return;
}

/******************************************************************/
/*  I2S send                                                      */
/*  Function : dmac_data_send                                     */
/*      Parameters                                                */
/*          Input  :  source address                              */
/*          Output :  Nothing                                     */
/******************************************************************/
void dmac_data_send(UWORD * tp)
{
	put_wvalue(DMACSAD0, (UWORD)tp);	/* source address */
	put_wvalue(DMACSIZ0, BUFF_SIZE);	/* number of transmission */
	put_wvalue(DMACMSK0, 0x0);	/* channel mask cancel */
	put_wvalue(I2SIMRO, 0xF);	/* available DMA request transmission */

	return;
}

/****************************************************************************/
/*  Registration of IRQ Handler                                             */
/*  Function : reg_irq_handler                                              */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/*  Note : Initialize of IRQ needs to be performed before this process.     */
/****************************************************************************/
void reg_irq_handler(void)
{
	/* register IRQ handlers into handler table */
	IRQ_HANDLER_TABLE[INT_DMA0] = dmacCH0_handler;

	/* setup interrupt level */
	set_wbit(EXILCA, ILC_ILC24 & ILC_INT_LV7);	/* dma handler(nIRQ[24]) -> level7 */

	return;
}

/*****************************************************************************/
/*  DMAC CH0 interrupt handler                                               */
/*      Function : dmacCH0_handler(void)                                     */
/*          Parameters                                                       */
/*              Input  : Nothing                                             */
/*              Output : Nothing                                             */
/*****************************************************************************/
void dmacCH0_handler(void)
{
	UWORD sta = get_wvalue(DMAINT);
	
	put_wvalue(DMACMSK0, 0x1);		/* channel mask */
	set_wbit(I2SIMRO, 0x10);		/* DMA mask */
	put_wvalue(DMACCINT0, 0xFF);	/* end status clear */
	
    if((sta & DMAINT_ISTA0)==DMAINT_ISTA0)
    {
		if((sta & DMAINT_ISTP0)==DMAINT_ISTP0)
		{	/* write error */
			err_status = DATA_SEND_ERR;
			led_pt = LED_1;	/* turn on LED error */
		}
		else
		{	/* read error */
			err_status = DATA_RECEIV_ERR;
			led_pt = LED_2;	/* turn on LED error */
		}
	}
	
	end_flag = 1;
    return;
}

/******************************************************************/
/*  setup dmac                                                    */
/*  Function : setup_dmac                                         */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void setup_dmac(void)
{
	put_wvalue(DMARQCNT, 0x8);		/* I2S transfer */
	put_wvalue(DMACMSK0, 0x1);		/* channel mask */
	
	/***********************************************************
	    DMACTMOD0_ARQ		dreq transmit request
	    DMACTMOD0_TSIZ		half word
	    DMACTMOD0_SDP		source address increment
	    DMACTMOD0_DDP		destination address fixation
	    DMACTMOD0_BRQ		cycle steal mode
	    DMACTMOD0_IML		interruption mask
	***********************************************************/
	put_wvalue(DMACTMOD0, 0x2C);
	
	put_wvalue(DMACCINT0, 0xFF);			/* DMACCINT0 clear */
	put_wvalue(DMACDAD0, I2SFIFOO);		/* destination address */
	
	return;
}

/******************************************************************/
/*  wait DMA end                                                  */
/*  Function : wait_dmaend                                        */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void wait_dmaend(void)
{
	while(end_flag!=1)
		;	/* Waiting for DMA data transfer finishing */
}

⌨️ 快捷键说明

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