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 + -
显示快捷键?