Created
June 20, 2018 07:53
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* \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 = ®_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