00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "hwacomp.h"
00027
00028 #include "irqsystem.h"
00029
00030 #define ACD 0x80
00031 #define ACO 0x20
00032 #define ACI 0x10
00033 #define ACIE 0x08
00034 #define ACIC 0x04
00035 #define ACIS1 0x02
00036 #define ACIS0 0x01
00037
00038
00039 HWAcomp::HWAcomp(AvrDevice *core, HWIrqSystem *irqsys, PinAtPort ain0, PinAtPort ain1, unsigned int _irqVec):
00040 Hardware(core),
00041 TraceValueRegister(core, "ACOMP"),
00042 irqSystem(irqsys),
00043 pinAin0(ain0), pinAin1(ain1),
00044 acsr_reg(this, "ACSR", this, &HWAcomp::GetAcsr, &HWAcomp::SetAcsr),
00045 irqVec(_irqVec)
00046 {
00047 irqSystem->DebugVerifyInterruptVector(irqVec, this);
00048 ain0.GetPin().RegisterCallback(this);
00049 ain1.GetPin().RegisterCallback(this);
00050 Reset();
00051 }
00052
00053
00054 void HWAcomp::Reset(){
00055 acsr=0;
00056 }
00057
00058 void HWAcomp::SetAcsr(unsigned char val) {
00059 unsigned char old= acsr&0x30;
00060 acsr=val&0x9f;
00061 acsr|= old;
00062 if (val & ACI) {
00063 acsr &=~ACI;
00064 }
00065
00066 if ( (acsr & ( ACI | ACIE) ) == ( ACI | ACIE) ) {
00067 irqSystem->SetIrqFlag(this, irqVec);
00068 } else {
00069 irqSystem->ClearIrqFlag(irqVec);
00070 }
00071
00072 }
00073
00074 unsigned char HWAcomp::GetAcsr() {
00075 return acsr;
00076 }
00077
00078 void HWAcomp::PinStateHasChanged(Pin *p) {
00079 bool oldComp=(acsr & ACO);
00080
00081
00082 if (pinAin0.GetAnalog()>pinAin1.GetAnalog()) {
00083 if (oldComp==false) {
00084 acsr|=ACO;
00085
00086 unsigned char irqMask= acsr & (ACIS1|ACIS0);
00087 if ( (irqMask==0) || (irqMask==( ACIS1 | ACIS0) ) ) {
00088 acsr|=ACI;
00089 if (acsr&ACIE) irqSystem->SetIrqFlag(this, irqVec);
00090 }
00091 }
00092 } else {
00093 if (oldComp==true) {
00094 acsr&=~ACO;
00095
00096 unsigned char irqMask= acsr & (ACIS1|ACIS0);
00097 if ( (irqMask==0) || (irqMask==( ACIS1 ) )) {
00098 acsr|=ACI;
00099 if (acsr&ACIE) irqSystem->SetIrqFlag(this, irqVec);
00100 }
00101 }
00102 }
00103
00104 }
00105
00106 void HWAcomp::ClearIrqFlag(unsigned int vector){
00107 if (vector==irqVec) {
00108 acsr&=~ACI;
00109 irqSystem->ClearIrqFlag(irqVec);
00110 }
00111 }
00112