[H8-ML(1872)] DMAのチャネルAとB
From: Akiya ISHIDA <ishida@xxxxxxxxxx>
Date: 2002年05月23日(木)17時48分52秒
はじめまして。(株)ラングの石田と申します。

H8初心者です。

H8S/2655の内蔵DAC/ADCからDMAを使ってデータを送り込み/吸い出したいので
すが、DMAのチャネル*Bでは動くのに、チャネル*Aでは動かないという症状に
悩まされています。チャネル0でも1でも、Bでは動くのにAでは動きません。

どうもマニュアル見ても何が悪いのか良く分からないので、質問させて下さい。

簡単なサンプルコードを添付します。イエローソフトの開発環境で試しています。

a2db.c が DMAチャネル0Bと1Bを使うもので動くバージョン、
a2da.c が DMAチャネル0Aと1Aを使う、動かないバージョンです。

どちらも、メモリに、バッファを2つ用意して、
	バッファ1のデータをDACに送り、
	ADCからのデータをバッファ2に書き込む
ということを2本のDMAを使って、同時に行ないます。
ADCのDMAが終った所で割り込みをかけ、バッファを入れ換えて上記繰り返す
というプログラムです。

チャネルAの方は何が悪いのでしょう。
(きっと何か見落としているのですよね…)
----
(株)ラング      石田 秋也 / ishida@xxxxxxxxxx




======= a2db.c ============= 動くバージョン ======
#include <stdio.h>
#include <string.h>
#include "h8s2655.h"
unsigned char sync, buf1[1400],buf2[1400];
void interrupt TGI2A() {
	TIER2 &= ~0x01;		
	TSR2 &= ~0x01;		
    TIER2 |= 0x01;		
}
void interrupt ADI() {
	ADCSR&=0x7F;		//clear ADI flag
}
void interrupt DEND1B() {	// the DMA process of ADC finished
	DMABCR&=~0x8;		//clear DEND1B interrupt flag
	DMABCR&=~0x20;		//stop DMA channel 0B operation (terminating)
	MAR0B=MAR1B-1024;
	ETCR0B=1024;
	sync=(sync==1)?2:1;
	MAR1B=(sync==1)?(unsigned long)buf2:(unsigned long)buf1;
	ETCR1B=1024;
	DMABCR|=0x88;		//start DMA channel 1B
	DMABCR|=0x20;		//start DMA channel 0B operation, /////dend0a interrupt enabled
}
main () {
	#asm	ANDC	#H'7F, CCR		//Enabling interrupts
	PGDDR=0xFF;			//for CS
	MSTPCR&=0xFBFF;		//clear DAC stop mode
	DACR=0xC0;			//Channel 0

	MSTPCR &= 0xDFFF;	//clear 16 bit TPU stop mode
	TCR2=0x20;			//Counter Clearing by TGP2A, Clock Rising Edge, internal clock
	TIER2=0x41;			//Enable TGI2A interrupt
	TGR2A=2470;			//8KHz

	MSTPCR&=0x7FFF;		//clear DMA stop mode
	DMAWER|=0x2;		//enable write to registers DMA channel 0B
	DMABCR=0x200;		//short address mode, DTA0B enabled
	DMACR0B=0xA;		//byte size, sequential mode, by TPU2A interrupt, MAR -> IOAR, MAR is incremental
	IOAR0B=0xFFA4;		//address of DADR0

	DMAWER|=0x8;			//enable write to registers channel 1B
	DMABCR|=0x800;		//short address mode, DTA1B, 
	IOAR1B=0xFF94;		//address of ADDRC
	DMACR1B=0x11;		//byte size, sequential mode, by ADI, IOAR -> MAR, MAR is incremental
	ETCR1B=1024;
	sync=1;
	MAR1B=(unsigned long)buf1;
	DMABCR|=0x88;		//start DMA channel 1B with DEND1B interruption
	
	MSTPCR&=0xFDFF;		//clear ADC stop mode
	ADCR=0x60;			//AD start by 8 bit timer, single mode
	ADCSR=0x52;			//select mode, ADI enabled, channel 2

	MSTPCR&=0xEFFF;		//clear 8 bit timer stop mode
	T8CR0=0xA;			//Compare with A and clear, internal clock/8192
	T8CSR0=0x10;
	T8CORA0=39;			//8KHz
	TSTR|=0x4;
	while (1);
}

======= a2da.c ============= 動かないバージョン ======
#include <stdio.h>
#include <string.h>
#include "h8s2655.h"
unsigned char sync, buf1[1400],buf2[1400];
void interrupt TGI2A() {
	TIER2 &= ~0x01;		
	TSR2 &= ~0x01;		
    TIER2 |= 0x01;		
}
void interrupt ADI() {
	ADCSR&=0x7F;		//clear ADI flag
}
void interrupt DEND1A() {	// the DMA process of ADC finished
	DMABCR&=~0x4;		//clear DEND1A interrupt flag
	DMABCR&=~0x10;		//stop DMA channel 0A operation (terminating)
	MAR0A=MAR1A-1024;
	ETCR0A=1024;
	sync=(sync==1)?2:1;
	MAR1A=(sync==1)?(unsigned long)buf2:(unsigned long)buf1;
	ETCR1A=1024;
	DMABCR|=0x44;		//start DMA channel 1A
	DMABCR|=0x10;		//start DMA channel 0A operation, /////dend0a interrupt enabled
}
main () {
	#asm	ANDC	#H'7F, CCR		//Enabling interrupts
	PGDDR=0xFF;			//for CS
	MSTPCR&=0xFBFF;		//clear DAC stop mode
	DACR=0xC0;			//Channel 0
	
	MSTPCR &= 0xDFFF;	//clear 16 bit TPU stop mode
	TCR2=0x20;			//Counter Clearing by TGP2A, Clock Rising Edge, internal clock
	TIER2=0x41;			//Enable TGI2A interrupt
	TGR2A=2470;			//8KHz
	
	MSTPCR&=0x7FFF;		//clear DMA stop mode
	DMAWER|=0x1;		//enable write to registers DMA channel 0A
	DMABCR=0x100;		//short address mode, DTA0A enabled
	DMACR0A=0xA;		//byte size, sequential mode, by TPU2A interrupt, MAR -> IOAR, MAR is incremental
	IOAR0A=0xFFA4;		//address of DADR0
	
	DMAWER|=4;			//enable write to registers channel 1A
	DMABCR|=0x400;		//short address mode, DTA1A, 
	IOAR1A=0xFF94;		//address of ADDRC
	DMACR1A=0x11;		//byte size, sequential mode, by ADI, IOAR -> MAR, MAR is incremental
	ETCR1A=1024;		//1024
	sync=1;
	MAR1A=(unsigned long)buf1;
	DMABCR|=0x44;		//start DMA channel 1A with DEND1A interruption
	
	MSTPCR&=0xFDFF;		//clear ADC stop mode
	ADCR=0x60;			//AD start by 8 bit timer, single mode
	ADCSR=0x52;			//select mode, ADI enabled, channel 2
	
	MSTPCR&=0xEFFF;		//clear 8 bit timer stop mode
	T8CR0=0xA;			//Compare with A and clear, internal clock/8192
	T8CSR0=0x10;
	T8CORA0=39;			//8KHz
	TSTR|=0x4;
	while (1);
}
スレッド概略
[表示中](起点)
 └[1898(1)]


投稿順に移動
[←前の記事へ(P)]
[→次の記事へ(N)]


リスト表示へ
[このスレッド(T)]
[本記事の前後(L)]