/*
Copyright (C) 1998-2003 Scott Dattalo
2003 Mike Durian
This file is part of gpsim.
gpsim is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
gpsim is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with gpsim; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef PIR_H
#define PIR_H
#include "assert.h"
#include "pie.h"
class INTCON;
//---------------------------------------------------------
// PIR Peripheral Interrupt register base class for PIR1 & PIR2
class PIR : public sfr_register
{
protected:
INTCON *intcon;
PIE *pie;
public:
int valid_bits;
int writable_bits;
PIR(INTCON *, PIE *, int _valid_bits);
// The PIR base class supports no PIR bits directly
virtual void clear_sspif(){}
virtual void clear_rcif(){}
virtual void clear_txif(){}
virtual void set_adif(){}
virtual void set_bclif(){}
virtual void set_ccpif(){}
virtual void set_cmif(){}
virtual void set_eccp1if(){}
virtual void set_eeif(){}
virtual void set_errif(){}
virtual void set_irxif(){}
virtual void set_lvdif(){}
virtual void set_pspif(){}
virtual void set_rcif(){}
virtual void set_rxb0if(){}
virtual void set_rxb1if(){}
virtual void set_sspif(){}
virtual void set_tmr1if(){}
virtual void set_tmr2if(){}
virtual void set_tmr3if(){}
virtual void set_txb0if(){}
virtual void set_txb1if(){}
virtual void set_txb2if(){}
virtual void set_txif(){}
virtual void set_wakif(){}
virtual unsigned int get_txif() { return 0;}
virtual unsigned int get_rcif() { return 0;}
virtual unsigned int get_sspif() { return 0;}
virtual bool interrupt_status();
virtual void put(unsigned int new_value);
virtual void setInterrupt(unsigned int bitMask);
virtual void setPeripheralInterrupt();
void set_intcon(INTCON *);
void set_pie(PIE *);
};
//---------------------------------------------------------
// InterruptSource
class InterruptSource
{
public:
InterruptSource(PIR *_pir, unsigned int bitMask);
void Trigger();
private:
PIR *m_pir;
unsigned int m_bitMask;
};
//---------------------------------------------------------
// PIR1 Peripheral Interrupt register # 1
//
// This is version 1 of the PIR1 register - as seen on the 16f62x
class PIR1v1 : public PIR
{
public:
enum {
TMR1IF = 1<<0,
TMR2IF = 1<<1,
CCP1IF = 1<<2,
SSPIF = 1<<3,
TXIF = 1<<4,
RCIF = 1<<5,
CMIF = 1<<6, // 16f62x
EEIF = 1<<7 // 16f62x
};
virtual void set_tmr1if()
{
put(get() | TMR1IF);
}
virtual void set_tmr2if()
{
put(get() | TMR2IF);
}
virtual void set_ccpif()
{
put(get() | CCP1IF);
}
virtual void set_sspif()
{
put(get() | SSPIF);
}
virtual void set_txif();
virtual void set_rcif();
virtual void set_cmif();
virtual void set_eeif();
virtual unsigned int get_sspif()
{
return value.get() & SSPIF;
}
void clear_sspif();
unsigned int get_txif()
{
return value.get() & TXIF;
}
void clear_txif();
unsigned int get_rcif()
{
return value.get() & RCIF;
}
virtual void clear_rcif();
PIR1v1(INTCON *, PIE *);
};
//---------------------------------------------------------
// PIR1 Peripheral Interrupt register # 1
//
// This is version 2 of the PIR1 register - as seen on the 18xxxx devices
// and devices like the 16c63a.
class PIR1v2 : public PIR
{
public:
enum {
TMR1IF = 1<<0,
TMR2IF = 1<<1,
CCP1IF = 1<<2,
SSPIF = 1<<3,
TXIF = 1<<4,
RCIF = 1<<5,
ADIF = 1<<6, // 18cxxx
PSPIF = 1<<7
};
virtual void set_tmr1if()
{
put(get() | TMR1IF);
}
virtual void set_tmr2if()
{
put(get() | TMR2IF);
}
virtual void set_ccpif()
{
put(get() | CCP1IF);
}
virtual void set_sspif();
unsigned int get_sspif()
{
return value.get() & SSPIF;
}
virtual void clear_sspif();
virtual void set_txif();
virtual void set_rcif();
virtual void set_adif()
{
put(get() | ADIF);
}
virtual void set_pspif();
virtual unsigned int get_txif()
{
return value.get() & TXIF;
}
virtual void clear_txif();
unsigned int get_rcif()
{
return value.get() & RCIF;
}
virtual void clear_rcif();
PIR1v2(INTCON *, PIE *);
};
//---------------------------------------------------------
// PIR2 Peripheral Interrupt register # 2
//
// This is version 1 of the PIR1 register - as seen on the 16f62x
class PIR2v1 : public PIR
{
public:
enum
{
CCP2IF = 1<<0
};
virtual void set_ccpif()
{
put(get() | CCP2IF);
}
PIR2v1(INTCON *, PIE *);
};
//---------------------------------------------------------
// PIR2 Peripheral Interrupt register # 2
//
// This is version 2 of the PIR2 register - as seen on the 18xxxx devices
// and devices like the 16c63a.
class PIR2v2 : public PIR
{
public:
enum
{
ECCP1IF = 1<<0, /* only on the PIC18F4xx devices */
TMR3IF = 1<<1,
LVDIF = 1<<2,
BCLIF = 1<<3,
EEIF = 1<<4,
CMIF = 1<<6 /* PIC16F87xA, PIC18F4xx devices */
};
virtual void set_eccp1if()
{
put(get() | ECCP1IF);
}
virtual void set_tmr3if()
{
put(get() | TMR3IF);
}
virtual void set_lvdif()
{
put(get() | LVDIF);
}
virtual void set_bclif();
virtual void set_eeif();
virtual void set_cmif();
PIR2v2(INTCON *, PIE *);
};
//---------------------------------------------------------
// PIR2 Peripheral Interrupt register # 3
//
// This is version 2 of the PIR3 register - as seen on the 18F248 devices
// Perhaps other devices too - it contains bits for the CAN device
class PIR3v2 : public PIR
{
public:
enum
{
RXB0IF = 1<<0,
RXB1IF = 1<<1,
TXB0IF = 1<<2,
TXB1IF = 1<<3,
TXB2IF = 1<<4,
ERRIF = 1<<5,
WAKIF = 1<<6,
IRXIF = 1<<7
};
virtual void set_rxb0if()
{
put(get() | RXB0IF);
}
virtual void set_rxb1if()
{
put(get() | RXB1IF);
}
virtual void set_txb0if()
{
put(get() | TXB0IF);
}
virtual void set_txb1if()
{
put(get() | TXB1IF);
}
virtual void set_txb2if()
{
put(get() | TXB2IF);
}
virtual void set_errif()
{
put(get() | ERRIF);
}
virtual void set_wakif()
{
put(get() | WAKIF);
}
virtual void set_irxif()
{
put(get() | IRXIF);
}
PIR3v2(INTCON *, PIE *);
};
/*
* PIR_SET defines and interface to some common interrupt capabilities.
* PIR_SET is a pure virtual class - you must instantiate a more specific
* version of PIR_SET.
*
* The idea behind PIR_SET is to hide the location of the interrupt bits.
* in some cases, a bit might be in PIR1, in others it might be in PIR2.
* Instead of accessing the register directly, you go through PIR_SET
* and it will find the proper PIR register.
*/
class PIR_SET
{
public:
virtual bool interrupt_status()
{
return false;
}
// uart stuff
virtual bool get_txif()
{
return false;
}
virtual void set_txif() {}
virtual void clear_txif() {}
virtual bool get_rcif()
{
return false;
}
virtual void set_rcif() {}
virtual void clear_rcif() {}
// ssp stuff
virtual bool get_sspif()
{
return false;
}
virtual void clear_sspif() {}
virtual void set_sspif() {}
virtual void set_bclif() {}
virtual void set_pspif() {}
virtual void set_cmif() {}
// eeprom stuff
virtual void set_eeif() {}
// CCP stuff
virtual void set_ccpif() {}
// Timer stuff
virtual void set_tmr1if() {}
virtual void set_tmr2if() {}
virtual void set_adif() {}
};
//----------------------------------------
// Supports 1 or 2 Pir version 1 registers
class PIR_SET_1 : public PIR_SET
{
public:
PIR_SET_1() { pir1 = 0; pir2 = 0; }
void set_pir1(PIR *p1) { pir1 = p1; }
void set_pir2(PIR *p2) { pir2 = p2; }
virtual bool interrupt_status() {
assert(pir1 != 0);
if (pir2 != 0)
return (pir1->interrupt_status() ||
pir2->interrupt_status());
else
return (pir1->interrupt_status());
}
// uart stuff
virtual bool get_txif() {
assert(pir1 != 0);
return (pir1->get_txif() != 0);
}
virtual void set_txif() {
assert(pir1 != 0);
pir1->set_txif();
}
virtual void clear_txif() {
assert(pir1 != 0);
pir1->clear_txif();
}
virtual bool get_rcif() {
assert(pir1 != 0);
return (pir1->get_rcif() != 0);
}
virtual void set_rcif() {
assert(pir1 != 0);
pir1->set_rcif();
}
virtual void clear_rcif() {
assert(pir1 != 0);
pir1->clear_rcif();
}
// ssp stuff
virtual bool get_sspif() {
assert(pir1 != 0);
return (pir1->get_sspif() != 0);
}
virtual void set_sspif() {
assert(pir1 != 0);
pir1->set_sspif();
}
virtual void clear_sspif() {
assert(pir1 != 0);
pir1->clear_sspif();
}
// eeprom stuff
virtual void set_eeif() {
assert(pir1 != 0);
pir1->set_eeif();
}
// CCP stuff
virtual void set_ccpif() {
assert(pir1 != 0);
pir1->set_ccpif();
}
// Timer stuff
virtual void set_tmr1if() {
assert(pir1 != 0);
pir1->set_tmr1if();
}
virtual void set_tmr2if() {
assert(pir1 != 0);
pir1->set_tmr2if();
}
// A/D stuff - not part of base PIR_SET class
virtual void set_adif() {
assert(pir1 != 0);
pir1->set_adif();
}
// Comparator
virtual void set_cmif() {
assert(pir1 != 0);
pir1->set_cmif();
}
private:
PIR *pir1;
PIR *pir2;
};
// Supports 1, 2 or 3 version 2 Pir registers
class PIR_SET_2 : public PIR_SET
{
public:
PIR_SET_2() { pir1 = 0; pir2 = 0; pir3 = 0; }
void set_pir1(PIR *p1) { pir1 = p1; }
void set_pir2(PIR *p2) { pir2 = p2; }
void set_pir3(PIR *p3) { pir3 = p3; }
virtual bool interrupt_status() {
assert(pir1 != 0);
if (pir1 != 0 && pir1->interrupt_status())
return(true);
else if (pir2 != 0 && pir2->interrupt_status())
return(true);
else if (pir3 != 0 && pir3->interrupt_status())
return(true);
return(false);
}
// uart stuff
virtual bool get_txif() {
assert(pir1 != 0);
return (pir1->get_txif() != 0);
}
virtual void set_txif() {
assert(pir1 != 0);
pir1->set_txif();
}
virtual void clear_txif() {
assert(pir1 != 0);
pir1->clear_txif();
}
virtual bool get_rcif() {
assert(pir1 != 0);
return (pir1->get_rcif() != 0);
}
virtual void set_rcif() {
assert(pir1 != 0);
pir1->set_rcif();
}
virtual void clear_rcif() {
assert(pir1 != 0);
pir1->clear_rcif();
}
// ssp stuff
virtual bool get_sspif() {
assert(pir1 != 0);
return (pir1->get_sspif() != 0);
}
virtual void set_sspif() {
assert(pir1 != 0);
pir1->set_sspif();
}
virtual void clear_sspif() {
assert(pir1 != 0);
pir1->clear_sspif();
}
// eeprom stuff
virtual void set_eeif() {
assert(pir2 != 0);
pir2->set_eeif();
}
// CCP stuff
virtual void set_ccpif() {
assert(pir1 != 0);
pir1->set_ccpif();
}
// Timer stuff
virtual void set_tmr1if() {
assert(pir1 != 0);
pir1->set_tmr1if();
}
virtual void set_tmr2if() {
assert(pir1 != 0);
pir1->set_tmr2if();
}
// A/D stuff - not part of base PIR_SET class
virtual void set_adif() {
assert(pir1 != 0);
pir1->set_adif();
}
// Comparator
virtual void set_cmif() {
assert(pir2 != 0);
pir2->set_cmif();
}
// I2C master
virtual void set_bclif() {
assert(pir2 != 0);
pir2->set_bclif();
}
// Parallel Slave Port
virtual void set_pspif() {
assert(pir1 != 0);
pir1->set_pspif();
}
private:
PIR *pir1;
PIR *pir2;
PIR *pir3;
};
#endif /* PIR_H */
syntax highlighted by Code2HTML, v. 0.9.1