📄 ski2c.c
字号:
pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN; } break; default: SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, SKERR_I2C_E001, SKERR_I2C_E001MSG); break; } pAC->I2c.SenTable[i].SenValue = 0; pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; pAC->I2c.SenTable[i].SenErrCts = 0; pAC->I2c.SenTable[i].SenBegErrTS = 0; pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor; pAC->I2c.SenTable[i].SenDev = LM80_ADDR; }#ifndef SK_DIAG pAC->I2c.DummyReads = pAC->I2c.MaxSens;#endif /* !SK_DIAG */ /* Clear I2C IRQ */ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); /* Now we are I/O initialized */ pAC->I2c.InitLevel = SK_INIT_IO; return(0);} /* SkI2cInit1 *//* * Init level 2: Start first sensor read. */static int SkI2cInit2(SK_AC *pAC, /* Adapter Context */SK_IOC IoC) /* I/O Context */{ int ReadComplete; SK_SENSOR *pSen; if (pAC->I2c.InitLevel != SK_INIT_IO) { /* ReInit not needed in I2C module */ /* Init0 and Init2 not permitted */ return(0); } pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); if (ReadComplete) { SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG); } /* Now we are correctly initialized */ pAC->I2c.InitLevel = SK_INIT_RUN; return(0);} /* SkI2cInit2*//* * Initialize I2C devices * * Get the first voltage value and discard it. * Go into temperature read mode. A default pointer is not set. * * The things to be done depend on the init level in the parameter list: * Level 0: * Initialize only the data structures. Do NOT access hardware. * Level 1: * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts. * Level 2: * Everything is possible. Interrupts may be used from now on. * * return: * 0 = success * other = error. */int SkI2cInit(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */int Level) /* Init Level */{ switch (Level) { case SK_INIT_DATA: return(SkI2cInit0(pAC)); case SK_INIT_IO: return(SkI2cInit1(pAC, IoC)); case SK_INIT_RUN: return(SkI2cInit2(pAC, IoC)); default: break; } return(0);} /* SkI2cInit */#ifndef SK_DIAG/* * Interrupt service function for the I2C Interface * * Clears the Interrupt source * * Reads the register and check it for sending a trap. * * Starts the timer if necessary. */void SkI2cIsr(SK_AC *pAC, /* Adapter Context */SK_IOC IoC) /* I/O Context */{ SK_EVPARA Para; /* Clear I2C IRQ */ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); Para.Para64 = 0; SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);} /* SkI2cIsr *//* * Check this sensors Value against the threshold and send events. */static void SkI2cCheckSensor(SK_AC *pAC, /* Adapter Context */SK_SENSOR *pSen){ SK_EVPARA ParaLocal; SK_BOOL TooHigh; /* Is sensor too high? */ SK_BOOL TooLow; /* Is sensor too low? */ SK_U64 CurrTime; /* Current Time */ SK_BOOL DoTrapSend; /* We need to send a trap */ SK_BOOL DoErrLog; /* We need to log the error */ SK_BOOL IsError; /* We need to log the error */ /* Check Dummy Reads first */ if (pAC->I2c.DummyReads > 0) { pAC->I2c.DummyReads--; return; } /* Get the current time */ CurrTime = SkOsGetTime(pAC); /* Set para to the most useful setting: The current sensor. */ ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens; /* Check the Value against the thresholds. First: Error Thresholds */ TooHigh = (pSen->SenValue > pSen->SenThreErrHigh); TooLow = (pSen->SenValue < pSen->SenThreErrLow); IsError = SK_FALSE; if (TooHigh || TooLow) { /* Error condition is satisfied */ DoTrapSend = SK_TRUE; DoErrLog = SK_TRUE; /* Now error condition is satisfied */ IsError = SK_TRUE; if (pSen->SenErrFlag == SK_SEN_ERR_ERR) { /* This state is the former one */ /* So check first whether we have to send a trap */ if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > CurrTime) { /* * Do NOT send the Trap. The hold back time * has to run out first. */ DoTrapSend = SK_FALSE; } /* Check now whether we have to log an Error */ if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > CurrTime) { /* * Do NOT log the error. The hold back time * has to run out first. */ DoErrLog = SK_FALSE; } } else { /* We came from a different state -> Set Begin Time Stamp */ pSen->SenBegErrTS = CurrTime; pSen->SenErrFlag = SK_SEN_ERR_ERR; } if (DoTrapSend) { /* Set current Time */ pSen->SenLastErrTrapTS = CurrTime; pSen->SenErrCts++; /* Queue PNMI Event */ SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? SK_PNMI_EVT_SEN_ERR_UPP : SK_PNMI_EVT_SEN_ERR_LOW), ParaLocal); } if (DoErrLog) { /* Set current Time */ pSen->SenLastErrLogTS = CurrTime; if (pSen->SenType == SK_SEN_TEMP) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); } else if (pSen->SenType == SK_SEN_VOLT) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); } else { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); } } } /* Check the Value against the thresholds */ /* 2nd: Warning thresholds */ TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh); TooLow = (pSen->SenValue < pSen->SenThreWarnLow); if (!IsError && (TooHigh || TooLow)) { /* Error condition is satisfied */ DoTrapSend = SK_TRUE; DoErrLog = SK_TRUE; if (pSen->SenErrFlag == SK_SEN_ERR_WARN) { /* This state is the former one */ /* So check first whether we have to send a trap */ if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { /* * Do NOT send the Trap. The hold back time * has to run out first. */ DoTrapSend = SK_FALSE; } /* Check now whether we have to log an Error */ if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { /* * Do NOT log the error. The hold back time * has to run out first. */ DoErrLog = SK_FALSE; } } else { /* We came from a different state -> Set Begin Time Stamp */ pSen->SenBegWarnTS = CurrTime; pSen->SenErrFlag = SK_SEN_ERR_WARN; } if (DoTrapSend) { /* Set current Time */ pSen->SenLastWarnTrapTS = CurrTime; pSen->SenWarnCts++; /* Queue PNMI Event */ SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? SK_PNMI_EVT_SEN_WAR_UPP : SK_PNMI_EVT_SEN_WAR_LOW), ParaLocal); } if (DoErrLog) { /* Set current Time */ pSen->SenLastWarnLogTS = CurrTime; if (pSen->SenType == SK_SEN_TEMP) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); } else if (pSen->SenType == SK_SEN_VOLT) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); } else { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); } } } /* Check for NO error at all */ if (!IsError && !TooHigh && !TooLow) { /* Set o.k. Status if no error and no warning condition */ pSen->SenErrFlag = SK_SEN_ERR_OK; } /* End of check against the thresholds */ /* Bug fix AF: 16.Aug.2001: Correct the init base * of LM80 sensor. */ if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) { pSen->SenInit = SK_SEN_DYN_INIT_NONE; if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) { /* 5V PCI-IO Voltage */ pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN; pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR; } else { /* 3.3V PCI-IO Voltage */ pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN; pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR; } }#if 0 /* Dynamic thresholds also for VAUX of LM80 sensor */ if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { pSen->SenInit = SK_SEN_DYN_INIT_NONE; /* 3.3V VAUX Voltage */ if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) { pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; } /* 0V VAUX Voltage */ else { pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR; pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR; } } /* * Check initialization state: * The VIO Thresholds need adaption */ if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && pSen->SenValue > SK_SEN_WARNLOW2C && pSen->SenValue < SK_SEN_WARNHIGH2) { pSen->SenThreErrLow = SK_SEN_ERRLOW2C; pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; pSen->SenInit = SK_TRUE; } if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && pSen->SenValue > SK_SEN_WARNLOW2 && pSen->SenValue < SK_SEN_WARNHIGH2C) { pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; pSen->SenInit = SK_TRUE; }#endif if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); }} /* SkI2cCheckSensor*//* * The only Event to be served is the timeout event * */int SkI2cEvent(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */SK_U32 Event, /* Module specific Event */SK_EVPARA Para) /* Event specific Parameter */{ int ReadComplete; SK_SENSOR *pSen; SK_U32 Time; SK_EVPARA ParaLocal; int i; /* New case: no sensors */ if (pAC->I2c.MaxSens == 0) { return(0); } switch (Event) { case SK_I2CEV_IRQ: pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); if (ReadComplete) { /* Check sensor against defined thresholds */ SkI2cCheckSensor (pAC, pSen); /* Increment Current sensor and set appropriate Timeout */ pAC->I2c.CurrSens++; if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) { pAC->I2c.CurrSens = 0; Time = SK_I2C_TIM_LONG; } else { Time = SK_I2C_TIM_SHORT; } /* Start Timer */ ParaLocal.Para64 = (SK_U64)0; pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, SKGE_I2C, SK_I2CEV_TIM, ParaLocal); } else { /* Start Timer */ ParaLocal.Para64 = (SK_U64)0; pAC->I2c.TimerMode = SK_TIMER_WATCH_STATEMACHINE; SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, SKGE_I2C, SK_I2CEV_TIM, ParaLocal); } break; case SK_I2CEV_TIM: if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) { ParaLocal.Para64 = (SK_U64)0; SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer); pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); if (ReadComplete) { /* Check sensor against defined thresholds */ SkI2cCheckSensor (pAC, pSen); /* Increment Current sensor and set appropriate Timeout */ pAC->I2c.CurrSens++; if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { pAC->I2c.CurrSens = 0; Time = SK_I2C_TIM_LONG; } else { Time = SK_I2C_TIM_SHORT; } /* Start Timer */ ParaLocal.Para64 = (SK_U64)0; pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, SKGE_I2C, SK_I2CEV_TIM, ParaLocal); } } else { pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; pSen->SenErrFlag = SK_SEN_ERR_FAULTY; SK_I2C_STOP(IoC); /* Increment Current sensor and set appropriate Timeout */ pAC->I2c.CurrSens++; if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { pAC->I2c.CurrSens = 0; Time = SK_I2C_TIM_LONG; } else { Time = SK_I2C_TIM_SHORT; } /* Start Timer */ ParaLocal.Para64 = (SK_U64)0; pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, SKGE_I2C, SK_I2CEV_TIM, ParaLocal); } break; case SK_I2CEV_CLEAR: for (i = 0; i < SK_MAX_SENSORS; i++) { pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; pAC->I2c.SenTable[i].SenErrCts = 0; pAC->I2c.SenTable[i].SenWarnCts = 0; pAC->I2c.SenTable[i].SenBegErrTS = 0; pAC->I2c.SenTable[i].SenBegWarnTS = 0; pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0; pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0; pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0; pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0; } break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG); } return(0);} /* SkI2cEvent*/#endif /* !SK_DIAG */#endif /* CONFIG_SK98 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -