#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define BMP280_ID 0xD0
#define BMP280_RESET 0xE0
#define BMP280_STATUS 0xF3
#define BMP280_CTRL_MEAS 0xF4
#define BMP280_CONFIG 0xF5
#define BMP280_PRESS_MSB 0xF7
#define BMP280_PRESS_LSB 0xF8
#define BMP280_PRESS_XLSB 0xF9
#define BMP280_TEMP_MSB 0xFA
#define BMP280_TEMP_LSB 0xFB
#define BMP280_TEMP_XLSB 0xFC
#define BMP280_DIG_T1_LSB 0x88
#define BMP280_DIG_T1_MSB 0x89
#define BMP280_DIG_T2_LSB 0x8A
#define BMP280_DIG_T2_MSB 0x8B
#define BMP280_DIG_T3_LSB 0x8C
#define BMP280_DIG_T3_MSB 0x8D
#define BMP280_DIG_P1_LSB 0x8E
#define BMP280_DIG_P1_MSB 0x8F
#define BMP280_DIG_P2_LSB 0x90
#define BMP280_DIG_P2_MSB 0x91
#define BMP280_DIG_P3_LSB 0x92
#define BMP280_DIG_P3_MSB 0x93
#define BMP280_DIG_P4_LSB 0x94
#define BMP280_DIG_P4_MSB 0x95
#define BMP280_DIG_P5_LSB 0x96
#define BMP280_DIG_P5_MSB 0x97
#define BMP280_DIG_P6_LSB 0x98
#define BMP280_DIG_P6_MSB 0x99
#define BMP280_DIG_P7_LSB 0x9A
#define BMP280_DIG_P7_MSB 0x9B
#define BMP280_DIG_P8_LSB 0x9C
#define BMP280_DIG_P8_MSB 0x9D
#define BMP280_DIG_P9_LSB 0x9E
#define BMP280_DIG_P9_MSB 0x9F
#define SPI_MOSI 23
#define SPI_MISO 19
#define SPI_SCLK 18
#define SPI_CS 5
static const char *TAG = "SPI-BMP280";
spi_device_handle_t bmp280_spi;
int32_t t_fine;
uint16_t dig_T1, dig_P1;
int16_t dig_T2, dig_T3, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
esp_err_t bmp280_read_reg(uint8_t reg_addr, uint8_t *reg_data, uint32_t len)
{
spi_transaction_t t;
memset(&t, 0, sizeof(spi_transaction_t));
t.addr = reg_addr | 0x80;
t.length = len * 8;
t.rx_buffer = reg_data;
return spi_device_transmit(bmp280_spi, &t);
}
esp_err_t bmp280_write_reg(uint8_t reg_addr, uint8_t reg_data)
{
spi_transaction_t t;
memset(&t, 0, sizeof(spi_transaction_t));
t.addr = reg_addr & 0x7F;
t.tx_buffer = ®_data;
t.length = 8;
return spi_device_transmit(bmp280_spi, &t);
}
void bmp280_read_calib_data()
{
uint8_t calib_data[24];
bmp280_read_reg(BMP280_DIG_T1_LSB, calib_data, 24);
dig_T1 = (calib_data[1] << 8) | calib_data[0];
dig_T2 = (calib_data[3] << 8) | calib_data[2];
dig_T3 = (calib_data[5] << 8) | calib_data[4];
dig_P1 = (calib_data[7] << 8) | calib_data[6];
dig_P2 = (calib_data[9] << 8) | calib_data[8];
dig_P3 = (calib_data[11] << 8) | calib_data[10];
dig_P4 = (calib_data[13] << 8) | calib_data[12];
dig_P5 = (calib_data[15] << 8) | calib_data[14];
dig_P6 = (calib_data[17] << 8) | calib_data[16];
dig_P7 = (calib_data[19] << 8) | calib_data[18];
dig_P8 = (calib_data[21] << 8) | calib_data[20];
dig_P9 = (calib_data[23] << 8) | calib_data[22];
}
uint32_t bmp280_read_adc_press()
{
uint8_t data[3];
bmp280_read_reg(BMP280_PRESS_MSB, data, 3);
uint32_t adc_P = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
return adc_P;
}
uint32_t bmp280_read_adc_temp()
{
uint8_t data[3];
bmp280_read_reg(BMP280_TEMP_MSB, data, 3);
uint32_t adc_T = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
return adc_T;
}
int32_t bmp280_compensate_temp(int32_t adc_T)
{
int32_t var1, var2, T;
var1 = ((((adc_T >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) * ((adc_T >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
uint32_t bmp280_compensate_press(int32_t adc_P)
{
int64_t var1, var2, p;
var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
var2 = var2 + (((int64_t)dig_P4) << 35);
var1 = ((var1 * var1 * (int64_t)dig_P3) >> 8) + ((var1 * (int64_t)dig_P2) << 12);
var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)dig_P1) >> 33;
if (var1 == 0)
{
return 0;
}
p = 1048576 - adc_P;
p = (((p << 31) - var2) * 3125) / var1;
var1 = (((int64_t)dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7) << 4);
return (uint32_t)p;
}
esp_err_t spi_master_init()
{
spi_bus_config_t spi_bus_config = {
.mosi_io_num = SPI_MOSI,
.miso_io_num = SPI_MISO,
.sclk_io_num = SPI_SCLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1};
spi_device_interface_config_t spi_device_config = {
.command_bits = 0,
.address_bits = 8,
.dummy_bits = 0,
.mode = 0,
.duty_cycle_pos = 0,
.cs_ena_pretrans = 0,
.cs_ena_posttrans = 0,
.clock_speed_hz = 1000000,
.input_delay_ns = 0,
.spics_io_num = SPI_CS,
.flags = 0,
.queue_size = 1};
ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &spi_bus_config, SPI_DMA_CH_AUTO));
ESP_ERROR_CHECK(spi_bus_add_device(SPI3_HOST, &spi_device_config, &bmp280_spi));
return ESP_OK;
}
void bmp280_init()
{
bmp280_write_reg(BMP280_CONFIG, 0x04);
bmp280_write_reg(BMP280_CTRL_MEAS, 0xB7);
bmp280_read_calib_data();
ESP_LOGI(TAG, "BMP280 initialized");
}
void app_main(void)
{
spi_master_init();
bmp280_init();
uint8_t WHO_AM_I;
while (1)
{
int32_t adc_T = bmp280_read_adc_temp();
int32_t adc_P = bmp280_read_adc_press();
float temperature = bmp280_compensate_temp(adc_T) / 100.0;
int32_t pressure = bmp280_compensate_press(adc_P) / 256.0;
bmp280_read_reg(BMP280_ID, &WHO_AM_I, 1);
ESP_LOGI(TAG, "WHO_AM_I: 0x%02X", WHO_AM_I);
ESP_LOGI(TAG, "Temperatura: %.2f °C, Pa: %d.%02d", temperature, (int)(pressure / 100), (int)(pressure % 100));
vTaskDelay(pdMS_TO_TICKS(3000));
}
}