/*
Copyright (C) 1998-2003 Scott Dattalo
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. */
#include <glib.h>
#include "trace.h"
#include "pir.h"
#include "intcon.h"
PIR::PIR(INTCON *_intcon, PIE *_pie, int _valid_bits)
: intcon(_intcon),pie(_pie),valid_bits(_valid_bits) ,writable_bits(0)
{
}
void PIR::put(unsigned int new_value)
{
// Only the "writable bits" can be written with put.
// The "read-only" ones (such as TXIF) are written
// through the set_/clear_ member functions.
trace.raw(write_trace.get() | value.get());
//trace.register_write(address,value.get());
value.put(new_value & writable_bits | value.get() & ~writable_bits);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR::set_intcon(INTCON *_intcon)
{
intcon = _intcon;
}
void PIR::set_pie(PIE *_pie)
{
pie = _pie;
}
void PIR::setInterrupt(unsigned int bitMask)
{
put(value.get() | bitMask);
}
void PIR::setPeripheralInterrupt()
{
if (intcon)
intcon->peripheral_interrupt();
}
bool PIR::interrupt_status()
{
assert(pie);
if( value.get() & valid_bits & pie->value.get())
return true;
return false;
}
InterruptSource::InterruptSource(PIR *_pir, unsigned int bitMask)
: m_pir(_pir), m_bitMask(bitMask)
{
assert(m_pir);
// Only one bit in the bit mask should be set.
assert(m_bitMask && ((m_bitMask & (m_bitMask-1)) == 0));
}
void InterruptSource::Trigger()
{
m_pir->setInterrupt(m_bitMask);
}
//------------------------------------------------------------------------
PIR1v1::PIR1v1(INTCON *_intcon, PIE *_pie)
: PIR(_intcon, _pie,0)
{
// Even though TXIF is a valid bit, it can't be written by the PIC
// source code. Its state reflects whether the usart txreg is full
// or not. Similarly for RCIF
valid_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | TXIF | RCIF | CMIF | EEIF;
writable_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | CMIF | EEIF;
}
void PIR1v1::clear_sspif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() & ~SSPIF);
}
void PIR1v1::set_txif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | TXIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR1v1::clear_txif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() & ~TXIF);
}
void PIR1v1::set_rcif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | RCIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR1v1::clear_rcif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() & ~RCIF);
}
void PIR1v1::set_cmif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | CMIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR1v1::set_eeif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | EEIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
//------------------------------------------------------------------------
//
PIR1v2::PIR1v2(INTCON *_intcon, PIE *_pie)
: PIR(_intcon, _pie,0)
{
// Even though TXIF is a valid bit, it can't be written by the PIC
// source code. Its state reflects whether the usart txreg is full
// or not. Similarly for RCIF
valid_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | TXIF | RCIF | ADIF | PSPIF;
writable_bits = TMR1IF | TMR2IF | CCP1IF | SSPIF | ADIF | PSPIF;
}
void PIR1v2::clear_sspif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() & ~SSPIF);
}
void PIR1v2::set_txif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | TXIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR1v2::set_pspif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | PSPIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR1v2::set_sspif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | SSPIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR1v2::clear_txif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() & ~TXIF);
}
void PIR1v2::set_rcif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | RCIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR1v2::clear_rcif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() & ~RCIF);
}
//------------------------------------------------------------------------
PIR2v1::PIR2v1(INTCON *_intcon, PIE *_pie)
: PIR(_intcon, _pie,0)
{
valid_bits = CCP2IF;
writable_bits = valid_bits;
}
//------------------------------------------------------------------------
PIR2v2::PIR2v2(INTCON *_intcon, PIE *_pie)
: PIR(_intcon, _pie,0)
{
valid_bits = ECCP1IF | TMR3IF | LVDIF | BCLIF | EEIF | CMIF;
writable_bits = valid_bits;
}
void PIR2v2::set_cmif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | CMIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR2v2::set_eeif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | EEIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
void PIR2v2::set_bclif(void)
{
trace.raw(write_trace.get() | value.get());
value.put(value.get() | BCLIF);
if( value.get() & pie->value.get() )
intcon->peripheral_interrupt();
}
//------------------------------------------------------------------------
PIR3v2::PIR3v2(INTCON *_intcon, PIE *_pie)
: PIR(_intcon, _pie,0)
{
valid_bits = RXB0IF | RXB1IF | TXB0IF | TXB1IF | TXB2IF | ERRIF |
WAKIF | IRXIF;
writable_bits = valid_bits;
}
syntax highlighted by Code2HTML, v. 0.9.1