00001 #include <assert.h>
00002 #include <iostream>
00003 #include "hwpinchange.h"
00004 #include "irqsystem.h"
00005
00006 using namespace std;
00007
00008 HWPcir::HWPcir( AvrDevice* avr,
00009 HWIrqSystem& irqSystem,
00010 unsigned vector0,
00011 unsigned vector1,
00012 unsigned vector2,
00013 unsigned vector3,
00014 unsigned vector4,
00015 unsigned vector5,
00016 unsigned vector6,
00017 unsigned vector7
00018 ) throw():
00019 Hardware(avr),
00020 _pcifr(0),
00021 _pcicr(0),
00022 _irqSystem(irqSystem),
00023 _vector0(vector0),
00024 _vector1(vector1),
00025 _vector2(vector2),
00026 _vector3(vector3),
00027 _vector4(vector4),
00028 _vector5(vector5),
00029 _vector6(vector6),
00030 _vector7(vector7),
00031 pcicr_reg(avr, "PINCHANGE.PCICR", this, &HWPcir::getPcicrMask,
00032 &HWPcir::setPcicrMask),
00033 pcifr_reg(avr, "PINCHANGE.PCIFR", this, &HWPcir::getPcifrMask,
00034 &HWPcir::setPcifrMask)
00035 {
00036 assert(false);
00037 irqSystem.DebugVerifyInterruptVector(_vector0, this);
00038 }
00039
00040 bool HWPcir::getPcifr(unsigned pcifrBit) throw(){
00041 return _pcifr & (1<<pcifrBit);
00042 }
00043
00044 unsigned HWPcir::convertBitToVector(unsigned bit) const throw(){
00045 unsigned vector = ~0;
00046 switch(bit){
00047 case 0:
00048 vector = _vector0;
00049 break;
00050 case 1:
00051 vector = _vector1;
00052 break;
00053 case 2:
00054 vector = _vector2;
00055 break;
00056 case 3:
00057 vector = _vector3;
00058 break;
00059 case 4:
00060 vector = _vector4;
00061 break;
00062 case 5:
00063 vector = _vector5;
00064 break;
00065 case 6:
00066 vector = _vector6;
00067 break;
00068 case 7:
00069 vector = _vector7;
00070 break;
00071 default:
00072 cerr << "HWPcir: invalid PCIFR bit specified.." << endl;
00073 break;
00074 };
00075 return vector;
00076 }
00077
00078 void HWPcir::setPcifr(unsigned pcifrBit) throw(){
00079 if(_pcifr & (1<<pcifrBit)){
00080
00081 return;
00082 }
00083
00084 _pcifr |= (1<<pcifrBit);
00085
00086 unsigned vector = convertBitToVector(pcifrBit);
00087
00088 if(vector == (unsigned)~0){
00089 cerr << "HWPcir: Attempt to set invalid pin-change interrupt." << endl;
00090 return;
00091 }
00092
00093 if(_pcicr & (1<<pcifrBit)){
00094 _irqSystem.SetIrqFlag(this,vector);
00095 }
00096 }
00097
00098 void HWPcir::setPcifrMask(unsigned char val) throw(){
00099
00100 val &= _pcifr;
00101
00102
00103 _pcifr ^= val;
00104
00105 for(unsigned i=0;i<8;++i){
00106 if(val & (1<<i)){
00107
00108
00109 if(_pcicr & (1<<i)){
00110
00111
00112 unsigned vector = convertBitToVector(i);
00113 _irqSystem.ClearIrqFlag(vector);
00114 }
00115 }
00116 }
00117
00118
00119 _pcifr ^= val;
00120 }
00121
00122 unsigned char HWPcir::getPcifrMask() throw(){
00123 return _pcifr;
00124 }
00125
00126 void HWPcir::setPcicrMask(unsigned char val) throw(){
00127 unsigned char pcicrChanges = _pcicr ^ val;
00128 for(unsigned i=0;i<8;++i){
00129 if(pcicrChanges & (1<<i)){
00130
00131 if(val & (1<<i)){
00132
00133 if(_pcifr & (1<<i)){
00134
00135 unsigned vector = convertBitToVector(i);
00136 _irqSystem.SetIrqFlag(this,vector);
00137 }
00138 }
00139 else {
00140
00141 if(val & (1<<i)){
00142
00143 unsigned vector = convertBitToVector(i);
00144 _irqSystem.ClearIrqFlag(vector);
00145 }
00146 }
00147 }
00148 }
00149 _pcicr = val;
00150 }
00151
00152 unsigned char HWPcir::getPcicrMask() throw(){
00153 return _pcicr;
00154 }
00155
00156
00157 void HWPcir::Reset(){
00158 _pcicr = 0;
00159 _pcifr = 0;
00160 }
00161
00162 void HWPcir::ClearIrqFlag(unsigned int vector){
00163 if(vector == _vector0){
00164 _pcifr &= ~(1<<0);
00165 _irqSystem.ClearIrqFlag(vector);
00166 return;
00167 }
00168 if(vector == _vector1){
00169 _pcifr &= ~(1<<1);
00170 _irqSystem.ClearIrqFlag(vector);
00171 return;
00172 }
00173 if(vector == _vector2){
00174 _pcifr &= ~(1<<2);
00175 _irqSystem.ClearIrqFlag(vector);
00176 return;
00177 }
00178 if(vector == _vector3){
00179 _pcifr &= ~(1<<3);
00180 _irqSystem.ClearIrqFlag(vector);
00181 return;
00182 }
00183 if(vector == _vector4){
00184 _pcifr &= ~(1<<4);
00185 _irqSystem.ClearIrqFlag(vector);
00186 return;
00187 }
00188 if(vector == _vector5){
00189 _pcifr &= ~(1<<5);
00190 _irqSystem.ClearIrqFlag(vector);
00191 return;
00192 }
00193 if(vector == _vector6){
00194 _pcifr &= ~(1<<6);
00195 _irqSystem.ClearIrqFlag(vector);
00196 return;
00197 }
00198 if(vector == _vector7){
00199 _pcifr &= ~(1<<7);
00200 _irqSystem.ClearIrqFlag(vector);
00201 return;
00202 }
00203 cerr << "HWPcir: Attempt to clear non-existent irq vector";
00204 }
00205
00206 HWPcmsk::HWPcmsk(
00207 AvrDevice *core,
00208 HWPcifrApi& pcifrApi,
00209 unsigned pcifrBit) throw():
00210 _pcifrApi(pcifrApi),
00211 _pcmsk(0),
00212 _pcifrBit(pcifrBit),
00213 pcmsk_reg(core, "PINCHANGE.PCMSK",
00214 this, &HWPcmsk::getPcmskMask,
00215 &HWPcmsk::setPcmskMask)
00216 {
00217 assert(false);
00218 }
00219
00220 void HWPcmsk::setPcmskMask(unsigned char val) throw(){
00221 _pcmsk = val;
00222 }
00223
00224 unsigned char HWPcmsk::getPcmskMask() throw(){
00225 return _pcmsk;
00226 }
00227
00228 void HWPcmsk::pinChanged(unsigned bit) throw(){
00229 if(_pcmsk & (1<<bit)){
00230 _pcifrApi.setPcifr(_pcifrBit);
00231 }
00232 }
00233
00234 PinChange::PinChange( Pin& pin,
00235 HWPcmskPinApi& pcmskPinApi,
00236 unsigned pcmskBit
00237 ) throw():
00238 _pin(pin),
00239 _pcmskPinApi(pcmskPinApi),
00240 _pcmskBit(pcmskBit),
00241 _prevState(true)
00242 {
00243 assert(false);
00244 pin.RegisterCallback(this);
00245 }
00246
00247 void PinChange::PinStateHasChanged(Pin* pin){
00248 bool currentState = (bool)*pin;
00249 if(currentState == _prevState){
00250 return;
00251 }
00252
00253 _prevState = currentState;
00254
00255 _pcmskPinApi.pinChanged(_pcmskBit);
00256 }
00257