simulavr  1.1.0
timerprescaler.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 "hwtimer/timerprescaler.h"
27 #include "traceval.h"
28 
29 HWPrescaler::HWPrescaler(AvrDevice *core, const std::string &tracename):
30  Hardware(core),
31  _resetBit(-1),
32  _resetSyncBit(-1),
33  countEnable(true)
34 {
35  core->AddToCycleList(this);
36  trace_direct(&(core->coreTraceGroup), "PRESCALER" + tracename, &preScaleValue);
37  resetRegister = NULL;
38 }
39 
41  const std::string &tracename,
42  IOSpecialReg *ioreg,
43  int resetBit):
44  Hardware(core),
45  _resetBit(resetBit),
46  _resetSyncBit(-1),
47  countEnable(true)
48 {
49  core->AddToCycleList(this);
50  trace_direct(&(core->coreTraceGroup), "PRESCALER" + tracename, &preScaleValue);
51  resetRegister = ioreg;
52  ioreg->connectSRegClient(this);
53 }
54 
56  const std::string &tracename,
57  IOSpecialReg *ioreg,
58  int resetBit,
59  int resetSyncBit):
60  Hardware(core),
61  _resetBit(resetBit),
62  _resetSyncBit(resetSyncBit),
63  countEnable(true)
64 {
65  core->AddToCycleList(this);
66  trace_direct(&(core->coreTraceGroup), "PRESCALER" + tracename, &preScaleValue);
67  resetRegister = ioreg;
68  ioreg->connectSRegClient(this);
69 }
70 
71 unsigned char HWPrescaler::set_from_reg(const IOSpecialReg *reg, unsigned char nv) {
72  // check, if this is the right register
73  if(reg != resetRegister) return nv;
74  // extract corresponding reset bit
75  int reset = (1 << _resetBit) & nv;
76  // extract reset sync bit, if available
77  int sync = 0;
78  if(_resetSyncBit >= 0)
79  sync = (1 << _resetSyncBit) & nv;
80 
81  if(reset) {
82  Reset(); // reset requested
83  if(sync)
84  countEnable = false; // sync asserted, stop counting
85  else {
86  countEnable = true; // let the counter run
87  return ~(1 << _resetBit) & nv; // reset the reset bit immediately, if no sync asserted
88  }
89  }
90  return nv; // return value unchanged
91 }
92 
94  const std::string &tracename,
95  PinAtPort tosc,
96  IOSpecialReg *asyreg,
97  int clockSelBit,
98  IOSpecialReg *ioreg,
99  int resetBit):
100  HWPrescaler(core, tracename, ioreg, resetBit),
101  tosc_pin(tosc),
102  clockSelectBit(clockSelBit)
103 {
104  asyncRegister = asyreg;
105  asyreg->connectSRegClient(this);
107  clockselect = false;
108 }
109 
111  const std::string &tracename,
112  PinAtPort tosc,
113  IOSpecialReg *asyreg,
114  int clockSelBit,
115  IOSpecialReg *ioreg,
116  int resetBit,
117  int resetSyncBit):
118  HWPrescaler(core, tracename, ioreg, resetBit, resetSyncBit),
119  tosc_pin(tosc),
120  clockSelectBit(clockSelBit)
121 {
122  asyncRegister = asyreg;
123  asyreg->connectSRegClient(this);
125  clockselect = false;
126 }
127 
129  bool e = true;
130  if(clockselect) {
131  bool ps = tosc_pin.GetPin();
132  if(pinstate || !ps) e = false; // count on positive edge!
133  pinstate = ps;
134  }
135  if(e && countEnable) {
136  preScaleValue++;
137  if(preScaleValue > 1023) preScaleValue = 0;
138  }
139  return 0;
140 }
141 
142 unsigned char HWPrescalerAsync::set_from_reg(const IOSpecialReg *reg, unsigned char nv) {
143  unsigned char v = HWPrescaler::set_from_reg(reg, nv);
144  if(reg != asyncRegister) return v;
145  if((1 << clockSelectBit) & v) {
146  clockselect = true;
147  //tosc_pin.SetAlternatePort(true);
148  } else {
149  clockselect = false;
150  //tosc_pin.SetAlternatePort(false);
151  }
152  return v;
153 }
154 
Pin & GetPin()
Definition: pinatport.cpp:45
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
bool pinstate
saved pin status of osc. pin
void AddToCycleList(Hardware *hw)
Definition: avrdevice.cpp:51
PinAtPort tosc_pin
input pin for external timer oscillator
IOSpecialReg * resetRegister
instance of IO register with reset bits
int _resetBit
holds bit position for reset bit on IO register
virtual unsigned int CpuCycle()
Count functionality for prescaler.
unsigned char set_from_reg(const IOSpecialReg *reg, unsigned char nv)
IO register interface set method, see IOSpecialRegClient.
void connectSRegClient(IOSpecialRegClient *c)
Registers a client to this IO register to inform this client on read or write access.
Definition: rwmem.h:429
IOSpecialReg * asyncRegister
instance of IO register with assr bits
int clockSelectBit
holds bit position of counter clock select
HWPrescalerAsync(AvrDevice *core, const std::string &tracename, PinAtPort tosc_pin, IOSpecialReg *asyreg, int clockSelBit, IOSpecialReg *resreg, int resetBit)
Creates HWPrescalerAsync instance with reset but without sync reset feature.
TraceValueCoreRegister coreTraceGroup
Definition: avrdevice.h:108
bool clockselect
holds the clock select state, true is external clock
void Reset()
Reset method, sets prescaler counter to 0.
int _resetSyncBit
holds sync bit position for prescaler reset synchronisation
Prescaler unit for support timers with clock.
unsigned short preScaleValue
prescaler counter value
HWPrescaler(AvrDevice *core, const std::string &tracename)
Creates HWPrescaler instance without reset feature.
unsigned char set_from_reg(const IOSpecialReg *reg, unsigned char nv)
IO register interface set method, see IOSpecialRegClient.
TraceValue * trace_direct(TraceValueRegister *t, const std::string &name, const bool *val)
Register a directly traced bool value.
Definition: traceval.cpp:788