Adapted the TMP102 sensor to Contiki's sensor API

This commit is contained in:
Antonio Lignan 2016-02-22 10:34:48 +01:00
parent 93b9089164
commit 151f532225
3 changed files with 95 additions and 118 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL * Copyright (c) 2010-2016, Zolertia <http://www.zolertia.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -32,9 +32,10 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**
* \file * \file
* A quick program for testing the tmp102 driver in the Z1 platform * A quick program for testing the tmp102 sensor in the Z1 platform
* \author * \author
* Enric M. Calvo <ecalvo@zolertia.com> * Enric M. Calvo <ecalvo@zolertia.com>
* Antonio Lignan <alinan@zolertia.com>
*/ */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#include <stdio.h> #include <stdio.h>
@ -44,7 +45,7 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#define TMP102_READ_INTERVAL (CLOCK_SECOND / 2) #define TMP102_READ_INTERVAL (CLOCK_SECOND / 2)
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS(temp_process, "Test Temperature process"); PROCESS(temp_process, "TMP102 Temperature sensor process");
AUTOSTART_PROCESSES(&temp_process); AUTOSTART_PROCESSES(&temp_process);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static struct etimer et; static struct etimer et;
@ -55,12 +56,12 @@ PROCESS_THREAD(temp_process, ev, data)
int16_t temp; int16_t temp;
tmp102_init(); SENSORS_ACTIVATE(tmp102);
while(1) { while(1) {
etimer_set(&et, TMP102_READ_INTERVAL); etimer_set(&et, TMP102_READ_INTERVAL);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
temp = tmp102_read_temp_x100(); temp = tmp102.value(TMP102_READ);
printf("Temp = %d\n", temp); printf("Temp = %d\n", temp);
} }
PROCESS_END(); PROCESS_END();

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2010, Swedish Institute of Computer Science. * Copyright (c) 2010, Swedish Institute of Computer Science.
* Copyright (c) 2016, Zolertia <http://www.zolertia.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -29,65 +30,55 @@
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
*/ */
/*---------------------------------------------------------------------------*/
/** /**
* \file * \file
* Device drivers for tmp102 temperature sensor in Zolertia Z1. * Device drivers for tmp102 temperature sensor in Zolertia Z1.
* \author * \author
* Enric M. Calvo, Zolertia <ecalvo@zolertia.com> * Enric M. Calvo, Zolertia <ecalvo@zolertia.com>
* Marcus Lundén, SICS <mlunden@sics.se> * Marcus Lundén, SICS <mlunden@sics.se>
* Antonio Lignan, Zolertia <alinan@zolertia.com>
*/ */
/*---------------------------------------------------------------------------*/
#include <stdio.h> #include <stdio.h>
#include "contiki.h" #include "contiki.h"
#include "i2cmaster.h" #include "i2cmaster.h"
#include "tmp102.h" #include "tmp102.h"
#include "lib/sensors.h"
/* Bitmasks and bit flag variable for keeping track of tmp102 status. */
enum TMP102_STATUSTYPES {
/* must be a bit and not more, not using 0x00. */
INITED = 0x01,
RUNNING = 0x02,
STOPPED = 0x04,
LOW_POWER = 0x08,
AAA = 0x10, /* available to extend this... */
BBB = 0x20, /* available to extend this... */
CCC = 0x40, /* available to extend this... */
DDD = 0x80 /* available to extend this... */
};
static enum TMP102_STATUSTYPES _TMP102_STATUS = 0x00;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* PROCESS(tmp102_process, "Temperature Sensor process"); */ #define DEBUG 0
#if DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*---------------------------------------------------------------------------*/
static uint8_t enabled;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Init the temperature sensor: ports, pins, registers, interrupts (none enabled), I2C,
default threshold values etc. */
void void
tmp102_init(void) tmp102_init(void)
{ {
if(!(_TMP102_STATUS & INITED)) { /* Power Up TMP102 via pin */
PRINTFDEBUG("TMP102 init\n"); TMP102_PWR_DIR |= TMP102_PWR_PIN;
_TMP102_STATUS |= INITED; TMP102_PWR_SEL &= ~TMP102_PWR_SEL;
/* Power Up TMP102 via pin */ TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL;
TMP102_PWR_DIR |= TMP102_PWR_PIN; TMP102_PWR_REN &= ~TMP102_PWR_SEL;
TMP102_PWR_SEL &= ~TMP102_PWR_SEL; TMP102_PWR_OUT |= TMP102_PWR_PIN;
TMP102_PWR_SEL2 &= ~TMP102_PWR_SEL;
TMP102_PWR_REN &= ~TMP102_PWR_SEL;
TMP102_PWR_OUT |= TMP102_PWR_PIN;
/* Set up ports and pins for I2C communication */ /* Set up ports and pins for I2C communication */
i2c_enable(); i2c_enable();
}
enabled = 1;
}
/*---------------------------------------------------------------------------*/
void
tmp102_stop(void)
{
/* Power off */
TMP102_PWR_OUT &= ~TMP102_PWR_PIN;
enabled = 0;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Write to a 16-bit register.
args:
reg register to write to
val value to write
*/
void void
tmp102_write_reg(uint8_t reg, uint16_t val) tmp102_write_reg(uint8_t reg, uint16_t val)
{ {
@ -98,26 +89,20 @@ tmp102_write_reg(uint8_t reg, uint16_t val)
i2c_transmitinit(TMP102_ADDR); i2c_transmitinit(TMP102_ADDR);
while(i2c_busy()); while(i2c_busy());
PRINTFDEBUG("I2C Ready to TX\n"); PRINTF("I2C Ready to TX\n");
i2c_transmit_n(3, tx_buf); i2c_transmit_n(3, tx_buf);
while(i2c_busy()); while(i2c_busy());
PRINTFDEBUG("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg); PRINTF("WRITE_REG 0x%04X @ reg 0x%02X\n", val, reg);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Read register.
args:
reg what register to read
returns the value of the read register type uint16_t
*/
uint16_t uint16_t
tmp102_read_reg(uint8_t reg) tmp102_read_reg(uint8_t reg)
{ {
uint8_t buf[] = { 0x00, 0x00 }; uint8_t buf[] = { 0x00, 0x00 };
uint16_t retVal = 0; uint16_t retVal = 0;
uint8_t rtx = reg; uint8_t rtx = reg;
PRINTFDEBUG("READ_REG 0x%02X\n", reg); PRINTF("READ_REG 0x%02X\n", reg);
/* transmit the register to read */ /* transmit the register to read */
i2c_transmitinit(TMP102_ADDR); i2c_transmitinit(TMP102_ADDR);
@ -136,19 +121,14 @@ tmp102_read_reg(uint8_t reg)
return retVal; return retVal;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Read temperature in a raw format. Further processing will be needed
to make an interpretation of these 12 or 13-bit data, depending on configuration
*/
uint16_t uint16_t
tmp102_read_temp_raw(void) tmp102_read_temp_raw(void)
{ {
uint16_t rd = 0; uint16_t rd = 0;
rd = tmp102_read_reg(TMP102_TEMP); rd = tmp102_read_reg(TMP102_TEMP);
return rd; return rd;
} }
/*---------------------------------------------------------------------------*/
int16_t int16_t
tmp102_read_temp_x100(void) tmp102_read_temp_x100(void)
{ {
@ -167,24 +147,47 @@ tmp102_read_temp_x100(void)
/* Integer part of the temperature value and percents*/ /* Integer part of the temperature value and percents*/
temp_int = (abstemp >> 8) * sign * 100; temp_int = (abstemp >> 8) * sign * 100;
temp_int += ((abstemp & 0xff) * 100) / 0x100; temp_int += ((abstemp & 0xff) * 100) / 0x100;
/* See test-tmp102.c on how to print values of temperature with decimals
fractional part in 1/10000 of degree
temp_frac = ((abstemp >>4) % 16) * 625;
Data could be multiplied by 63 to have less bit-growth and 1/1000 precision
Data could be multiplied by 64 (<< 6) to trade-off precision for speed
*/
return temp_int; return temp_int;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Simple Read temperature. Return is an integer with temperature in 1deg. precision
Return value is a signed 8 bit integer.
*/
int8_t int8_t
tmp102_read_temp_simple(void) tmp102_read_temp_simple(void)
{ {
/* Casted to int8_t: We don't expect temperatures outside -128 to 127 C */ /* Casted to int8_t: We don't expect temperatures outside -128 to 127 C */
return tmp102_read_temp_x100() / 100; return tmp102_read_temp_x100() / 100;
} }
/*---------------------------------------------------------------------------*/
static int
configure(int type, int value)
{
if(type != SENSORS_ACTIVE) {
return TMP102_ERROR;
}
if(value) {
tmp102_init();
} else {
tmp102_stop();
}
enabled = value;
return TMP102_SUCCESS;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
switch(type) {
case SENSORS_ACTIVE:
case SENSORS_READY:
return enabled;
}
return TMP102_SUCCESS;
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
return (int)tmp102_read_temp_x100();
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(tmp102, TMP102_SENSOR, value, configure, status);
/*---------------------------------------------------------------------------*/

View file

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2010, Swedish Institute of Computer Science. * Copyright (c) 2010, Swedish Institute of Computer Science.
* Copyright (c) 2016, Zolertia <http://www.zolertia.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -32,75 +33,47 @@
/** /**
* \file * \file
* Device drivers header file for tmp102 temperature sensor in Zolertia Z1 WSN Platform. * Device drivers header file for tmp102 temperature sensor in Zolertia
* Z1 WSN Platform.
* \author * \author
* Enric M. Calvo, Zolertia <ecalvo@zolertia.com> * Enric M. Calvo, Zolertia <ecalvo@zolertia.com>
* Marcus Lundén, SICS <mlunden@sics.se> * Marcus Lundén, SICS <mlunden@sics.se>
* Antonio Lignan, Zolertia <alinan@zolertia.com>
*/ */
/* -------------------------------------------------------------------------- */
#ifndef TMP102_H_ #ifndef TMP102_H_
#define TMP102_H_ #define TMP102_H_
#include <stdio.h> #include <stdio.h>
#include "lib/sensors.h"
#include "i2cmaster.h" #include "i2cmaster.h"
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Init the temperature sensor: ports, pins, I2C, interrupts (XXX none so far), void tmp102_init(void);
*/ void tmp102_write_reg(uint8_t reg, uint16_t val);
void tmp102_init(void);
/* Write to a register.
args:
reg register to write to
val value to write
*/
void tmp102_write_reg(uint8_t reg, uint16_t val);
/* Read one register.
args:
reg what register to read
returns the value of the read register
*/
uint16_t tmp102_read_reg(uint8_t reg); uint16_t tmp102_read_reg(uint8_t reg);
/* Read temperature in raw format
no args needed
*/
uint16_t tmp102_read_temp_raw(); uint16_t tmp102_read_temp_raw();
/* Read only integer part of the temperature in 1deg. precision.
no args needed
*/
int8_t tmp102_read_temp_simple(); int8_t tmp102_read_temp_simple();
/* Read only integer part of the temperature in 1deg. precision.
no args needed
*/
int16_t tmp102_read_temp_x100(); int16_t tmp102_read_temp_x100();
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* Reference definitions */
/* TMP102 slave address */
#define TMP102_ADDR 0x48 #define TMP102_ADDR 0x48
#define TMP102_TEMP 0x00
/* TMP102 registers */
#define TMP102_TEMP 0x00 // read only
#define TMP102_CONF 0x01 #define TMP102_CONF 0x01
#define TMP102_TLOW 0x02 #define TMP102_TLOW 0x02
#define TMP102_THIGH 0x03 #define TMP102_THIGH 0x03
/* TMP102 Ports */ /* TMP102 pin-out */
/* Accelerometer hardware ports, pins and registers on the msp430 µC */
#define TMP102_PWR_DIR P5DIR #define TMP102_PWR_DIR P5DIR
#define TMP102_PWR_SEL P5SEL #define TMP102_PWR_SEL P5SEL
#define TMP102_PWR_SEL2 P5SEL2 #define TMP102_PWR_SEL2 P5SEL2
#define TMP102_PWR_REN P5REN #define TMP102_PWR_REN P5REN
#define TMP102_PWR_OUT P5OUT #define TMP102_PWR_OUT P5OUT
#define TMP102_PWR_PIN (1<<0) // P5.0 #define TMP102_PWR_PIN (1<<0) /* P5.0 */
//#define TMP102_INT_PIN (1<<7) // P1.7 /* -------------------------------------------------------------------------- */
#define TMP102_SUCCESS 0
#define TMP102_ERROR (-1)
#define TMP102_READ 0x01
/* -------------------------------------------------------------------------- */
#define TMP102_SENSOR "TMP102 sensor"
/* -------------------------------------------------------------------------- */
extern const struct sensors_sensor tmp102;
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
#endif /* ifndef TMP102_H_ */ #endif /* ifndef TMP102_H_ */