www.pudn.com > vxworks0108.rar > lm75.c


#include "usr/or_types.h"
#include "hardware/lm75.h"
#include "hardware/smbus.h"
#include "vxworks/smbus.h"
#include "vxworks/lm75.h"
/*******************************************************************************
*
* sysLm75IsAvailable - Check if the LM75 can be accessed
*
* This function reads the status register of the LM75.
*
* RETURNS: TRUE  - LM75 is installed
*          FALSE - no LM75 device on SMBus
*
*/

BOOL sysLm75IsAvailable(void)
{
    unsigned char dummy;

    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(FALSE);
    }

    /* try to access the LM75 */
    if (SMB_ReadDataByte (SMB_ID_LM75, SEL_CONF_REG_LM75, &dummy) != OK_SMB)
    {
        SMB_Deinit ();
        return (FALSE);
    }

    SMB_Deinit ();

    return (TRUE);
}


/*******************************************************************************
*
* sysLm75ConfigGet - Get the Config Byte of the LM75
*
* This function reads the status register of the LM75.
*
* RETURNS: 0 = OK
*          else error
*
* SEE ALSO: sysLm75TConfigSet()
*
*/

int sysLm75ConfigGet
    (
    unsigned char *pConfigByte    /* ptr to LM75 configuration byte */
    )
{
    unsigned char tempVal;


    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(-1);
    }

    /* read the Configuration Register(8 Bit) of the LM75 */
    if (SMB_ReadDataByte (SMB_ID_LM75, SEL_CONF_REG_LM75, &tempVal) != OK_SMB)
    {
        SMB_Deinit ();
        return (-1);
    }


    *pConfigByte = tempVal;

    SMB_Deinit ();

    return (0);

}


/*******************************************************************************
*
* sysLm75TemperatureGet - Read the Temperature Value
*
* This function reads the temperature register of the LM75 and converts
* the result in "degrees celsius".
*
* RETURNS: 0 = OK
*          else error
*
*/

int sysLm75TemperatureGet
    (
    int *pTemperature       /* ptr to LM75 temperature */
    )
{
    unsigned short tempVal;
    int temp;

    *pTemperature = 0;

    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(-1);
    }

    /* read the Temperature Register (16Bit) of the LM75 */
    if (SMB_ReadDataWord (SMB_ID_LM75, SEL_TEMP_REG_LM75, &tempVal) != OK_SMB)
    {
        SMB_Deinit ();
        return (-1);
    }

    /* convert the temperature in degrees celsius */
    if (tempVal & 0x8000)
    {
        /* negative temperature */
        temp = (int)((short)tempVal >> (1+TEMP_SHIFT_LM75));
    } else
    {
        temp = (int)tempVal;
        temp >>= (1+TEMP_SHIFT_LM75);
    }

    *pTemperature = temp;

    SMB_Deinit ();

    return (0);

}


/*******************************************************************************
*
* sysLm75T_OS_Get - Read the O.S. Temperature Value
*
* This function reads the O.S. temperature register of the LM75 and converts
* the result in "degrees celsius".
* This value is the upper limit of the temperature before the event will be
* signalled through an output pin.
*
* RETURNS: 0 = OK
*          else error
*
* SEE ALSO: sysLm75T_OS_Set()
*
*/

int sysLm75T_OS_Get
    (
    int *pTemperature       /* ptr to LM75 HYST temperature */
    )
{
    unsigned short tempVal;
    int temp;

    *pTemperature = 0;

    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(-1);
    }

    /* read the Temperature Register (16Bit) of the LM75 */
    if (SMB_ReadDataWord (SMB_ID_LM75, SEL_TOS_REG_LM75, &tempVal) != OK_SMB)
    {
        SMB_Deinit ();
        return (-1);
    }

    /* convert the temperature in degrees celsius */
    if (tempVal & 0x8000)
    {
        /* negative temperature */
        temp = (int)((short)tempVal >> (1+TEMP_SHIFT_LM75));
    } else
    {
        temp = (int)tempVal;
        temp >>= (1+TEMP_SHIFT_LM75);
    }

    *pTemperature = temp;

    SMB_Deinit ();

    return (0);

}


