i2s_sample_slave.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 333 行
C
333 行
/**************************************************************************/
/* */
/* Copyright (C) 2005 Oki Electric Industry Co., LTD. */
/* */
/* System Name : ML67Q4051/ML67Q4061 series */
/* Module Name : ML67Q4051/ML67Q4061 i2s sample program (Slave) */
/* File Name : i2s_sample_slave.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 0x1500
#define TMRCYC (30) /* interval of timer interrupt (ms) */
#define SYSCLK (32) /* SYSCLK (MHz)*/
#define VALUE_OF_TMRLR /* reload value of timer */\
(65536 - (TMRCYC * SYSCLK * 1000) / 16)
#if ((VALUE_OF_TMRLR) < 0 || 0x10000 <= (VALUE_OF_TMRLR))
#error "Invalid value : VALUE_OF_TMRLR"
#endif
/* functions */
int main(void); /* Main routine */
void init_i2s(void); /* Initialize I2S */
void dmac_data_receiv(UWORD *); /* I2S receive process */
void reg_irq_handler(void); /* Registration of IRQ Handler */
void dmacCH0_handler(void); /* DMAC CH0 interrupt handler */
void timer_handler(void); /* System Timer handler */
void setup_dmac(void); /* setup dmac */
void setup_timer(void); /* Setup of timer */
void remained_data_read(void); /* Reading remained data */
/* global variables */
unsigned long I2S_ReceivData1[BUFF_SIZE]; /* Receive buffer1 */
unsigned long I2S_ReceivData2[BUFF_SIZE+10]; /* Receive buffer2 */
UBYTE led_pt; /* LED pattern */
UHWORD err_status; /* Error status */
volatile UHWORD end_flag; /* Flag for Program end */
UHWORD timeout_flag; /* Flag for Time Out */
static volatile int counter;
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 (Slave) */
/* Parameters */
/* Input : Nothing */
/* Output : 0 */
/******************************************************************/
int main(void)
{
UWORD *rp = I2S_ReceivData1;
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 */
setup_timer(); /* setup system timer */
set_wbit(I2SCONI, I2SCONI_RSET_ISRUN); /* receiver start */
end_flag = 0;
led_pt = LED_NORMAL_END_PATTERN;
#ifdef __IAR__ /* Enable interrupts */
__enable_interrupt();
#else
irq_en();
#endif
dmac_data_receiv(rp); /* DMAC data receiver */
if(err_status==NO_ERR)
{
if(timeout_flag==1)
{ /* Reading remained data */
timeout_flag = 0;
remained_data_read();
}
end_flag = 0;
rp = I2S_ReceivData2;
dmac_data_receiv(rp);
if(timeout_flag==1)
{ /* Reading remained data */
timeout_flag = 0;
remained_data_read();
}
}
#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 (Slave) */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/******************************************************************/
void init_i2s(void)
{
UHWORD i;
/***********************************************************
Setup of I2S
I2SCONI_TSET_ISSCKF 32FS
I2SCONI_TSET_ISBIT 16bit
I2SCONI_TSET_AFO I2S
***********************************************************/
put_wvalue(I2SCONI, 0x40);
put_wvalue(I2SAFRI, 0x20); /* almost full threshold 32 */
put_wvalue(I2SAERI, 0x01); /* almost empty 1 */
set_wbit(I2SCLKI, I2SCLKI_RSET_ISMST); /* slave mode */
set_wbit(I2SCLKI, I2SCLKI_RSET_ISCLR); /* FIFO clear */
set_wbit(PORTSEL3, PORTSEL3_I2S); /* selection of a secondary function */
/***********************************************************
Clear receive_buffer and err_status
***********************************************************/
for(i=0; i<BUFF_SIZE; i++)
{
I2S_ReceivData1[i] = 0xFF;
I2S_ReceivData2[i] = 0xFF;
}
err_status = NO_ERR;
return;
}
/******************************************************************/
/* I2S receive */
/* Function : dmac_data_receiv */
/* Parameters */
/* Input : destination address */
/* Output : Nothing */
/******************************************************************/
void dmac_data_receiv(UWORD * rp)
{
put_wvalue(DMACDAD0, (UWORD)rp); /* destination address */
put_wvalue(DMACSIZ0, BUFF_SIZE); /* number of transmission */
put_wvalue(DMACMSK0, 0x0); /* channel mask cancel */
put_wvalue(I2SIMRI, 0xF); /* available DMA request transmission */
counter = 0;
timeout_flag = 0;
put_wvalue(TMEN, 0x01); /* enable timer (write '1' in TMEN[0]) */
while(end_flag!=1)
{ /* Waiting for DMA data transfer finishing */
if(counter>200)
{
timeout_flag = 1;
break;
}
}
put_wvalue(TMEN, 0x0); /* disable timer (write '0' in TMEN[0])*/
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;
IRQ_HANDLER_TABLE[INT_SYSTEM_TIMER] = timer_handler;
/* setup interrupt level */
set_wbit(EXILCA, ILC_ILC24 & ILC_INT_LV7); /* dmac handler(nIRQ[24]) -> level7 */
set_wbit(ILC0, ILC0_ILR0 & ILC0_INT_LV1); /* timer handler(nIRQ[0]) -> level1 */
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(I2SIMRI, 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, 0x9); /* I2S reception(CH0) */
put_wvalue(DMACMSK0, 0x1); /* channel mask */
/***********************************************************
DMACTMOD0_ARQ dreq transmit request
DMACTMOD0_TSIZ half word
DMACTMOD0_SDP source address fixation
DMACTMOD0_DDP destination address increment
DMACTMOD0_BRQ cycle steal mode
DMACTMOD0_IML interruption mask
***********************************************************/
put_wvalue(DMACTMOD0, 0x34);
put_wvalue(DMACCINT0, 0xFF); /* DMACCINT0 clear */
put_wvalue(DMACSAD0, I2SFIFOI); /* source address */
return;
}
/****************************************************************************/
/* Setup of timer */
/* Function : setup_timer */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/****************************************************************************/
void setup_timer(void)
{
put_wvalue(TMEN, 0x0); /* disable timer (write '0' in TMEN[0])*/
put_wvalue(TMOVF, 0x1); /* clear overflow register (write '1' in TMOVF[0])*/
put_wvalue(TMRLR, VALUE_OF_TMRLR); /* set TMRLR */
return;
}
/*****************************************************************************/
/* System Timer handler */
/* Function : timer_handler */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/*****************************************************************************/
void timer_handler(void)
{
counter++;
put_wvalue(TMOVF, 0x01); /* clear TMOVF register (write '1' in TMOVF[0]) */
return;
}
/******************************************************************/
/* Reading remained data */
/* Function : remained_data_read */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/******************************************************************/
void remained_data_read(void)
{
UWORD data_size;
UWORD * rp;
put_wvalue(DMACMSK0, 0x1); /* channel mask */
set_wbit(I2SIMRI, 0x10); /* DMA mask */
data_size = (get_wvalue(I2SLRSI) & I2SLRSI_RFIFOLVL) >>8;
rp = (UWORD *)get_wvalue(DMACDAD0);
for(; data_size>0; rp++, data_size--)
{
*rp = get_wvalue(I2SFIFOI);
}
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?