From 45b36786064478c4405310e6b2abc12a1677068b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 17 Oct 2019 23:18:18 +0200 Subject: [PATCH] First test draft --- .gitignore | 7 ++ Makefile | 4 +- include/meas.h | 22 ++++++ lcd.c | 14 +--- main.c | 200 ++++++++++++++++--------------------------------- meas.c | 131 ++++++++++++++++++++++++++++++++ 6 files changed, 232 insertions(+), 146 deletions(-) create mode 100644 include/meas.h create mode 100644 meas.c diff --git a/.gitignore b/.gitignore index ada3d1d..6cd0363 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,11 @@ memmap.map +*.config +*.creator +*.cxxflags +*.files +*.includes +*.cflags + *.o *.d *.elf diff --git a/Makefile b/Makefile index 731a1e1..904290a 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ #Add Files and Folders below######################################################### CFILES = main.c syscalls/syscalls.c setup/system_init.c startup/startup_stm32f0xx.c ASFILES = -INCLUDEPATH = -Iinclude -Iinclude/cmsis +INCLUDEPATH = -Iinclude -Iinclude/cmsis -Ibme680-driver-fork target = bme680-air-meter @@ -17,7 +17,7 @@ mapfile = memmap ##Custom Files### -CFILES += bme680-driver-fork/bme680.c lcd.c delay.c +CFILES += bme680-driver-fork/bme680.c lcd.c delay.c meas.c ################################################################################### diff --git a/include/meas.h b/include/meas.h new file mode 100644 index 0000000..87595be --- /dev/null +++ b/include/meas.h @@ -0,0 +1,22 @@ +#ifndef __MEAS_H__ +#define __MEAS_H__ + +#include +#include + +/** + * @brief Initialize sensor + * @return 0 if successful + */ +int meas_init_without_gas(void); + +/** + * @brief Do a single measurement + * @param gas_enable select if gas measurement should be done + * @param meas_data read data + * @param ambient_temp Ambient Temperature + * @return 0 if successful + */ +int meas_do(bool gas_enable, struct bme680_field_data *meas_data, int8_t ambient_temp); + +#endif /* __MEAS_H__ */ diff --git a/lcd.c b/lcd.c index 03d1c5c..b48fcac 100644 --- a/lcd.c +++ b/lcd.c @@ -125,37 +125,31 @@ void lcd_clear(void) delay_ms(3); } - -//////////////////////////////////////////////////////////////////////////////// -// Sendet den Befehl: Cursor Home void lcd_home( void ) { lcd_command(LCD_CURSOR_HOME); delay_ms(3); } -//////////////////////////////////////////////////////////////////////////////// -// Setzt den Cursor in Spalte x (0..15) Zeile y (1..4) - void lcd_setcursor( uint8_t x, uint8_t y ) { uint8_t data; switch (y) { - case 1: // 1. Zeile + case 0: // 1. Zeile data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x; break; - case 2: // 2. Zeile + case 1: // 2. Zeile data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x; break; - case 3: // 3. Zeile + case 2: // 3. Zeile data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x; break; - case 4: // 4. Zeile + case 3: // 4. Zeile data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x; break; diff --git a/main.c b/main.c index 7cc7476..94e763b 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,10 @@ #include -#include "bme680-driver-fork/bme680.h" #include #include #include +#include +#include + unsigned int i = 0x12345678; unsigned char c = 2; @@ -13,60 +15,8 @@ unsigned char c = 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) +static void setup_hw(void) { - 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; @@ -76,16 +26,7 @@ int main(void) { 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..."); + GPIOF->ODR &= ~(1<<0); GPIOB->MODER |= OUTPUT(1); GPIOB->ODR &= ~(1<<1); @@ -95,84 +36,74 @@ int main(void) { 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; + /* Configure Systick for 1ms interval */ + SysTick_Config(8000/*00*/); + lcd_init(); +} - int8_t rslt = BME680_OK; - rslt = bme680_init(&gas_sensor); +static void format(int temp, char *string, uint8_t decimals, uint8_t digits) +{ + int digit; - 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; + for (digit = decimals+digits; digit >= 1; digit--) { + if (digit >= digits+1) + string[digit] = (temp % 10) + 0x30; else - gas_sensor.gas_sett.run_gas = BME680_DISABLE_GAS_MEAS; + string[digit-1] = (temp % 10) + 0x30; + temp /= 10; + } - 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; + string[digits] = '.'; + string[decimals+digits+1] = 0x00; +} - 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); +static void print_data_to_display(int32_t temp, uint32_t pressure, uint32_t humidity) +{ + char lcd_line[17]; + lcd_clear(); + lcd_home(); + lcd_string("Temp: "); + format(temp, lcd_line, 2, 2); + lcd_string(lcd_line); + lcd_setcursor(0, 1); + lcd_string("RH: "); + format((int)humidity, lcd_line, 3, 2); + lcd_string(lcd_line); + lcd_setcursor(0, 2); + lcd_string("Pr.: "); + format((int)pressure, lcd_line, 2, 4); + lcd_string(lcd_line); - 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); +int main(void) { + struct bme680_field_data data; + int8_t ambient_temp = 25; + int32_t temp_calib; + int i; + + setup_hw(); + meas_init_without_gas(); + + temp_calib = 0; + lcd_home(); + lcd_string("Initializing..."); + for (i = 0; i < 8; i++) { + i = 0; + delay_ms(1000); + if (meas_do(false, &data, ambient_temp)) { + /* Measurement failed. retry */ + i--; + continue; } - } while(1); + temp_calib += data.temperature; + ambient_temp = (int8_t)(data.temperature / 100); + + print_data_to_display(data.temperature, data.pressure, data.humidity); + } + temp_calib /= 8; + } @@ -183,6 +114,7 @@ void HardFault_Handler(void) void SysTick_Handler(void) { static int internal_tick = 0; + static volatile uint8_t backlight_counter; /* Blink bad air LED */ tick++; internal_tick++; @@ -199,6 +131,6 @@ void SysTick_Handler(void) { } else if (backlight_counter == 0) { GPIOB->ODR &= ~(1U<<1); } - GPIOF->ODR ^= (1<<0); + //GPIOF->ODR ^= (1<<0); } } diff --git a/meas.c b/meas.c new file mode 100644 index 0000000..f7e3bc7 --- /dev/null +++ b/meas.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include "bme680-driver-fork/bme680.h" + + +static struct bme680_dev gas_sensor; + +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; +} + +int meas_init_without_gas(void) +{ + int ret; + + 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; + + gas_sensor.amb_temp = 25; + + ret = (int)bme680_init(&gas_sensor); + if (ret) + return ret; + + 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 */ + ret = (int)bme680_set_sensor_settings(set_required_settings,&gas_sensor); + + return ret; +} + +int meas_do(bool gas_enable, struct bme680_field_data *meas_data, int8_t ambient_temp) +{ + uint16_t meas_duration; + int res; + + if (!meas_data) + return -100; + + gas_sensor.power_mode = BME680_FORCED_MODE; + + gas_sensor.gas_sett.run_gas = (gas_enable ? BME680_RUN_GAS_ENABLE : BME680_RUN_GAS_DISABLE); + + gas_sensor.amb_temp = ambient_temp; + + res = (int)bme680_set_sensor_settings(BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | + BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL, + &gas_sensor); + + /* Set the power mode */ + res = (int)bme680_set_sensor_mode(&gas_sensor); + if (res) + return res; + + bme680_get_profile_dur(&meas_duration, &gas_sensor); + delay_ms(meas_duration); + + res = (int)bme680_get_sensor_data(meas_data, &gas_sensor); + if (res) + return res; + + gas_sensor.power_mode = BME680_SLEEP_MODE; + res = (int)bme680_set_sensor_mode(&gas_sensor); + + return res; +}