simulavr  1.1.0
hwad.cpp
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
5  * Copyright (C) 2001, 2002, 2003 Klaus Rudolph
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  ****************************************************************************
22  *
23  * $Id$
24  */
25 
26 #include "hwad.h"
27 #include "irqsystem.h"
28 #include "avrerror.h"
29 
31  HWARef(_core),
32  aref_pin() {
33  core->RegisterPin("AREF", &aref_pin);
34 }
35 
36 float HWARefPin::GetRefValue(int select, float vcc) {
37  return aref_pin.GetAnalogValue(vcc);
38 }
39 
40 HWARef4::HWARef4(AvrDevice *_core, int _type):
41  HWARefPin(_core),
42  refType(_type) { }
43 
44 float HWARef4::GetRefValue(int select, float vcc) {
45  switch((select >> 6) & 0x3) {
46  case 0:
47  return aref_pin.GetAnalogValue(vcc);
48 
49  case 1:
50  return vcc;
51 
52  case 2:
53  if(refType != REFTYPE_BG3) {
54  avr_warning("ADC reference select invalid");
55  return 0.0;
56  }
57  return core->v_bandgap.GetRawAnalog();
58 
59  case 3:
60  if(refType == REFTYPE_BG4)
61  return core->v_bandgap.GetRawAnalog();
62  return 2.56;
63  }
64  // should not come here
65  return 0.0;
66 }
67 
68 float HWARef8::GetRefValue(int select, float vcc) {
69  switch(((select >> 6) & 0x3) | ((select >> 2) & 0x4)) {
70  case 0:
71  case 4:
72  return vcc;
73 
74  case 1:
75  case 5:
76  return aref_pin->GetAnalogValue(vcc);
77 
78  case 2:
79  return core->v_bandgap.GetRawAnalog();
80 
81  case 3:
82  avr_warning("ADC reference select invalid");
83  return 0.0;
84 
85  case 6:
86  case 7:
87  return 2.56;
88  }
89  // should not come here
90  return 0.0;
91 }
92 
93 void HWAdmux::SetMuxSelect(int select) {
94  int oldSelect = muxSelect;
95  muxSelect = select & 0xf; // only values 0..15 allowed!
96  if(numPins < 9)
97  muxSelect &= 0x7; // only values 0..7 allowed!
98  if(numPins < 6)
99  muxSelect &= 0x3; // only values 0..3 allowed!
100  if((notifyClient != NULL) && (oldSelect != muxSelect))
101  notifyClient->NotifySignalChanged();
102 }
103 
105  Pin *selected = ad[muxSelect];
106  if((notifyClient != NULL) && (selected == p))
107  notifyClient->NotifySignalChanged();
108 }
109 
111  Pin* _ad1,
112  Pin* _ad2,
113  Pin* _ad3,
114  Pin* _ad4,
115  Pin* _ad5):
116  HWAdmux(c, 6) {
117  ad[0] = _ad0;
118  _ad0->RegisterCallback(this);
119  ad[1] = _ad1;
120  _ad1->RegisterCallback(this);
121  ad[2] = _ad2;
122  _ad2->RegisterCallback(this);
123  ad[3] = _ad3;
124  _ad3->RegisterCallback(this);
125  ad[4] = _ad4;
126  _ad4->RegisterCallback(this);
127  ad[5] = _ad5;
128  _ad5->RegisterCallback(this);
129  ad[6] = NULL;
130  ad[7] = NULL;
131 }
132 
133 float HWAdmux6::GetValue(int select, float vcc) {
134  if(core->fuses->GetFuseBit(3) && ((select & 0x40) == 0x40))
135  return 1.22; // ADCBG is set and BODEN-fuse is programmed (at90x4433 only)
136  int adChannel = select & 0x07; // bit 2:0 is multiplexer selector
137  if(adChannel >= numPins) {
138  avr_warning("adc multiplexer has selected non existent channel %d", adChannel);
139  return 0.0;
140  }
141  return ad[adChannel]->GetAnalogValue(vcc);
142 }
143 
145  Pin* _ad1,
146  Pin* _ad2,
147  Pin* _ad3,
148  Pin* _ad4,
149  Pin* _ad5,
150  Pin* _ad6,
151  Pin* _ad7):
152  HWAdmux(c, 8) {
153  ad[0] = _ad0;
154  _ad0->RegisterCallback(this);
155  ad[1] = _ad1;
156  _ad1->RegisterCallback(this);
157  ad[2] = _ad2;
158  _ad2->RegisterCallback(this);
159  ad[3] = _ad3;
160  _ad3->RegisterCallback(this);
161  ad[4] = _ad4;
162  _ad4->RegisterCallback(this);
163  ad[5] = _ad5;
164  _ad5->RegisterCallback(this);
165  ad[6] = _ad6;
166  _ad6->RegisterCallback(this);
167  ad[7] = _ad7;
168  _ad7->RegisterCallback(this);
169 }
170 
172  Pin* _ad1,
173  Pin* _ad2,
174  Pin* _ad3):
175  HWAdmux(c, 4) {
176  ad[0] = _ad0;
177  _ad0->RegisterCallback(this);
178  ad[1] = _ad1;
179  _ad1->RegisterCallback(this);
180  ad[2] = _ad2;
181  _ad2->RegisterCallback(this);
182  ad[3] = _ad3;
183  _ad3->RegisterCallback(this);
184  ad[4] = NULL;
185  ad[5] = NULL;
186  ad[6] = NULL;
187  ad[7] = NULL;
188 }
189 
190 float HWAdmuxM8::GetValue(int select, float vcc) {
191  int adChannel = select & 0x0f; // bit 3:0 is multiplexer selector
192  if(adChannel == 15)
193  return 0.0; // GND channel
194  if(adChannel == 14)
195  return core->v_bandgap.GetRawAnalog(); // BG channel
196  if(adChannel >= numPins) {
197  avr_warning("adc multiplexer has selected non existent channel %d", adChannel);
198  return 0.0;
199  }
200  return ad[adChannel]->GetAnalogValue(vcc);
201 }
202 
203 float HWAdmuxM8::GetValueAComp(int select, float vcc) {
204  int adChannel = select & 0x07; // bit 2:0 is multiplexer selector for analog comparator
205  return ad[adChannel]->GetAnalogValue(vcc);
206 }
207 
209  Pin* _ad1,
210  Pin* _ad2,
211  Pin* _ad3,
212  Pin* _ad4,
213  Pin* _ad5,
214  Pin* _ad6,
215  Pin* _ad7):
216  HWAdmuxM8(c, _ad0, _ad1, _ad2, _ad3, _ad4, _ad5, _ad6, _ad7) { }
217 
218 float HWAdmuxM16::GetValue(int select, float vcc) {
219  int adChannel = select & 0x1f; // bit 4:0 is multiplexer selector
220  if(adChannel == 31)
221  return 0.0; // GND channel
222  if(adChannel == 30)
223  return core->v_bandgap.GetRawAnalog(); // BG channel
224  if(adChannel < 8)
225  return ad[adChannel]->GetAnalogValue(vcc); // single channel
226  if(adChannel >= 24) {
227  float neg = ad[2]->GetAnalogValue(vcc); // channel 2 is negative difference channel, gain is 1
228  return ad[adChannel - 24]->GetAnalogValue(vcc) - neg;
229  }
230  if(adChannel >= 16) {
231  float neg = ad[1]->GetAnalogValue(vcc); // channel 1 is negative difference channel, gain is 1
232  return ad[adChannel - 16]->GetAnalogValue(vcc) - neg;
233  }
234  if((adChannel == 8) || (adChannel == 9) || (adChannel == 12) || (adChannel == 13)) {
235  float neg = ad[(adChannel > 9) ? 2 : 0]->GetAnalogValue(vcc); // channel 0/2 is negative difference channel, gain is 10
236  if(adChannel == 8)
237  return (ad[0]->GetAnalogValue(vcc) - neg) * 10.0;
238  if(adChannel == 9)
239  return (ad[1]->GetAnalogValue(vcc) - neg) * 10.0;
240  if(adChannel == 12)
241  return (ad[2]->GetAnalogValue(vcc) - neg) * 10.0;
242  return (ad[3]->GetAnalogValue(vcc) - neg) * 10.0;
243  }
244  float neg = ad[(adChannel > 11) ? 2 : 0]->GetAnalogValue(vcc); // channel 0/2 is negative difference channel, gain is 200
245  if(adChannel == 10)
246  return (ad[0]->GetAnalogValue(vcc) - neg) * 200.0;
247  if(adChannel == 11)
248  return (ad[1]->GetAnalogValue(vcc) - neg) * 200.0;
249  if(adChannel == 14)
250  return (ad[2]->GetAnalogValue(vcc) - neg) * 200.0;
251  return (ad[3]->GetAnalogValue(vcc) - neg) * 200.0;
252 }
253 
255  int adChannel = select & 0x1f; // bit 4:0 is multiplexer selector
256  return (adChannel >= 8) && (adChannel < 30);
257 }
258 
260  Pin* _ad1,
261  Pin* _ad2,
262  Pin* _ad3):
263  HWAdmuxM8(c, _ad0, _ad1, _ad2, _ad3) { }
264 
265 float HWAdmuxT25::GetValue(int select, float vcc) {
266  int adChannel = select & 0xf; // bit 3:0 is multiplexer selector
267  if(adChannel == 15)
268  return 0.322; // Temp. sensor, temperature about 25°C
269  if(adChannel == 14) {
270  avr_warning("adc multiplexer has selected non existent channel %d", adChannel);
271  return 0.0; // not available
272  }
273  if(adChannel == 13)
274  return 0.0; // GND channel
275  if(adChannel == 12)
276  return core->v_bandgap.GetRawAnalog(); // BG channel
277  if(adChannel < 4)
278  return ad[adChannel]->GetAnalogValue(vcc); // single channel
279  // all other are difference channel
280  if(adChannel == 4)
281  return (ad[2]->GetAnalogValue(vcc) - ad[2]->GetAnalogValue(vcc)) * 1.0;
282  if(adChannel == 5)
283  return (ad[2]->GetAnalogValue(vcc) - ad[2]->GetAnalogValue(vcc)) * 20.0;
284  if(adChannel == 6)
285  return (ad[2]->GetAnalogValue(vcc) - ad[3]->GetAnalogValue(vcc)) * 1.0;
286  if(adChannel == 7)
287  return (ad[2]->GetAnalogValue(vcc) - ad[3]->GetAnalogValue(vcc)) * 20.0;
288  if(adChannel == 8)
289  return (ad[0]->GetAnalogValue(vcc) - ad[0]->GetAnalogValue(vcc)) * 1.0;
290  if(adChannel == 9)
291  return (ad[0]->GetAnalogValue(vcc) - ad[0]->GetAnalogValue(vcc)) * 20.0;
292  if(adChannel == 10)
293  return (ad[0]->GetAnalogValue(vcc) - ad[1]->GetAnalogValue(vcc)) * 1.0;
294  // adChannel == 11
295  return (ad[0]->GetAnalogValue(vcc) - ad[1]->GetAnalogValue(vcc)) * 20.0;
296 }
297 
299  int adChannel = select & 0xf; // bit 3:0 is multiplexer selector
300  return (adChannel >= 4) && (adChannel < 12);
301 }
302 
304  Pin* _ad1,
305  Pin* _ad2,
306  Pin* _ad3,
307  Pin* _ad4,
308  Pin* _ad5,
309  Pin* _ad6,
310  Pin* _ad7,
311  Pin* _ad8,
312  Pin* _ad9,
313  Pin* _ad10,
314  Pin* _ad11,
315  Pin* _ad12,
316  Pin* _ad13,
317  Pin* _ad14,
318  Pin* _ad15):
319  HWAdmux(c, 16) {
320  ad[0] = _ad0;
321  _ad0->RegisterCallback(this);
322  ad[1] = _ad1;
323  _ad1->RegisterCallback(this);
324  ad[2] = _ad2;
325  _ad2->RegisterCallback(this);
326  ad[3] = _ad3;
327  _ad3->RegisterCallback(this);
328  ad[4] = _ad4;
329  _ad4->RegisterCallback(this);
330  ad[5] = _ad5;
331  _ad5->RegisterCallback(this);
332  ad[6] = _ad6;
333  _ad6->RegisterCallback(this);
334  ad[7] = _ad7;
335  _ad7->RegisterCallback(this);
336  ad[8] = _ad8;
337  _ad8->RegisterCallback(this);
338  ad[9] = _ad9;
339  _ad9->RegisterCallback(this);
340  ad[10] = _ad10;
341  _ad10->RegisterCallback(this);
342  ad[11] = _ad11;
343  _ad11->RegisterCallback(this);
344  ad[12] = _ad12;
345  _ad12->RegisterCallback(this);
346  ad[13] = _ad13;
347  _ad13->RegisterCallback(this);
348  ad[14] = _ad14;
349  _ad14->RegisterCallback(this);
350  ad[15] = _ad15;
351  _ad15->RegisterCallback(this);
352 }
353 
354 float HWAdmuxM2560::GetValue(int select, float vcc) {
355  bool high_channel = ((select & 0x20) == 0x20);
356  int adChannel = select & 0x1f; // bit 4:0 is multiplexer selector
357  if(adChannel == 31) {
358  if(high_channel) {
359  avr_warning("ADC channel 63 invalid");
360  return 0.0;
361  }
362  return 0.0; // GND channel
363  }
364  if(adChannel == 30) {
365  if(high_channel) {
366  avr_warning("ADC channel 62 invalid");
367  return 0.0;
368  }
369  return core->v_bandgap.GetRawAnalog(); // BG channel
370  }
371  if(adChannel < 8) { // single channel
372  int sel = adChannel + (high_channel ? 8 : 0);
373  float val = ad[sel]->GetAnalogValue(vcc);
374  return val;
375  }
376  if(adChannel >= 24) {
377  float neg = ad[2 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc); // channel 2 is negative difference channel, gain is 1
378  return ad[adChannel - 24 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg;
379  }
380  if(adChannel >= 16) {
381  float neg = ad[1 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc); // channel 1 is negative difference channel, gain is 1
382  return ad[adChannel - 16 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg;
383  }
384  if((adChannel == 8) || (adChannel == 9) || (adChannel == 12) || (adChannel == 13)) {
385  float neg = ad[((adChannel > 9) ? 2 : 0) + (high_channel ? 8 : 0)]->GetAnalogValue(vcc); // channel 0/2 is negative difference channel, gain is 10
386  if(adChannel == 8)
387  return (ad[0 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 10.0;
388  if(adChannel == 9)
389  return (ad[1 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 10.0;
390  if(adChannel == 12)
391  return (ad[2 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 10.0;
392  return (ad[3 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 10.0;
393  }
394  float neg = ad[((adChannel > 11) ? 2 : 0) + (high_channel ? 8 : 0)]->GetAnalogValue(vcc); // channel 0/2 is negative difference channel, gain is 200
395  if(adChannel == 10)
396  return (ad[0 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 200.0;
397  if(adChannel == 11)
398  return (ad[1 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 200.0;
399  if(adChannel == 14)
400  return (ad[2 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 200.0;
401  return (ad[3 + (high_channel ? 8 : 0)]->GetAnalogValue(vcc) - neg) * 200.0;
402 }
403 
404 HWAd::HWAd(AvrDevice *c, int _typ, HWIrqSystem *i, unsigned int iv, HWAdmux *a, HWARef *r):
405  Hardware(c),
406  TraceValueRegister(c, "AD"),
407  adType(_typ),
408  core(c),
409  mux(a),
410  aref(r),
411  irqSystem(i),
412  irqVec(iv),
413  notifyClient(NULL),
414  adch_reg(this, "ADCH", this, &HWAd::GetAdch, 0),
415  adcl_reg(this, "ADCL", this, &HWAd::GetAdcl, 0),
416  adcsra_reg(this, "ADCSRA", this, &HWAd::GetAdcsrA, &HWAd::SetAdcsrA),
417  adcsrb_reg(this, "ADCSRB", this, &HWAd::GetAdcsrB, &HWAd::SetAdcsrB),
418  admux_reg(this, "ADMUX", this, &HWAd::GetAdmux, &HWAd::SetAdmux) {
419  mux->RegisterNotifyClient(this);
421  core->AddToCycleList(this);
422 
423  Reset();
424 }
425 
426 void HWAd::Reset(void) {
427  adcsra = adcsrb = 0;
428  adch = 0;
429  adcl = 0;
430  admux = adMuxConfig = 0;
431  state = IDLE;
432  prescaler = 0;
433  prescalerSelect = 0;
434  conversionState = 0;
435  firstConversion = true;
436  adchLocked = false;
437 }
438 
440  if((notifyClient != NULL) && !IsADEnabled())
442 }
443 
444 unsigned char HWAd::GetAdch(void) {
445  adchLocked = false;
446  return adch;
447 }
448 
449 unsigned char HWAd::GetAdcl(void) {
450  adchLocked = true;
451  return adcl;
452 }
453 
454 void HWAd::SetAdcsrA(unsigned char val) {
455  bool enabled = (adcsra & ADEN) == ADEN;
456  // clear IRQ Flag if set in val, otherwise do not overwrite ADIF
457  if((val & ADIF) == ADIF)
458  val &= ~ADIF;
459  else if((adcsra & ADIF) == ADIF)
460  val |= ADIF;
461  // if ADSC is set, don't clear it till end of conversion
462  if((adcsra & ADSC) == ADSC)
463  val |= ADSC;
464  // store value
465  adcsra = val;
466 
467  // set prescaler selection
469 
470  // set first conversion flag (first conversion after enable ADC)
471  if(!enabled && ((adcsra & ADEN) == ADEN))
472  firstConversion = true;
473 
474  // handle interrupt, if fresh enabled
475  if((adcsra & (ADIE | ADIF)) == (ADIE | ADIF))
476  irqSystem->SetIrqFlag(this, irqVec);
477  else
479 
480  // handle connection to analog comparator
482 }
483 
484 void HWAd::SetAdcsrB(unsigned char val) {
485  if(adType == AD_T25)
486  val &= 0xe7; // reset bit4,3
487  else if(adType == AD_M64)
488  val &= 0x07; // reset bit7,6,5,4,3
489  else if(adType == AD_M2560) {
490  val &= 0x4f; // reset bit7,5,4 (to pass MUX5)
491  }
492  else
493  val &= 0x47; // reset bit7,5,4,3
494  adcsrb = val;
495 
496  // handle connection to analog comparator
498 }
499 
500 void HWAd::SetAdmux(unsigned char val) {
501  if(adType == AD_4433)
502  val &= 0x47; // reset bit7,5,4,3
503  else if((adType == AD_M8) || (adType == AD_M48))
504  val &= 0xef; // reset bit4
505  admux = val;
506  bool high_channel = ((adcsrb & MUX5) == MUX5);
507  mux->SetMuxSelect((int)admux + (high_channel ? 8 : 0));
508 }
509 
510 void HWAd::ClearIrqFlag(unsigned int vector){
511  if(vector == irqVec) {
512  adcsra &= ~ADIF;
514  }
515 }
516 
517 /* ATTENTION: prescaler clock here runs 2 times faster then clock cycle in spec.
518  we need the half clock for getting the analog values
519  by cycle 1.5 as noted in AVR spec., this means cycle 3 in this model! */
521  if((adcsra & ADEN) == 0) {
522  // ADC disabled, prescaler remains in reset
523  prescaler = 0;
524  return false;
525  }
526 
527  // ADC enabled, prescaler counts continuously
528  prescaler++;
529  if(prescaler >= 64) // counter size = 7bit, but we count with double speed
530  prescaler = 0;
531 
532  switch(prescalerSelect) {
533  case 0:
534  case 1: // CLKx2
535  return true;
536 
537  case 2: // CLKx4
538  return (prescaler % 2) == 0;
539 
540  case 3: // CLKx8
541  return (prescaler % 4) == 0;
542 
543  case 4: // CLKx16
544  return (prescaler % 8) == 0;
545 
546  case 5: // CLKx32
547  return (prescaler % 16) == 0;
548 
549  case 6: // CLKx64
550  return (prescaler % 32) == 0;
551 
552  case 7: // CLKx128
553  return (prescaler % 64) == 0;
554 
555  }
556  // should not happen
557  return false;
558 }
559 
561  return adcsrb & ADTS;
562 }
563 
565  if((adType == AD_4433) || (adType == AD_M8) || (adType == AD_M128))
566  // only freerunning mode, no autotrigger modes
567  return (adcsra & ADFR) == ADFR;
568  // all other have ADATE flag and autotrigger modes
569  if((adcsra & ADATE) == ADATE) {
570  // does have ADTS[2:0] in SFIOR register or in ADCSRB register
571  return GetTriggerSource() == 0; // mode 0 is freerunning mode
572  }
573  // not freerunning
574  return false;
575 }
576 
577 int HWAd::ConversionBipolar(float value, float ref) {
578  // max value is 511 (positive), min value is -512 (negative)
579  int adcmax = (1 << 9) - 1;
580  int adcmin = -(1 << 9);
581  // delimiting range -Vref to Vref
582  if(value > ref)
583  value = ref;
584  else if(value < -ref)
585  value = -ref;
586  // convert to int
587  if(ref == 0.0) {
588  if(value < 0.0)
589  return adcmin;
590  else
591  return adcmax;
592  } else
593  return ((int)((value * (adcmax + 1)) / ref)) & 0x3ff;
594 }
595 
596 int HWAd::ConversionUnipolar(float value, float ref) {
597  // max value is 1023, min value is 0
598  int adcmax = (1 << 10) - 1;
599  // delimiting range GND to Vref
600  if(value > ref)
601  value = ref;
602  else if(value < 0.0)
603  value = 0.0;
604  // convert to int
605  if(ref == 0.0)
606  return adcmax;
607  else
608  return (int)((value * (adcmax + 1)) / ref);
609 
610 }
611 
612 unsigned int HWAd::CpuCycle() {
613 
614  if(IsPrescalerClock()) { // prescaler clock event
615 
616  conversionState++;
617 
618  switch (state) {
619 
620  case IDLE:
621  conversionState = 0;
622  if((adcsra & ADSC) == ADSC) { //start a conversion
623  adMuxConfig = admux; // buffer ADMUX state
624  if(firstConversion) {
625  state = INIT;
626  firstConversion = false;
627  } else
628  state = RUNNING;
629  }
630  break;
631 
632  case INIT:
633  // we have to wait 13 clocks extra
634  if (conversionState == (13 * 2)) {
635  state = RUNNING;
636  conversionState = (1 * 2);
637  /* we goes 1 clock ahead while waiting only 12 cycles in real
638  only corrected while avr spec say : after 13 cycles...
639  Normally that can also be done after 12 cycles and start a
640  14 cycle long normal run... but this is here spec conform :-) */
641  }
642  break;
643 
644  case RUNNING:
645  if(conversionState == ((1 * 2) + 1)) { // sample time
646  bool high_channel = ((adcsrb & MUX5) == MUX5);
647  float vcc = core->v_supply.GetRawAnalog();
648  float adref = aref->GetRefValue(adMuxConfig, vcc);
649  int fullMux = adMuxConfig;
650  if (high_channel) {
651  fullMux = fullMux | 0x20;
652  }
653  float muxval = mux->GetValue(fullMux, vcc);
655  if(adType == AD_T25) {
656  if((adcsrb & BIN) == BIN)
657  adSample = ConversionBipolar(muxval, adref);
658  else {
659  if((adcsrb & IPR) == IPR)
660  adSample = ConversionUnipolar(-muxval, adref);
661  else
662  adSample = ConversionUnipolar(muxval, adref);
663  }
664  } else
665  adSample = ConversionBipolar(muxval, adref);
666  } else
667  adSample = ConversionUnipolar(muxval, adref);
668  } else if(conversionState == (13 * 2)) {
669  // calculate sample to go to 10 bit value
670  if((admux & ADLAR) == ADLAR)
671  adSample <<= (16 - 10); // left-justify sample
672  // set ADCL and ADCH
673  if(adchLocked) {
674  // TODO: how to rewrite this, is traceOut right? Replace output to stderr.
675  if(core->trace_on)
676  traceOut << "ADC result lost, adch is locked!" << std::endl;
677  else
678  std::cerr << "AD-Result lost adch is locked!" << std::endl;
679  } else // adch is unlocked
680  adch = adSample >> 8;
681  adcl = adSample & 0xff;
682 
683  // set irq flag (conversion complete) and trigger interrupt, if enabled
684  adcsra |= ADIF;
685  if((adcsra & (ADIE | ADIF)) == (ADIE | ADIF))
686  irqSystem->SetIrqFlag(this, irqVec);
687 
688  if(IsFreeRunning()) { // free running mode: start again and state is running again
689  conversionState = 0;
690  adMuxConfig = admux; // buffer ADMUX state
691  } else
692  adcsra &= ~ADSC; // not free running -> clear ADSC Bit
693  } else if(conversionState == (14 * 2)) {
694  conversionState = 0;
695  state = IDLE;
696  }
697  break;
698 
699  } // end of switch state
700  }
701 
702  return 0;
703 }
704 
705 HWAd_SFIOR::HWAd_SFIOR(AvrDevice *c, int _typ, HWIrqSystem *i, unsigned int iv, HWAdmux *a, HWARef *r, IOSpecialReg *s):
706  HWAd(c, _typ, i, iv, a, r),
707  sfior_reg(s) {
708  adts = 0;
710 }
711 
712 unsigned char HWAd_SFIOR::set_from_reg(const IOSpecialReg* reg, unsigned char nv) {
713  adts = (nv >> 5) & 0x7;
714  return nv;
715 }
716 
717 // EOF
virtual int GetTriggerSource(void)
Definition: hwad.cpp:560
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
HWARef4(AvrDevice *_core, int _type)
Definition: hwad.cpp:40
0:aref, 1:vcc, 2:bg, 3:2.56V
Definition: hwad.h:68
virtual bool IsDifferenceChannel(int select)
Definition: hwad.cpp:254
unsigned int irqVec
Definition: hwad.h:217
int refType
Definition: hwad.h:63
int adType
Definition: hwad.h:207
void AddToCycleList(Hardware *hw)
Definition: avrdevice.cpp:51
AvrFuses * fuses
Definition: avrdevice.h:100
virtual float GetRefValue(int select, float vcc)=0
Definition: hwad.h:90
Pin class, handles input and output to external parts.
Definition: pin.h:98
int adSample
Definition: hwad.h:220
void SetAdcsrB(unsigned char)
Definition: hwad.cpp:484
virtual float GetValueAComp(int select, float vcc)
Definition: hwad.cpp:203
AnalogSignalChange * notifyClient
Definition: hwad.h:94
ADC reference is taken from special ADREF pin (no port pin)
Definition: hwad.h:48
HWAdmuxM8(AvrDevice *c, Pin *_ad0, Pin *_ad1, Pin *_ad2, Pin *_ad3)
Definition: hwad.cpp:171
virtual float GetValue(int select, float vcc)
Definition: hwad.cpp:190
#define traceOut
Definition: avrerror.h:121
void RegisterPin(const std::string &name, Pin *p)
Definition: avrdevice.h:171
unsigned char admux
Definition: hwad.h:212
int prescaler
Definition: hwad.h:222
HWAdmux * mux
Definition: hwad.h:214
void connectSRegClient(IOSpecialRegClient *c)
Registers a client to this IO register to inform this client on read or write access.
Definition: rwmem.h:429
void RegisterNotifyClient(AnalogSignalChange *client)
Definition: hwad.h:114
virtual float GetRefValue(int select, float vcc)
Definition: hwad.cpp:68
void ClearIrqFlag(unsigned int vec)
Definition: hwad.cpp:510
virtual float GetRefValue(int select, float vcc)
Definition: hwad.cpp:44
bool IsPrescalerClock(void)
Definition: hwad.cpp:520
int prescalerSelect
Definition: hwad.h:223
HWAdmux6(AvrDevice *c, Pin *_ad0, Pin *_ad1, Pin *_ad2, Pin *_ad3, Pin *_ad4, Pin *_ad5)
Definition: hwad.cpp:110
int ConversionUnipolar(float value, float ref)
Definition: hwad.cpp:596
virtual float GetValue(int select, float vcc)=0
int numPins
Multiplexer channel, can&#39;t be used for ADC sampling because of buffering on conversion start! ...
Definition: hwad.h:96
HWIrqSystem * irqSystem
Definition: hwad.h:216
ADC type M2560: ADC on atmega2560.
Definition: hwad.h:266
void Reset(void)
Definition: hwad.cpp:426
Build a register for TraceValue&#39;s.
Definition: traceval.h:442
void PinStateHasChanged(Pin *)
Definition: hwad.cpp:104
ADC type M8: ADC on atmega8.
Definition: hwad.h:259
AvrDevice * core
Definition: hwad.h:38
int conversionState
Definition: hwad.h:224
ADC type M64: ADC on atmega64.
Definition: hwad.h:261
void SetIrqFlag(Hardware *, unsigned int vector_index)
Definition: irqsystem.cpp:243
bool adchLocked
Definition: hwad.h:219
0:aref, 1:vcc, 2:-, 3:bg
Definition: hwad.h:69
Reference source for ADC (base class)
Definition: hwad.h:35
virtual float GetValue(int select, float vcc)
Definition: hwad.cpp:218
AvrDevice * core
Definition: hwad.h:97
unsigned char GetAdch(void)
Definition: hwad.cpp:444
int ConversionBipolar(float value, float ref)
Definition: hwad.cpp:577
unsigned char adcl
Definition: hwad.h:209
virtual float GetValue(int select, float vcc)
Definition: hwad.cpp:354
void SetAdcsrA(unsigned char)
Definition: hwad.cpp:454
void SetAdmux(unsigned char val)
Definition: hwad.cpp:500
Pin aref_pin
Definition: hwad.h:51
HWAd_SFIOR(AvrDevice *c, int _typ, HWIrqSystem *i, unsigned int iv, HWAdmux *a, HWARef *r, IOSpecialReg *s)
Definition: hwad.cpp:705
unsigned char adcsrb
Definition: hwad.h:211
IOSpecialReg * sfior_reg
Definition: hwad.h:311
void RegisterCallback(HasPinNotifyFunction *)
Definition: pin.cpp:60
ADC type 4433: ADC on at90s/l4433.
Definition: hwad.h:258
void SetMuxSelect(int select)
Definition: hwad.cpp:93
virtual void NotifySignalChanged(void)=0
#define avr_warning(...)
Definition: avrerror.h:133
Pin v_supply
represents supply voltage level, needed for analog peripherals
Definition: avrdevice.h:112
unsigned char adcsra
Definition: hwad.h:210
ADC type T25: ADC on attiny25/45/85.
Definition: hwad.h:265
bool IsADEnabled(void)
Check, if ADC is enabled.
Definition: hwad.h:296
Pin * ad[16]
Definition: hwad.h:93
ADC type M128: ADC on atmega128.
Definition: hwad.h:262
AnalogSignalChange * notifyClient
Definition: hwad.h:226
enum HWAd::T_State state
Pin v_bandgap
represents bandgap (ref) voltage level, needed for analog peripherals
Definition: avrdevice.h:113
void DebugVerifyInterruptVector(unsigned int vector_index, const Hardware *source)
In datasheets RESET vector is index 1 but we use 0! And not a byte address.
Definition: irqsystem.cpp:297
unsigned int CpuCycle()
Definition: hwad.cpp:612
HWARef * aref
Definition: hwad.h:215
int trace_on
Definition: avrdevice.h:90
int adMuxConfig
Definition: hwad.h:221
AvrDevice * core
Definition: hwad.h:213
virtual bool IsDifferenceChannel(int select)
Definition: hwad.cpp:298
virtual float GetValue(int select, float vcc)
Definition: hwad.cpp:133
HWAdmuxT25(AvrDevice *c, Pin *_ad0, Pin *_ad1, Pin *_ad2, Pin *_ad3)
Definition: hwad.cpp:259
void NotifySignalChanged(void)
Definition: hwad.cpp:439
void ClearIrqFlag(unsigned int vector_index)
Definition: irqsystem.cpp:258
bool GetFuseBit(int index)
Get fuse bit by bit index, starts with 0 on lfuse bit 0, bit = 0 means true!
Definition: flashprog.h:125
int adts
Definition: hwad.h:312
Definition: hwad.h:204
unsigned char GetAdcl(void)
Definition: hwad.cpp:449
HWAdmuxM2560(AvrDevice *c, Pin *_ad0, Pin *_ad1, Pin *_ad2, Pin *_ad3, Pin *_ad4, Pin *_ad5, Pin *_ad6, Pin *_ad7, Pin *_ad8, Pin *_ad9, Pin *_ad10, Pin *_ad11, Pin *_ad12, Pin *_ad13, Pin *_ad14, Pin *_ad15)
Definition: hwad.cpp:303
float GetRawAnalog(void) const
get back raw analog value (just variable content!)
Definition: pin.h:149
HWARefPin(AvrDevice *_core)
Definition: hwad.cpp:30
HWAdmuxM16(AvrDevice *c, Pin *_ad0, Pin *_ad1, Pin *_ad2, Pin *_ad3, Pin *_ad4, Pin *_ad5, Pin *_ad6, Pin *_ad7)
Definition: hwad.cpp:208
HWAd(AvrDevice *c, int _typ, HWIrqSystem *i, unsigned int iv, HWAdmux *a, HWARef *r)
Definition: hwad.cpp:404
virtual float GetRefValue(int select, float vcc)
Definition: hwad.cpp:36
bool IsFreeRunning(void)
Definition: hwad.cpp:564
float GetAnalogValue(float vcc)
Returns real analog input value of pin.
Definition: pin.h:150
virtual bool IsDifferenceChannel(int select)
Definition: hwad.h:111
ADC type M48: ADC on atmega48/88/168/328.
Definition: hwad.h:263
virtual float GetValue(int select, float vcc)
Definition: hwad.cpp:265
bool firstConversion
Definition: hwad.h:225
unsigned char adch
Definition: hwad.h:208
unsigned char set_from_reg(const IOSpecialReg *reg, unsigned char nv)
Definition: hwad.cpp:712