Revision: 1716
Author: vsurducan
Date: Sat Feb 27 09:20:50 2010
Log: [No log message]
http://code.google.com/p/jallib/source/detail?r=1716
Added:
/trunk/include/external/temperature/SMbus_MLX90615.jal
=======================================
--- /dev/null
+++ /trunk/include/external/temperature/SMbus_MLX90615.jal Sat Feb 27
09:20:50 2010
@@ -0,0 +1,397 @@
+--
-------------------------------------------------------------------------
+-- Title: SM bus library for Melexis IR sensor MLX90615
+--
+-- Author: Vasile Surducan, Copyright (c) 2010...2012, all rights reserved.
+--
+-- Adapted-by:
+--
+-- Compiler: >=2.4m
+--
+-- This file is part of jallib (http://jallib.googlecode.com)
+-- Released under the BSD license
(http://www.opensource.org/licenses/bsd-license.php)
+--
+-- Description: software implementation for single SMbus master, use 4 hw
stack
+-- --
+-- define SM_bus pins like:
+-- alias SM_SCL is pin_C3
+-- alias SM_SCL_direction is pin_C3_direction
+
+-- alias SM_SDA is pin_C4
+-- alias SM_SDA_direction is pin_C4_direction
+-- ATTENTION: both SM_SDA and SM_SCL must have pull-up resistors
+--
+-- Procedures which can be used by application program:
+
+-- procedure SM_START_bit
+-- procedure SM_STOP_bit
+-- function SM_transmit_byte( byte in TX_buffer )return bit
+-- function SM_receive_byte( bit in ack_noack ) return byte
+-- procedure read_MEM ( byte in senzor_address, byte in MEM_address )
+-- procedure write_MEM ( byte in senzor_address, byte in MEM_address,
+-- byte in MEM_high, byte in MEM_low, byte in PEC )is
+-- procedure MLX90615_sleep ( byte in senzor_address )
+-- procedure MLX90615_wake
+-- procedure calculate_temp_C
+-- procedure calculate_temp_K
+-- todo: procedure calculate_CRC8 and/or procedure
SM_receive_byte_with_CRC8
+
+include delay
+
+-- -----------------------------------------------------
+-- MLX90615 EEPROM addresses
+-- -----------------------------------------------------
+
+const SMbus_SA = 0 ; SMbus Slave Address 7 bit, 0 to 6; 0x5b factory
default
+const PWM_T_range = 0x01
+const config_reg = 0x02
+const emissivity = 0x03
+ ; 0x04 to 0x0D factory reserved, do not alter!
+const ID_number0 = 0x0E ; read only
+const ID_number1 = 0x0F ; read only
+
+-- -----------------------------------------------------
+
+var word config
+var volatile bit mode_select at config: 0 ; 1=SMbus, 0=PWM
+var volatile bit PWM_frequency at config: 1 ; 1=low, 0=high
+var volatile bit PWM_output_temp at config: 2 ; 1=Tambiant, 0=Tobject
+var volatile bit*9 factory_cal at config: 3 ; do not alter
+var volatile bit*3 IIR_setting at config: 12 ; see table below
+var volatile bit zero at config: 15 ; keep 0
+
+-- binary settling time spike response
+-- (samples) (percent %)
+-- --------------------------------------
+-- 001 1 100
+-- 010 10 50
+-- 011 18 33.3
+-- 100 24 25
+-- 101 31 20
+-- 110 38 16.6
+-- 111 45 14.286
+-- --------------------------------------
+
+-- -----------------------------------------------------
+-- MLX90615 RAM addresses
+-- -----------------------------------------------------
+
+-- 0x04 to 0x4h Melexis reserved
+const raw_IR_data = 0x05
+const Tambiant = 0x06
+const Tobject = 0x07
+-- 0x08 to 0x0F Melexis reserved
+
+-- -----------------------------------------------------
+
+-- -----------------------------------------------------
+-- MLX90615 commands
+-- -----------------------------------------------------
+
+const EEPROM_access = 0b0001_0000
+const RAM_access = 0b0010_0000
+const SLEEP_mode = 0b1100_0110
+
+-- -----------------------------------------------------
+
+
+-- -----------------------------------------------------
+-- SMbus bit config, SMbus direction config
+-- -----------------------------------------------------
+
+const bit ACK = low
+const bit NACK = high
+
+
+procedure _SDA_high is
+ SM_SDA_direction = input
+end procedure
+
+
+procedure _SDA_low is
+ SM_SDA_direction = output
+ SM_SDA = low
+end procedure
+
+procedure _SCL_HIGH is
+ SM_SCL_direction = input
+end procedure
+
+procedure _SCL_low is
+ SM_SCL_direction = output
+ SM_SCL = low
+end procedure
+
+procedure SM_BUS_initialize is ; not necesary if SMbus is POR default
+ SM_SDA_direction = input ; SM_SDA = high from pull-up
+ SM_SCL_direction = input ; SM_SCL = high from pull-up
+
+ _SCL_low
+ delay_1mS ( 30 )
+ _SCL_high ; SM_bus mode
+end procedure
+-- -------------------------------------------------------------------
+
+-- -----------------------------
+-- SMbus start bit
+-- -----------------------------
+procedure SM_START_bit is
+ _SDA_high
+ _usec_delay ( 2 )
+ _SCL_high
+ _usec_delay ( 5 )
+ _SDA_low
+ _usec_delay ( 4 )
+ _SCL_low
+ _usec_delay ( 2 )
+end procedure
+-- -----------------------------
+
+-- -----------------------------
+-- SMbus stop bit
+-- -----------------------------
+procedure SM_STOP_bit is
+ _SCL_low
+ _usec_delay ( 2 )
+ _SDA_low
+ _usec_delay ( 2 )
+ _SCL_high
+ _usec_delay ( 4 )
+ _SDA_high
+end procedure
+-- -----------------------------
+
+-- ---------------------------------------------------
+-- Transmit one bit on SM bus (for internal use only )
+-- ---------------------------------------------------
+procedure _SM_send_bit (bit in x) is
+; SM_SDA_direction = x
+ if x == low then
+ _SDA_low
+ else
+ _SDA_high
+ end if
+ _usec_delay ( 3 )
+ _SCL_high
+ _usec_delay ( 11 )
+ _SCL_low
+ _usec_delay ( 4 ) ; 11 + 4 18uS clk
+end procedure
+-- ---------------------------------------------------
+
+-- -------------------------------------------------
+-- Receive one bit on SM bus (for internal use only)
+-- -------------------------------------------------
+procedure _SM_receive_bit (bit out x) is
+ SM_SDA_direction = input
+ _SCL_high
+ _usec_delay ( 11 )
+ x = SM_SDA
+ _SCL_low
+ _usec_delay ( 4 )
+end procedure
+-- -------------------------------------------------
+
+-- --------------------------------------------------------
+-- Transmit one byte on SM bus
+-- --------------------------------------------------------
+function SM_transmit_byte (byte in TX_buffer) return bit is
+ var bit b at TX_buffer : 7
+ var bit ack_noack
+
+ for 8 loop
+ _SM_send_bit( b )
+ TX_buffer = TX_buffer << 1
+ end loop
+ _SM_receive_bit ( ack_noack )
+ return ack_noack ; 0=ack received, 1=no ack received
+end function
+
+-- ---------------------------------------------------------
+
+-- ---------------------------------------------------------
+-- Receive one byte on SM bus
+-- ---------------------------------------------------------
+function SM_receive_byte (bit in ack_noack) return byte is
+ var byte RX_buffer
+ var bit b at RX_buffer : 0
+ for 8 loop
+ RX_buffer = RX_buffer << 1
+ _SM_receive_bit ( b )
+ end loop
+ _SM_send_bit (ack_noack); 0=ack, 1 = no_ack
+ return RX_buffer
+end function
+-- ---------------------------------------------------------
+
+var bit MLX90615_ACK = high
+var byte MEM_low = 0
+var byte MEM_high = 0
+-- var byte T_low = 0
+var byte T_high = 0
+var sword s_T_high = 0
+var word w_T_high = 0
+var byte PEC = 0
+var sword temperature = 0
+var word temp = 0
+var sword temperature_C = 0
+var word temperature_K = 0
+var byte nack_counter = 0
+
+-- -------------------------------------------------------------------
+-- read RAM & EEPROM routine
+-- MLX90615 senzor_address = 0x5b and 0x00
+-- examples:
+-- MEM_address = RAM_access + Tobject ; read Tobject
+-- MEM_address = RAM_access + Tambiant; read Tambiant (senzor package
temperature)
+-- MEM_address = EEPROM_access + config_address; read config
+-- -------------------------------------------------------------------
+
+procedure read_MEM ( byte in senzor_address, byte in MEM_address )is
+SM_START_bit
+MLX90615_ACK = SM_transmit_byte ((senzor_address << 1)& 0b1111_1110 + 0) ;
address, wr
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MLX90615_ACK = SM_transmit_byte ( MEM_address );
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+SM_START_bit
+MLX90615_ACK = SM_transmit_byte ((senzor_address << 1)& 0b1111_1110 + 1) ;
address, rd
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MEM_low = SM_receive_byte (ACK)
+MEM_high = SM_receive_byte (ACK)
+PEC = SM_receive_byte (ACK)
+SM_STOP_bit
+end procedure
+
+-- ------------------------------------------------------------------
+
+-- ------------------------------------------------------------------
+-- write EEPROM routine
+-- ------------------------------------------------------------------
+procedure write_MEM ( byte in senzor_address, byte in MEM_address,
+ byte in MEM_high, byte in MEM_low, byte in PEC )is
+SM_START_bit
+MLX90615_ACK = SM_transmit_byte ((senzor_address << 1)& 0b1111_1110 + 0) ;
address, wr
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MLX90615_ACK = SM_transmit_byte ( MEM_address );
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MLX90615_ACK = SM_transmit_byte ( MEM_low );
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MLX90615_ACK = SM_transmit_byte ( MEM_high );
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MLX90615_ACK = SM_transmit_byte ( PEC );
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+SM_STOP_bit
+delay_1mS ( 5 )
+end procedure
+-- -------------------------------------------------------------------
+
+-- ----------------------------------
+-- put MLX90615 in sleep mode
+-- ----------------------------------
+
+procedure MLX90615_sleep ( byte in senzor_address ) is
+SM_START_bit
+MLX90615_ACK = SM_transmit_byte ((senzor_address << 1)& 0b1111_1110 + 0) ;
address, wr
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MLX90615_ACK = SM_transmit_byte ( SLEEP_mode );
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+MLX90615_ACK = SM_transmit_byte ( 0x49 ); PEC value
+ if MLX90615_ACK == NACK then
+ nack_counter = nack_counter + 1
+ SM_STOP_bit
+ return
+ end if
+SM_STOP_bit
+_SCL_low
+end procedure
+
+-- ----------------------------------
+
+-- ----------------------------------------------------------------------
+-- exit from sleep
+-- ----------------------------------------------------------------------
+
+procedure MLX90615_wake is
+_SCL_low
+ delay_1mS ( 60 )
+_SCL_high
+SM_START_bit
+MLX90615_ACK = SM_transmit_byte (0b1111_1110) ; send a dummy
+SM_STOP_bit
+end procedure
+
+-- ----------------------------------------------------------------------
+
+-- ----------------------------------
+-- conversion to celsius
+-- ----------------------------------
+
+procedure calculate_temp_C is
+const sword c27315 = 27315
+; T_low = MEM_low
+ s_T_high = sword (MEM_high)
+; make it word (positive temperature only) or sword (positive or negative
temperature)
+; temperature = 256*s_T_high + T_low
+ temperature = 256*s_T_high + MEM_low
+ temperature_C = (temperature * 2 - c27315) / 10
+end procedure
+
+-- ----------------------------------
+
+-------------------------------------
+-- conversion to kelvin
+-- ----------------------------------
+procedure calculate_temp_K is
+
+; T_low = MEM_low
+ w_T_high = word (MEM_high)
+; temperature = 256*w_T_high + T_low
+ temp = word (temperature) ; make it word (positive temperature only)
+ temp = 256*w_T_high + MEM_low
+ temperature_K = temp* 2 / 100
+end procedure
+
+-------------------------------------
+
+
+
+
--
You received this message because you are subscribed to the Google Groups
"jallib" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jallib?hl=en.