dmac_sample.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 283 行
C
283 行
/*************************************************************************************/
/* */
/* Copyright (C) 2005 Oki Electric Industry Co., LTD. */
/* */
/* System Name : ML674051/ML674061 series */
/* Module Name : DMAC Sample Functions */
/* File Name : dmac_sample.c */
/* Revision : 1.00 */
/* Date : 2005/02/18 */
/* */
/*************************************************************************************/
#include "ML674061.h"
#include "common.h"
#include "irq.h"
#ifdef __IAR__
#include "intrinsics.h"
#endif
/* DMAC channel base address */
#define DMAC_BASE0 0x7BE00100 /* DMAC CH0 base address */
#define DMAC_BASE1 0x7BE00200 /* DMAC CH1 base address */
/* DMAC channel registers (offset) */
#define MSK 0x0000 /* channel mask register */
#define TMOD 0x0004 /* transmit mode register */
#define SAD 0x0008 /* source data address register */
#define DAD 0x000c /* destination data address register */
#define SIZ 0x0010 /* transmit size register */
#define CINT 0x0014 /* clear interrupt register */
/* setting channel */
#define CH0_MODE 0x003b /* auto request, 16 bit transmission,
source data type(incremental address device),
destination data type(incremental address device),
cycle steal mode,
interrupt mask clear */
#define CH1_MODE 0x001b /* auto request, 16 bit transmission,
source data type(incremental address device),
destination data type(incremental address device),
burst mode,
interrupt mask clear */
static HWORD ch0_dest_buffer[2048] ;
static HWORD ch1_dest_buffer[2048] ;
/* transmit start address */
#define CH0_S_START_ADD 0x08000000 /* source data start address CH0 */
#define CH0_D_START_ADD ch0_dest_buffer /* destination data start address CH0 */
#define CH1_S_START_ADD 0x08001000 /* source data start address CH1 */
#define CH1_D_START_ADD ch1_dest_buffer /* destination data start address CH1 */
/* the number of times of transmission */
#define NUM_OF_TIME_CH0 2048 /* the number of times of transmission CH0 */
#define NUM_OF_TIME_CH1 2048 /* the number of times of transmission CH1 */
/* LED lighting pattern */
#define READ_ERR_CH0 LED_1 /* read cycle error CH0 */
#define READ_ERR_CH1 LED_2 /* read cycle error CH1 */
#define WRITE_ERR_CH0 LED_3 /* write cycle error CH0 */
#define WRITE_ERR_CH1 LED_4 /* write cycle error CH1 */
#define RR_ERR_BOTH LED_5 /* read cycle error CH0 & read cycle error CH1 */
#define WR_ERR_BOTH LED_6 /* write cycle error CH0 & read cycle error CH1 */
#define RW_ERR_BOTH LED_7 /* read cycle error CH0 & write cycle error CH1 */
#define WW_ERR_BOTH LED_8 /* write cycle error CH0 & write cycle error CH1 */
/* functions */
int main(void); /* main routine */
static void reg_irq_handler(void); /* registration of IRQ handler */
static void setup_dmac(UWORD,UWORD,UWORD,HWORD*,UWORD); /* setup Channel */
static void dmacCH0_handler(void); /* DMAC CH0 interrupt handler */
static void dmacCH1_handler(void); /* DMAC CH1 interrupt handler */
/* global variables */
static volatile unsigned int ch0_flag; /* end flag CH0(0: dma ch0 not end,
1: dma ch0 end) */
static volatile unsigned int ch1_flag; /* end flag CH1(0: dma ch1 not end,
1: dma ch1 end) */
static volatile unsigned int err_sta; /* error status(0x00: no error
0x01: read cycle error CH0,0x02: read cycle error CH1,
0x04: write cycle error CH0,0x08: write cycle error CH1,
0x03: read cycle error CH0 & read cycle error CH1,
0x06: write cycle error CH0 & read cycle error CH1,
0x09: read cycle error CH0 & write cycle error CH1,
0x0c: write cycle error CH0 & write cycle error CH1)*/
/****************************************************************************/
/* Entry point */
/* Function : main */
/* Parameters */
/* Input : Nothing */
/* Output : 0 */
/****************************************************************************/
int main(void)
{
/* initialize irq */
init_irq();
/* registration of IRQ handler */
reg_irq_handler();
/* initialize LED */
init_led(); /* set output mode */
led_on(LED_START_PATTERN); /* light LED start pattern */
/* initialize variables */
ch0_flag = 0;
ch1_flag = 0;
err_sta = 0x00;
/* the order of priority */
put_wvalue(DMAMOD,DMAMOD_FIX); /* priority of DMA channel : CH0 > CH1 */
/* setup DMAC CH0 */
setup_dmac(DMAC_BASE0,CH0_MODE,CH0_S_START_ADD,CH0_D_START_ADD,NUM_OF_TIME_CH0);
/* setup DMAC CH1 */
setup_dmac(DMAC_BASE1,CH1_MODE,CH1_S_START_ADD,CH1_D_START_ADD,NUM_OF_TIME_CH1);
/* enable IRQ */
#ifdef __IAR__
__enable_interrupt();
#else
irq_en();
#endif
/* DMA transmit start */
clr_wbit(DMACMSK0,(UWORD)DMACMSK_MSK); /* CH0 start */
clr_wbit(DMACMSK1,(UWORD)DMACMSK_MSK); /* CH1 start */
while((ch0_flag == 0)||(ch1_flag == 0 )) /* DMA transfer end ? */
;
/* end pattern */
switch(err_sta){
case (0x00): /* normal end */
led_on(LED_NORMAL_END_PATTERN);
break;
case (0x01): /* CH0 read cycle error */
led_on(READ_ERR_CH0);
break;
case (0x02): /* CH1 read cycle error */
led_on(READ_ERR_CH1);
break;
case (0x04): /* CH0 write cycle error */
led_on(WRITE_ERR_CH0);
break;
case (0x08): /* CH1 write cycle error */
led_on(WRITE_ERR_CH1);
break;
case (0x03): /* CH0 read cycle error & CH1 read cycle error */
led_on(RR_ERR_BOTH);
break;
case (0x06): /* CH0 write cycle error & CH1 read cycle error */
led_on(WR_ERR_BOTH);
break;
case (0x09): /* CH0 read cycle error & CH1 write cycle error */
led_on(RW_ERR_BOTH);
break;
case (0x0c): /* CH0 write cycle error & CH1 write cycle error */
led_on(WW_ERR_BOTH);
break;
default:
break;
}
put_wvalue(ILC0, 0x0); /* disable all interrupts */
put_wvalue(ILC1, 0x0); /* disable all interrupts */
#ifdef __IAR__
__disable_interrupt();
#else
irq_dis(); /* disable all interrupts */
#endif
return(0);
}
/****************************************************************************/
/* Setup of DMAC */
/* Function : setup_dmac(UWORD,UWORD,UWORD,UWORD,UWORD) */
/* Parameters */
/* Input : UWORD dmac_add ... dmac channel base address */
/* mode ... dmac setting mode */
/* s_add ... source data start address */
/* d_add ... destination data start address */
/* num_of_time ... number of time of transmit */
/* Output : Nothing */
/****************************************************************************/
void setup_dmac(UWORD dmac_add,UWORD mode,UWORD s_add,HWORD* d_add,UWORD num_of_time)
{
set_wbit((dmac_add + MSK),DMACMSK_MSK); /* DMA stop */
put_wvalue((dmac_add + CINT),0x00ff); /* end status clear */
/* setup mode */
put_wvalue((dmac_add + TMOD),mode);
put_wvalue((dmac_add + SAD),s_add); /* set source data start address */
put_wvalue((dmac_add + DAD),(UWORD)d_add); /* set destination data start address */
put_wvalue((dmac_add + SIZ),num_of_time); /* set the number of times
of transmission */
return;
}
/*****************************************************************************/
/* DMAC CH0 interrupt handler */
/* Function : dmacCH0_handler(void) */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/*****************************************************************************/
void dmacCH0_handler(void)
{
UWORD sta = get_wvalue(DMAINT);
set_wbit(DMACMSK0,DMACMSK_MSK); /* DMA CH0 stop */
put_wvalue(DMACCINT0,0x00ff); /* end status clear */
if(sta & DMAINT_ISTA0){ /* error end ? */
if(sta & DMAINT_ISTP0) /* when did the error occur? */
err_sta |= 0x04; /* write cycle error */
else
err_sta |= 0x01; /* read cycle error */
}
else
;
ch0_flag = 1;
return;
}
/*****************************************************************************/
/* DMAC CH1 interrupt handler */
/* Function : dmacCH1_handler(void) */
/* Parameters */
/* Input : Nothing */
/* Output : Nothing */
/*****************************************************************************/
void dmacCH1_handler(void)
{
UWORD sta= get_wvalue(DMAINT);
set_wbit(DMACMSK1,DMACMSK_MSK); /* DMA CH1 stop */
put_wvalue(DMACCINT1,0x00ff); /* end status clear */
if(sta & DMAINT_ISTA1){ /* error end ? */
if(sta & DMAINT_ISTP1) /* when did the error occur? */
err_sta |= 0x08; /* write cycle error */
else
err_sta |= 0x02; /* read cycle error */
}
else
;
ch1_flag = 1;
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_DMA1] = dmacCH1_handler;
/* setup interrupt level */
set_wbit(EXILCA, ILC_ILC24 & ILC_INT_LV7);/* dma handler(nIRQ[24]) -> level7 */
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?