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);
}
【このカテゴリーの最新記事】
-
no image
-
no image
-
no image
-
no image
-
no image
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7102650
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。
この記事へのトラックバック