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