はじめまして。(株)ラングの石田と申します。
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);
}