simulavr  1.1.0
hwtimer.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 "hardware.h"
27 #include "avrdevice.h"
28 #include "hwtimer/timerprescaler.h"
29 #include "hwtimer/hwtimer.h"
30 #include "helper.h"
31 #include "systemclock.h"
32 
33 #include <cstdlib>
34 #include <time.h>
35 
36 using namespace std;
37 
40  int unit,
41  IRQLine* tov,
42  IRQLine* tcap,
43  ICaptureSource* icapsrc,
44  int countersize):
45  Hardware(core),
46  TraceValueRegister(core, "TIMER" + int2str(unit)),
47  eventListener(NULL),
48  core(core),
49  premx(p),
50  timerOverflow(tov),
51  timerCapture(tcap),
52  icapSource(icapsrc)
53 {
54  // check counter size and set limit_max
55  if(countersize != 8 && countersize != 16)
56  avr_error("wrong parameter: countersize=%d", countersize);
57  if(countersize == 8)
58  limit_max = 0xff;
59  else
60  limit_max = 0xffff;
61 
62  // set input capture register
63  icapRegister = 0;
64 
65  // create TraceValue for counter itself
66  counterTrace = new TraceValue(countersize, GetTraceValuePrefix() + "Counter");
69 
70  // disable all compare registers, output pins and reset Compare IRQ's
71  for(int i = 0; i < OCRIDX_maxUnits; i++) {
72  compareEnable[i] = false;
73  timerCompare[i] = NULL;
74  }
75 
76  // set wgm functions
77  for(int i = 0; i < WGM_tablesize; i++)
79 
80  // set saved input capture state and variables for noise canceler
81  captureInputState = false;
82  icapNCcounter = 0;
83  icapNCstate = false;
84 
85  // reset internal values
86  Reset();
87 
88 }
89 
91  vlast_tcnt = vtcnt; // save cycle - 1 counter value
92  if(updown_counting) {
93  // first handle compare events
94  if(compareEnable[0]) {
95  if(vlast_tcnt == compare[0])
97  if(compareEnable[1]) {
98  if(vlast_tcnt == compare[1])
100  if(compareEnable[2]) {
101  if(vlast_tcnt == compare[2])
103  }
104  }
105  }
106 
107  // then handle overflow events
108  if(vlast_tcnt == limit_bottom)
110  else if(vlast_tcnt == limit_top)
112 
113  // counter counts up and down
114  if(count_down) {
115  vtcnt--;
117  if(vtcnt == limit_bottom)
118  count_down = false; // now count up
119  } else {
120  vtcnt++;
122  if(vtcnt == limit_top)
123  count_down = true; // now count down
124  }
125  } else {
126  // first simple up counting till overflow (used in normal mode)
127  vtcnt++;
128  if(vtcnt > limit_max) { // overflow?
130  vtcnt &= limit_max; // reset overflow
131  }
132 
133  // handle bottom event
134  if(vlast_tcnt == limit_bottom)
136 
137  // handle top event
138  if(vlast_tcnt == limit_top)
140 
141  // handle compare events (to fire interrupts or change counter
142  if(compareEnable[0]) {
143  if(vlast_tcnt == compare[0])
145  if(compareEnable[1]) {
146  if(vlast_tcnt == compare[1])
148  if(compareEnable[2]) {
149  if(vlast_tcnt == compare[2])
151  }
152  }
153  }
154 
155  // trace the counter change
157  }
158 }
159 
161  if(icapSource != NULL && !WGMuseICR()) {
162  // get the current state
163  bool tmp = icapSource->GetSourceState();
164  if(icapNoiseCanceler) {
165  // use noise canceler
166  if(tmp == icapNCstate) {
167  if(icapNCcounter < 4) {
168  icapNCcounter++;
169  tmp = captureInputState; // do not trigger event!
170  }
171  } else {
172  // state change, reset counter
173  icapNCcounter = 0;
174  icapNCstate = tmp;
175  tmp = captureInputState; // do not trigger event!
176  }
177  }
178 
179  // detect change
180  if(tmp != captureInputState) {
181  if(tmp == icapRisingEdge) {
182  // right edge seen, capture timer counter
184  // fire capture interrupt
185  if(timerCapture)
187  }
188  captureInputState = tmp;
189  }
190  }
191 }
192 
194  cs = mode;
195  if(cs != 0) {
196  core->AddToCycleList(this);
197  } else {
198  core->RemoveFromCycleList(this);
199  }
200 }
201 
202 void BasicTimerUnit::SetCounter(unsigned long val) {
203  vtcnt = val;
204  vlast_tcnt = 0x10000; // set to a invalid value!
205  counterTrace->change(val);
206 }
207 
209  com[idx] = mode;
210  if(compare_output[idx].active()) {
211  if(mode == COM_NOOP)
213  else {
216  }
217  }
218 }
219 
221  COMtype mode = com[idx];
222  bool new_state=false, old_state = compare_output_state[idx];
223  switch(mode) {
224  case COM_NOOP:
225  return;
226 
227  case COM_TOGGLE:
228  new_state = old_state ? false : true;
229  break;
230 
231  case COM_CLEAR:
232  new_state = false;
233  break;
234 
235  case COM_SET:
236  new_state = true;
237  break;
238  }
239  compare_output_state[idx] = new_state;
240  if(compare_output[idx].active() && old_state != new_state)
241  compare_output[idx].SetAlternatePort(new_state);
242 }
243 
244 void BasicTimerUnit::SetPWMCompareOutput(int idx, bool topOrDown) {
245  COMtype mode = com[idx];
246  bool new_state=false, old_state = compare_output_state[idx];
247  switch(mode) {
248  case COM_NOOP:
249  return;
250 
251  case COM_TOGGLE:
252  if((wgm == WGM_FASTPWM_OCRA ||
253  wgm == WGM_PCPWM_OCRA ||
254  wgm == WGM_PFCPWM_OCRA) && idx == OCRIDX_A)
255  // special mode in case of WGM_FASTPWM_OCRA!
257  else
258  avr_warning("COM==1 in PWM mode is reserved!");
259  break;
260 
261  case COM_CLEAR:
262  if(topOrDown)
263  new_state = true;
264  else
265  new_state = false;
266  break;
267 
268  case COM_SET:
269  if(topOrDown)
270  new_state = false;
271  else
272  new_state = true;
273  break;
274  }
275  compare_output_state[idx] = new_state;
276  if(compare_output[idx].active() && old_state != new_state)
277  compare_output[idx].SetAlternatePort(new_state);
278 }
279 
281  switch(event) {
282  case EVT_MAX_REACHED:
284  break;
285 
286  case EVT_COMPARE_1:
287  if(timerCompare[0]) {
289  SetCompareOutput(0);
290  }
291  break;
292 
293  case EVT_COMPARE_2:
294  if(timerCompare[1]) {
296  SetCompareOutput(1);
297  }
298  break;
299 
300  case EVT_COMPARE_3:
301  if(timerCompare[2]) {
303  SetCompareOutput(2);
304  }
305  break;
306 
307  default:
308  break;
309  }
310 }
311 
313  switch(event) {
314  case EVT_MAX_REACHED:
316  break;
317 
318  case EVT_TOP_REACHED:
320  break;
321 
322  case EVT_COMPARE_1:
323  if(timerCompare[0]) {
325  SetCompareOutput(0);
326  }
327  break;
328 
329  case EVT_COMPARE_2:
330  if(timerCompare[1]) {
332  SetCompareOutput(1);
333  }
334  break;
335 
336  case EVT_COMPARE_3:
337  if(timerCompare[2]) {
339  SetCompareOutput(2);
340  }
341  break;
342 
343  default:
344  break;
345  }
346 }
347 
349  switch(event) {
350  case EVT_TOP_REACHED:
351  // fire overflow interrupt
353  // if ICR or OCRA mode, fire too this interrupts
354  if(wgm == WGM_FASTPWM_OCRA) {
357  } else if(wgm == WGM_FASTPWM_ICR) {
358  if(timerCapture)
360  }
361  // process compare output unit
362  for(int i = 0; i < OCRIDX_maxUnits; i++)
363  SetPWMCompareOutput(i, true);
364  // reset counter
366  break;
367 
368  case EVT_BOTTOM_REACHED:
369  // update OC registers
370  for(int i = 0; i < OCRIDX_maxUnits; i++) {
371  if(i == OCRIDX_A) {
372  if(wgm == WGM_FASTPWM_8BIT)
373  // mask to 0xff
374  compare[i] = compare_dbl[i] & 0xff;
375  else if(wgm == WGM_FASTPWM_9BIT)
376  // mask to 0x1ff
377  compare[i] = compare_dbl[i] & 0x1ff;
378  else if(wgm == WGM_FASTPWM_10BIT)
379  // mask to 0x3ff
380  compare[i] = compare_dbl[i] & 0x3ff;
381  else if(wgm == WGM_FASTPWM_OCRA)
382  // set new top value
383  limit_top = compare_dbl[i];
384  else
386  } else
387  compare[i] = compare_dbl[i];
388  }
389  break;
390 
391  case EVT_COMPARE_1:
392  if(timerCompare[0] && wgm != WGM_FASTPWM_OCRA) {
394  SetPWMCompareOutput(0, false);
395  }
396  break;
397 
398  case EVT_COMPARE_2:
399  if(timerCompare[1]) {
401  SetPWMCompareOutput(1, false);
402  }
403  break;
404 
405  case EVT_COMPARE_3:
406  if(timerCompare[2]) {
408  SetPWMCompareOutput(2, false);
409  }
410  break;
411 
412  default:
413  break;
414  }
415 }
416 
418  switch(event) {
419  case EVT_TOP_REACHED:
420  // if ICR or OCRA mode, fire this interrupts
421  if(wgm == WGM_PCPWM_OCRA) {
424  } else if(wgm == WGM_PCPWM_ICR) {
425  if(timerCapture)
427  }
428  // update OC registers
429  for(int i = 0; i < OCRIDX_maxUnits; i++) {
430  if(i == OCRIDX_A) {
431  if(wgm == WGM_PCPWM_8BIT)
432  // mask to 0xff
433  compare[i] = compare_dbl[i] & 0xff;
434  else if(wgm == WGM_PCPWM_9BIT)
435  // mask to 0x1ff
436  compare[i] = compare_dbl[i] & 0x1ff;
437  else if(wgm == WGM_PCPWM_10BIT)
438  // mask to 0x3ff
439  compare[i] = compare_dbl[i] & 0x3ff;
440  else if(wgm == WGM_PCPWM_OCRA) {
441  // set new top value
442  limit_top = compare_dbl[i];
443  // and process output
444  SetPWMCompareOutput(0, false);
445  } else
447 
448  } else
449  compare[i] = compare_dbl[i];
450  }
451  break;
452 
453  case EVT_BOTTOM_REACHED:
454  // fire overflow interrupt
456  break;
457 
458  case EVT_COMPARE_1:
459  if(timerCompare[0] && wgm != WGM_PCPWM_OCRA) {
462  }
463  break;
464 
465  case EVT_COMPARE_2:
466  if(timerCompare[1]) {
469  }
470  break;
471 
472  case EVT_COMPARE_3:
473  if(timerCompare[2]) {
476  }
477  break;
478 
479  default:
480  break;
481  }
482 }
483 
485  (this->*wgmfunc[wgm])(event);
486  if(eventListener != NULL) eventListener->fireEvent(event);
487 }
488 
490  switch(event) {
491  case EVT_TOP_REACHED:
492  // if ICR or OCRA mode, fire this interrupts
493  if(wgm == WGM_PFCPWM_OCRA) {
496  } else if(wgm == WGM_PFCPWM_ICR) {
497  if(timerCapture)
499  }
500  // process output from OC A in case of WGM_PFCPWM_OCRA
501  if(wgm == WGM_PFCPWM_OCRA)
502  SetPWMCompareOutput(0, false);
503  break;
504 
505  case EVT_BOTTOM_REACHED:
506  // fire overflow interrupt
508  // update OC registers
509  for(int i = 0; i < OCRIDX_maxUnits; i++) {
510  if(i == OCRIDX_A) {
511  if(wgm == WGM_PFCPWM_OCRA)
512  // set new top value
513  limit_top = compare_dbl[i];
514  else
516  } else
517  compare[i] = compare_dbl[i];
518  }
519  break;
520 
521  case EVT_COMPARE_1:
522  if(timerCompare[0] && wgm != WGM_PFCPWM_OCRA) {
525  }
526  break;
527 
528  case EVT_COMPARE_2:
529  if(timerCompare[1]) {
532  }
533  break;
534 
535  case EVT_COMPARE_3:
536  if(timerCompare[2]) {
539  }
540  break;
541 
542  default:
543  break;
544  }
545 }
546 
548  vtcnt = 0;
549  limit_bottom = 0;
552  for(int i = 0; i < OCRIDX_maxUnits; i++) {
553  compare_dbl[i] = 0;
554  compare[i] = 0;
556  compare_output_state[i] = false;
557  }
558  SetClockMode(0);
559  updown_counting = false;
560  count_down = false;
561  wgm = WGM_NORMAL;
562  icapRisingEdge = false;
563  icapNoiseCanceler = false;
564 }
565 
566 unsigned int BasicTimerUnit::CpuCycle() {
567  if(premx->isClock(cs))
568  CountTimer();
569  InputCapture();
570  return 0;
571 }
572 
574  if(icapSource != NULL)
575  icapSource->RegisterAComp(acomp);
576 }
577 
580  int unit,
581  IRQLine* tov,
582  IRQLine* tcompA,
583  const PinAtPort& outA,
584  IRQLine* tcompB,
585  const PinAtPort& outB):
586  BasicTimerUnit(core, p, unit, tov, NULL, NULL, 8),
587  tcnt_reg(this, "TCNT",
588  this, &HWTimer8::Get_TCNT, &HWTimer8::Set_TCNT),
589  ocra_reg(this, "OCRA",
590  this, &HWTimer8::Get_OCRA, &HWTimer8::Set_OCRA),
591  ocrb_reg(this, "OCRB",
592  this, &HWTimer8::Get_OCRB, &HWTimer8::Set_OCRB)
593 {
594  // enable OC units and disable registers
595  if(tcompA) {
596  compareEnable[0] = true;
597  timerCompare[0] = tcompA;
598  compare_output[0] = outA;
599  } else
601  if(tcompB) {
602  compareEnable[1] = true;
603  timerCompare[1] = tcompB;
604  compare_output[1] = outB;
605  } else
607 
608  // set WGM table
613 
614  // reset unit
615  Reset();
616 }
617 
618 void HWTimer8::Reset(void) {
620 }
621 
623  wgm = mode;
624  switch(wgm) {
625  case WGM_PCPWM_9BIT:
626  case WGM_PCPWM_10BIT:
627  case WGM_FASTPWM_9BIT:
628  case WGM_FASTPWM_10BIT:
629  case WGM_PFCPWM_ICR:
630  case WGM_PFCPWM_OCRA:
631  case WGM_PCPWM_ICR:
632  case WGM_PCPWM_OCRA:
633  case WGM_CTC_ICR:
634  case WGM_RESERVED:
635  case WGM_FASTPWM_ICR:
636  case WGM_FASTPWM_OCRA:
637  case WGM_tablesize:
638  break;
639 
640  case WGM_NORMAL:
642  updown_counting = false;
643  break;
644 
645  case WGM_CTC_OCRA:
646  limit_top = compare[0];
647  updown_counting = false;
648  break;
649 
650  case WGM_FASTPWM_8BIT:
652  updown_counting = false;
653  break;
654 
655  case WGM_PCPWM_8BIT:
657  updown_counting = true;
658  count_down = false;
659  break;
660  }
661 }
662 
663 void HWTimer8::SetCompareRegister(int idx, unsigned char val) {
664  if(WGMisPWM())
665  compare_dbl[idx] = val;
666  else {
667  compare[idx] = val;
668  compare_dbl[idx] = val;
669  if(wgm == WGM_CTC_OCRA && idx == 0)
670  // in case od setting OCRA and WGM mode is CTC with OCRA, then set
671  // also counter top value here
672  limit_top = val;
673  }
674 }
675 
676 unsigned char HWTimer8::GetCompareRegister(int idx) {
677  if(WGMisPWM())
678  return compare_dbl[idx] & 0xff;
679  else
680  return compare[idx] & 0xff;
681 }
682 
685  int unit,
686  IRQLine* tov,
687  IRQLine* tcompA,
688  const PinAtPort& outA,
689  IRQLine* tcompB,
690  const PinAtPort& outB,
691  IRQLine* tcompC,
692  const PinAtPort& outC,
693  IRQLine* ticap,
694  ICaptureSource* icapsrc):
695  BasicTimerUnit(core, p, unit, tov, ticap, icapsrc, 16),
696  tcnt_h_reg(this, "TCNTH",
697  this, &HWTimer16::Get_TCNTH, &HWTimer16::Set_TCNTH),
698  tcnt_l_reg(this, "TCNTL",
699  this, &HWTimer16::Get_TCNTL, &HWTimer16::Set_TCNTL),
700  ocra_h_reg(this, "OCRAH",
701  this, &HWTimer16::Get_OCRAH, &HWTimer16::Set_OCRAH),
702  ocra_l_reg(this, "OCRAL",
703  this, &HWTimer16::Get_OCRAL, &HWTimer16::Set_OCRAL),
704  ocrb_h_reg(this, "OCRBH",
705  this, &HWTimer16::Get_OCRBH, &HWTimer16::Set_OCRBH),
706  ocrb_l_reg(this, "OCRBL",
707  this, &HWTimer16::Get_OCRBL, &HWTimer16::Set_OCRBL),
708  ocrc_h_reg(this, "OCRCH",
709  this, &HWTimer16::Get_OCRCH, &HWTimer16::Set_OCRCH),
710  ocrc_l_reg(this, "OCRCL",
711  this, &HWTimer16::Get_OCRCL, &HWTimer16::Set_OCRCL),
712  icr_h_reg(this, "ICRH",
713  this, &HWTimer16::Get_ICRH, &HWTimer16::Set_ICRH),
714  icr_l_reg(this, "ICRL",
715  this, &HWTimer16::Get_ICRL, &HWTimer16::Set_ICRL)
716 {
717  // enable OC units and disable registers
718  if(tcompA) {
719  compareEnable[0] = true;
720  timerCompare[0] = tcompA;
721  compare_output[0] = outA;
722  } else {
725  }
726  if(tcompB) {
727  compareEnable[1] = true;
728  timerCompare[1] = tcompB;
729  compare_output[1] = outB;
730  } else {
733  }
734  if(tcompC) {
735  compareEnable[2] = true;
736  timerCompare[2] = tcompC;
737  compare_output[2] = outC;
738  } else {
741  }
742 
743  // set WGM table
759 
760  // reset unit
761  Reset();
762 }
763 
764 void HWTimer16::Reset(void) {
766  // initialize temp. register for 16Bit access
767  accessTempRegister = 0;
768 }
769 
770 void HWTimer16::SetCompareRegister(int idx, bool high, unsigned char val) {
771  unsigned long temp;
772  if(high) {
773  accessTempRegister = val;
774  } else {
775  temp = (accessTempRegister << 8) + val;
776  if(WGMisPWM())
777  compare_dbl[idx] = temp;
778  else {
779  compare[idx] = temp;
780  compare_dbl[idx] = temp;
781  if(wgm == WGM_CTC_OCRA && idx == 0)
782  // in case od setting OCRA and WGM mode is CTC with OCRA, then set
783  // also counter top value here
784  limit_top = temp;
785  }
786  }
787 }
788 
789 unsigned char HWTimer16::GetCompareRegister(int idx, bool high) {
790  unsigned long temp;
791  if(WGMisPWM())
792  temp = compare_dbl[idx];
793  else
794  temp = compare[idx];
795  if(high)
796  return (temp >> 8) & 0xff;
797  else
798  return temp & 0xff;
799 }
800 
801 void HWTimer16::SetComplexRegister(bool is_icr, bool high, unsigned char val) {
802  if(high) {
803  if(is_icr && !WGMuseICR())
804  avr_warning("ICRxH isn't writable in a non-ICR WGM mode");
805  else
806  accessTempRegister = val;
807  } else {
808  if(is_icr) {
809  if(WGMuseICR()) {
810  icapRegister = (accessTempRegister << 8) + val;
811  if(wgm == WGM_FASTPWM_ICR)
813  } else
814  avr_warning("ICRxL isn't writable in a non-ICR WGM mode");
815  } else
816  SetCounter((accessTempRegister << 8) + val);
817  }
818 }
819 
820 unsigned char HWTimer16::GetComplexRegister(bool is_icr, bool high) {
821  if(high)
822  return accessTempRegister;
823  else {
824  if(is_icr) {
825  accessTempRegister = (icapRegister >> 8) & 0xff;
826  return icapRegister & 0xff;
827  } else {
828  accessTempRegister = (vtcnt >> 8) & 0xff;
829  return vtcnt & 0xff;
830  }
831  }
832 }
833 
835  wgm = mode;
836  switch(wgm) {
837  case WGM_RESERVED:
838  case WGM_tablesize:
839  break;
840 
841  case WGM_NORMAL:
843  updown_counting = false;
844  break;
845 
846  case WGM_CTC_OCRA:
847  limit_top = compare[0];
848  updown_counting = false;
849  break;
850 
851  case WGM_CTC_ICR:
853  updown_counting = false;
854  break;
855 
856  case WGM_FASTPWM_8BIT:
857  limit_top = 0xff;
858  updown_counting = false;
859  break;
860 
861  case WGM_FASTPWM_9BIT:
862  limit_top = 0x1ff;
863  updown_counting = false;
864  break;
865 
866  case WGM_FASTPWM_10BIT:
867  limit_top = 0x3ff;
868  updown_counting = false;
869  break;
870 
871  case WGM_FASTPWM_OCRA:
872  limit_top = compare[0];
873  updown_counting = false;
874  break;
875 
876  case WGM_FASTPWM_ICR:
878  updown_counting = false;
879  break;
880 
881  case WGM_PCPWM_8BIT:
882  limit_top = 0xff;
883  updown_counting = true;
884  count_down = false;
885  break;
886 
887  case WGM_PCPWM_9BIT:
888  limit_top = 0x1ff;
889  updown_counting = true;
890  count_down = false;
891  break;
892 
893  case WGM_PCPWM_10BIT:
894  limit_top = 0x3ff;
895  updown_counting = true;
896  count_down = false;
897  break;
898 
899  case WGM_PCPWM_OCRA:
900  case WGM_PFCPWM_OCRA:
901  limit_top = compare[0];
902  updown_counting = true;
903  count_down = false;
904  break;
905 
906  case WGM_PCPWM_ICR:
907  case WGM_PFCPWM_ICR:
909  updown_counting = true;
910  count_down = false;
911  break;
912  }
913 }
914 
917  int unit,
918  IRQLine* tov):
919  HWTimer8(core, p, unit, tov, NULL, PinAtPort(), NULL, PinAtPort()),
920  tccr_reg(this, "TCCR",
921  this, &HWTimer8_0C::Get_TCCR, &HWTimer8_0C::Set_TCCR)
922 {
924 }
925 
926 void HWTimer8_0C::Set_TCCR(unsigned char val) {
927  SetClockMode(val & 0x7);
928  tccr_val = val;
929 }
930 
932  HWTimer8::Reset();
933  tccr_val = 0;
934 }
935 
938  int unit,
939  IRQLine* tov,
940  IRQLine* tcompA,
941  const PinAtPort& outA):
942  HWTimer8(core, p, unit, tov, tcompA, outA, NULL, PinAtPort()),
943  tccr_reg(this, "TCCR",
945 
946 void HWTimer8_1C::Set_TCCR(unsigned char val) {
947  WGMtype temp;
948  int raw_wgm = ((val & 0x8) >> 2) + ((val & 0x40) >> 6);
949  switch(raw_wgm) {
950  case 0: temp = WGM_NORMAL; break;
951  case 1: temp = WGM_PCPWM_8BIT; break;
952  case 2: temp = WGM_CTC_OCRA; break;
953  case 3: temp = WGM_FASTPWM_8BIT; break;
954  }
955  if(wgm != temp)
956  ChangeWGM((WGMtype)temp);
957  SetCompareOutputMode(0, (COMtype)((val >> 4) & 0x3));
958  SetClockMode(val & 0x7);
959  if(!WGMisPWM() && val & 0x80)
960  // FOCx
961  SetCompareOutput(0);
962 
963  tccr_val = val & 0x7f;
964 }
965 
967  HWTimer8::Reset();
968  tccr_val = 0;
969 }
970 
973  int unit,
974  IRQLine* tov,
975  IRQLine* tcompA,
976  const PinAtPort& outA,
977  IRQLine* tcompB,
978  const PinAtPort& outB):
979  HWTimer8(core, p, unit, tov, tcompA, outA, tcompB, outB),
980  tccra_reg(this, "TCCRA",
981  this, &HWTimer8_2C::Get_TCCRA, &HWTimer8_2C::Set_TCCRA),
982  tccrb_reg(this, "TCCRB",
983  this, &HWTimer8_2C::Get_TCCRB, &HWTimer8_2C::Set_TCCRB) {}
984 
985 void HWTimer8_2C::Set_WGM(int val) {
986  WGMtype w;
987  if(wgm_raw != val) {
988  // translate WGM modes
989  switch(val & 0x7) {
990  case 0: w = WGM_NORMAL; break;
991  case 1: w = WGM_PCPWM_8BIT; break;
992  case 2: w = WGM_CTC_OCRA; break;
993  case 3: w = WGM_FASTPWM_8BIT; break;
994  case 4: w = WGM_RESERVED; break;
995  case 5: w = WGM_PCPWM_OCRA; break;
996  case 6: w = WGM_RESERVED; break;
997  case 7: w = WGM_FASTPWM_OCRA; break;
998  }
999  ChangeWGM(w);
1000  // save new raw value
1001  wgm_raw = val;
1002  }
1003 }
1004 
1005 void HWTimer8_2C::Set_TCCRA(unsigned char val) {
1006  int temp = wgm_raw;
1007  temp &= ~0x3;
1008  temp += val & 0x3;
1009  Set_WGM(temp);
1010  SetCompareOutputMode(0, (COMtype)((val >> 6) & 0x3));
1011  SetCompareOutputMode(1, (COMtype)((val >> 4) & 0x3));
1012 
1013  tccra_val = val;
1014 }
1015 
1016 void HWTimer8_2C::Set_TCCRB(unsigned char val) {
1017  int temp = wgm_raw;
1018  temp &= ~0x4;
1019  temp += (val >> 1) & 0x4;
1020  Set_WGM(temp);
1021  SetClockMode(val & 0x7);
1022  if(!WGMisPWM()) {
1023  if(val & 0x80)
1024  // FOCxA
1025  SetCompareOutput(0);
1026  if(val & 0x40)
1027  // FOCxB
1028  SetCompareOutput(1);
1029  }
1030 
1031  tccrb_val = val & 0x3f;
1032 }
1033 
1035  HWTimer8::Reset();
1036  tccra_val = 0;
1037  tccrb_val = 0;
1038  wgm_raw = 0;
1039 }
1040 
1043  int unit,
1044  IRQLine* tov,
1045  IRQLine* tcompA,
1046  const PinAtPort& outA,
1047  IRQLine* ticap,
1048  ICaptureSource* icapsrc):
1049  HWTimer16(core, p, unit, tov, tcompA, outA, NULL, PinAtPort(), NULL, PinAtPort(), ticap, icapsrc),
1050  tccra_reg(this, "TCCRA",
1052  tccrb_reg(this, "TCCRB",
1054 
1055 void HWTimer16_1C::Set_WGM(int val) {
1056  WGMtype w;
1057  if(wgm_raw != val) {
1058  // translate WGM modes
1059  switch(val & 0x7) {
1060  case 0: w = WGM_NORMAL; break;
1061  case 1: w = WGM_PCPWM_8BIT; break;
1062  case 2: w = WGM_PCPWM_9BIT; break;
1063  case 3: w = WGM_PCPWM_10BIT; break;
1064  case 4: w = WGM_CTC_OCRA; break;
1065  case 5: w = WGM_PCPWM_8BIT; break;
1066  case 6: w = WGM_PCPWM_9BIT; break;
1067  case 7: w = WGM_PCPWM_10BIT; break;
1068  }
1069  ChangeWGM(w);
1070  // save new raw value
1071  wgm_raw = val;
1072  }
1073 }
1074 
1075 void HWTimer16_1C::Set_TCCRA(unsigned char val) {
1076  int temp = wgm_raw;
1077  temp &= ~0x3;
1078  temp += val & 0x3;
1079  Set_WGM(temp);
1080  SetCompareOutputMode(0, (COMtype)((val >> 6) & 0x3));
1081 
1082  tccra_val = val;
1083 }
1084 
1085 void HWTimer16_1C::Set_TCCRB(unsigned char val) {
1086  int temp = wgm_raw;
1087  temp &= ~0x4;
1088  temp += (val >> 1) & 0x4;
1089  Set_WGM(temp);
1090  SetClockMode(val & 0x7);
1091  icapNoiseCanceler = (val & 0x80) == 0x80;
1092  icapRisingEdge = (val & 0x40) == 0x40;
1093 
1094  tccrb_val = val;
1095 }
1096 
1098  HWTimer16::Reset();
1099  tccra_val = 0;
1100  tccrb_val = 0;
1101  wgm_raw = 0;
1102 }
1103 
1106  int unit,
1107  IRQLine* tov,
1108  IRQLine* tcompA,
1109  const PinAtPort& outA,
1110  IRQLine* tcompB,
1111  const PinAtPort& outB,
1112  IRQLine* ticap,
1113  ICaptureSource* icapsrc,
1114  bool is_at8515):
1115  HWTimer16(core, p, unit, tov, tcompA, outA, tcompB, outB, NULL, PinAtPort(), ticap, icapsrc),
1116  at8515_mode(is_at8515),
1117  tccra_reg(this, "TCCRA",
1119  tccrb_reg(this, "TCCRB",
1121 {}
1122 
1123 void HWTimer16_2C2::Set_WGM(int val) {
1124  if(wgm_raw != val) {
1125  // translate WGM modes
1126  if(at8515_mode) {
1127  WGMtype w;
1128  switch(val & 0x7) {
1129  case 0: w = WGM_NORMAL; break;
1130  case 1: w = WGM_PCPWM_8BIT; break;
1131  case 2: w = WGM_PCPWM_9BIT; break;
1132  case 3: w = WGM_PCPWM_10BIT; break;
1133  case 4: w = WGM_CTC_OCRA; break;
1134  case 5: w = WGM_PCPWM_8BIT; break;
1135  case 6: w = WGM_PCPWM_9BIT; break;
1136  case 7: w = WGM_PCPWM_10BIT; break;
1137  }
1138  ChangeWGM(w);
1139  } else
1140  ChangeWGM((WGMtype)val);
1141  // save new raw value
1142  wgm_raw = val;
1143  }
1144 }
1145 
1146 void HWTimer16_2C2::Set_TCCRA(unsigned char val) {
1147  int temp = wgm_raw;
1148  temp &= ~0x3;
1149  temp += val & 0x3;
1150  Set_WGM(temp);
1151  SetCompareOutputMode(0, (COMtype)((val >> 6) & 0x3));
1152  SetCompareOutputMode(1, (COMtype)((val >> 4) & 0x3));
1153  if(!WGMisPWM() && !at8515_mode) {
1154  if(val & 0x08)
1155  // FOCxA
1156  SetCompareOutput(0);
1157  if(val & 0x04)
1158  // FOCxB
1159  SetCompareOutput(1);
1160  }
1161 
1162  tccra_val = val;
1163 }
1164 
1165 void HWTimer16_2C2::Set_TCCRB(unsigned char val) {
1166  int mask = at8515_mode ? 0x4 : 0xc;
1167  int temp = wgm_raw;
1168  temp &= ~mask;
1169  temp += (val >> 1) & mask;
1170  Set_WGM(temp);
1171  SetClockMode(val & 0x7);
1172  icapNoiseCanceler = (val & 0x80) == 0x80;
1173  icapRisingEdge = (val & 0x40) == 0x40;
1174 
1175  tccrb_val = val;
1176 }
1177 
1179  HWTimer16::Reset();
1180  tccra_val = 0;
1181  tccrb_val = 0;
1182  wgm_raw = 0;
1183 }
1184 
1187  int unit,
1188  IRQLine* tov,
1189  IRQLine* tcompA,
1190  const PinAtPort& outA,
1191  IRQLine* tcompB,
1192  const PinAtPort& outB,
1193  IRQLine* ticap,
1194  ICaptureSource* icapsrc):
1195  HWTimer16(core, p, unit, tov, tcompA, outA, tcompB, outB, NULL, PinAtPort(), ticap, icapsrc),
1196  tccra_reg(this, "TCCRA",
1198  tccrb_reg(this, "TCCRB",
1200  tccrc_reg(this, "TCCRC",
1201  this, &HWTimer16_2C3::Get_TCCRC, &HWTimer16_2C3::Set_TCCRC) {}
1202 
1203 void HWTimer16_2C3::Set_TCCRA(unsigned char val) {
1204  int temp = (int)wgm;
1205  temp &= ~0x3;
1206  temp += val & 0x3;
1207  if(wgm != (WGMtype)temp)
1208  ChangeWGM((WGMtype)temp);
1209  SetCompareOutputMode(0, (COMtype)((val >> 6) & 0x3));
1210  SetCompareOutputMode(1, (COMtype)((val >> 4) & 0x3));
1211 
1212  tccra_val = val;
1213 }
1214 
1215 void HWTimer16_2C3::Set_TCCRB(unsigned char val) {
1216  int temp = (int)wgm;
1217  temp &= ~0xc;
1218  temp += (val >> 1) & 0xc;
1219  if(wgm != (WGMtype)temp)
1220  ChangeWGM((WGMtype)temp);
1221  SetClockMode(val & 0x7);
1222  icapNoiseCanceler = (val & 0x80) == 0x80;
1223  icapRisingEdge = (val & 0x40) == 0x40;
1224 
1225  tccrb_val = val;
1226 }
1227 
1228 void HWTimer16_2C3::Set_TCCRC(unsigned char val) {
1229  if(!WGMisPWM()) {
1230  if(val & 0x80)
1231  // FOCxA
1232  SetCompareOutput(0);
1233  if(val & 0x40)
1234  // FOCxB
1235  SetCompareOutput(1);
1236  }
1237 }
1238 
1240  HWTimer16::Reset();
1241  tccra_val = 0;
1242  tccrb_val = 0;
1243 }
1244 
1247  int unit,
1248  IRQLine* tov,
1249  IRQLine* tcompA,
1250  const PinAtPort& outA,
1251  IRQLine* tcompB,
1252  const PinAtPort& outB,
1253  IRQLine* tcompC,
1254  const PinAtPort& outC,
1255  IRQLine* ticap,
1256  ICaptureSource* icapsrc):
1257  HWTimer16(core, p, unit, tov, tcompA, outA, tcompB, outB, tcompC, outC, ticap, icapsrc),
1258  tccra_reg(this, "TCCRA",
1260  tccrb_reg(this, "TCCRB",
1262  tccrc_reg(this, "TCCRC",
1264 
1265 void HWTimer16_3C::Set_TCCRA(unsigned char val) {
1266  int temp = (int)wgm;
1267  temp &= ~0x3;
1268  temp += val & 0x3;
1269  if(wgm != (WGMtype)temp)
1270  ChangeWGM((WGMtype)temp);
1271  SetCompareOutputMode(0, (COMtype)((val >> 6) & 0x3));
1272  SetCompareOutputMode(1, (COMtype)((val >> 4) & 0x3));
1273  SetCompareOutputMode(2, (COMtype)((val >> 2) & 0x3));
1274 
1275  tccra_val = val;
1276 }
1277 
1278 void HWTimer16_3C::Set_TCCRB(unsigned char val) {
1279  int temp = (int)wgm;
1280  temp &= ~0xc;
1281  temp += (val >> 1) & 0xc;
1282  if(wgm != (WGMtype)temp)
1283  ChangeWGM((WGMtype)temp);
1284  SetClockMode(val & 0x7);
1285  icapNoiseCanceler = (val & 0x80) == 0x80;
1286  icapRisingEdge = (val & 0x40) == 0x40;
1287 
1288  tccrb_val = val;
1289 }
1290 
1291 void HWTimer16_3C::Set_TCCRC(unsigned char val) {
1292  if(!WGMisPWM()) {
1293  if(val & 0x80)
1294  // FOCxA
1295  SetCompareOutput(0);
1296  if(val & 0x40)
1297  // FOCxB
1298  SetCompareOutput(1);
1299  if(val & 0x20)
1300  // FOCxC
1301  SetCompareOutput(2);
1302  }
1303 }
1304 
1306  HWTimer16::Reset();
1307  tccra_val = 0;
1308  tccrb_val = 0;
1309 }
1310 
1312 
1317 const int HWTimerTinyX5_nextdelay[8] = { 16, 15, 16, 16, 15, 16, 15, 16 };
1318 
1320  IOSpecialReg *gtccr,
1321  IOSpecialReg *pllcsr,
1322  IRQLine* tov,
1323  IRQLine* tocra,
1324  const PinAtPort& ocra_out,
1325  const PinAtPort& ocra_outinv,
1326  IRQLine* tocrb,
1327  const PinAtPort& ocrb_out,
1328  const PinAtPort& ocrb_outinv):
1329  Hardware(core),
1330  TraceValueRegister(core, "TIMER1"),
1331  ocra_unit(ocra_out, ocra_outinv),
1332  ocrb_unit(ocrb_out, ocrb_outinv),
1333  core(core),
1334  timerOverflowInt(tov),
1335  timerOCRAInt(tocra),
1336  timerOCRBInt(tocrb),
1337  tccr_reg(this, "TCCR1",
1338  this, &HWTimerTinyX5::Get_TCCR, &HWTimerTinyX5::Set_TCCR),
1339  tcnt_reg(this, "TCNT1",
1340  this, &HWTimerTinyX5::Get_TCNT, &HWTimerTinyX5::Set_TCNT),
1341  tocra_reg(this, "OCR1A",
1342  this, &HWTimerTinyX5::Get_OCRA, &HWTimerTinyX5::Set_OCRA),
1343  tocrb_reg(this, "OCR1B",
1344  this, &HWTimerTinyX5::Get_OCRB, &HWTimerTinyX5::Set_OCRB),
1345  tocrc_reg(this, "OCR1C",
1346  this, &HWTimerTinyX5::Get_OCRC, &HWTimerTinyX5::Set_OCRC),
1347  dtps1_reg(this, "DTPS1",
1348  this, &HWTimerTinyX5::Get_DTPS1, &HWTimerTinyX5::Set_DTPS1),
1349  dt1a_reg(this, "DT1A",
1350  this, &HWTimerTinyX5::Get_DT1A, &HWTimerTinyX5::Set_DT1A),
1351  dt1b_reg(this, "DT1B",
1352  this, &HWTimerTinyX5::Get_DT1B, &HWTimerTinyX5::Set_DT1B)
1353 {
1354  // gtccr and pllcsr register
1355  gtccrRegister = gtccr;
1357  pllcsrRegister = pllcsr;
1359 
1360  // create TraceValue for counter itself and for prescaler
1361  counterTrace = new TraceValue(8, GetTraceValuePrefix() + "Counter");
1364  prescalerTrace = new TraceValue(14, GetTraceValuePrefix() + "Prescaler");
1367  dTPrescalerTrace = new TraceValue(3, GetTraceValuePrefix() + "DeadTimePrescaler");
1370 
1371  // connect to core to get core cycles
1372  core->AddToCycleList(this);
1373 
1374  // pre initialization for async mode, starts with sync mode
1375  asyncClock_async = false;
1376  asyncClock_step = -1;
1377 
1378  // reset internal values
1379  Reset();
1380 }
1381 
1383  counter = 0;
1384  tcnt_out_val = tcnt_in_val = 0;
1385  tcnt_set_flag = false;
1387  prescaler = 0;
1388  dtprescaler = 0;
1389  tccr_inout_val.Reset(0);
1390  cfg_prescaler = 0;
1392  cfg_com_a = cfg_com_b = 0;
1393  cfg_ctc = false;
1394  ocra_inout_val.Reset(0);
1395  ocra_internal_val = 0;
1396  ocrb_inout_val.Reset(0);
1397  ocrb_internal_val = 0;
1398  ocrc_inout_val.Reset(0xff);
1399  dtps1_inout_val = 0;
1400  dt1a_inout_val.Reset(0);
1401  dt1b_inout_val.Reset(0);
1402  gtccr_in_val.Reset(0);
1404 
1405  ocra_unit.Reset();
1406  ocrb_unit.Reset();
1407 
1408  SetPrescalerClock(false); // reset prescaler to sync. clock mode, if necessary!
1409 }
1410 
1411 int HWTimerTinyX5::Step(bool &untilCoreStepFinished, SystemClockOffset *nextStepIn_ns) {
1412  if(asyncClock_async) {
1413  *nextStepIn_ns = HWTimerTinyX5_nextdelay[asyncClock_step];
1414  asyncClock_step++;
1415  if(asyncClock_lsm) {
1416  *nextStepIn_ns += HWTimerTinyX5_nextdelay[asyncClock_step];
1417  asyncClock_step++;
1418  }
1419  if(asyncClock_step == 8) asyncClock_step = 0;
1420  // process prescaler and timer
1421  TimerCounter();
1422  // dump_manager->cycle() needed to get correct trace display
1424  // transfer input register values to real used operation registers (pll clock delay 1 step in async mode)
1426  } else {
1427  // switch to sync clock
1428  asyncClock_step = -1; // this activates timer calculation in CpuCycle()
1429  *nextStepIn_ns = -1; // this removes timer from syncMembers list
1430  }
1431  return 0;
1432 }
1433 
1434 unsigned int HWTimerTinyX5::CpuCycle() {
1435  // transfer output register values to readable register by core
1437  // if sync mode ...
1438  if(asyncClock_step == -1) {
1439  // transfer input register values to real used operation registers (system clock delay 1 step in sync mode)
1441  // count prescaler, if sync. mode, e.g. timer clock is system clock
1442  TimerCounter();
1443  }
1444 
1445  // control pll state
1446  if(asyncClock_pll) {
1447  if(!asyncClock_plllock && (SystemClock::Instance().GetCurrentTime() >= asyncClock_locktime))
1448  asyncClock_plllock = true;
1449  }
1450  return 0;
1451 }
1452 
1454  // if prescaler mux gets a pulse ...
1455  if(PrescalerMux()) {
1456  // count pulse for timer
1457  counter++;
1458  // detect counter overflow (== OCRC + 1 or 0xff + 1!) ...
1459  if((counter > 0xff) ||
1460  (((cfg_mode != TMODE_NORMAL) || cfg_ctc) && ((counter - 1) == (unsigned char)ocrc_inout_val))) {
1461  counter = 0;
1462  // set TOV1 event but not in CTC mode!
1463  if((cfg_mode != TMODE_NORMAL) || !cfg_ctc)
1464  tov_internal_flag = true;
1465  // load compare values for OCR1A and OCR1B in PWM mode
1466  if(cfg_mode != TMODE_NORMAL) {
1469  }
1470  // trigger pin change (reset)
1471  ocra_unit.TimerEvent(false);
1472  ocrb_unit.TimerEvent(false);
1473  }
1474  // detect OCR1A event ...
1475  if(counter == ocra_compare) {
1476  // set OCF1A event
1477  tocra_internal_flag = true;
1478  // trigger pin change
1479  if(!(cfg_mode & TMODE_PWMA) || (ocra_compare < ocrc_inout_val))
1480  // no compare pin change, if PWM and OCRB == OCRC
1481  ocra_unit.TimerEvent(true);
1482  }
1483  // detect OCR1B event ...
1484  if(counter == ocrb_compare) {
1485  // set OCF1B event
1486  tocrb_internal_flag = true;
1487  // trigger pin change
1488  if(!(cfg_mode & TMODE_PWMB) || (ocrb_compare < ocrc_inout_val))
1489  // no compare pin change, if PWM and OCRB == OCRC
1490  ocrb_unit.TimerEvent(true);
1491  }
1493  }
1494  // handle DeadTimePrescaler-Mux ...
1495  if(DeadTimePrescalerMux()) {
1496  // handle dead time counter
1499  }
1500 }
1501 
1503  // count prescaler, free running
1504  prescaler++;
1505  if(prescaler == 0x4000) prescaler = 0; // prescaler with = 14 bit
1507  // select prescaler tap
1508  switch(cfg_prescaler) {
1509  case 0: // no clock, counter stop
1510  return false;
1511 
1512  case 1: // every clock
1513  return true;
1514 
1515  case 2: // CKx2
1516  return (bool)((prescaler % 2) == 0);
1517 
1518  case 3: // CKx4
1519  return (bool)((prescaler % 4) == 0);
1520 
1521  case 4: // CKx8
1522  return (bool)((prescaler % 8) == 0);
1523 
1524  case 5: // CKx16
1525  return (bool)((prescaler % 16) == 0);
1526 
1527  case 6: // CKx32
1528  return (bool)((prescaler % 32) == 0);
1529 
1530  case 7: // CKx64
1531  return (bool)((prescaler % 64) == 0);
1532 
1533  case 8: // CKx128
1534  return (bool)((prescaler % 128) == 0);
1535 
1536  case 9: // CKx256
1537  return (bool)((prescaler % 256) == 0);
1538 
1539  case 10: // CKx512
1540  return (bool)((prescaler % 512) == 0);
1541 
1542  case 11: // CKx1024
1543  return (bool)((prescaler % 1024) == 0);
1544 
1545  case 12: // CKx2048
1546  return (bool)((prescaler % 2048) == 0);
1547 
1548  case 13: // CKx4096
1549  return (bool)((prescaler % 4096) == 0);
1550 
1551  case 14: // CKx8192
1552  return (bool)((prescaler % 8192) == 0);
1553 
1554  case 15: // CKx16384
1555  return (bool)((prescaler % 16384) == 0);
1556  }
1557 
1558  // should not happen
1559  return 0;
1560 }
1561 
1563  // count prescaler, freerunning
1564  dtprescaler++;
1565  if(dtprescaler == 0x8) dtprescaler = 0; // dead time prescaler with = 3 bit
1567  // select dead time prescaler tap
1568  switch(cfg_dtprescaler) {
1569  case 0: // every clock
1570  return true;
1571 
1572  case 1: // CKx2
1573  return (bool)((dtprescaler % 2) == 0);
1574 
1575  case 2: // CKx4
1576  return (bool)((dtprescaler % 4) == 0);
1577 
1578  case 3: // CKx8
1579  return (bool)((dtprescaler % 8) == 0);
1580  }
1581 
1582  // should not happen
1583  return 0;
1584 }
1585 
1586 unsigned char HWTimerTinyX5::set_from_reg(const IOSpecialReg *reg, unsigned char nv) {
1587  if(reg == gtccrRegister) {
1588  // check prescaler reset bit [bit1]
1589  if((nv & 0x02) == 0x02) {
1590  nv &= ~0x02; // reset bit immediately
1591  prescaler = 0; // reset prescaler
1592  }
1593  gtccr_in_val = nv;
1594  } else if(reg == pllcsrRegister) {
1595  // reflect and control pll state
1596  bool pll = (nv & 0x02) == 0x02;
1597  if(asyncClock_pll) {
1598  if(!pll) {
1599  asyncClock_pll = false;
1600  asyncClock_plllock = false;
1601  }
1602  } else {
1603  if(pll) {
1604  asyncClock_pll = true;
1605  asyncClock_plllock = false;
1606  // delay about 100µs, uses rand() function, but this is ok here, we don't need
1607  // real random values, just a "jitter", results in a delay 100µs +- 1µs!
1608  // (but because data sheet dosn't tell anything about time deviation, this
1609  // is a assumption and to prove!)
1610  srand(time(NULL));
1611  unsigned long delay = 100000 + rand() % 2000 - 1000;
1613  }
1614  }
1615  // get clock source for timer 1 [bit7 = LSM, bit2 = PCKE]
1616  asyncClock_lsm = (nv & 0x80) == 0x80;
1617  SetPrescalerClock((nv & 0x04) == 0x04);
1618  }
1619  return nv;
1620 }
1621 
1622 unsigned char HWTimerTinyX5::get_from_client(const IOSpecialReg *reg, unsigned char v) {
1623  if(reg == pllcsrRegister) {
1624  if(asyncClock_plllock)
1625  v |= 0x01;
1626  else
1627  v &= ~0x01;
1628  }
1629  if(reg == gtccrRegister) {
1630  v &= ~0x0c; // FOC1A and FOC1B will be read back as 0 in every case
1631  }
1632  return v;
1633 }
1634 
1636  if(pcke) {
1637  // Async clock enabled?
1638  if(!asyncClock_async) {
1639  asyncClock_async = true;
1640  asyncClock_step = 0; // this disabled also timer calculation in CpuCycle() to be secure
1641  SystemClock::Instance().Add(this); // now the async clock is activated
1642  } else {
1643  if(asyncClock_lsm) asyncClock_step &= ~1; // on lsm async mode we take every second step
1644  }
1645  } else {
1646  // Sync clock enabled?
1647  if(asyncClock_step >= 0) {
1648  // switch to sync clock
1649  asyncClock_async = false; // disable is delayed to next call of Step()
1650  }
1651  }
1652 }
1653 
1655  // settings from TCCR
1657  cfg_prescaler = tccr_inout_val & 0x0f;
1658  if((tccr_inout_val & 0x40) == 0x40)
1659  cfg_mode |= TMODE_PWMA;
1660  else
1661  cfg_mode &= ~TMODE_PWMA;
1662  cfg_com_a = (tccr_inout_val >> 4) & 0x3;
1663  ocra_unit.SetOCRMode((tccr_inout_val & 0x40) == 0x40, (tccr_inout_val >> 4) & 0x3);
1664  // set ctc mode, this is only possible, if counter counts till OCR1C value!
1665  cfg_ctc = (tccr_inout_val & 0x80) == 0x80;
1666  }
1667  // settings from GTCCR
1669  cfg_com_b = (gtccr_in_val >> 4) & 0x3;
1670  if((gtccr_in_val & 0x40) == 0x40)
1671  cfg_mode |= TMODE_PWMB;
1672  else
1673  cfg_mode &= ~TMODE_PWMB;
1674  ocrb_unit.SetOCRMode((gtccr_in_val & 0x40) == 0x40, (gtccr_in_val >> 4) & 0x3);
1675  if(gtccr_in_val & 0x04) {
1677  gtccr_in_val.MaskOutSync(0x04);
1678  }
1679  if(gtccr_in_val & 0x08) {
1681  gtccr_in_val.MaskOutSync(0x08);
1682  }
1683  }
1684  // OCRA settings
1686  if(cfg_mode != TMODE_NORMAL)
1687  // take over value on timer overflow
1689  else
1690  // take over value immediately
1692  }
1693  // OCRB settings
1695  if(cfg_mode != TMODE_NORMAL)
1696  // take over value on timer overflow
1698  else
1699  // take over value immediately
1701  }
1702  // OCRC settings
1704  // timer update
1705  if(tcnt_set_flag) {
1706  counter = tcnt_in_val;
1707  tcnt_set_flag = false;
1708  }
1709  // settings from DTPS1
1711  // settings from DT1A
1713  ocra_unit.SetDeadTime((dt1a_inout_val >> 4) & 0x0f, dt1a_inout_val & 0x0f);
1714  // settings from DT1B
1716  ocrb_unit.SetDeadTime((dt1b_inout_val >> 4) & 0x0f, dt1b_inout_val & 0x0f);
1717 }
1718 
1720  // counter value TCNT
1721  if(asyncClock_step == -1)
1722  // in sync mode
1724  else
1725  // in async mode
1728  // TOV interrupt
1729  if(tov_internal_flag) {
1730  tov_internal_flag = false;
1732  }
1733  // OCFxA interrupt
1734  if(tocra_internal_flag) {
1735  tocra_internal_flag = false;
1737  }
1738  // OCFxB interrupt
1739  if(tocrb_internal_flag) {
1740  tocrb_internal_flag = false;
1742  }
1743 }
1744 
1745 TimerTinyX5_OCR::TimerTinyX5_OCR(const PinAtPort& pinOut, const PinAtPort& pinOutInv) {
1746  outPin = pinOut;
1747  outPinInv = pinOutInv;
1748 
1749  Reset();
1750 }
1751 
1753  ocrComMode = 0;
1754  ocrPWM = false;
1755  ocrOut = false;
1756  dtHigh = 0;
1757  dtLow = 0;
1758  dtCounter = 0;
1759 }
1760 
1762  if(dtCounter > 0) {
1763  dtCounter--;
1764  if(dtCounter == 0) {
1765  // dead time arrived, set output or inverted output
1766  if(ocrOut)
1767  outPin.SetAlternatePort(ocrOut);
1768  else
1769  outPinInv.SetAlternatePort(!ocrOut);
1770  }
1771  }
1772 }
1773 
1774 void TimerTinyX5_OCR::SetOCRMode(bool isPWM, int comMode) {
1775  // if switch output on, then get value of out pin (for toggle function)
1776  if((ocrComMode == 0) && (comMode != 0)) {
1777  ocrOut = outPin.GetPort();
1778  }
1779  // enable/disable alternate port pin
1780  if(ocrComMode != comMode) {
1781  if(comMode > 0) {
1782  // connect normal pin
1783  outPin.SetUseAlternatePortIfDdrSet(true);
1784  outPin.SetAlternatePort(ocrOut);
1785  if(isPWM && comMode == 1) {
1786  // connect inverted pin
1787  outPinInv.SetUseAlternatePortIfDdrSet(true);
1788  outPinInv.SetAlternatePort(!ocrOut);
1789  }
1790  } else {
1791  // disconnect both pins
1792  outPin.SetUseAlternatePortIfDdrSet(false);
1793  outPinInv.SetUseAlternatePortIfDdrSet(false);
1794  }
1795  }
1796  // store values
1797  ocrComMode = comMode;
1798  ocrPWM = isPWM;
1799 }
1800 
1801 void TimerTinyX5_OCR::SetPWM(bool isCompareEvent) {
1802  bool out = ocrOut;
1803  if(ocrPWM) {
1804  // in PWM mode
1805  if(isCompareEvent) {
1806  switch(ocrComMode) {
1807  case 0:
1808  // output is disabled, do not change pin
1809  break;
1810 
1811  case 1:
1812  case 2:
1813  // clear on compare
1814  out = false;
1815  break;
1816 
1817  case 3:
1818  // set on compare
1819  out = true;
1820  break;
1821  }
1822  } else {
1823  switch(ocrComMode) {
1824  case 0:
1825  // output is disabled, do not change pin
1826  break;
1827 
1828  case 1:
1829  case 2:
1830  // set on overflow
1831  out = true;
1832  break;
1833 
1834  case 3:
1835  // clear on overflow
1836  out = false;
1837  break;
1838  }
1839  }
1840  SetDeadTime(out);
1841  } else {
1842  // in normal mode (only compare event)
1843  if(isCompareEvent) {
1844  switch(ocrComMode) {
1845  case 0:
1846  // output is disabled, do not change pin
1847  break;
1848 
1849  case 1:
1850  // toggle output
1851  if(out)
1852  out = false;
1853  else
1854  out = true;
1855  break;
1856 
1857  case 2:
1858  // clear pin
1859  out = false;
1860  break;
1861 
1862  case 3:
1863  // set pin
1864  out = true;
1865  break;
1866  }
1867  SetDeadTime(out);
1868  }
1869  }
1870 }
1871 
1872 void TimerTinyX5_OCR::SetDeadTime(bool pwmValue) {
1873  if((ocrComMode == 1) && ocrPWM) {
1874  // dead time generator is only active in mode 1 and PWM
1875  if(pwmValue && !ocrOut) {
1876  // rising edge
1877  if(dtHigh > 0)
1878  dtCounter = dtHigh + 1;
1879  else {
1880  // no dead time, set output immediately
1881  outPin.SetAlternatePort(pwmValue);
1882  }
1883  outPinInv.SetAlternatePort(!pwmValue);
1884  } else if(!pwmValue && ocrOut) {
1885  // falling edge
1886  if(dtLow > 0)
1887  dtCounter = dtLow + 1;
1888  else {
1889  // no dead time, set inverted output immediately
1890  outPinInv.SetAlternatePort(!pwmValue);
1891  }
1892  outPin.SetAlternatePort(pwmValue);
1893  }
1894  } else
1895  // set output immediately
1896  outPin.SetAlternatePort(pwmValue);
1897  ocrOut = pwmValue;
1898 }
1899 
1900 // EOF
TraceValue * counterTrace
TraceValue instance for counter itself.
Definition: hwtimer.h:784
COMtype
types of compare match output modes
Definition: hwtimer.h:115
TimerEventListener * eventListener
event listener for timer events
Definition: hwtimer.h:56
int cfg_com_b
internal (async) setting for compare output modul B
Definition: hwtimer.h:824
void Add(SimulationMember *dev)
Add a simulation member (normally a device)
void WGMfunc_pfcpwm(CEtype event)
WGM function for phase and frequency correct pwm mode (unique for all different timers) ...
Definition: hwtimer.cpp:489
bool WGMisPWM(void)
returns true, if WGM is in one of the PWM modes
Definition: hwtimer.h:183
int Step(bool &untilCoreStepFinished, SystemClockOffset *nextStepIn_ns)
Performs the async clocking, if necessary.
Definition: hwtimer.cpp:1411
unsigned char Get_TCCRA()
Register access to read control register A.
Definition: hwtimer.h:544
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
unsigned long vlast_tcnt
timercounter BEFORE count operation
Definition: hwtimer.h:136
bool asyncClock_plllock
pll frequency is locked
Definition: hwtimer.h:837
void MaskOutSync(unsigned char mask)
Mask out a value inside sync area and do not force a change event.
Definition: hwtimer.h:772
int asyncClock_step
step counter for step delays. -1, if not in async mode
Definition: hwtimer.h:833
bool tocrb_internal_flag
OCFxB flag is set, have to be delayed by 1 CK.
Definition: hwtimer.h:810
unsigned char GetComplexRegister(bool is_icr, bool high)
Getter method for TCNT and ICR register.
Definition: hwtimer.cpp:820
int icapNCcounter
counter for input capture noise canceler
Definition: hwtimer.h:54
void SetPWM(bool isCompareEvent)
Calculate output pin value (before dead time generator)
Definition: hwtimer.cpp:1801
timer in PWM mode, upcounting from 0 to OCRC, PWM A active
Definition: hwtimer.h:828
void SetPWMCompareOutput(int idx, bool topOrDown)
Set compare output pins in pwm mode.
Definition: hwtimer.cpp:244
IOSpecialReg * gtccrRegister
instance of GTCCR register
Definition: hwtimer.h:842
unsigned long counter
THE timer counter.
Definition: hwtimer.h:789
unsigned char dtprescaler
dead time prescaler counter
Definition: hwtimer.h:791
IOReg< HWTimer16 > ocrc_h_reg
output compare C register, high byte
Definition: hwtimer.h:316
void AddToCycleList(Hardware *hw)
Definition: avrdevice.cpp:51
int wgm_raw
this is the wgm raw value from register
Definition: hwtimer.h:419
timer in PWM mode, upcounting from 0 to OCRC, PWM B active
Definition: hwtimer.h:829
SystemClockOffset GetCurrentTime() const
Returns the current simulation time.
Definition: systemclock.h:95
compare[0] value reached for one count cycle
Definition: hwtimer.h:64
int cfg_com_a
internal (async) setting for compare output modul A
Definition: hwtimer.h:823
IRQLine * timerOCRBInt
irq line for output compare B interrupt
Definition: hwtimer.h:849
unsigned char Get_TCCRB()
Register access to read control register B.
Definition: hwtimer.h:607
void WGMFunc_noop(CEtype event)
WGM noop function.
Definition: hwtimer.h:187
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:1239
TraceValue * counterTrace
TraceValue instance for counter itself.
Definition: hwtimer.h:52
bool icapNCstate
state for input capture noise canceler
Definition: hwtimer.h:55
void Set_WGM(int val)
Handle special WGM setting, translate wgm raw value to wgm value.
Definition: hwtimer.cpp:985
unsigned char tccrb_val
register value TCCRB
Definition: hwtimer.h:426
unsigned char Get_TCCRB()
Register access to read control register B.
Definition: hwtimer.h:549
virtual void InputCapture(void)
Supports the input capture function.
Definition: hwtimer.cpp:160
HWTimerTinyX5_SyncReg tccr_inout_val
register value TCCR1
Definition: hwtimer.h:794
IOReg< HWTimer16 > ocra_h_reg
output compare A register, high byte
Definition: hwtimer.h:312
Timer unit with 8Bit counter and one output compare unit.
Definition: hwtimer.h:377
int cfg_mode
internal (async) timer mode setting
Definition: hwtimer.h:821
Extends BasicTimerUnit to provide common support to all types of 8Bit timer units.
Definition: hwtimer.h:202
unsigned long limit_top
TOP value for counting.
Definition: hwtimer.h:143
void Set_TCCRA(unsigned char val)
Register access to set control register.
Definition: hwtimer.cpp:1005
unsigned char tccra_val
register value TCCRA
Definition: hwtimer.h:538
TOP reached for one count cycle.
Definition: hwtimer.h:61
IOReg< HWTimer16 > ocra_l_reg
output compare A register, low byte
Definition: hwtimer.h:313
void Set_TCCRA(unsigned char val)
Register access to set control register A.
Definition: hwtimer.cpp:1146
bool WGMuseICR(void)
returns true, if WGM uses IC register for defining TOP counter value
Definition: hwtimer.h:185
void Set_TCCR(unsigned char val)
Register access to set control register.
Definition: hwtimer.cpp:946
HWTimerTinyX5_SyncReg ocrb_inout_val
register value OCRB
Definition: hwtimer.h:796
STL namespace.
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:1034
virtual bool GetSourceState(void)
Returns the digital input state of input capture source(s)
Definition: icapturesrc.cpp:34
unsigned char ocra_internal_val
internal (async) register value for OCRA1
Definition: hwtimer.h:813
IOReg< HWTimer16 > ocrc_l_reg
output compare C register, low byte
Definition: hwtimer.h:317
unsigned char tccrb_val
register value TCCRB
Definition: hwtimer.h:660
void Reset()
Perform a reset of this unit.
Definition: hwtimer.cpp:618
unsigned char accessTempRegister
the high byte temporary register for read/write access to TCNT and ICR
Definition: hwtimer.h:250
Represents a timer interrupt line, Frontend for timer interrupts.
Definition: timerirq.h:42
void WGMfunc_pcpwm(CEtype event)
WGM function for phase correct pwm mode (unique for all different timers)
Definition: hwtimer.cpp:417
BOTTOM reached for one count cycle.
Definition: hwtimer.h:63
virtual bool isClock(unsigned int cs)
bool count_down
counter counts down, used for precise pwm modes
Definition: hwtimer.h:141
unsigned char tccra_val
register value TCCRA
Definition: hwtimer.h:479
void SetOCRMode(bool isPWM, int comMode)
Configure OCR mode.
Definition: hwtimer.cpp:1774
unsigned long ocra_compare
active compare value for OCR A unit
Definition: hwtimer.h:814
unsigned long limit_bottom
BOTTOM value for up/down counting.
Definition: hwtimer.h:142
const int HWTimerTinyX5_nextdelay[8]
Step time in ns for async clock by pll.
Definition: hwtimer.cpp:1317
unsigned char tccrb_val
register value TCCRB
Definition: hwtimer.h:480
unsigned char tccr_val
register value TCCR
Definition: hwtimer.h:380
unsigned char Get_TCCRC()
Register access to read control register C.
Definition: hwtimer.h:612
void Set_TCCRB(unsigned char val)
Register access to set control register B.
Definition: hwtimer.cpp:1165
amount of possible OC units
Definition: hwtimer.h:126
bool DeadTimePrescalerMux(void)
Dead time prescaler multiplex function, returns true, if a count pulse is happen. ...
Definition: hwtimer.cpp:1562
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 CountTimer(void)
Supports the count operation, emits count events to HandleEvent method.
Definition: hwtimer.cpp:90
unsigned char dtps1_inout_val
register value DTPS1
Definition: hwtimer.h:799
unsigned char get_from_client(const IOSpecialReg *reg, unsigned char v)
IO register interface get method, see IOSpecialRegClient.
Definition: hwtimer.cpp:1622
IOReg< HWTimer16_2C3 > tccra_reg
control register A
Definition: hwtimer.h:615
COMtype com[OCRIDX_maxUnits]
compare match output mode
Definition: hwtimer.h:156
IOReg< HWTimer8_2C > tccrb_reg
control register B
Definition: hwtimer.h:440
int cfg_prescaler
internal (async) prescaler setting
Definition: hwtimer.h:819
bool asyncClock_pll
pll is switched on
Definition: hwtimer.h:836
void WGMfunc_normal(CEtype event)
WGM function for normal mode (unique for all different timers)
Definition: hwtimer.cpp:280
void Reset()
Perform a reset of this unit.
Definition: hwtimer.cpp:547
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:931
void SetUseAlternatePortIfDdrSet(bool val)
Definition: pinatport.cpp:95
unsigned long prescaler
THE prescaler counter.
Definition: hwtimer.h:790
IOReg< HWTimer16_2C3 > tccrb_reg
control register B
Definition: hwtimer.h:616
bool captureInputState
saved state for input capture
Definition: hwtimer.h:53
void Set_TCCRB(unsigned char val)
Register access to set control register B.
Definition: hwtimer.cpp:1278
bool asyncClock_lsm
mode switch for lsm mode (32MHz clock)
Definition: hwtimer.h:835
an counter overflow occured
Definition: hwtimer.h:62
void Set_TCCRA(unsigned char val)
Register access to set control register A.
Definition: hwtimer.cpp:1265
IOReg< HWTimer8_2C > tccra_reg
control register A
Definition: hwtimer.h:439
HWTimer16_2C3(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA, IRQLine *tcompB, const PinAtPort &outB, IRQLine *ticap, ICaptureSource *icapsrc)
Definition: hwtimer.cpp:1185
void set_written()
Definition: traceval.cpp:99
BasicTimerUnit(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcap, ICaptureSource *icapsrc, int countersize=8)
Create a basic Timer/Counter unit.
Definition: hwtimer.cpp:38
#define avr_error(...)
Definition: avrerror.h:135
Basic timer unit.
Definition: hwtimer.h:48
timer in normal mode, upcounting from 0x0 to 0xff or 0 to OCRC (CTC mode)
Definition: hwtimer.h:827
HWTimer16_1C(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA, IRQLine *ticap, ICaptureSource *icapsrc)
Definition: hwtimer.cpp:1041
void SetPrescalerClock(bool pcke)
Set clock source for prescaler.
Definition: hwtimer.cpp:1635
TraceValue * dTPrescalerTrace
TraceValue instance for dead time prescaler.
Definition: hwtimer.h:786
TimerTinyX5_OCR ocra_unit
OCR control unit for OCR channel A.
Definition: hwtimer.h:815
PrescalerMultiplexer * premx
prescaler multiplexer
Definition: hwtimer.h:131
void WGMfunc_fastpwm(CEtype event)
WGM function for fast pwm mode (unique for all different timers)
Definition: hwtimer.cpp:348
void SetAlternatePort(bool val)
Definition: pinatport.cpp:85
Timer unit with 16Bit counter and 2 output compare units, but 3 config registers. ...
Definition: hwtimer.h:593
void TransferInputValues(void)
Transfer register input to internal register set.
Definition: hwtimer.cpp:1654
void WGMfunc_ctc(CEtype event)
WGM function for ctc mode (unique for all different timers)
Definition: hwtimer.cpp:312
IRQLine * timerOCRAInt
irq line for output compare A interrupt
Definition: hwtimer.h:848
virtual unsigned int CpuCycle()
Process timer/counter unit operations by CPU cycle.
Definition: hwtimer.cpp:566
Build a register for TraceValue&#39;s.
Definition: traceval.h:442
HWTimer8(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA, IRQLine *tcompB, const PinAtPort &outB)
Definition: hwtimer.cpp:578
void SetCompareOutputMode(int idx, COMtype mode)
Set compare output mode.
Definition: hwtimer.cpp:208
TimerTinyX5_OCR(const PinAtPort &pinOut, const PinAtPort &pinOutInv)
Definition: hwtimer.cpp:1745
void SetCompareRegister(int idx, unsigned char val)
Setter method for compare register.
Definition: hwtimer.cpp:663
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:764
void RegisterTraceValue(TraceValue *t)
Registers a TraceValue for this register.
Definition: traceval.cpp:217
unsigned char tccrb_val
register value TCCRB
Definition: hwtimer.h:597
compare[1] value reached for one count cycle
Definition: hwtimer.h:65
static SystemClock & Instance()
Returns the central SystemClock instance for the application.
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:1097
timer unit for timer 1 on ATtiny25/45/85
Definition: hwtimer.h:778
void Set_TCCRB(unsigned char val)
Register access to set control register B.
Definition: hwtimer.cpp:1085
void SetCompareRegister(int idx, bool high, unsigned char val)
Setter method for compare register.
Definition: hwtimer.cpp:770
unsigned char tcnt_in_val
input register value for TCNT
Definition: hwtimer.h:806
unsigned char tcnt_out_val
output register value for TCNT
Definition: hwtimer.h:804
void TimerCounter(void)
Count function, contains prescaler, multiplexer and counter functionality.
Definition: hwtimer.cpp:1453
unsigned long compare[OCRIDX_maxUnits]
compare values for output compare events
Definition: hwtimer.h:153
unsigned char Get_TCCRA()
Register access to read control register.
Definition: hwtimer.h:431
Timer unit with 16Bit counter and 2 output compare units and 2 config registers.
Definition: hwtimer.h:528
int cs
select value for prescaler multiplexer
Definition: hwtimer.h:51
HWTimerTinyX5_SyncReg dt1a_inout_val
register value DT1A
Definition: hwtimer.h:800
HWTimerTinyX5(AvrDevice *core, IOSpecialReg *gtccr, IOSpecialReg *pllcsr, IRQLine *tov, IRQLine *tocra, const PinAtPort &ocra_out, const PinAtPort &ocra_outinv, IRQLine *tocrb, const PinAtPort &ocrb_out, const PinAtPort &ocrb_outinv)
Definition: hwtimer.cpp:1319
bool icapRisingEdge
Input capture on rising edge.
Definition: hwtimer.h:148
void TimerEvent(bool isCompareEvent)
OCR event.
Definition: hwtimer.h:730
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:1305
void Reset()
Perform a reset of this unit.
Definition: hwtimer.cpp:1382
TimerTinyX5_OCR ocrb_unit
OCR control unit for OCR channel B.
Definition: hwtimer.h:818
void ChangeWGM(WGMtype mode)
Change WGM mode, set counter limits.
Definition: hwtimer.cpp:622
bool icapNoiseCanceler
Noise canceler for input capturing enabled.
Definition: hwtimer.h:149
void RegisterAComp(HWAcomp *_acomp)
Register analog comparator.
Definition: icapturesrc.h:49
void fireInterrupt(void)
inform interrupt system, that an interrupt occured
Definition: timerirq.cpp:46
void SetCounter(unsigned long val)
Set the counter itself.
Definition: hwtimer.cpp:202
unsigned long compare_dbl[OCRIDX_maxUnits]
double buffer values for compare values
Definition: hwtimer.h:154
unsigned char tccr_val
register value TCCR
Definition: hwtimer.h:350
long long SystemClockOffset
unsigned char Get_TCCR()
Register access to read control register.
Definition: hwtimer.h:355
bool tocra_internal_flag
OCFxA flag is set, have to be delayed by 1 CK.
Definition: hwtimer.h:809
TraceValue * prescalerTrace
TraceValue instance for prescaler.
Definition: hwtimer.h:785
bool ClockAndChanged(void)
check after one clock, if register value has changed
Definition: hwtimer.h:769
std::string int2str(int i)
Convert an int into a string.
Definition: helper.cpp:59
HWTimerTinyX5_SyncReg dt1b_inout_val
register value DT1B
Definition: hwtimer.h:801
IOReg< HWTimer16_1C > tccrb_reg
control register B
Definition: hwtimer.h:494
HWTimer8_2C(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA, IRQLine *tcompB, const PinAtPort &outB)
Definition: hwtimer.cpp:971
void Set_TCCRC(unsigned char val)
Register access to set control register C.
Definition: hwtimer.cpp:1228
IOReg< HWTimer16 > ocrb_l_reg
output compare B register, low byte
Definition: hwtimer.h:315
WGMtype
types of waveform generation modes
Definition: hwtimer.h:95
compare[2] value reached for one count cycle
Definition: hwtimer.h:66
Timer unit with 16Bit counter and 3 output compare units.
Definition: hwtimer.h:656
HWTimerTinyX5_SyncReg ocra_inout_val
register value OCRA
Definition: hwtimer.h:795
wgmfunc_t wgmfunc[WGM_tablesize]
waveform generator mode function table
Definition: hwtimer.h:152
unsigned long icapRegister
Input capture register.
Definition: hwtimer.h:146
unsigned long limit_max
MAX value for counting.
Definition: hwtimer.h:144
int wgm_raw
this is the wgm raw value from register
Definition: hwtimer.h:531
unsigned char ocrb_internal_val
internal (async) register value for OCRB1
Definition: hwtimer.h:816
virtual void fireEvent(int event)=0
void SetCompareOutput(int idx)
Set compare output pins in non pwm mode.
Definition: hwtimer.cpp:220
AvrDevice * core
pointer to device core
Definition: hwtimer.h:130
unsigned char tccra_val
register value TCCRA
Definition: hwtimer.h:425
void Reset()
Reset internal states on device reset.
Definition: hwtimer.cpp:1752
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:966
unsigned char Get_TCCRB()
Register access to read control register.
Definition: hwtimer.h:436
void RegisterACompForICapture(HWAcomp *acomp)
register analog comparator unit for input capture source
Definition: hwtimer.cpp:573
#define avr_warning(...)
Definition: avrerror.h:133
HWTimer8_0C(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov)
Definition: hwtimer.cpp:915
int updown_counting
count direction control flag, true, if up/down counting
Definition: hwtimer.h:140
void Set_TCCRC(unsigned char val)
Register access to set control register C.
Definition: hwtimer.cpp:1291
unsigned char GetCompareRegister(int idx)
Getter method for compare register.
Definition: hwtimer.cpp:676
Timer unit with 16Bit counter and one output compare unit.
Definition: hwtimer.h:470
void Set_TCCRA(unsigned char val)
Register access to set control register A.
Definition: hwtimer.cpp:1203
HWTimerTinyX5_SyncReg ocrc_inout_val
register value OCRC
Definition: hwtimer.h:797
IRQLine * timerOverflow
irq line for overflow interrupt
Definition: hwtimer.h:132
void RemoveFromCycleList(Hardware *hw)
Removes from the cycle list, if possible.
Definition: avrdevice.cpp:56
IOReg< HWTimer16_1C > tccra_reg
control register A
Definition: hwtimer.h:493
void TransferOutputValues(void)
Transfer internal register values (if needed) to by core readable register.
Definition: hwtimer.cpp:1719
unsigned long vtcnt
THE timercounter.
Definition: hwtimer.h:135
Timer unit with 8Bit counter and no output compare unit.
Definition: hwtimer.h:347
unsigned char set_from_reg(const IOSpecialReg *reg, unsigned char nv)
IO register interface set method, see IOSpecialRegClient.
Definition: hwtimer.cpp:1586
HWTimer16_2C2(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA, IRQLine *tcompB, const PinAtPort &outB, IRQLine *ticap, ICaptureSource *icapsrc, bool is_at8515)
Definition: hwtimer.cpp:1104
void Set_TCCR(unsigned char val)
Register access to set control register.
Definition: hwtimer.cpp:926
const std::string GetTraceValuePrefix(void)
Returns the scope prefix.
Definition: traceval.h:487
void HandleEvent(CEtype event)
Receives count events.
Definition: hwtimer.cpp:484
bool PrescalerMux(void)
Prescaler multiplex function, returns true, if a count pulse is happen.
Definition: hwtimer.cpp:1502
IOReg< HWTimer8_0C > tccr_reg
control register
Definition: hwtimer.h:358
void Set_TCCRA(unsigned char val)
Register access to set control register A.
Definition: hwtimer.cpp:1075
IOReg< HWTimer16 > ocrb_h_reg
output compare B register, high byte
Definition: hwtimer.h:314
int wgm_raw
this is the wgm raw value from register
Definition: hwtimer.h:473
void ForceEvent()
Manual change of OCR unit by force bit.
Definition: hwtimer.h:733
int cfg_dtprescaler
internal (async) dead time prescaler setting
Definition: hwtimer.h:820
void Reset(unsigned char v)
perform a reset to set valid reset values without clock
Definition: hwtimer.h:755
IOReg< HWTimer16_2C3 > tccrc_reg
control register C
Definition: hwtimer.h:617
PrescalerMultiplexer without external count pin.
Definition: prescalermux.h:35
bool compare_output_state[OCRIDX_maxUnits]
status compare output pin
Definition: hwtimer.h:159
HWTimer16(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA, IRQLine *tcompB, const PinAtPort &outB, IRQLine *tcompC, const PinAtPort &outC, IRQLine *ticap, ICaptureSource *icapsrc)
Definition: hwtimer.cpp:683
bool at8515_mode
signals, that this timer units is used in AT90S8515
Definition: hwtimer.h:532
IOReg< HWTimer8 > ocra_reg
output compare A register
Definition: hwtimer.h:230
unsigned char tccra_val
register value TCCRA
Definition: hwtimer.h:659
unsigned char tccrb_val
register value TCCRB
Definition: hwtimer.h:539
void Set_WGM(int val)
Handle special WGM setting, translate wgm raw value to wgm value.
Definition: hwtimer.cpp:1123
PinAtPort compare_output[OCRIDX_maxUnits]
output pins for compare units
Definition: hwtimer.h:158
IRQLine * timerCompare[OCRIDX_maxUnits]
irq line for compare interrupt
Definition: hwtimer.h:157
Class, which provides input capture source for 16bit timers.
Definition: icapturesrc.h:34
IRQLine * timerCapture
irq line for capture interrupt
Definition: hwtimer.h:133
bool tcnt_set_flag
flag to signal, that a new counter value was set
Definition: hwtimer.h:807
unsigned char Get_TCCRA()
Register access to read control register A.
Definition: hwtimer.h:485
unsigned char tccra_val
register value TCCRA
Definition: hwtimer.h:596
Timer unit with 8Bit counter and 2 output compare unit.
Definition: hwtimer.h:416
ICaptureSource * icapSource
Input capture source.
Definition: hwtimer.h:147
static DumpManager * Instance(void)
Singleton class access.
Definition: traceval.cpp:567
index for OCR unit A
Definition: hwtimer.h:123
bool compareEnable[OCRIDX_maxUnits]
enables compare operation
Definition: hwtimer.h:155
unsigned char Get_TCCRB()
Register access to read control register B.
Definition: hwtimer.h:490
void Set_TCCRB(unsigned char val)
Register access to set control register.
Definition: hwtimer.cpp:1016
void change(unsigned val)
Log a change on this value.
Definition: traceval.cpp:68
unsigned char Get_TCCRA()
Register access to read control register A.
Definition: hwtimer.h:602
CEtype
event types for timer/counter
Definition: hwtimer.h:60
void Set_WGM(int val)
Handle special WGM setting, translate wgm raw value to wgm value.
Definition: hwtimer.cpp:1055
IOReg< HWTimer16_2C2 > tccrb_reg
control register B
Definition: hwtimer.h:553
void SetDeadTime(bool pwmValue)
Calculate output pin value after dead time generator.
Definition: hwtimer.cpp:1872
unsigned long ocrb_compare
active compare value for OCR B unit
Definition: hwtimer.h:817
bool cfg_ctc
internal (async) flag for clear timer counter
Definition: hwtimer.h:822
HWTimer16_3C(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA, IRQLine *tcompB, const PinAtPort &outB, IRQLine *tcompC, const PinAtPort &outC, IRQLine *ticap, ICaptureSource *icapsrc)
Definition: hwtimer.cpp:1245
void ChangeWGM(WGMtype mode)
Change WGM mode, set counter limits.
Definition: hwtimer.cpp:834
Extends BasicTimerUnit to provide common support to all types of 16Bit timer units.
Definition: hwtimer.h:246
SystemClockOffset asyncClock_locktime
time, when pll is locked
Definition: hwtimer.h:838
unsigned char GetCompareRegister(int idx, bool high)
Getter method for compare register.
Definition: hwtimer.cpp:789
void cycle()
Definition: traceval.cpp:686
void SetClockMode(int _cs)
Set clock mode.
Definition: hwtimer.cpp:193
bool tov_internal_flag
TOV flag is set, have to be delayed by 1 CK.
Definition: hwtimer.h:808
IOReg< HWTimer8 > ocrb_reg
output compare B register
Definition: hwtimer.h:231
void Set_TCCRB(unsigned char val)
Register access to set control register B.
Definition: hwtimer.cpp:1215
HWTimerTinyX5_SyncReg gtccr_in_val
input register value GTCCR
Definition: hwtimer.h:798
void Reset(void)
Perform a reset of this unit.
Definition: hwtimer.cpp:1178
void DTClockCycle()
Run one clock cycle from dead time prescaler.
Definition: hwtimer.cpp:1761
unsigned char tcnt_out_async_tmp
temporary register value for TCNT in async mode
Definition: hwtimer.h:805
IOSpecialReg * pllcsrRegister
instance of PLLCSR register
Definition: hwtimer.h:843
Analog comparator peripheral.
Definition: hwacomp.h:42
void SetComplexRegister(bool is_icr, bool high, unsigned char val)
Setter method for TCNT and ICR register.
Definition: hwtimer.cpp:801
IRQLine * timerOverflowInt
irq line for overflow interrupt
Definition: hwtimer.h:847
HWTimer8_1C(AvrDevice *core, PrescalerMultiplexer *p, int unit, IRQLine *tov, IRQLine *tcompA, const PinAtPort &outA)
Definition: hwtimer.cpp:936
void releaseTraceValue(void)
Definition: rwmem.h:320
IOReg< HWTimer16_2C2 > tccra_reg
control register A
Definition: hwtimer.h:552
WGMtype wgm
waveform generation mode
Definition: hwtimer.h:151
bool asyncClock_async
mode switch for async mode
Definition: hwtimer.h:834
unsigned int CpuCycle()
Process timer/counter unit operations by CPU cycle.
Definition: hwtimer.cpp:1434