/*******************************************************************************
*
* sysLm75T_HYST_Get - Read the HYST Temperature Value
*
* This function reads the HYST temperature register of the LM75 and converts
* the result in "degrees celsius".
* This value is the lower limit the temperature must drop below before the event
* will be signalled inactive.
*
* RETURNS: 0 = OK
*          else error
*
* SEE ALSO: sysLm75T_HYST_Set()
*
*/

int sysLm75T_HYST_Get
    (
    int *pTemperature       /* ptr to LM75 HYST temperature */
    )
{
    unsigned short tempVal;
    int temp;

    *pTemperature = 0;

    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(-1);
    }

    /* read the Temperature Register (16Bit) of the LM75 */
    if (SMB_ReadDataWord (SMB_ID_LM75, SEL_THYST_REG_LM75, &tempVal) != OK_SMB)
    {
        SMB_Deinit ();
        return (-1);
    }

    /* convert the temperature in degrees celsius */
    if (tempVal & 0x8000)
    {
        /* negative temperature */
        temp = (int)((short)tempVal >> (1+TEMP_SHIFT_LM75));
    } else
    {
        temp = (int)tempVal;
        temp >>= (1+TEMP_SHIFT_LM75);
    }

    *pTemperature = temp;

    SMB_Deinit ();

    return (0);

}


/*******************************************************************************
*
* sysLm75ConfigSet - Set the Config Byte of the LM75
*
* This function sets the Configuration register of the LM75.
*
* RETURNS: 0 = OK
*          else error
*
* SEE ALSO: sysLm75TConfigGet()
*
*/

int sysLm75ConfigSet
    (
    unsigned char configByte    /* LM75 configuration byte */
    )
{

    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(-1);
    }

    /* write to the Configuration Register(8 Bit) of the LM75 */
    if (SMB_WriteDataByte (SMB_ID_LM75, SEL_CONF_REG_LM75, configByte) != OK_SMB)
    {
        SMB_Deinit ();
        return (-1);
    }


    SMB_Deinit ();

    return (0);

}


/*******************************************************************************
*
* sysLm75T_OS_Set - Write the O.S. Temperature Value
*
* This function sets the O.S. temperature register of the LM75.
* The alarm condition switches to active, if the temperature exceeds this
* alarm threshold value.
*
* RETURNS: 0 = OK
*          else error
*
* SEE ALSO: sysLm75T_OS_Get()
*
*/

int sysLm75T_OS_Set
    (
    int temperature     /* LM75 O.S. temperature in degrees celsius */
    )
{
    unsigned short tempVal;

    /* check if the given value is within the chips limits */
    if ((temperature < LM75_TEMP_MIN) || (temperature > LM75_TEMP_MAX))
    {
        return (SYSLM75_ILLEGAL_TEMPERATURE);
    }


    /* convert the temperature from degrees celsius to binary register value */
    if (temperature < 0)
    {
        /* negative temperature */
        tempVal = (unsigned short)temperature;
        tempVal <<= (1+TEMP_SHIFT_LM75);
    } else
    {
        tempVal = (unsigned short)temperature;
        tempVal <<= (1+TEMP_SHIFT_LM75);
    }

    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(-1);
    }

    /* read the Temperature Register (16Bit) of the LM75 */
    if (SMB_WriteDataWord (SMB_ID_LM75, SEL_TOS_REG_LM75, tempVal) != OK_SMB)
    {
        SMB_Deinit ();
        return (-1);
    }


    SMB_Deinit ();

    return (0);

}

/*******************************************************************************
*
* sysLm75T_HYST_Set - Write the HYST Temperature Value
*
* This function sets the HYST temperature register of the LM75.
* The alarm condition goes away, if the temperature drops below this HYST value.
*
* RETURNS: 0 = OK
*          else error
*
* SEE ALSO: sysLm75T_HYST_Get()
*
*/

int sysLm75T_HYST_Set
    (
    int temperature     /* LM75 HYST temperature in degrees celsius */
    )
{
    unsigned short tempVal;

    /* check if the given value is within the chips limits */
    if ((temperature < LM75_TEMP_MIN) || (temperature > LM75_TEMP_MAX))
    {
        return (SYSLM75_ILLEGAL_TEMPERATURE);
    }


    /* convert the temperature from degrees celsius to binary register value */
    if (temperature < 0)
    {
        /* negative temperature */
        tempVal = (unsigned short)temperature;
        tempVal <<= (1+TEMP_SHIFT_LM75);
    } else
    {
        tempVal = (unsigned short)temperature;
        tempVal <<= (1+TEMP_SHIFT_LM75);
    }

    /* try to init SMBus */
    if (OK_SMB != SMB_Init ())
    {
        return(-1);
    }

    /* read the Temperature Register (16Bit) of the LM75 */
    if (SMB_WriteDataWord (SMB_ID_LM75, SEL_THYST_REG_LM75, tempVal) != OK_SMB)
    {
        SMB_Deinit ();
        return (-1);
    }


    SMB_Deinit ();

    return (0);

}


