// ****************************************************************************
// INCLUDE FILES: Header files of modules referenced by this module
// ****************************************************************************
#include <ISTPManager.h>
#include <toggle.h>
#include <conf_board.h>
#include <powerlinemanager.h>


// ****************************************************************************
// PRIVATE TYPES: Private types used by this module only
// ****************************************************************************


// ****************************************************************************
// PRIVATE MACROS: Private #define directives used by this module only
// ****************************************************************************
#define ISTPM_SAMPLE_RATE_DEF_HZ   (100)
#define ISTPM_SCHED_RATE_DEF_HZ    (100)


// ****************************************************************************
// PRIVATE VARIABLES: Variables used by this module only (static)
// ****************************************************************************
static ISTPGlobalProperties_t  ISTPGlobalProperties =
{
    .SamplingStatus = ISTP_SAMPLING_INACTIVE,
    .FifoMode = ISTP_FIFO_MODE_INACTIVE,
    .SampleRateHz = ISTPM_SAMPLE_RATE_DEF_HZ,
    .SchedulerRateHz = ISTPM_SCHED_RATE_DEF_HZ,
    .NominalFifoSamplesNum = (ISTPM_SAMPLE_RATE_DEF_HZ / ISTPM_SCHED_RATE_DEF_HZ),
    .HealthDataStatus = ISTP_HEALTH_DATA_INACTIVE
};

static ISTPAlerts_t ISTPAlerts = 
{
    .FifoOverflow = 0,
    .SchedulerFrameTimeOverflow = 0,
    .TxBufferOverflow = 0
};

static uint8_t safetyCheckPointPassed = 0;

// ****************************************************************************
// PRIVATE FUNCTIONS PROTOTYPES: Functions used by this module only (static)
// ****************************************************************************


// ****************************************************************************
// PUBLIC VARIABLES: Public variables shared with other modules
// ****************************************************************************


// ****************************************************************************
// PRIVATE FUNCTIONS: Private functions used by this module only
// ****************************************************************************


// ****************************************************************************
// PUBLIC FUNCTIONS: Public functions shared with other modules
// ****************************************************************************
ISTPGlobalProperties_t * ISTPMGetGlobalProperties(void)
{
    return &ISTPGlobalProperties;    
}

ISTPAlerts_t * ISTPMGetAlerts(void)
{
    return &ISTPAlerts;
}

ISTPSamplingStatus_t ISTPMGetSamplingStatus(void)
{
    return ISTPGlobalProperties.SamplingStatus;
}

void ISTPMSetSamplingStatus( ISTPSamplingStatus_t samplingStatus)
{
    irqflags_t irqFlags;
    
    // Start of critical section
    irqFlags = cpu_irq_save();
    
    // Sampling status is used in scheduler tick interrupt service routine,
    // thus modified with disabled interrupts.
    ISTPGlobalProperties.SamplingStatus = samplingStatus;

    // End of critical section
    cpu_irq_restore( irqFlags );

    if( ISTP_SAMPLING_ACTIVE == ISTPGlobalProperties.SamplingStatus )
    {
        PLMswitchRail( POWER_RAIL_EXT, POWER_RAIL_ON, 0 );
    }
    else
    {
        PLMswitchRail( POWER_RAIL_EXT, POWER_RAIL_OFF, 0 );
    }
}

void ISTPMSetFifoMode( ISTPFifoMode_t fifoMode)
{
    ISTPGlobalProperties.FifoMode = fifoMode;
}

void ISTPMSetSampleRateHz( uint16_t sampleRateHz)
{
    ISTPGlobalProperties.SampleRateHz = sampleRateHz;
    ISTPGlobalProperties.NominalFifoSamplesNum = 
        (ISTPGlobalProperties.SampleRateHz / ISTPGlobalProperties.SchedulerRateHz);
}

void ISTPMSetSchedulerRateHz( uint16_t schedulerRateHz)
{
    ISTPGlobalProperties.SchedulerRateHz = schedulerRateHz;
    ISTPGlobalProperties.NominalFifoSamplesNum =
    (ISTPGlobalProperties.SampleRateHz / ISTPGlobalProperties.SchedulerRateHz);
}

void ISTPMSetHealthDataStatus( ISTPHealtDataStatus_t healthDataStatus )
{
    ISTPGlobalProperties.HealthDataStatus = healthDataStatus;
}

void ISTPMSetAlertFifoOverflow( uint8_t fifoOverflowActive )
{
    ISTPAlerts.FifoOverflow = fifoOverflowActive;
}

void ISTPMSetAlertSchFrameOverflow( uint8_t SchFrameOverflowActive )
{
    ISTPAlerts.SchedulerFrameTimeOverflow = SchFrameOverflowActive;
}

void ISTPMSetAlertTxBufferOverflow( uint8_t txBuffOvrflwActive )
{
    ISTPAlerts.TxBufferOverflow = txBuffOvrflwActive;
}

void ISTPMLedAlertCode( void )
{
    static uint8_t currentlyShownAlert = 0;

    switch(currentlyShownAlert)
    {
        case 0:
        {
            if(ISTPAlerts.SchedulerFrameTimeOverflow)
            {
                toggleMainLeds(PIOA, LED_C, 1);
                toggleMainLeds(PIOA, LED_L, 0);
            }
            else
            {
                toggleMainLeds(PIOA, LED_C, 0);
                toggleMainLeds(PIOA, LED_L, 0);
            }
            currentlyShownAlert = 1;
            break;
        }
        case 1:
        {
            if(ISTPAlerts.FifoOverflow)
            {
                toggleMainLeds(PIOA, LED_C, 0);
                toggleMainLeds(PIOA, LED_L, 1);
            }
            else
            {
                toggleMainLeds(PIOA, LED_C, 0);
                toggleMainLeds(PIOA, LED_L, 0);
            }
            currentlyShownAlert = 2;
            break;
        }
        case 2:
        {
            if(ISTPAlerts.TxBufferOverflow)
            {
                toggleMainLeds(PIOA, LED_C, 1);
                toggleMainLeds(PIOA, LED_L, 1);
            }
            else
            {
                toggleMainLeds(PIOA, LED_C, 0);
                toggleMainLeds(PIOA, LED_L, 0);
            }
            currentlyShownAlert = 0;
            break;
        }
    }
}

void ISTPMResetLedAlertCode( void )
{
    toggleMainLeds(PIOA, LED_C, 0);
    toggleMainLeds(PIOA, LED_L, 0);
}

uint8_t ISTPMSafetyCheckPointGet( void )
{
    return safetyCheckPointPassed;
}

void ISTPMSafetyCheckPointSet( void )
{
    irqflags_t irqFlags;
    
    // Start of critical section
    irqFlags = cpu_irq_save();
    
    safetyCheckPointPassed = 1;

    // End of critical section
    cpu_irq_restore( irqFlags );
    
}

void ISTPMSafetyCheckPointReset( void )
{
    safetyCheckPointPassed = 0;
}

uint8_t ISTPHealthDataStatusGet( void )
{
	if(ISTPGlobalProperties.HealthDataStatus == ISTP_HEALTH_DATA_ACTIVE)
		return 1;
	else
		return 0;
}

uint16_t ISTPSampleRateGet( void )
{
	return ISTPGlobalProperties.SampleRateHz;
}