bme280: reworked to allow platform-specific I2C implementations

This commit is contained in:
Antonio Lignan 2016-11-03 11:12:20 +01:00
parent bd1a6bf94e
commit f9b32f8139
10 changed files with 207 additions and 75 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Copyright Robert Olsson
* Copyright (c) 2016, Zolertia <http://www.zolertia.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,24 +25,21 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*
* Author : Robert Olsson rolss@kth.se/robert@radio-sensors.com
* Created : 2016-09-14
*/
/*---------------------------------------------------------------------------*/
#ifndef BME280_ARCH_H
#define BME280_ARCH_H
/**
* \file
* Architecture-specific definitions for the BME280 sensor for avr-rss2
* \author
* Robert Olsson
*/
/* Initialize the I2C module */
void bme280_arch_i2c_init();
#include "i2c.h"
/* I2C read registers */
void bme280_arch_i2c_read_mem(uint8_t addr, uint8_t reg, uint8_t *buf,
uint8_t bytes);
/* I2C write to a single register */
void bme280_arch_i2c_write_mem(uint8_t addr, uint8_t reg, uint8_t value);
#endif
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -37,13 +37,10 @@
#include "lib/sensors.h"
#include "dev/bme280/bme280.h"
#include "dev/bme280/bme280-sensor.h"
const struct sensors_sensor bme280_sensor;
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
/* Read all measurements with one burst read */
bme280_read(BME280_MODE_WEATHER);
@ -66,14 +63,17 @@ value(int type)
}
return 0;
}
/*---------------------------------------------------------------------------*/
static int
status(int type)
{
return 0;
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int c)
{
return bme280_init(BME280_MODE_WEATHER);
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(bme280_sensor, "bme280", value, configure, status);

View file

@ -36,7 +36,6 @@
#ifndef BME280_SENSOR_H_
#define BME280_SENSOR_H_
#include "lib/sensors.h"
#include "lib/sensors.h"
#include "bme280.h"

View file

@ -35,13 +35,14 @@
/**
* \file
* Basic functions for Bosch BME280 based on datasheel Rev 1.1
* Basic functions for Bosch BME280 based on datasheet Rev 1.1
*/
#include "contiki.h"
#include <string.h>
#include "bme280.h"
#include "dev/bme280-arch.h"
#include "bme280-arch.h"
#include "lib/sensors.h"
static struct {
unsigned short dig_t1;
@ -160,19 +161,21 @@ bme280_init(uint8_t mode)
{
uint8_t buf[26];
bme280_arch_i2c_init();
/* Do not mess with other chips */
i2c_read_mem(BME280_ADDR, 0xD0, buf, 1);
bme280_arch_i2c_read_mem(BME280_ADDR, 0xD0, buf, 1);
if(buf[0] != BME280_CHIP_ID) {
return 0;
}
i2c_write_mem(BME280_ADDR, BME280_CNTL_RESET, 0xB6);
clock_delay_msec(BME280_MAX_WAIT);
bme280_arch_i2c_write_mem(BME280_ADDR, BME280_CNTL_RESET, 0xB6);
clock_delay_usec(BME280_MAX_WAIT);
memset(buf, 0, sizeof(buf));
/* Burst read of all calibration part 1 */
i2c_read_mem(BME280_ADDR, BME280_DIG_T1_ADDR, buf, sizeof(buf));
bme280_arch_i2c_read_mem(BME280_ADDR, BME280_DIG_T1_ADDR, buf, sizeof(buf));
bm.dig_t1 = ((uint16_t)buf[1] << 8) | (uint16_t)buf[0];
bm.dig_t2 = ((int16_t)buf[3] << 8) | (uint16_t)buf[2];
bm.dig_t3 = ((int16_t)buf[5] << 8) | (uint16_t)buf[4];
@ -189,7 +192,7 @@ bme280_init(uint8_t mode)
bm.dig_h1 = (unsigned char)buf[25];
/* Burst read of all calibration part 2 */
i2c_read_mem(BME280_ADDR, BME280_DIG_H2_ADDR, buf, 8);
bme280_arch_i2c_read_mem(BME280_ADDR, BME280_DIG_H2_ADDR, buf, 8);
bm.dig_h2 = ((int16_t)buf[1] << 8) | (uint16_t)buf[0];
bm.dig_h3 = (unsigned char)buf[2];
bm.dig_h4 = ((int16_t)buf[3] << 4) | (((uint16_t)buf[4]) & 0xF);
@ -217,23 +220,23 @@ bme280_read(uint8_t mode)
/* Weather mode. See sectiom 3.5 Datasheet */
if(mode == BME280_MODE_WEATHER) {
/* Humidity oversampling *1 */
i2c_write_mem(BME280_ADDR, BME280_CNTL_HUM, 0x01);
bme280_arch_i2c_write_mem(BME280_ADDR, BME280_CNTL_HUM, 0x01);
/* 00100111 0x27 oversampling *1 for t and p plus normal mode */
/* 0.5 ms -- no filter -- no SPI */
i2c_write_mem(BME280_ADDR, BME280_CONTROL, 0x00);
bme280_arch_i2c_write_mem(BME280_ADDR, BME280_CONTROL, 0x00);
/* 00100110 0x26 oversampling *1 for t and p plus forced mode */
/* Trigger measurement needed for every time in forced mode */
i2c_write_mem(BME280_ADDR, BME280_CNTL_MEAS, 0x26);
bme280_arch_i2c_write_mem(BME280_ADDR, BME280_CNTL_MEAS, 0x26);
/* Wait to get into sleep mode == measurement done */
for(i = 0; i < BME280_MAX_WAIT; i++) {
i2c_read_mem(BME280_ADDR, BME280_CNTL_MEAS, &sleep, 1);
bme280_arch_i2c_read_mem(BME280_ADDR, BME280_CNTL_MEAS, &sleep, 1);
sleep = sleep& 0x03;
if(sleep== 0) {
break;
} else {
clock_delay_msec(1);
clock_delay_usec(1000);
}
}
if(i == BME280_MAX_WAIT) {
@ -244,7 +247,7 @@ bme280_read(uint8_t mode)
}
/* Burst read of all measurements */
i2c_read_mem(BME280_ADDR, BME280_PRESS, buf, 8);
bme280_arch_i2c_read_mem(BME280_ADDR, BME280_PRESS, buf, 8);
ut = (uint32_t)(buf[3]) << 12 | (uint32_t)(buf[4]) << 4 | (uint32_t)buf[5] >> 4;
up = (uint32_t)(buf[0]) << 12 | (uint32_t)(buf[1]) << 4 | (uint32_t)buf[2] >> 4;
uh = (uint32_t)(buf[6]) << 8 | (uint32_t)buf[7];

View file

@ -36,7 +36,7 @@
/**
* \file
* Definitions for the Bosch BME280 based on datasheel Rev 1.1
* Definitions for the Bosch BME280 based on datasheet Rev 1.1
*/
#ifndef BME280_H
@ -49,53 +49,52 @@
uint8_t bme280_init(uint8_t mode);
void bme280_read(uint8_t mode);
#ifdef I2C_BME280_ADDR
#define BME280_ADDR I2C_BME280_ADDR
#ifdef BME280_CONF_ADDR
#define BME280_ADDR BME280_CONF_ADDR
#else
#define BME280_ADDR (0x77 << 1) /* Alternative 0x76 */
#define BME280_ADDR (0x77 << 1) /* Alternative 0x76 */
#endif
/* Diffrent BOSCH chip id's */
#define BMP085_CHIP_ID 0x55 /* And also BMP180 */
#define BMP280_CHIP_ID 0x58
#define BME280_CHIP_ID 0x60
#define BMP085_CHIP_ID 0x55 /* And also BMP180 */
#define BMP280_CHIP_ID 0x58
#define BME280_CHIP_ID 0x60
/* Address map */
#define BME280_DIG_T1_ADDR 0x88
#define BME280_DIG_T2_ADDR 0x8A
#define BME280_DIG_T3_ADDR 0x8C
#define BME280_DIG_P1_ADDR 0x8E
#define BME280_DIG_P2_ADDR 0x90
#define BME280_DIG_P3_ADDR 0x92
#define BME280_DIG_P4_ADDR 0x94
#define BME280_DIG_P5_ADDR 0x96
#define BME280_DIG_P6_ADDR 0x98
#define BME280_DIG_P7_ADDR 0x9A
#define BME280_DIG_P8_ADDR 0x9C
#define BME280_DIG_P9_ADDR 0x9E
#define BME280_DIG_H1_ADDR 0xA1
#define BMP_CHIP_ID_ADDR 0xD0
#define BME280_CNTL_RESET 0xE0
#define BME280_DIG_H2_ADDR 0xE1
#define BME280_DIG_H3_ADDR 0xE3
#define BME280_DIG_H4_ADDR 0xE4
#define BME280_DIG_H5_ADDR 0xE5
#define BME280_DIG_H6_ADDR 0xE7
#define BME280_CNTL_HUM 0xF2
#define BME280_STATUS 0xF3
#define BME280_CNTL_MEAS 0xF4
#define BME280_CONTROL 0xF5
#define BME280_PRESS 0xF7
#define BME280_DIG_T1_ADDR 0x88
#define BME280_DIG_T2_ADDR 0x8A
#define BME280_DIG_T3_ADDR 0x8C
#define BME280_DIG_P1_ADDR 0x8E
#define BME280_DIG_P2_ADDR 0x90
#define BME280_DIG_P3_ADDR 0x92
#define BME280_DIG_P4_ADDR 0x94
#define BME280_DIG_P5_ADDR 0x96
#define BME280_DIG_P6_ADDR 0x98
#define BME280_DIG_P7_ADDR 0x9A
#define BME280_DIG_P8_ADDR 0x9C
#define BME280_DIG_P9_ADDR 0x9E
#define BME280_DIG_H1_ADDR 0xA1
#define BMP_CHIP_ID_ADDR 0xD0
#define BME280_CNTL_RESET 0xE0
#define BME280_DIG_H2_ADDR 0xE1
#define BME280_DIG_H3_ADDR 0xE3
#define BME280_DIG_H4_ADDR 0xE4
#define BME280_DIG_H5_ADDR 0xE5
#define BME280_DIG_H6_ADDR 0xE7
#define BME280_CNTL_HUM 0xF2
#define BME280_STATUS 0xF3
#define BME280_CNTL_MEAS 0xF4
#define BME280_CONTROL 0xF5
#define BME280_PRESS 0xF7
/* Function modes outlined in datasheet */
#define BME280_MODE_NONE 0
#define BME280_MODE_WEATHER 1
#define BME280_MODE_HUMIDITY 2
#define BME280_MODE_INDOOR_NAVIGATION 3
#define BME280_MODE_GAMING 4
#define BME280_MODE_NONE 0
#define BME280_MODE_WEATHER 1
#define BME280_MODE_HUMIDITY 2
#define BME280_MODE_INDOOR_NAVIGATION 3
#define BME280_MODE_GAMING 4
#define BME280_MAX_WAIT 300 /* ms. Forced mode max wait */
#define BME280_STARTUP_TIME 2 /* ms */
#define BME280_MAX_WAIT 300000 /* ms. Forced mode max wait */
struct {
int32_t t_overscale100;

View file

@ -11,7 +11,7 @@ CONTIKI_PROJECT += test-bme280
CONTIKI_TARGET_SOURCEFILES += tsl256x.c sht25.c bmpx8x.c motion-sensor.c
CONTIKI_TARGET_SOURCEFILES += adc-sensors.c weather-meter.c grove-gyro.c
CONTIKI_TARGET_SOURCEFILES += rgb-bl-lcd.c pm10-sensor.c iaq.c zonik.c relay.c
CONTIKI_TARGET_SOURCEFILES += dht22.c servo.c ac-dimmer.c
CONTIKI_TARGET_SOURCEFILES += dht22.c servo.c ac-dimmer.c bme280-arch.c
MODULES += /dev/bme280

View file

@ -50,6 +50,9 @@
#define MOTION_SENSOR_PIN 5
#define MOTION_SENSOR_VECTOR GPIO_A_IRQn
/* Use the following I2C address for the BME280 sensor (from MikroElektronika) */
#define BME280_CONF_ADDR 0x76
#endif /* PROJECT_CONF_H_ */
/** @} */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Zolertia <http://www.zolertia.com>
* Copyright (c) 2016, Zolertia <http://www.zolertia.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -29,6 +29,7 @@
* This file is part of the Contiki operating system.
*
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup zoul-examples
* @{
@ -46,7 +47,8 @@
/*---------------------------------------------------------------------------*/
#include <stdio.h>
#include "contiki.h"
#include "dev/bme280.h"
#include "dev/bme280/bme280.h"
#include "dev/bme280/bme280-sensor.h"
/*---------------------------------------------------------------------------*/
#define BME280_USE_STD_API 1
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2016, Zolertia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#include "i2c.h"
/*---------------------------------------------------------------------------*/
void
bme280_arch_i2c_init(void)
{
/* Does nothing */
}
/*---------------------------------------------------------------------------*/
void
bme280_arch_i2c_write_mem(uint8_t addr, uint8_t reg, uint8_t value)
{
i2c_write_mem(addr, reg, value);
}
/*---------------------------------------------------------------------------*/
void
bme280_arch_i2c_read_mem(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t bytes)
{
i2c_read_mem(addr, reg, buf, bytes);
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2015, Zolertia
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup zoul-bme280-sensor
* @{
*
* \file
* Architecture-specific I2C for the external BME280 weather sensor
*
* \author
* Antonio Lignan <alinan@zolertia.com>
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#include "dev/i2c.h"
/*---------------------------------------------------------------------------*/
void
bme280_arch_i2c_init(void)
{
i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN,
I2C_SCL_NORMAL_BUS_SPEED);
}
/*---------------------------------------------------------------------------*/
void
bme280_arch_i2c_write_mem(uint8_t addr, uint8_t reg, uint8_t value)
{
uint8_t buf[2];
buf[0] = reg;
buf[1] = value;
i2c_master_enable();
i2c_burst_send(addr, buf, 2);
}
/*---------------------------------------------------------------------------*/
void
bme280_arch_i2c_read_mem(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t bytes)
{
i2c_master_enable();
if(i2c_single_send(addr, reg) == I2C_MASTER_ERR_NONE) {
while(i2c_master_busy());
i2c_burst_receive(addr, buf, bytes);
}
}
/*---------------------------------------------------------------------------*/
/**
* @}
*/