bme680-air-meter-sw/main.c

205 lines
5.0 KiB
C

#include <stm32f0xx.h>
#include "bme680-driver-fork/bme680.h"
#include <delay.h>
#include <lcd.h>
#include <stdlib.h>
unsigned int i = 0x12345678;
unsigned char c = 2;
#define OUTPUT(pin) (0x01U << (pin * 2))
#define PULLUP(pin) (0x1U << (pin* 2))
#define ALTFUNC(pin) ((0x2) << (pin * 2))
#define PINMASK(pin) ((0x3) << (pin * 2))
#define SETAF(PORT,PIN,AF) PORT->AFR[(PIN < 8 ? 0 : 1)] |= AF << ((PIN < 8 ? PIN : (PIN - 8)) * 4)
static struct bme680_dev gas_sensor;
static volatile uint8_t backlight_counter;
static uint8_t spi_transfer(uint8_t out_data)
{
while(SPI1->SR & SPI_SR_BSY);
SPI1->DR.DR8.DR8_1 = out_data;
__DSB();
while((SPI1->SR & SPI_SR_BSY) || !(SPI1->SR & SPI_SR_TXE));
return (uint8_t)(SPI1->DR.DR8.DR8_1 & 0xFF);
}
static int8_t write_spi(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
(void)dev_id;
int i;
GPIOA->ODR &= ~(1U<<4);
spi_transfer(reg_addr);
for (i = 0; i < len; i++)
spi_transfer(reg_data[i]);
GPIOA->ODR |= (1U<<4);
return 0;
}
static int8_t read_spi(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
{
(void)dev_id;
int i;
GPIOA->ODR &= ~(1U<<4);
spi_transfer(reg_addr);
for (i = 0; i < len; i++)
reg_data[i] = spi_transfer(0x00);
GPIOA->ODR |= (1U<<4);
return 0;
}
uint32_t gas_res;
int16_t temp = 2000;
struct bme680_field_data data;
int main(void) {
char display_data[20];
RCC->AHBENR |= RCC_AHBENR_GPIOFEN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
GPIOA->MODER |= OUTPUT(4) | ALTFUNC(5) | ALTFUNC(7) | ALTFUNC(6) | OUTPUT(0) | OUTPUT(1) | OUTPUT(2) | OUTPUT(3) | OUTPUT(9) | OUTPUT(10);
SETAF(GPIOA, 5, 0);
SETAF(GPIOA, 6, 0);
SETAF(GPIOA, 7, 0);
GPIOF->MODER |= OUTPUT(0);
GPIOF->PUPDR |= PULLUP(1);
GPIOF->ODR |= (1<<0);
/* Configure Systick for 1ms interval */
SysTick_Config(8000/*00*/);
lcd_init();
lcd_setcursor(0,4);
lcd_string("Initializing...");
GPIOB->MODER |= OUTPUT(1);
GPIOB->ODR &= ~(1<<1);
GPIOA->ODR |= (1<<4);
SPI1->CR1 = SPI_CR1_BR_2 | SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI;
SPI1->CR1 |= SPI_CR1_SPE;
/* You may assign a chip select identifier to be handled later */
gas_sensor.dev_id = 0;
gas_sensor.intf = BME680_SPI_INTF;
gas_sensor.read = read_spi;
gas_sensor.write = write_spi;
gas_sensor.delay_ms = delay_ms;
/* amb_temp can be set to 25 prior to configuring the gas sensor
* or by performing a few temperature readings without operating the gas sensor.
*/
gas_sensor.amb_temp = 12;
int8_t rslt = BME680_OK;
rslt = bme680_init(&gas_sensor);
uint8_t set_required_settings;
/* Set the temperature, pressure and humidity settings */
gas_sensor.tph_sett.os_hum = BME680_OS_8X;
gas_sensor.tph_sett.os_pres = BME680_OS_8X;
gas_sensor.tph_sett.os_temp = BME680_OS_8X;
gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_7;
/* Set the remaining gas sensor settings and link the heating profile */
gas_sensor.gas_sett.run_gas = BME680_DISABLE_GAS_MEAS;
/* Create a ramp heat waveform in 3 steps */
gas_sensor.gas_sett.heatr_temp = 320; /* degree Celsius */
gas_sensor.gas_sett.heatr_dur = 150; /* milliseconds */
/* Select the power mode */
/* Must be set before writing the sensor configuration */
gas_sensor.power_mode = BME680_FORCED_MODE;
/* Set the required sensor settings needed */
set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL;
/* Set the desired sensor configuration */
rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor);
/* Set the power mode */
rslt = bme680_set_sensor_mode(&gas_sensor);
uint16_t meas_period;
uint8_t meas_gas = 0;
do {
bme680_get_profile_dur(&meas_period, &gas_sensor);
delay_ms(meas_period); /* Delay till the measurement is ready */
if (meas_gas)
gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
else
gas_sensor.gas_sett.run_gas = BME680_DISABLE_GAS_MEAS;
rslt = bme680_get_sensor_data(&data, &gas_sensor);
temp = data.temperature - 300;
gas_sensor.amb_temp = (int8_t)(data.temperature / 100)-3;
/* Avoid using measurements from an unstable heating setup */
if(data.status & BME680_GASM_VALID_MSK)
gas_res = data.gas_resistance;
lcd_home();
display_data[0] = 0;
itoa((int)data.temperature, display_data, 10);
display_data[4] = display_data[3];
display_data[3] = display_data[2];
display_data[2] = '.';
display_data[5] = 0x0;
lcd_string(display_data);
delay_ms(1000);
if (gas_sensor.power_mode == BME680_FORCED_MODE) {
bme680_set_sensor_settings(set_required_settings,&gas_sensor);
rslt = bme680_set_sensor_mode(&gas_sensor);
}
} while(1);
}
void HardFault_Handler(void)
{
while(1);
}
void SysTick_Handler(void) {
static int internal_tick = 0;
/* Blink bad air LED */
tick++;
internal_tick++;
if (!(GPIOF->IDR & (1U<<1))) {
backlight_counter = 30;
GPIOB->ODR |= (1U<<1);
}
if (internal_tick > 200) {
internal_tick = 0;
if (backlight_counter > 0) {
backlight_counter--;
} else if (backlight_counter == 0) {
GPIOB->ODR &= ~(1U<<1);
}
GPIOF->ODR ^= (1<<0);
}
}