/*
 *  Test and sample routines
 */
#if defined(INCLUDE_LM75_SAMPLE)   /* include lm75 sample application */

/******************************************************************************
*
* testLm75Temp - test application for LM75 temperature sensor
*
* This function tests the access to LM75 temperature sensor registers.
*
* RETURNS:  0 if OK, -1 otherwise
*
* SEE ALSO: sysLm75IsAvailable(), sysLm75TemperatureGet(),
*           sysLm75T_OS_Get(), sysLm75T_HYST_Get()
*/
int testLm75Temp(void)
{
    int temperature;

    /* check for presence of LM75 */
    if (sysLm75IsAvailable() == FALSE)
    {
        printf ("sysLm75: LM75 is not installed on this board\n");
        return (-1);
    }

    /* get T_OS setting */
    if (sysLm75T_OS_Get(&temperature) != 0)
    {
        printf("sysLm75: Can not obtain O.S. Temperature from LM75\n");
        return (-1);
    }

    printf ("sysLm75: O.S. Temperature is: %d degrees Celsius\n", temperature);

    /* get T_HYST setting */
    if (sysLm75T_HYST_Get(&temperature) != 0)
    {
        printf("sysLm75: Can not obtain HYST Temperature from LM75\n");
        return (-1);
    }

    printf ("sysLm75: HYST Temperature is: %d degrees Celsius\n", temperature);

    /* get actual temperature */
    if (sysLm75TemperatureGet(&temperature) != 0)
    {
        printf("sysLm75: Can not obtain Temperature from LM75\n");
        return (-1);
    }

    printf ("sysLm75: Temperature is: %d degrees Celsius\n", temperature);

    /* check setting of T O.S. */

    temperature = 99;

    printf ("\n..setting T O.S. to %d degrees celsius\n", temperature);

    if (sysLm75T_OS_Set(temperature) != 0)
    {
        printf("sysLm75: Can not set O.S. Temperature on LM75\n");
        return (-1);
    }

    if (sysLm75T_OS_Get(&temperature) != 0)
    {
        printf("sysLm75: Can not obtain O.S. Temperature from LM75\n");
        return (-1);
    }

    printf ("sysLm75: O.S. Temperature is: %d degrees Celsius\n", temperature);

    temperature = -25;

    printf ("\n..setting T O.S. to %d degrees celsius\n", temperature);

    if (sysLm75T_OS_Set(temperature) != 0)
    {
        printf("sysLm75: Can not set O.S. Temperature on LM75\n");
        return (-1);
    }

    if (sysLm75T_OS_Get(&temperature) != 0)
    {
        printf("sysLm75: Can not obtain O.S. Temperature from LM75\n");
        return (-1);
    }

    printf ("sysLm75: O.S. Temperature is: %d degrees Celsius\n", temperature);


    /* check setting of T HYST. */

    temperature = 110;

    printf ("\n..setting HYST. to %d degrees celsius\n", temperature);

    if (sysLm75T_HYST_Set(temperature) != 0)
    {
        printf("sysLm75: Can not set HYST Temperature on LM75\n");
        return (-1);
    }

    if (sysLm75T_HYST_Get(&temperature) != 0)
    {
        printf("sysLm75: Can not obtain HYST Temperature from LM75\n");
        return (-1);
    }

    printf ("sysLm75: HYST Temperature is: %d degrees Celsius\n", temperature);

    temperature = -50;

    printf ("\n..setting HYST to %d degrees celsius\n", temperature);

    if (sysLm75T_HYST_Set(temperature) != 0)
    {
        printf("sysLm75: Can not set HYST. Temperature on LM75\n");
        return (-1);
    }

    if (sysLm75T_HYST_Get(&temperature) != 0)
    {
        printf("sysLm75: Can not obtain HYST Temperature from LM75\n");
        return (-1);
    }

    printf ("sysLm75: HYST Temperature is: %d degrees Celsius\n", temperature);


    return (0);
}

