#include "stm32c0xx_hal.h"
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
void Error_Handler(void);
#define User_Button_Pin GPIO_PIN_13
#define User_Button_GPIO_Port GPIOC
#define User_Button_EXTI_IRQn EXTI4_15_IRQn
#define Led_Pin GPIO_PIN_5
#define Led_GPIO_Port GPIOA
/**
* BMP280 or BME280 address is 0x77 if SDO pin is high, and is 0x76 if
* SDO pin is low.
*/
#define BMP280_I2C_ADDRESS_0 0x76
#define BMP280_I2C_ADDRESS_1 0x77
#define BMP280_CHIP_ID 0x58 /* BMP280 has chip-id 0x58 */
#define BME280_CHIP_ID 0x60 /* BME280 has chip-id 0x60 */
/**
* Mode of BMP280 module operation.
* Forced - Measurement is initiated by user.
* Normal - Continues measurement.
*/
typedef enum {
BMP280_MODE_SLEEP = 0,
BMP280_MODE_FORCED = 1,
BMP280_MODE_NORMAL = 3
} BMP280_Mode;
typedef enum {
BMP280_FILTER_OFF = 0,
BMP280_FILTER_2 = 1,
BMP280_FILTER_4 = 2,
BMP280_FILTER_8 = 3,
BMP280_FILTER_16 = 4
} BMP280_Filter;
/**
* Pressure oversampling settings
*/
typedef enum {
BMP280_SKIPPED = 0, /* no measurement */
BMP280_ULTRA_LOW_POWER = 1, /* oversampling x1 */
BMP280_LOW_POWER = 2, /* oversampling x2 */
BMP280_STANDARD = 3, /* oversampling x4 */
BMP280_HIGH_RES = 4, /* oversampling x8 */
BMP280_ULTRA_HIGH_RES = 5 /* oversampling x16 */
} BMP280_Oversampling;
/**
* Stand by time between measurements in normal mode
*/
typedef enum {
BMP280_STANDBY_05 = 0, /* stand by time 0.5ms */
BMP280_STANDBY_62 = 1, /* stand by time 62.5ms */
BMP280_STANDBY_125 = 2, /* stand by time 125ms */
BMP280_STANDBY_250 = 3, /* stand by time 250ms */
BMP280_STANDBY_500 = 4, /* stand by time 500ms */
BMP280_STANDBY_1000 = 5, /* stand by time 1s */
BMP280_STANDBY_2000 = 6, /* stand by time 2s BMP280, 10ms BME280 */
BMP280_STANDBY_4000 = 7, /* stand by time 4s BMP280, 20ms BME280 */
} BMP280_StandbyTime;
/**
* Configuration parameters for BMP280 module.
* Use function bmp280_init_default_params to use default configuration.
*/
typedef struct {
BMP280_Mode mode;
BMP280_Filter filter;
BMP280_Oversampling oversampling_pressure;
BMP280_Oversampling oversampling_temperature;
BMP280_Oversampling oversampling_humidity;
BMP280_StandbyTime standby;
} bmp280_params_t;
typedef struct {
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
/* Humidity compensation for BME280 */
uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
uint16_t addr;
I2C_HandleTypeDef* i2c;
bmp280_params_t params;
uint8_t id; /* Chip ID */
} BMP280_HandleTypedef;
/**
* Initialize default parameters.
* Default configuration:
* mode: NORAML
* filter: OFF
* oversampling: x4
* standby time: 250ms
*/
void bmp280_init_default_params(bmp280_params_t *params);
/**
* Initialize BMP280 module, probes for the device, soft resets the device,
* reads the calibration constants, and configures the device using the supplied
* parameters. Returns true on success otherwise false.
*
* The I2C address is assumed to have been initialized in the dev, and
* may be either BMP280_I2C_ADDRESS_0 or BMP280_I2C_ADDRESS_1. If the I2C
* address is unknown then try initializing each in turn.
*
* This may be called again to soft reset the device and initialize it again.
*/
bool bmp280_init(BMP280_HandleTypedef *dev, bmp280_params_t *params);
/**
* Start measurement in forced mode.
* The module remains in forced mode after this call.
* Do not call this method in normal mode.
*/
bool bmp280_force_measurement(BMP280_HandleTypedef *dev);
/**
* Check if BMP280 is busy with measuring temperature/pressure.
* Return true if BMP280 is busy.
*/
bool bmp280_is_measuring(BMP280_HandleTypedef *dev);
/**
* Read compensated temperature and pressure data:
*
* Temperature in degrees Celsius times 100.
*
* Pressure in Pascals in fixed point 24 bit integer 8 bit fraction format.
*
* Humidity is optional and only read for the BME280, in percent relative
* humidity as a fixed point 22 bit interger and 10 bit fraction format.
*/
bool bmp280_read_fixed(BMP280_HandleTypedef *dev, int32_t *temperature,
uint32_t *pressure, uint32_t *humidity);
/**
* Read compensated temperature and pressure data:
* Temperature in degrees Celsius.
* Pressure in Pascals.
* Humidity is optional and only read for the BME280, in percent relative
* humidity.
*/
bool bmp280_read_float(BMP280_HandleTypedef *dev, float *temperature,
float *pressure, float *humidity);
/**
* Ciastkolog.pl (https://github.com/ciastkolog)
*
*/
/**
* The MIT License (MIT)
*
* Copyright (c) 2016 sheinz (https://github.com/sheinz)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* BMP280 registers
*/
#define BMP280_REG_TEMP_XLSB 0xFC /* bits: 7-4 */
#define BMP280_REG_TEMP_LSB 0xFB
#define BMP280_REG_TEMP_MSB 0xFA
#define BMP280_REG_TEMP (BMP280_REG_TEMP_MSB)
#define BMP280_REG_PRESS_XLSB 0xF9 /* bits: 7-4 */
#define BMP280_REG_PRESS_LSB 0xF8
#define BMP280_REG_PRESS_MSB 0xF7
#define BMP280_REG_PRESSURE (BMP280_REG_PRESS_MSB)
#define BMP280_REG_CONFIG 0xF5 /* bits: 7-5 t_sb; 4-2 filter; 0 spi3w_en */
#define BMP280_REG_CTRL 0xF4 /* bits: 7-5 osrs_t; 4-2 osrs_p; 1-0 mode */
#define BMP280_REG_STATUS 0xF3 /* bits: 3 measuring; 0 im_update */
#define BMP280_REG_CTRL_HUM 0xF2 /* bits: 2-0 osrs_h; */
#define BMP280_REG_RESET 0xE0
#define BMP280_REG_ID 0xD0
#define BMP280_REG_CALIB 0x88
#define BMP280_REG_HUM_CALIB 0x88
#define BMP280_RESET_VALUE 0xB6
void bmp280_init_default_params(bmp280_params_t *params) {
params->mode = BMP280_MODE_NORMAL;
params->filter = BMP280_FILTER_OFF;
params->oversampling_pressure = BMP280_STANDARD;
params->oversampling_temperature = BMP280_STANDARD;
params->oversampling_humidity = BMP280_STANDARD;
params->standby = BMP280_STANDBY_250;
}
static bool read_register16(BMP280_HandleTypedef *dev, uint8_t addr, uint16_t *value) {
uint16_t tx_buff;
uint8_t rx_buff[2];
tx_buff = (dev->addr << 1);
if (HAL_I2C_Mem_Read(dev->i2c, tx_buff, addr, 1, rx_buff, 2, 5000)
== HAL_OK) {
*value = (uint16_t) ((rx_buff[1] << 8) | rx_buff[0]);
return true;
} else
return false;
}
static inline int read_data(BMP280_HandleTypedef *dev, uint8_t addr, uint8_t *value,
uint8_t len) {
uint16_t tx_buff;
printf("REACHED READ DATA, I AM GOING TO READ ADDRESS %x in %x\n",addr,dev->addr);
tx_buff = (dev->addr << 1);
if (HAL_I2C_Mem_Read(dev->i2c, tx_buff, addr, 1, value, len, 5000) == HAL_OK)
{printf("THIS IS MY SUCCESSFUL READ\n");
return 0;}
else
{
printf("FAILURE\n");
printf("THE VALUE I GOT IS %x\n",*value);
return 1;}
}
static bool read_calibration_data(BMP280_HandleTypedef *dev) {
if (read_register16(dev, 0x88, &dev->dig_T1)
&& read_register16(dev, 0x8a, (uint16_t *) &dev->dig_T2)
&& read_register16(dev, 0x8c, (uint16_t *) &dev->dig_T3)
&& read_register16(dev, 0x8e, &dev->dig_P1)
&& read_register16(dev, 0x90, (uint16_t *) &dev->dig_P2)
&& read_register16(dev, 0x92, (uint16_t *) &dev->dig_P3)
&& read_register16(dev, 0x94, (uint16_t *) &dev->dig_P4)
&& read_register16(dev, 0x96, (uint16_t *) &dev->dig_P5)
&& read_register16(dev, 0x98, (uint16_t *) &dev->dig_P6)
&& read_register16(dev, 0x9a, (uint16_t *) &dev->dig_P7)
&& read_register16(dev, 0x9c, (uint16_t *) &dev->dig_P8)
&& read_register16(dev, 0x9e,
(uint16_t *) &dev->dig_P9)) {
return true;
}
return false;
}
static bool read_hum_calibration_data(BMP280_HandleTypedef *dev) {
uint16_t h4, h5;
if (!read_data(dev, 0xa1, &dev->dig_H1, 1)
&& read_register16(dev, 0xe1, (uint16_t *) &dev->dig_H2)
&& !read_data(dev, 0xe3, &dev->dig_H3, 1)
&& read_register16(dev, 0xe4, &h4)
&& read_register16(dev, 0xe5, &h5)
&& !read_data(dev, 0xe7, (uint8_t *) &dev->dig_H6, 1)) {
dev->dig_H4 = (h4 & 0x00ff) << 4 | (h4 & 0x0f00) >> 8;
dev->dig_H5 = h5 >> 4;
return true;
}
return false;
}
static int write_register8(BMP280_HandleTypedef *dev, uint8_t addr, uint8_t value) {
uint16_t tx_buff;
tx_buff = (dev->addr << 1);
if (HAL_I2C_Mem_Write(dev->i2c, tx_buff, addr, 1, &value, 1, 10000) == HAL_OK)
return false;
else
return true;
}
bool bmp280_init(BMP280_HandleTypedef *dev, bmp280_params_t *params) {
printf("HELLO5\n");
if (dev->addr != BMP280_I2C_ADDRESS_0
&& dev->addr != BMP280_I2C_ADDRESS_1) {
return false;
}
printf("HELLO66\n");
if (read_data(dev, BMP280_REG_ID, &dev->id, 1)) {
return false;
}
printf("THE ID READ IS %x\n",dev->id);
if (dev->id != BMP280_CHIP_ID && dev->id != BME280_CHIP_ID) {
return false;
}
// Soft reset.
if (write_register8(dev, BMP280_REG_RESET, BMP280_RESET_VALUE)) {
return false;
}
// Wait until finished copying over the NVP data.
while (1) {
uint8_t status;
if (!read_data(dev, BMP280_REG_STATUS, &status, 1)
&& (status & 1) == 0)
break;
}
if (!read_calibration_data(dev)) {
return false;
}
if (dev->id == BME280_CHIP_ID && !read_hum_calibration_data(dev)) {
return false;
}
uint8_t config = (params->standby << 5) | (params->filter << 2);
if (write_register8(dev, BMP280_REG_CONFIG, config)) {
return false;
}
if (params->mode == BMP280_MODE_FORCED) {
params->mode = BMP280_MODE_SLEEP; // initial mode for forced is sleep
}
uint8_t ctrl = (params->oversampling_temperature << 5)
| (params->oversampling_pressure << 2) | (params->mode);
if (dev->id == BME280_CHIP_ID) {
// Write crtl hum reg first, only active after write to BMP280_REG_CTRL.
uint8_t ctrl_hum = params->oversampling_humidity;
if (write_register8(dev, BMP280_REG_CTRL_HUM, ctrl_hum)) {
return false;
}
}
if (write_register8(dev, BMP280_REG_CTRL, ctrl)) {
return false;
}
return true;
}
bool bmp280_force_measurement(BMP280_HandleTypedef *dev) {
uint8_t ctrl;
if (read_data(dev, BMP280_REG_CTRL, &ctrl, 1))
return false;
ctrl &= ~0b11; // clear two lower bits
ctrl |= BMP280_MODE_FORCED;
if (write_register8(dev, BMP280_REG_CTRL, ctrl)) {
return false;
}
return true;
}
bool bmp280_is_measuring(BMP280_HandleTypedef *dev) {
uint8_t status;
if (read_data(dev, BMP280_REG_STATUS, &status, 1))
return false;
if (status & (1 << 3)) {
return true;
}
return false;
}
/**
* Compensation algorithm is taken from BMP280 datasheet.
*
* Return value is in degrees Celsius.
*/
static inline int32_t compensate_temperature(BMP280_HandleTypedef *dev, int32_t adc_temp,
int32_t *fine_temp) {
int32_t var1, var2;
var1 = ((((adc_temp >> 3) - ((int32_t) dev->dig_T1 << 1)))
* (int32_t) dev->dig_T2) >> 11;
var2 = (((((adc_temp >> 4) - (int32_t) dev->dig_T1)
* ((adc_temp >> 4) - (int32_t) dev->dig_T1)) >> 12)
* (int32_t) dev->dig_T3) >> 14;
*fine_temp = var1 + var2;
return (*fine_temp * 5 + 128) >> 8;
}
/**
* Compensation algorithm is taken from BMP280 datasheet.
*
* Return value is in Pa, 24 integer bits and 8 fractional bits.
*/
static inline uint32_t compensate_pressure(BMP280_HandleTypedef *dev, int32_t adc_press,
int32_t fine_temp) {
int64_t var1, var2, p;
var1 = (int64_t) fine_temp - 128000;
var2 = var1 * var1 * (int64_t) dev->dig_P6;
var2 = var2 + ((var1 * (int64_t) dev->dig_P5) << 17);
var2 = var2 + (((int64_t) dev->dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t) dev->dig_P3) >> 8)
+ ((var1 * (int64_t) dev->dig_P2) << 12);
var1 = (((int64_t) 1 << 47) + var1) * ((int64_t) dev->dig_P1) >> 33;
if (var1 == 0) {
return 0; // avoid exception caused by division by zero
}
p = 1048576 - adc_press;
p = (((p << 31) - var2) * 3125) / var1;
var1 = ((int64_t) dev->dig_P9 * (p >> 13) * (p >> 13)) >> 25;
var2 = ((int64_t) dev->dig_P8 * p) >> 19;
p = ((p + var1 + var2) >> 8) + ((int64_t) dev->dig_P7 << 4);
return p;
}
/**
* Compensation algorithm is taken from BME280 datasheet.
*
* Return value is in Pa, 24 integer bits and 8 fractional bits.
*/
static inline uint32_t compensate_humidity(BMP280_HandleTypedef *dev, int32_t adc_hum,
int32_t fine_temp) {
int32_t v_x1_u32r;
v_x1_u32r = fine_temp - (int32_t) 76800;
v_x1_u32r = ((((adc_hum << 14) - ((int32_t) dev->dig_H4 << 20)
- ((int32_t) dev->dig_H5 * v_x1_u32r)) + (int32_t) 16384) >> 15)
* (((((((v_x1_u32r * (int32_t) dev->dig_H6) >> 10)
* (((v_x1_u32r * (int32_t) dev->dig_H3) >> 11)
+ (int32_t) 32768)) >> 10) + (int32_t) 2097152)
* (int32_t) dev->dig_H2 + 8192) >> 14);
v_x1_u32r = v_x1_u32r
- (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7)
* (int32_t) dev->dig_H1) >> 4);
v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r;
v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;
return v_x1_u32r >> 12;
}
bool bmp280_read_fixed(BMP280_HandleTypedef *dev, int32_t *temperature, uint32_t *pressure,
uint32_t *humidity) {
int32_t adc_pressure;
int32_t adc_temp;
uint8_t data[8];
// Only the BME280 supports reading the humidity.
if (dev->id != BME280_CHIP_ID) {
if (humidity)
*humidity = 0;
humidity = NULL;
}
// Need to read in one sequence to ensure they match.
size_t size = humidity ? 8 : 6;
if (read_data(dev, 0xf7, data, size)) {
return false;
}
adc_pressure = data[0] << 12 | data[1] << 4 | data[2] >> 4;
adc_temp = data[3] << 12 | data[4] << 4 | data[5] >> 4;
int32_t fine_temp;
*temperature = compensate_temperature(dev, adc_temp, &fine_temp);
*pressure = compensate_pressure(dev, adc_pressure, fine_temp);
if (humidity) {
int32_t adc_humidity = data[6] << 8 | data[7];
*humidity = compensate_humidity(dev, adc_humidity, fine_temp);
}
return true;
}
bool bmp280_read_float(BMP280_HandleTypedef *dev, float *temperature, float *pressure,
float *humidity) {
int32_t fixed_temperature;
uint32_t fixed_pressure;
uint32_t fixed_humidity;
if (bmp280_read_fixed(dev, &fixed_temperature, &fixed_pressure,
humidity ? &fixed_humidity : NULL)) {
*temperature = (float) fixed_temperature / 100;
*pressure = (float) fixed_pressure / 256;
if (humidity)
*humidity = (float) fixed_humidity / 1024;
return true;
}
return false;
}
/**
* @author Alexander Hoffman
* @email [email protected]
* @website http://alexhoffman.info
* @license GNU GPL v3
* @brief STM32 HAL library for BH1750 devices
*
@verbatim
----------------------------------------------------------------------
Copyright (C) Alexander Hoffman, 2017
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
----------------------------------------------------------------------
@endverbatim
*/
//#ifndef BH1750_H_
//#define BH1750_H_
//Device Address
//Please note that arduino uses 7 bit addresses, STM32 uses 8
#define BH1750_NO_GROUND_ADDR_WRITE (0xB9 + 0)
#define BH1750_NO_GROUND_ADDR_READ (0xB9 + 1)
#define BH1750_GROUND_ADDR_WRITE (0x46 + 0)
#define BH1750_GROUND_ADDR_READ (0x46 + 1)
//instructions
//datasheet ref http://cpre.kmutnb.ac.th/esl/learning/bh1750-light-sensor/bh1750fvi-e_datasheet.pdf
#define CMD_POWER_DOWN 0x00
#define CMD_POWER_ON 0x01
#define CMD_RESET 0x03
#define CMD_H_RES_MODE 0x10
#define CMD_H_RES_MODE2 0x11
#define CMD_L_RES_MODE 0x13
#define CMD_ONE_H_RES_MODE 0x20
#define CMD_ONE_H_RES_MODE2 0x21
#define CMD_ONE_L_RES_MODE 0x23
#define CMD_CNG_TIME_HIGH 0x30 // 3 LSB set time
#define CMD_CNG_TIME_LOW 0x60 // 5 LSB set time
#ifndef bool
#define bool uint8_t
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
typedef struct BH1750_device BH1750_device_t;
struct BH1750_device{
char* name;
I2C_HandleTypeDef* i2c_handle;
uint8_t address_r;
uint8_t address_w;
uint16_t value;
uint8_t buffer[2];
uint8_t mode;
void (* poll)(BH1750_device_t*);
} ;
HAL_StatusTypeDef BH1750_read_dev(BH1750_device_t* dev);
HAL_StatusTypeDef BH1750_init_i2c(I2C_HandleTypeDef* i2c_handle);
BH1750_device_t* BH1750_init_dev_struct(I2C_HandleTypeDef* i2c_handle,
char* name, bool addr_grounded);
HAL_StatusTypeDef BH1750_init_dev(BH1750_device_t* dev);
HAL_StatusTypeDef BH1750_get_lumen(BH1750_device_t* dev);
#include "stm32c0xx_hal.h"
void _Error_Handler(char * file, int line)
{
while(1)
{
}
}
HAL_StatusTypeDef BH1750_send_command(BH1750_device_t* dev, uint8_t cmd)
{
//TODO hal checks
if(HAL_I2C_Master_Transmit(
dev->i2c_handle, //I2C Handle
dev->address_w, //I2C addr of dev
&cmd, //CMD to be executed
1, //8bit addr
10 //Wait time
) != HAL_OK) return HAL_ERROR;
return HAL_OK;
}
void BH1750_poll_self(BH1750_device_t* self)
{
BH1750_get_lumen(self);
}
BH1750_device_t* BH1750_init_dev_struct(I2C_HandleTypeDef* i2c_handle,
char* name, bool addr_grounded)
{
BH1750_device_t* init =
(BH1750_device_t*)calloc(1, sizeof(BH1750_device_t));
if(init == NULL) return NULL;
if(addr_grounded){
init->address_r = BH1750_GROUND_ADDR_READ;
init->address_w = BH1750_GROUND_ADDR_WRITE;
}else{
init->address_r = BH1750_NO_GROUND_ADDR_READ;
init->address_w = BH1750_NO_GROUND_ADDR_WRITE;
}
init->name = (char*)malloc(sizeof(char) * strlen(name));
if(init->name == NULL) return NULL;
init->i2c_handle = i2c_handle;
strcpy(init->name, name);
init->poll = &BH1750_poll_self;
return init;
}
HAL_StatusTypeDef BH1750_init_dev(BH1750_device_t* dev)
{
BH1750_send_command(dev, CMD_POWER_ON);
BH1750_send_command(dev, CMD_RESET);
BH1750_send_command(dev, CMD_H_RES_MODE);
return HAL_OK;
}
HAL_StatusTypeDef BH1750_read_dev(BH1750_device_t* dev)
{
if(HAL_I2C_Master_Receive(dev->i2c_handle,
dev->address_r,
dev->buffer,
2,
10
) != HAL_OK) return HAL_ERROR;
return HAL_OK;
}
HAL_StatusTypeDef BH1750_convert(BH1750_device_t* dev)
{
dev->value = dev->buffer[0];
dev->value = (dev->value << 8) | dev->buffer[1];
//TODO check float stuff
dev->value/=1.2;
return HAL_OK;
}
HAL_StatusTypeDef BH1750_get_lumen(BH1750_device_t* dev)
{
BH1750_read_dev(dev);
BH1750_convert(dev);
return HAL_OK;
}
BMP280_HandleTypedef bmp280;
float pressure, temperature, humidity;
uint16_t size;
uint8_t Data[256];
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART1_UART_Init(void);
int main(void)
{
printf("HELLO\n");
// HAL_INIT();
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
printf("HELLO1\n");
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
printf("HELLO2\n");
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
printf("HELLO3\n");
/* USER CODE BEGIN 2 */
bmp280_init_default_params(&bmp280.params);
bmp280.addr = BMP280_I2C_ADDRESS_0;
bmp280.i2c = &hi2c1;
bmp280_init(&bmp280, &bmp280.params);
//while (!bmp280_init(&bmp280, &bmp280.params)) {
printf("HELLO4\n");/*
size = sprintf((char *)Data, "BMP280 initialization failed\n");
HAL_UART_Transmit(&huart1, Data, size, 1000);
HAL_Delay(2000);
}
bool bme280p = bmp280.id == BME280_CHIP_ID;
printf("HELLO5\n");
size = sprintf((char *)Data, "BMP280: found %s\n", bme280p ? "BME280" : "BMP280");
HAL_UART_Transmit(&huart1, Data, size, 1000);
while (1) {
HAL_Delay(100);
while (!bmp280_read_float(&bmp280, &temperature, &pressure, &humidity)) {
size = sprintf((char *)Data,
"Temperature/pressure reading failed\n");
HAL_UART_Transmit(&huart1, Data, size, 1000);
HAL_Delay(2000);
}
size = sprintf((char *)Data,"Pressure: %.2f Pa, Temperature: %.2f C",
pressure, temperature);
HAL_UART_Transmit(&huart1, Data, size, 1000);
if (bme280p) {
size = sprintf((char *)Data,", Humidity: %.2f\n", humidity);
HAL_UART_Transmit(&huart1, Data, size, 1000);
}
else {
size = sprintf((char *)Data, "\n");
HAL_UART_Transmit(&huart1, Data, size, 1000);
}
HAL_Delay(2000);
}
*/
/* USER CODE END 3 */
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief I2C1 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* Enable GPIOB clock (for I2C1 SCL and SDA) */
__HAL_RCC_GPIOB_CLK_ENABLE();
/* Configure I2C1 SCL and SDA pins (PB6 and PB7) */
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; // SCL (PB6), SDA (PB7)
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; // Open drain mode
GPIO_InitStruct.Pull = GPIO_PULLUP; // Enable pull-up resistors
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // High speed for I2C
GPIO_InitStruct.Alternate = GPIO_AF7_I2C1; // I2C1 Alternate function
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Initialize GPIOB pins
/* USER CODE BEGIN I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x20303E5D; // Timing value for I2C
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/** Configure Analog filter */
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter */
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END I2C1_Init 1 */
}
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_2, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
/*Configure GPIO pin : User_Button_Pin */
GPIO_InitStruct.Pin = User_Button_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(User_Button_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PA0 PA2 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : Led_Pin */
GPIO_InitStruct.Pin = Led_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(Led_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PB0 PB2 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PC6 */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : PD0 PD1 PD2 */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */