simulavr  1.1.0
hwpinchange.cpp
Go to the documentation of this file.
1 #include <assert.h>
2 #include <iostream>
3 #include "hwpinchange.h"
4 #include "irqsystem.h"
5 
6 using namespace std;
7 
9  HWIrqSystem& irqSystem,
10  unsigned vector0,
11  unsigned vector1,
12  unsigned vector2,
13  unsigned vector3,
14  unsigned vector4,
15  unsigned vector5,
16  unsigned vector6,
17  unsigned vector7
18  ) throw():
19  Hardware(avr),
20  _pcifr(0),
21  _pcicr(0),
22  _irqSystem(irqSystem),
23  _vector0(vector0),
24  _vector1(vector1),
25  _vector2(vector2),
26  _vector3(vector3),
27  _vector4(vector4),
28  _vector5(vector5),
29  _vector6(vector6),
30  _vector7(vector7),
31  pcicr_reg(avr, "PINCHANGE.PCICR", this, &HWPcir::getPcicrMask,
33  pcifr_reg(avr, "PINCHANGE.PCIFR", this, &HWPcir::getPcifrMask,
35 {
36  assert(false); // Unreachable. No code ever constructs this class.
37  irqSystem.DebugVerifyInterruptVector(_vector0, this);
38 }
39 
40 bool HWPcir::getPcifr(unsigned pcifrBit) throw(){
41  return _pcifr & (1<<pcifrBit);
42  }
43 
44 unsigned HWPcir::convertBitToVector(unsigned bit) const throw(){
45  unsigned vector = ~0;
46  switch(bit){
47  case 0:
48  vector = _vector0;
49  break;
50  case 1:
51  vector = _vector1;
52  break;
53  case 2:
54  vector = _vector2;
55  break;
56  case 3:
57  vector = _vector3;
58  break;
59  case 4:
60  vector = _vector4;
61  break;
62  case 5:
63  vector = _vector5;
64  break;
65  case 6:
66  vector = _vector6;
67  break;
68  case 7:
69  vector = _vector7;
70  break;
71  default:
72  cerr << "HWPcir: invalid PCIFR bit specified.." << endl;
73  break;
74  };
75  return vector;
76  }
77 
78 void HWPcir::setPcifr(unsigned pcifrBit) throw(){
79  if(_pcifr & (1<<pcifrBit)){
80  // Already set/pending
81  return;
82  }
83  // At this point we have a *new* pin-change interrupt.
84  _pcifr |= (1<<pcifrBit);
85 
86  unsigned vector = convertBitToVector(pcifrBit);
87 
88  if(vector == (unsigned)~0){
89  cerr << "HWPcir: Attempt to set invalid pin-change interrupt." << endl;
90  return;
91  }
92 
93  if(_pcicr & (1<<pcifrBit)){
94  _irqSystem.SetIrqFlag(this,vector);
95  }
96  }
97 
98 void HWPcir::setPcifrMask(unsigned char val) throw(){
99  // Only XOR bits that are set/pending
100  val &= _pcifr;
101 
102  // Clear the appropriate pending interrupts
103  _pcifr ^= val;
104 
105  for(unsigned i=0;i<8;++i){
106  if(val & (1<<i)){
107  // We're trying to clear an interrupt
108  // An interrupt is pending
109  if(_pcicr & (1<<i)){
110  // The interrupt is enabled and pending,
111  // so tell the interrupt system
112  unsigned vector = convertBitToVector(i);
113  _irqSystem.ClearIrqFlag(vector);
114  }
115  }
116  }
117 
118  // Clear the bits in the register
119  _pcifr ^= val;
120  }
121 
122 unsigned char HWPcir::getPcifrMask() throw(){
123  return _pcifr;
124  }
125 
126 void HWPcir::setPcicrMask(unsigned char val) throw(){
127  unsigned char pcicrChanges = _pcicr ^ val;
128  for(unsigned i=0;i<8;++i){
129  if(pcicrChanges & (1<<i)){
130  // Bit changed
131  if(val & (1<<i)){
132  // Bit is being enabled
133  if(_pcifr & (1<<i)){
134  // Change interrupt pending
135  unsigned vector = convertBitToVector(i);
136  _irqSystem.SetIrqFlag(this,vector);
137  }
138  }
139  else {
140  // Bit is being disabled
141  if(val & (1<<i)){
142  // Change interrupt pending
143  unsigned vector = convertBitToVector(i);
144  _irqSystem.ClearIrqFlag(vector);
145  }
146  }
147  }
148  }
149  _pcicr = val;
150  }
151 
152 unsigned char HWPcir::getPcicrMask() throw(){
153  return _pcicr;
154  }
155 
156 
158  _pcicr = 0;
159  _pcifr = 0;
160  }
161 
162 void HWPcir::ClearIrqFlag(unsigned int vector){
163  if(vector == _vector0){
164  _pcifr &= ~(1<<0);
165  _irqSystem.ClearIrqFlag(vector);
166  return;
167  }
168  if(vector == _vector1){
169  _pcifr &= ~(1<<1);
170  _irqSystem.ClearIrqFlag(vector);
171  return;
172  }
173  if(vector == _vector2){
174  _pcifr &= ~(1<<2);
175  _irqSystem.ClearIrqFlag(vector);
176  return;
177  }
178  if(vector == _vector3){
179  _pcifr &= ~(1<<3);
180  _irqSystem.ClearIrqFlag(vector);
181  return;
182  }
183  if(vector == _vector4){
184  _pcifr &= ~(1<<4);
185  _irqSystem.ClearIrqFlag(vector);
186  return;
187  }
188  if(vector == _vector5){
189  _pcifr &= ~(1<<5);
190  _irqSystem.ClearIrqFlag(vector);
191  return;
192  }
193  if(vector == _vector6){
194  _pcifr &= ~(1<<6);
195  _irqSystem.ClearIrqFlag(vector);
196  return;
197  }
198  if(vector == _vector7){
199  _pcifr &= ~(1<<7);
200  _irqSystem.ClearIrqFlag(vector);
201  return;
202  }
203  cerr << "HWPcir: Attempt to clear non-existent irq vector";
204  }
205 
207  AvrDevice *core,
208  HWPcifrApi& pcifrApi,
209  unsigned pcifrBit) throw():
210  _pcifrApi(pcifrApi),
211  _pcmsk(0),
212  _pcifrBit(pcifrBit),
213  pcmsk_reg(core, "PINCHANGE.PCMSK",
214  this, &HWPcmsk::getPcmskMask,
216  {
217  assert(false); // Unreachable. No code ever constructs this class.
218  }
219 
220 void HWPcmsk::setPcmskMask(unsigned char val) throw(){
221  _pcmsk = val;
222  }
223 
224 unsigned char HWPcmsk::getPcmskMask() throw(){
225  return _pcmsk;
226  }
227 
228 void HWPcmsk::pinChanged(unsigned bit) throw(){
229  if(_pcmsk & (1<<bit)){
230  _pcifrApi.setPcifr(_pcifrBit);
231  }
232  }
233 
235  HWPcmskPinApi& pcmskPinApi,
236  unsigned pcmskBit
237  ) throw():
238  _pcmskPinApi(pcmskPinApi),
239  _pcmskBit(pcmskBit),
240  _prevState(true)
241  {
242  assert(false); // Unreachable. No code ever constructs this class.
243  pin.RegisterCallback(this);
244  }
245 
247  bool currentState = (bool)*pin;
248  if(currentState == _prevState){
249  return;
250  }
251 
252  _prevState = currentState;
253 
254  _pcmskPinApi.pinChanged(_pcmskBit);
255  }
256 
void setPcifr(unsigned pcifrBit)
Definition: hwpinchange.cpp:78
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
HWPcmsk(AvrDevice *core, HWPcifrApi &pcifrApi, unsigned pcifrBit)
Pin class, handles input and output to external parts.
Definition: pin.h:98
unsigned char getPcicrMask()
bool getPcifr(unsigned pcifrBit)
Definition: hwpinchange.cpp:40
HWPcir(AvrDevice *avr, HWIrqSystem &irqSystem, unsigned vector0=~0, unsigned vector1=~0, unsigned vector2=~0, unsigned vector3=~0, unsigned vector4=~0, unsigned vector5=~0, unsigned vector6=~0, unsigned vector7=~0)
Definition: hwpinchange.cpp:8
STL namespace.
void Reset()
PinChange(Pin &pin, HWPcmskPinApi &pcmskPinApi, unsigned pcmskBit)
void setPcicrMask(unsigned char val)
void PinStateHasChanged(Pin *)
unsigned convertBitToVector(unsigned bit) const
Definition: hwpinchange.cpp:44
void setPcifrMask(unsigned char val)
Definition: hwpinchange.cpp:98
void pinChanged(unsigned bit)
unsigned char getPcifrMask()
unsigned char getPcmskMask()
void setPcmskMask(unsigned char val)
void ClearIrqFlag(unsigned int vector)