/******************************************************************************
*
* sysSmiExcHandler - handle a SMI
*
* This routine will process SMI received from the southbridge (M1543C).
*
* RETURNS: N/A
*
* SEE ALSO: testLm75TempSmi()
*/

void sysSmiExcHandler (void)
{
    UINT16  tmp16;

    /* assert SMI acknowledge */
    pciConfigModifyByte (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_SMICNTL, 0x40, 0x40);

    logMsg( "SMI occured!\n", 0,0,0,0,0,0 );

    /* reset SMI status bit */
    if (OK == pciConfigInWord (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_SESS, &tmp16))
    {
        if (tmp16 & 0x100)
        {
            logMsg( "Thermal SMI occured (LM75)!\n", 0,0,0,0,0,0 );
            pciConfigOutWord (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_SESS, 0x100);
        }
    }

    /* deasssert SMI acknowledge */
    pciConfigModifyByte (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_SMICNTL, 0x40, 0x00);

    return;
}

/******************************************************************************
*
* testLm75TempSmi - test application for LM75 temperature sensor interrupt
*
* This function tests the SMI generation by the LM75
*
* RETURNS:  0 if OK, -1 otherwise
*
* SEE ALSO: sysLm75IsAvailable(), sysLm75TemperatureGet(),
*           sysLm75T_OS_Get(), sysLm75T_HYST_Get()
*/
int testLm75TempSmi(void)
{
    FUNCPTR excFunc;
    int     savLm75OsTemp,
            savLm75HystTemp,
            lm75Temp,
            temp;
    Uint8   savLm75Config;


    printf ("\nTesting LM75 SMI generation\n\n");

    /* check for presence of LM75 */
    if (sysLm75IsAvailable() == FALSE)
    {
        printf ("sysLm75: LM75 is not installed on this board\n");
        return (-1);
    }

    /* save current LM75 HYST temperature */
    if (sysLm75T_HYST_Get(&savLm75HystTemp) != 0)
    {
        printf("sysLm75: Can not obtain HYST Temperature from LM75\n");
        return (-1);
    }
    printf ("Current HYST temperature is %d degrees celsius\n", savLm75HystTemp);

    /* save current LM75 O.S. temperature */
    if (sysLm75T_OS_Get(&savLm75OsTemp) != 0)
    {
        printf("sysLm75: Can not obtain O.S. Temperature from LM75\n");
        return (-1);
    }
    printf ("Current O.S. temperature is %d degrees celsius\n", savLm75OsTemp);

    /* save current LM75 configuration register */
    if (sysLm75ConfigGet(&savLm75Config) != 0)
    {
        printf("sysLm75: Can not obtain configuration register from LM75\n");
        return (-1);
    }
    printf ("Current LM75 configuration register is 0x%02x\n", savLm75Config);

    /* get current LM75 temperature */
    if (sysLm75TemperatureGet(&lm75Temp) != 0)
    {
        printf("sysLm75: Can not obtain Temperature from LM75\n");
        return (-1);
    }
    printf ("Current temperature is %d degrees celsius\n", lm75Temp);

    /* set default LM75 configuration (comparator mode, O.S. active low) */
    printf ("Now setting default LM75 configuration (comparator mode, O.S. active low)\n");
    if (sysLm75ConfigSet((unsigned char)0) != 0)
    {
        printf("sysLm75: Cannot set configuration  on LM75\n");
        return (-1);
    }

    /* configure THRMJ input pin (= LM75 O.S. output) to detect falling and rising edges */
    printf ("Now configuring SMI in M1543C southbridge\n");
    if (OK != pciConfigModifyLong (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_COESI, 0x7000, 0x6000))
    {
        printf("Cannot configure COESI in PMU of southbridge\n");
        return (-1);
    }

    /* enable SMI toggle for events specified in M1543C_PMU_COESI */
    if (OK != pciConfigModifyWord (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_EESS, 0x0100, 0x0100))
    {
        printf("Cannot configure COESI in PMU of southbridge\n");
        return (-1);
    }

    /* save default exception handler for SMI */
    excFunc = excVecGet ((FUNCPTR *)_EXC_OFF_SYS_MNG);

    /* set LM75 O.S. temperature to a value above the current temperature */
    temp = lm75Temp+10;
    printf ("Now setting O.S. temperature above current temperature (%d)\n", temp);
    if (sysLm75T_OS_Set(temp) != 0)
    {
        printf("sysLm75: Cannot set HYST Temperature on LM75\n");
        return (-1);
    }

    /* set LM75 HYST temperature to a value above the current temperature */
    temp = lm75Temp+5;
    printf ("Now setting HYST temperature above current temperature (%d)\n", temp);
    if (sysLm75T_HYST_Set(temp) != 0)
    {
        printf("sysLm75: Cannot set HYST Temperature on LM75\n");
        return (-1);
    }

    /* connect our SMI handler */
    printf ("Now connecting our SMI handler\n");
    excIntConnect ((VOIDFUNCPTR *) _EXC_OFF_SYS_MNG, sysSmiExcHandler);

    /* reset SMI status bit */
    if (OK != pciConfigModifyWord (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_SESS, 0x0100, 0x0000))
    {
        printf("Cannot configure COESI in PMU of southbridge\n");
        return (-1);
    }

    /* enable SMI */
    printf ("\n");
    printf ("Now enabling SMI\n");
    if (OK != pciConfigModifyByte (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_SMICNTL, 0x5f, 0x08))
    {
        printf("Cannot configure COESI in PMU of southbridge\n");
        return (-1);
    }
    taskDelay(sysClkRateGet());

    /* set LM75 HYST temperature to a value below the current temperature */
    temp = lm75Temp-10;
    printf ("Now setting HYST temperature below current temperature (%d)\n", temp);
    if (sysLm75T_HYST_Set(temp) != 0)
    {
        printf("sysLm75: Cannot set HYST Temperature on LM75\n");
        return (-1);
    }

    /* set LM75 O.S. temperature to a value below the current temperature */
    temp = lm75Temp-5;
    printf ("Now setting O.S. temperature below current temperature (%d)\n", temp);
    printf ("\n");
    printf ("Waiting for SMI...\n");
    if (sysLm75T_OS_Set(temp) != 0)
    {
        printf("sysLm75: Cannot set HYST Temperature on LM75\n");
        return (-1);
    }
    taskDelay(sysClkRateGet());

    /* set LM75 O.S. temperature to a value above the current temperature */
    temp = lm75Temp+10;
    printf ("\n");
    printf ("Now setting O.S. temperature above current temperature (%d)\n", temp);
    taskDelay(sysClkRateGet());
    if (sysLm75T_OS_Set(temp) != 0)
    {
        printf("sysLm75: Cannot set HYST Temperature on LM75\n");
        return (-1);
    }

    temp = lm75Temp+5;
    printf ("Now setting HYST temperature above current temperature (%d)\n", temp);
    printf ("\n");
    printf ("Waiting for SMI...\n");
    if (sysLm75T_HYST_Set(temp) != 0)
    {
        printf("sysLm75: Cannot set HYST Temperature on LM75\n");
        return (-1);
    }
    taskDelay(sysClkRateGet());


    /* disable SMI */
    printf ("\nNow disabling SMI\n");
    if (OK != pciConfigModifyByte (0, PCI_DEV_NO_M1543C_PMU, 0, M1543C_PMU_SMICNTL, 0x08, 0x00))
    {
        printf("Cannot configure COESI in PMU of southbridge\n");
        return (-1);
    }

    /* restore exception handler for SMI */
    printf ("Now restoring original SMI handler\n");
    excConnect ((VOIDFUNCPTR *)_EXC_OFF_SYS_MNG, (VOIDFUNCPTR)excFunc);

    /* restore LM75 configuration register */
    printf ("Now restoring original LM75 configuration\n");
    if (sysLm75ConfigGet(&savLm75Config) != 0)
    {
        printf("sysLm75: Can not obtain configuration register from LM75\n");
        return (-1);
    }

    /* restore LM75 O.S. temperature */
    if (sysLm75T_OS_Get(&savLm75OsTemp) != 0)
    {
        printf("sysLm75: Can not obtain O.S. Temperature from LM75\n");
        return (-1);
    }

    /* restore LM75 HYST temperature */
    if (sysLm75T_HYST_Get(&savLm75HystTemp) != 0)
    {
        printf("sysLm75: Can not obtain HYST Temperature from LM75\n");
        return (-1);
    }

    return (0);
}

#endif /* defined(INCLUDE_LM75_SAMPLE) */