Fram_fr
Joined: 29 Oct 2008 Posts: 13
|
MAX6650/6651 driver |
Posted: Wed Oct 29, 2008 1:28 pm |
|
|
Hi all,
Here is a code for driving a MAXIM DALLAS MAX6650/MAX6651.
It's a fan speed regulator and monitor with SMBUS/I2C bus interface.
Code: |
//****************************************************************************//
//
// File: max6650 sensor driver.c
//
// Purpose: MAX6650 routines.
//
// Description: This file contains a set of useful routines for use with
// a MAX6650 (fan speed regulator and monitor).
//****************************************************************************//
//****************************************************************************//
// MAX6650 ID
//****************************************************************************//
#define MAX6650_ID 0b10010000 // see your HW and MAX6650 datasheet for ID value
//****************************************************************************//
// MAX6650 BYTE REGISTER
//****************************************************************************//
#define MAX6650_SPEED_REG 0b00000000 // fan speed R/W
#define MAX6650_CONFIG_REG 0b00000010 // configuration R/W
#define MAX6650_GPIODEF_REG 0b00000100 // GPIO definition R/W
#define MAX6650_DAC_REG 0b00000110 // DAC R/W
#define MAX6650_ALARMENABLE_REG 0b00001000 // alarm enable R/W
#define MAX6650_ALARM_REG 0b00001010 // alarm status R
#define MAX6650_TACHO_0_REG 0b00001100 // tachometer 0 count R
#define MAX6650_GPIOSTAT_REG 0b00010100 // GPIO status R
#define MAX6650_COUNT_REG 0b00010110 // tachometer count time R/W
//****************************************************************************//
// MAX6650 register values and variables
//****************************************************************************//
unsigned int8 config_off= 0b00011000; //max6650 register values
unsigned int8 config_full_on= 0b00001000; //max6650 register values
unsigned int8 config_closed_loop= 0b00101000; //max6650 register values
unsigned int8 gpioo= 0b11110101; //max6650 register values
unsigned int8 alarm_reg= 0b00000111; //max6650 register values
unsigned int8 count_t= 0b00000011; //max6650 register values
unsigned int8 kscale = 1; // see MAX6650 datasheet for the best value according to your fan speed
unsigned int8 countt = 2; // see MAX6650 datasheet for the best value according to your fan speed
//****************************************************************************//
// essentials routines for the MAXIM MAX6650 ic
//****************************************************************************//
//
// MAX6650_write_byte(); writes a byte into address
// MAX6650_read_byte(); read a byte from address
// MAX6650_receive_byte(); receive a byte from address
// MAX6650_init(); initializes device for continous temperature readings
// max6650_get_speed(); get fan speed from max6650 tacho register
// max6650_set_speed(); set fan speed to max6650 speed register
//
//****************************************************************************//
// MAX6650 CONFIG. BYTE REGISTER
//****************************************************************************//
//
// 7(MSB) to 6 : always 0
//
// 5 to 4 : Operating mode
//
// 00 software full-on (default)
// 01 software off
// 10 closed-loop operation
// 11 open-loop operation
//
// 3 : fan/tachometer voltage
//
// 0 5V fan/tachometer voltage
// 1 12V fan/tachometer voltage (default)
//
// 2 to 0(LSB) : Prescaler division (Kscale)
//
// 000 Divide by 1
// 001 Divide by 2
// 010 Divide by 4 (default)
// 011 Divide by 8
// 100 Divide by 16
//
//****************************************************************************//
// MAX6650 GPIODEF BYTE REGISTER
//****************************************************************************//
//
// 7(MSB) to 4 : always 1 for MAX6650
//
// 3 to 2 : GPIO1
//
// 00 outputs a logic-level high or serves as an input
// 01 serves as a FULL_ON input
// 10 outputs a logic-level low
// 11 outputs a logic-level high or serves as an input
//
// 1 to 0 : GPIO2
//
// 00 outputs a logic-level high or serves as an input
// 01 serves as an ALERT output
// 10 outputs a logic-level low
// 11 outputs a logic-level high or serves as an input
//
//****************************************************************************//
// MAX6650 ALARMENABLE BYTE REGISTER
//****************************************************************************//
//
// 7(MSB) to 4 : always 0 for MAX6650
//
// 3 : GPIO1 Alarm
//
// 0 disable
// 1 enable
//
// 2 : Tachometre overflow Alarm
//
// 0 disable
// 1 enable
//
// 1 : Minimum output level Alarm
//
// 0 disable
// 1 enable
//
// 0 : Maximum output level Alarm
//
// 0 disable
// 1 enable
//
//****************************************************************************//
void max6650_write_byte(int address, int data)
{
i2c_start();
i2c_write(MAX6650_ID); /* mode is write */
i2c_write(address); /* address of memory to write to */
i2c_write(data); /* data to be written */
i2c_stop();
}
BYTE max6650_read_byte(int address)
{
int data;
i2c_start();
i2c_write(MAX6650_ID); /* mode is write */
i2c_write(address); /* address of memory to read to */
i2c_start(); /* mode is read */
i2c_write(MAX6650_ID + 0X01); /* mode is write */ /* for read operation LSB commande bit must be set to 1 */
data = i2c_read(0);
i2c_stop();
return(data);
}
//!BYTE max6650_receive_byte(int data)
//!{
//! i2c_start(); /* mode is read */
//! i2c_write(MAX6650_ID + 0X01); /* for read operation LSB commande bit must be set to 1 */
//! data=i2c_read(0);
//! i2c_stop();
//! return(data);
//!}
void max6650_init(int alarm,int count,int config,int gpio)
{
max6650_write_byte(MAX6650_ALARMENABLE_REG, alarm); //configure ALARMENABLE register
max6650_write_byte(MAX6650_COUNT_REG, count); //configure COUNT register
max6650_write_byte(MAX6650_CONFIG_REG, config); //configure CONFIG register
max6650_write_byte(MAX6650_GPIODEF_REG, gpio); //configure GPIODEF register
}
//****************************************************************************//
// Set the fan speed to the specified RPM (or read back the RPM setting).
//
// The MAX6650/1 will automatically control fan speed when in closed loop
// mode.
//
// Assumptions:
//
// 1) The MAX6650/1 is running from its internal 254kHz clock (perhaps
// this should be made a module parameter).
//
// 2) The prescaler (low three bits of the config register) has already
// been set to an appropriate value.
//
// The relevant equations are given on pages 21 and 22 of the datasheet.
//
// From the datasheet, the relevant equation when in regulation is:
//
// [fCLK / (128 x (KTACH + 1))] = 2 x FanSpeed / KSCALE
//
// where:
//
// fCLK is the oscillator frequency (either the 254kHz internal
// oscillator or the externally applied clock)
//
// KTACH is the value in the speed register
//
// FanSpeed is the speed of the fan in rps
//
// KSCALE is the prescaler value (1, 2, 4, 8, or 16)
//
// When reading, we need to solve for FanSpeed :
//
// FanSpeed = (tacho / 2) x count_t
//
// then multiply by 60 to give fanspeed in rpm
//
// When writing, we need to solve for KTACH, using the datasheet equation:
//
// Divide the required speed by 60 to get from rpm to rps
//
// KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1
//
// If the internal oscillator is used, setting fCLK to 254kHz
// can further reduce the equations:
//
// Divide the required speed by 60 to get from rpm to rps
//
// KTACH = (992 x KSCALE / FanSpeed) - 1
//
// Note: this tachometer is completely separate from the tachometers
// used to measure the fan speeds. Only one fan's speed (fan1) is
// controlled.
//****************************************************************************//
int16 max6650_get_speed()
{
unsigned int8 rps;
i2c_start();
i2c_write(MAX6650_ID); /* mode is write */
i2c_write(MAX6650_TACHO_0_REG); /* address of memory to write to */
i2c_start(); /* mode is read */
i2c_write(MAX6650_ID + 0X01); /* mode is write */ /* for read operation LSB commande bit must be set to 1 */
rps=i2c_read(0);
i2c_stop();
rps = ((rps /2)/countt);
return(rps); //need to multiply rps by 60 to give fanspeed in rpm
}
void max6650_set_speed(unsigned int16 rpm)
{
unsigned int8 ktach;
ktach=(((992 * kscale) /(rpm/60) ) - 1);
i2c_start();
i2c_write(MAX6650_ID); /* mode is write */
i2c_write(MAX6650_SPEED_REG); /* address of memory to write to */
i2c_write(ktach); /* data to be writen */
i2c_stop();
}
|
|
|