アフィリエイト広告を利用しています
Ad×Ad


Ad×Adは表示されるだけで報酬がもらえます。
以下から登録すると100ptもらえます。
 → アドアド -あなたの街の無料広告サイト-
検索
最新記事

広告

posted by fanblog

2017年12月18日

modeequiv() について調べたこと(備忘録)

ソースコードは下記の通り。


void
modeequiv()
{
   static const struct eqdic_s {
       byte   tkn;
       byte   tdif;
       int    rnum;
       word   wu;
   } eqdic[] = {
       {20,  2,  52,  4000},
       {10,  4, 104,  4000},
       { 4, 10, 260, 10000},
       { 2, 20, 520, 20000},
   };
   const struct eqdic_s   *eq;
   int    realnum, i;
   byte   at, crcnt, tokadif, toka, tokanum;
   byte   ch, chnum, vh, adch, adchT;
   word   ui1, waituntil, sinterval;

   rminit(false);

   eq = &eqdic[oscspeed & 3];
   tokanum   = eq->tkn;
   waituntil = eq->wu;
   realnum   = eq->rnum;
   tokadif   = eq->tdif;
   sinterval = 40;      // 20us

   uartjob();

   // ADMUX reg values
   switch(oscinput) {
   default:
   case 0x00: adch = 0x61; chnum = 1;  break;
   case 0x01: adch = 0x62; chnum = 1;  break;
   case 0x02: adch = 0x61; chnum = 2;
       tokanum >>= 1;
       tokadif <<= 1;
       break;
   }
   adchT = 0x61 + (osctrig & 7);

   header(2, 0);
   // This data packet contines to MARC-A

   sinterval--;
   crcnt = 0;
   at = 0;
   for(toka = 0; toka < tokanum; toka++) {
       for(ch = 0; ch < chnum; ch++) {
           // reset and initialize timer1
           TCCR1B = 0x00; // stop, set normal mode
           TCCR1A = 0x00;
           TIMSK1 = 0x00; // no irq
           ICR1   = 0x0000;
           TCNT1  = 0x0000;
           TIFR1  = 0x27; // clear flags;

           // analog comparator setting
           // The D6 pin is the positive input.
           // The negative input is A1, A2, A3, or A4 pin.
           ACSR   = 0x94;  // analog comparator off
           DIDR1  = 0x03;  // disable the digital input func of D6 and D7.
           ADMUX  = adchT; // select the negative input
           ADCSRA = 0x04;
           ADCSRB = 0x40;

           // start time1 with pre=1/8 (2MHz)
           // input capture noise canceler ON
           TCCR1B = (osctrig & 0x10) ? 0xc2 : 0x82;  // edge selection
           ACSR   = 0x14; // capture-on, aco to caputure timer1
           TIFR1  = 0x27; // clear flags again

           ui1 = (tokadif * toka) + (osctdly << 1);

           // falling edge detection(rising edge for ICES1)
           // doesn't stabilize without a 20usec wait below.
           while(TCNT1 < 40)
               ;
           TIFR1 = 0x27;
           // wait until a trigger event happens
           while(true) {
               if (TIFR1 & 0x20) {
                   // trigger event has happened.
                   ui1 += ICR1;
                   at = 0; // a trigger event has happened.
                   break;
               }
               if (TCNT1 > waituntil) {
                   ui1 += TCNT1;
                   at = 1; // trigger failed.
                   break;
               }
               uartjob();
           }

           // at:0 -> trigger event has happened, 1 -> not happened
           ACSR   = 0x94; // disable analog comparator
           ADCSRB = 0x00;
           ADCSRA = 0x84; // adc enable

           TCCR1B = 0x1a; // timer1 CTC-ICR1 mode pre1/8
           TCCR1A = 0x00; //             CTC mode;
           ICR1   = ui1;
           TIFR1  = 0x27; // clear flags

           ADMUX  = 0x60; // adc target is A0 pin to get trigger value;
           ADCSRB = 0x07; // timer1 capture event;
           ADCSRA = 0xf4; // adc auto trigger, force 1st conversion

           // wait until the 1st conversion finishes.
           while((ADCSRA & 0x10) == 0x00)
               uartjob();
           vh = ADCH;  // trigger level
           osctvolt = vh;

           ADMUX = adch + ch;
           ADCSRA = 0xb4;   // clear flag, 1MHz, adate on

           if (toka == 0 && ch == 0) {   // needed only for the 1st loop
               // MARC-A  continued
               txput1(at);
               txput1(vh);
               txputcrc(false);
               txgo(); // start to trasmit a packet
               if (at)
                   goto  ex;  // send header only when trigger failed
           }

           for(i = 0; i < realnum; i++) {
               while(true) {
                   if (TIFR1 & 0x20) {
                       ICR1 = sinterval;
                       TIFR1 = 0x27; // clear timer1 flags;
                   }
                   if ((ADCSRA & 0x10) != 0x00)
                       break;
                   uartjob();
               }
               vh = ADCH;
               ADCSRA = 0xb4;   // clear flag, 1MHz, adate on
               txput1(vh);

               if (++crcnt >= 200) {
                   crcnt = 0;
                   // cause crc error on purpose if trigger failed(at > 0).
                   txputcrc((at > 0) ? true : false);
               }
           }
       }
   }
   //if (crcnt > 0)
   //    sysdown(800);
   if (crcnt == 40) {
       txputcrc((at > 0) ? true : false);
   }
   else
       sysdown(800);


ex:
   txfinish(true, true);
}

この記事へのコメント
コメントを書く

お名前: 必須項目

メールアドレス: 必須項目


ホームページアドレス: 必須項目

コメント: 必須項目

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/7102650
※ブログオーナーが承認したトラックバックのみ表示されます。

※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック
×

この広告は30日以上新しい記事の更新がないブログに表示されております。