/***************************************************************************
 *   Copyright (C) 2021 by Santiago González                               *
 *                                                                         *
 ***( see copyright.txt file at root folder )*******************************/

#include "rtclock.h"
#include "iopin.h"
#include "simulator.h"

RtClock::RtClock( QString id )
       : eElement ( id )
{
    m_disabled  = true; 
}
RtClock::~RtClock(){}

void RtClock::initialize()
{
    m_outEnable = false; 
    m_disOut    = false; 

    m_freqBase = 32768; 
    m_halfPeriod = 1e12/m_freqBase/2;   // Period in ps
    m_toggle = 1; 
    m_tCount = 1; 
    m_sCount = m_freqBase*2; 

    Simulator::self()->addEvent( m_halfPeriod, this ); 
}

void RtClock::runEvent()
{
    Simulator::self()->addEvent( m_halfPeriod, this ); 
    if( m_disabled ) return; 

    if( --m_tCount == 0 ) // Toggle Pin if enabled
    {
        m_tCount = m_toggle; 
        if( m_outEnable ) m_outpin->scheduleState( !m_outpin->getOutState(), 0 ); 
    }
    if( --m_sCount == 0 ) // Increment 1 second
    {
        m_sCount = m_freqBase*2; 
        m_time = m_time.addSecs( 1 ); 
        if( m_time == QTime( 0, 0, 0 ) ) m_date = m_date.addDays( 1 ); 
    }
}

void RtClock::setCurrentTime()
{
    m_date = QDate::currentDate(); 
    m_time = QTime::currentTime(); 
}

void RtClock::setFreq( uint64_t freq )
{
    m_toggle = m_freqBase/freq; 
    m_tCount = m_toggle; 
}

void RtClock::enableOut( bool en )
{
    if( m_outEnable == en ) return; 
    m_outEnable = en; 
    if( !en ) m_outpin->setOutState( m_disOut ); 
}

void RtClock::setDisOut( bool d )
{
    if( m_disOut == d ) return; 
    m_disOut = d; 
    if( !m_outEnable ) m_outpin->setOutState( m_disOut ); 
}
