1
0
Files
irix-657m-src/stand/arcs/xbox/monitor.c
2022-09-29 17:59:04 +03:00

343 lines
9.3 KiB
C
Executable File

//#pragma option v
/* monitor.c */
/*
* monitors data structure contain task status. Calls appropriate routine for
* any outstanding tasks.
*/
//#include <16c74.h>
//#include <elsc.h>
//#include <proto.h>
/*
* These global statements will be removed as soon as I can figure
* out how to handle global varibles between modules.
*/
/* Global Structure Declarations */
//extern struct MONITOR tasks; /* data structure containing task status */
//extern struct SYS_STATE reg_state; /* data struct containing copies of reg. */
//extern struct TIMER TCB; /* data structure containing task status */
/******************************************************************************
* *
* monitor() - polls the task data sturcture for outstanding tasks, and *
* calls the appropriate routing to handle the task. The *
* individual task routines are responsible for resetting the *
* data structure's bits. *
* *
* Upon entry the first job is to check for initial conditions *
* that require task handling. This is necessary because *
* interrupts are generated by either a change in state or an *
* edge transition. *
* *
******************************************************************************/
void
monitor()
{
while (1) {
/* Reset the Watch Dog Timer */
CLRWDT();
/* Check on Polled Inputs */
if ((PORTA ^ reg_state.reg_ra) & INPUT_MASK_PA)
inputPortA();
/* Check on Polled Inputs */
if ((PORTB ^ reg_state.reg_rb) & INPUT_MASK_PB)
inputPortB();
t_reg = extMemRd();
if (t_reg ^ reg_state.pwr_add)
inputPwr();
if (tasks.fw_logical != 0)
tasks_fw();
if ((fan_ptr.fan_stat_2.STAT2_CNT_CHK == 1) || fan_ptr.fan_stat_2.STAT2_FAN_LRTR)
tasks_fan();
/* check for expired time out conditions */
if (TCB.to_status || TCB.to_status_1)
tasks_to();
}
}
/***************************************************************************
* *
* inputPortA - Handles monitor inputs from Port A for the following *
* signals: *
* PSOK *
* *
***************************************************************************/
void
inputPortA()
{
t_reg = PORTA;
/* Power Supply Failure */
if (((t_reg ^ reg_state.reg_ra) & PSOK_MASK) && !t_reg.PSOK && !reg_state.reg_ra.PWRON_L) {
/* let's wait for 10 msec and sample again, to avoid any glitches */
to_value = MSEC_10;
delay();
t_reg = PORTA;
if(!t_reg.PSOK) {
tasks.fw_logical.FWL_PWR_DN = 1;
NoPower = 1;
cntLED(FP_LED, LED_RED|LED_BLINK);
to_value = TWO_SEC;
delay();
}
}
reg_state.reg_ra.PSOK = t_reg.PSOK;
}
/***************************************************************************
* *
* inputPortB - Handles monitor inputs from Port B for the following *
* signals: *
* Over Temperture *
* High Temperature *
* MFG_MODE *
* POWER UP/DOWN *
* *
* *
***************************************************************************/
void
inputPortB()
{
bits t_reg;
t_reg = PORTB;
/* Manufacturing Mode */
mfg_mode = t_reg.MFG_MODE_L ? 0 : 1;
reg_state.reg_rb.MFG_MODE_L = t_reg.MFG_MODE_L;
/* XBOX Over Temperature */
if (!t_reg.TEMP_OVER_L && reg_state.reg_rb.TEMP_OVER_L && tasks.env.ENV_TMP_EN) {
/* let's wait for 10 msec and sample again, to avoid any glitches */
to_value = MSEC_10;
delay();
t_reg = PORTB;
if(!t_reg.TEMP_OVER_L) {
/* turn on RED LED */
cntLED(FP_LED, LED_BLINK|LED_RED);
/* update the status register */
reg_state.reg_xbox_status.OVER_TEMP = 1;
extMemWt(STATUS_REG);
/* update the register copy of the port */
reg_state.reg_rb.TEMP_OVER_L = 0;
if (!mfg_mode)
tasks.fw_logical.FWL_SFT_PWR_DN = 1;
}
}
/* XBOX Temperature Normal (Not an over temperature condition) */
else if(t_reg.TEMP_OVER_L && !reg_state.reg_rb.TEMP_OVER_L) {
/* update the status register */
reg_state.reg_xbox_status.OVER_TEMP = 0;
extMemWt(STATUS_REG);
/* update the register copy of the port */
reg_state.reg_rb.TEMP_OVER_L = 1;
}
/* Check for power up */
if (!tasks.status.STAT_SYSPWR && !NoPower && (t_reg.X9_RMTOK || t_reg.XA_RMTOK)) {
tasks.fw_logical.FWL_PWR_UP = 1;
reg_state.reg_rb.X9_RMTOK = t_reg.X9_RMTOK;
reg_state.reg_rb.XA_RMTOK = t_reg.XA_RMTOK;
}
/* Check for power down */
if (!t_reg.X9_RMTOK && !t_reg.XA_RMTOK) {
if (tasks.status.STAT_SYSPWR) {
/* power is applied then do a shutdown */
tasks.fw_logical.FWL_PWR_DN = 1;
reg_state.reg_rb.X9_RMTOK = 0;
reg_state.reg_rb.XA_RMTOK = 0;
}
/* always reset the NoPower Flag */
NoPower = 0;
}
#if 0
/* High temperature is not used, but the reg. copy has to be updated */
reg_state.reg_rb.TEMP_UNDER_L = t_reg.TEMP_UNDER_L;
#endif
}
/***************************************************************************
* *
* inputPwr - Handles monitor inputs from the PAL for POK *
* *
***************************************************************************/
void
inputPwr()
{
/* Check for a Power Ok error flag */
if (!t_reg.SC_LPOK && reg_state.reg_pwr_add.SC_LPOK) {
/* Read it again to avoid any glitches */
t_reg = extMemRd();
if(!t_reg.SC_LPOK) {
cntLED(FP_LED, LED_RED);
tasks.fw_logical.FWL_PWR_DN = 1;
NoPower = 1;
reg_state.reg_pwr_add = t_reg;
}
}
}
/***************************************************************************
* *
* tasks_fan - Check for operation of fans with-in the correct tolerance *
* *
***************************************************************************/
void
tasks_fan()
{
long pulse_cnt;
/* set the expected RPM value */
if (fan_ptr.fan_add == 2)
pulse_cnt = PCI_FAN_HI_CNT;
else
pulse_cnt = X_FAN_HI_CNT;
/* Reset Monitor Flag */
fan_ptr.fan_stat_2.STAT2_CNT_CHK = 0;
/* check for out of tolerance conditions */
// A fan failure is any fan operating below the lower tolerance.
if (fan_ptr.fan_stat_2.STAT2_FAN_LRTR) {
/* adjust the multiplexer now to avoid unstable address lines, the lines
* are also adjusted in the interrupt capture routine.
*/
if (!tasks.env.ENV_FAN_RUNNING)
fan_ptr.fan_retry = FAN_MAX_RETRY;
fan_fail();
}
else if ((char)fan_ptr.fan_period > (char) pulse_cnt)
fan_fail();
else {
fan_ptr.fan_retry = 0;
/*
* before addressing the next fan, make sure the current
* fan is marked as good
*/
if (fan_ptr.fan_add == 0)
fan_ptr.fan_stat_1.STAT1_FAN_0 = 0;
else if (fan_ptr.fan_add == 1)
fan_ptr.fan_stat_1.STAT1_FAN_1 = 0;
else if (fan_ptr.fan_add == 2)
fan_ptr.fan_stat_1.STAT1_FAN_2 = 0;
next_fan();
}
}
/***************************************************************************
* *
* tasks_fw - Executes outstanding tasks logical firmware actions *
* The tasks executed are: *
* power up *
* power down *
* *
***************************************************************************/
void
tasks_fw()
{
if (tasks.fw_logical.FWL_PWR_UP) {
power_up();
tasks.fw_logical.FWL_PWR_UP = 0;
}
else if (tasks.fw_logical.FWL_PWR_DN) {
shutdown_pending = 1;
power_dn();
tasks.fw_logical.FWL_PWR_DN = 0;
}
else if (tasks.fw_logical.FWL_SFT_PWR_DN) {
shutdown_pending = 1;
to_value = SOFT_PWR_DN_DELAY;
timeout(PWR_DOWN_TO);
tasks.fw_logical.FWL_SFT_PWR_DN = 0;
}
}
/***************************************************************************
* *
* tasks_to - handles the timeout queue status when a timeeout period *
* has expired. *
* The timeout tasks handled are: *
* NMI button debounce timeout *
* RESET button debounce timeout *
* Front Panel Switch debounce timeout *
* heart beat *
* *
***************************************************************************/
void
tasks_to()
{
bits reg;
if (TCB.to_status.FAN_TO) {
TCB.to_status.FAN_TO = 0;
/* enable temperature monitoring */
tasks.env.ENV_TMP_EN = 1;
/* only check the fans if the manufacturing mode jumper is not installed */
if (!mfg_mode) {
if (fan_ptr.fan_stat_2.STAT2_FAN_CHK) {
/* No tach pulse recevied, could be a locked rotor */
fan_ptr.fan_stat_2.STAT2_FAN_LRTR = 1;
}
else
/* Begin checking for fan pulses */
next_fan();
}
}
if (TCB.to_status.PWR_DOWN_TO) {
/*
* The soft power down timeout has expired, therefore we must shut the XBOX down
* without waiting any longer for the CPU to signal a timeout
*/
TCB.to_status.PWR_DOWN_TO = 0;
tasks.fw_logical.FWL_PWR_DN = 1;
NoPower = 1;
}
}