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 #ifndef EXTERNALIRQ_INCLUDED
00027 #define EXTERNALIRQ_INCLUDED
00028
00029 #include <vector>
00030
00031 #include "hardware.h"
00032 #include "irqsystem.h"
00033 #include "rwmem.h"
00034 #include "avrdevice.h"
00035 #include "pinnotify.h"
00036 #include "hwport.h"
00037
00038 class ExternalIRQ;
00039
00041 class ExternalIRQHandler: public Hardware, public IOSpecialRegClient {
00042
00043 protected:
00044 HWIrqSystem *irqsystem;
00045 IOSpecialReg *mask_reg;
00046 IOSpecialReg *flag_reg;
00047 std::vector<ExternalIRQ*> extirqs;
00048 unsigned char irq_mask;
00049 unsigned char irq_flag;
00050 unsigned char reg_mask;
00051 std::vector<int> vectors;
00052 std::vector<int> irqbits;
00053 std::map<int, int> vector2idx;
00054
00055 void fireInterrupt(int idx);
00056
00057 friend class ExternalIRQ;
00058
00059 public:
00060 ExternalIRQHandler(AvrDevice* core, HWIrqSystem* irqsys, IOSpecialReg *mask, IOSpecialReg *flag);
00061 ~ExternalIRQHandler();
00062 void registerIrq(int vector, int irqBit, ExternalIRQ* extirq);
00063
00064
00065 virtual void ClearIrqFlag(unsigned int vector);
00066 virtual void Reset(void);
00067 virtual bool IsLevelInterrupt(unsigned int vector);
00068 virtual bool LevelInterruptPending(unsigned int vector);
00069
00070
00071 virtual unsigned char set_from_reg(const IOSpecialReg* reg, unsigned char nv);
00072 virtual unsigned char get_from_client(const IOSpecialReg* reg, unsigned char v);
00073
00074 };
00075
00077 class ExternalIRQ: public IOSpecialRegClient {
00078
00079 protected:
00080 int handlerIndex;
00081 ExternalIRQHandler *handler;
00082 int bitshift;
00083 unsigned char mask;
00084 unsigned char mode;
00085
00087 void setHandlerIndex(ExternalIRQHandler *h, int idx) { handler = h; handlerIndex = idx; }
00089 void fireInterrupt(void) { handler->fireInterrupt(handlerIndex); }
00091 virtual void ResetMode(void) { mode = 0; }
00093 virtual void ChangeMode(unsigned char m) { mode = m; }
00095 virtual bool fireAgain(void) { return false; }
00097 virtual bool mustSetFlagOnFire(void) { return true; }
00098
00099 friend class ExternalIRQHandler;
00100
00101 public:
00102 ExternalIRQ(IOSpecialReg *ctrl, int ctrlOffset, int ctrlBits);
00103
00104
00105 virtual unsigned char set_from_reg(const IOSpecialReg* reg, unsigned char nv);
00106 virtual unsigned char get_from_client(const IOSpecialReg* reg, unsigned char v);
00107 };
00108
00110 class ExternalIRQSingle: public ExternalIRQ, public HasPinNotifyFunction {
00111
00112 protected:
00113 bool state;
00114 bool twoBitMode;
00115 bool mode8515;
00116
00117 enum {
00118 MODE_LEVEL_LOW = 0,
00119 MODE_EDGE_ALL = 1,
00120 MODE_EDGE_FALL = 2,
00121 MODE_EDGE_RISE = 3
00122 };
00123
00124 public:
00125 ExternalIRQSingle(IOSpecialReg *ctrl, int ctrlOffset, int ctrlBits, Pin *pin, bool _8515mode = false);
00126
00127
00128 void ChangeMode(unsigned char m);
00129 bool fireAgain(void);
00130 bool mustSetFlagOnFire(void);
00131
00132
00133 void PinStateHasChanged(Pin *pin);
00134 };
00135
00137 class ExternalIRQPort: public ExternalIRQ, public HasPinNotifyFunction {
00138
00139 protected:
00140 bool state[8];
00141 Pin* pins[8];
00142 int portSize;
00143
00144 public:
00145 ExternalIRQPort(IOSpecialReg *ctrl, HWPort *port);
00146
00147
00148 void PinStateHasChanged(Pin *pin);
00149 };
00150
00151 #endif