Skip to content

Instantly share code, notes, and snippets.

@BST-Github-Admin
Created June 20, 2018 07:53
Show Gist options
  • Save BST-Github-Admin/5ff33891ae823ef9288666b8d915c09b to your computer and use it in GitHub Desktop.
Save BST-Github-Admin/5ff33891ae823ef9288666b8d915c09b to your computer and use it in GitHub Desktop.
Example using BME280 in normal mode over I2C using the SAM21 Xplained Pro
/**
* \file
*
* \brief BME280 ASF example for the SAMD21 xplained pro
*
*/
#include <asf.h>
#include <string.h>
#include <stdio.h>
#include <delay.h>
#undef delay_ms
#define _delay_ms(delay) ((delay) ? cpu_delay_ms(delay) : cpu_delay_us(1))
#include "bme280.h"
// PREPROCESSOR CONSTANTS
#define BAUDRATE 115200
// STRUCTURES
struct usart_module uart_instance;
struct i2c_master_module i2c_master_instance;
// PROTOTYPES
void handle_bme280_error(int8_t _rslt);
void uart_setup(void);
void i2c_master_setup(void);
void user_delay_ms(uint32_t period);
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len);
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len);
int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev);
int main (void)
{
struct bme280_dev bme;
int8_t rslt = BME280_OK;
system_init();
delay_init();
uart_setup();
i2c_master_setup();
bme.dev_id = BME280_I2C_ADDR_PRIM;
bme.intf = BME280_I2C_INTF;
bme.read = user_i2c_read;
bme.write = user_i2c_write;
bme.delay_ms = user_delay_ms;
rslt = bme280_init(&bme);
handle_bme280_error(rslt);
rslt = stream_sensor_data_normal_mode(&bme);
handle_bme280_error(rslt);
while (1)
{
}
}
// UART SETUP
void uart_setup(void)
{
struct usart_config uart_configuration;
usart_get_config_defaults(&uart_configuration);
uart_configuration.baudrate = BAUDRATE;
uart_configuration.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
uart_configuration.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
uart_configuration.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
stdio_serial_init(&uart_instance, EDBG_CDC_MODULE, &uart_configuration);
usart_enable(&uart_instance);
}
// I2C CONFIGURATION:
void i2c_master_setup(void)
{
struct i2c_master_config i2c_master_configuration;
i2c_master_get_config_defaults(&i2c_master_configuration);
i2c_master_configuration.generator_source = GCLK_GENERATOR_0;
i2c_master_configuration.baud_rate = I2C_MASTER_BAUD_RATE_100KHZ;
i2c_master_configuration.pinmux_pad0 = PINMUX_PA08C_SERCOM0_PAD0;
i2c_master_configuration.pinmux_pad1 = PINMUX_PA09C_SERCOM0_PAD1;
while(i2c_master_init(&i2c_master_instance, SERCOM0, &i2c_master_configuration) != STATUS_OK);
i2c_master_enable(&i2c_master_instance);
}
int8_t stream_sensor_data_normal_mode(struct bme280_dev *dev)
{
int8_t rslt;
uint8_t settings_sel;
struct bme280_data comp_data;
/* Recommended mode of operation: Indoor navigation */
dev->settings.osr_h = BME280_OVERSAMPLING_1X;
dev->settings.osr_p = BME280_OVERSAMPLING_16X;
dev->settings.osr_t = BME280_OVERSAMPLING_2X;
dev->settings.filter = BME280_FILTER_COEFF_16;
dev->settings.standby_time = BME280_STANDBY_TIME_62_5_MS;
settings_sel = BME280_OSR_PRESS_SEL;
settings_sel |= BME280_OSR_TEMP_SEL;
settings_sel |= BME280_OSR_HUM_SEL;
settings_sel |= BME280_STANDBY_SEL;
settings_sel |= BME280_FILTER_SEL;
rslt = bme280_set_sensor_settings(settings_sel, dev);
rslt = bme280_set_sensor_mode(BME280_NORMAL_MODE, dev);
printf("Temperature (deg C * 100), Pressure (hPa * 10000), Humidity (perc rH * 1024)\r\n");
while(1) {
/* Delay while the sensor completes a measurement */
dev->delay_ms(100);
rslt = bme280_get_sensor_data(BME280_ALL, &comp_data, dev);
handle_bme280_error(rslt);
printf("%ld, %ld, %ld\r\n",comp_data.temperature, comp_data.pressure, comp_data.humidity);
}
return rslt;
}
void handle_bme280_error(int8_t _rslt)
{
if (_rslt < BME280_OK) {
printf("BME280 Error code: %d", _rslt);
for(;;); /* Trap if error */
}
else if (_rslt > BME280_OK) {
printf("BME280 Warning code: %d", _rslt);
}
}
void user_delay_ms(uint32_t period)
{
_delay_ms(period);
}
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
/* Initialize i2c packet. */
struct i2c_master_packet packet = {
.address = dev_id,
.data_length = 1,
.data = &reg_addr,
.ten_bit_address = false,
.high_speed = false,
.hs_master_code = 0x0,
};
if (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
return -1;
}
packet.data = reg_data;
packet.data_length = len;
if (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
return -1;
}
return 0;
}
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
uint8_t merged_data[len + 1];
merged_data[0] = reg_addr;
for(uint16_t i = 0; i < len; i++)
merged_data[i + 1] = reg_data[i];
struct i2c_master_packet packet = {
.address = dev_id,
.data_length = len + 1,
.data = merged_data,
.ten_bit_address = false,
.high_speed = false,
.hs_master_code = 0x0,
};
if(i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) {
return -1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment