diff --git a/components-todo/bmp280/CMakeLists.txt b/components/bmp280/CMakeLists.txt similarity index 100% rename from components-todo/bmp280/CMakeLists.txt rename to components/bmp280/CMakeLists.txt diff --git a/components-todo/bmp280/README.md b/components/bmp280/README.md similarity index 100% rename from components-todo/bmp280/README.md rename to components/bmp280/README.md diff --git a/components-todo/bmp280/bmp280.c b/components/bmp280/bmp280.c similarity index 74% rename from components-todo/bmp280/bmp280.c rename to components/bmp280/bmp280.c index d2f3795..9dde52b 100644 --- a/components-todo/bmp280/bmp280.c +++ b/components/bmp280/bmp280.c @@ -23,6 +23,7 @@ */ #include #include "bmp280.h" +#include "driver/i2c.h" #ifdef BMP280_DEBUG #include @@ -65,36 +66,58 @@ void bmp280_init_default_params(bmp280_params_t *params) params->standby = BMP280_STANDBY_250; } -static bool read_register16(i2c_dev_t *dev, uint8_t addr, uint16_t *value) +static inline esp_err_t read_data(bmp280_i2c_dev_t *dev, uint8_t addr, uint8_t *value, uint8_t len) { - uint8_t d[] = {0, 0}; - if (!i2c_slave_read(dev->bus, dev->addr, &addr, d, sizeof(d))) { - *value = d[0] | (d[1] << 8); - return true; - } - return false; + int ret; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, dev->addr << 1 | I2C_MASTER_WRITE, true); + i2c_master_write_byte(cmd, addr, true); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, dev->addr << 1 | I2C_MASTER_READ, true); + i2c_master_read(cmd, value, len, I2C_MASTER_LAST_NACK); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(dev->i2c_num, cmd, pdMS_TO_TICKS(BMP280_I2C_TIMEOUT_MS)); + i2c_cmd_link_delete(cmd); + return ret; } -static inline int read_data(i2c_dev_t *dev, uint8_t addr, uint8_t *value, uint8_t len) +static esp_err_t read_register16(bmp280_i2c_dev_t *dev, uint8_t addr, uint16_t *value) { - return i2c_slave_read(dev->bus, dev->addr, &addr, value, len); + uint8_t bytes[2]; + esp_err_t ret = read_data(dev, addr, bytes, 2); + *value = bytes[1] << 8 | bytes[0]; + return ret; } -static bool read_calibration_data(bmp280_t *dev) +static esp_err_t write_register8(bmp280_i2c_dev_t *dev, uint8_t addr, uint8_t value) { + int ret; + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, dev->addr << 1 | I2C_MASTER_WRITE, 1); + i2c_master_write_byte(cmd, addr, true); + i2c_master_write_byte(cmd, value, true); + i2c_master_stop(cmd); + ret = i2c_master_cmd_begin(dev->i2c_num, cmd, pdMS_TO_TICKS(BMP280_I2C_TIMEOUT_MS)); + i2c_cmd_link_delete(cmd); + return ret; +} - if (read_register16(&dev->i2c_dev, 0x88, &dev->dig_T1) && - read_register16(&dev->i2c_dev, 0x8a, (uint16_t *)&dev->dig_T2) && - read_register16(&dev->i2c_dev, 0x8c, (uint16_t *)&dev->dig_T3) && - read_register16(&dev->i2c_dev, 0x8e, &dev->dig_P1) && - read_register16(&dev->i2c_dev, 0x90, (uint16_t *)&dev->dig_P2) && - read_register16(&dev->i2c_dev, 0x92, (uint16_t *)&dev->dig_P3) && - read_register16(&dev->i2c_dev, 0x94, (uint16_t *)&dev->dig_P4) && - read_register16(&dev->i2c_dev, 0x96, (uint16_t *)&dev->dig_P5) && - read_register16(&dev->i2c_dev, 0x98, (uint16_t *)&dev->dig_P6) && - read_register16(&dev->i2c_dev, 0x9a, (uint16_t *)&dev->dig_P7) && - read_register16(&dev->i2c_dev, 0x9c, (uint16_t *)&dev->dig_P8) && - read_register16(&dev->i2c_dev, 0x9e, (uint16_t *)&dev->dig_P9)) { +static bool read_calibration_data(bmp280_t *dev) +{ + if (ESP_OK == read_register16(&dev->i2c_dev, 0x88, &dev->dig_T1) && + ESP_OK == read_register16(&dev->i2c_dev, 0x8a, (uint16_t *)&dev->dig_T2) && + ESP_OK == read_register16(&dev->i2c_dev, 0x8c, (uint16_t *)&dev->dig_T3) && + ESP_OK == read_register16(&dev->i2c_dev, 0x8e, &dev->dig_P1) && + ESP_OK == read_register16(&dev->i2c_dev, 0x90, (uint16_t *)&dev->dig_P2) && + ESP_OK == read_register16(&dev->i2c_dev, 0x92, (uint16_t *)&dev->dig_P3) && + ESP_OK == read_register16(&dev->i2c_dev, 0x94, (uint16_t *)&dev->dig_P4) && + ESP_OK == read_register16(&dev->i2c_dev, 0x96, (uint16_t *)&dev->dig_P5) && + ESP_OK == read_register16(&dev->i2c_dev, 0x98, (uint16_t *)&dev->dig_P6) && + ESP_OK == read_register16(&dev->i2c_dev, 0x9a, (uint16_t *)&dev->dig_P7) && + ESP_OK == read_register16(&dev->i2c_dev, 0x9c, (uint16_t *)&dev->dig_P8) && + ESP_OK == read_register16(&dev->i2c_dev, 0x9e, (uint16_t *)&dev->dig_P9)) { debug("Calibration data received:"); debug("dig_T1=%d", dev->dig_T1); @@ -120,12 +143,13 @@ static bool read_hum_calibration_data(bmp280_t *dev) { uint16_t h4, h5; - if (!read_data(&dev->i2c_dev, 0xa1, &dev->dig_H1, 1) && - read_register16(&dev->i2c_dev, 0xe1, (uint16_t *)&dev->dig_H2) && - !read_data(&dev->i2c_dev, 0xe3, &dev->dig_H3, 1) && - read_register16(&dev->i2c_dev, 0xe4, &h4) && - read_register16(&dev->i2c_dev, 0xe5, &h5) && - !read_data(&dev->i2c_dev, 0xe7, (uint8_t *)&dev->dig_H6, 1)) { + if (ESP_OK == read_data(&dev->i2c_dev, 0xa1, &dev->dig_H1, 1) && + ESP_OK == read_register16(&dev->i2c_dev, 0xe1, (uint16_t *)&dev->dig_H2) && + ESP_OK == read_data(&dev->i2c_dev, 0xe3, &dev->dig_H3, 1) && + ESP_OK == read_register16(&dev->i2c_dev, 0xe4, &h4) && + ESP_OK == read_register16(&dev->i2c_dev, 0xe5, &h5) && + ESP_OK == read_data(&dev->i2c_dev, 0xe7, (uint8_t *)&dev->dig_H6, 1)) + { dev->dig_H4 = (h4 & 0x00ff) << 4 | (h4 & 0x0f00) >> 8; dev->dig_H5 = h5 >> 4; debug("Calibration data received:"); @@ -141,11 +165,6 @@ static bool read_hum_calibration_data(bmp280_t *dev) return false; } -static int write_register8(i2c_dev_t *dev, uint8_t addr, uint8_t value) -{ - return i2c_slave_write(dev->bus, dev->addr, &addr, &value, 1); -} - bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) { @@ -154,7 +173,7 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) return false; } - if (read_data(&dev->i2c_dev, BMP280_REG_ID, &dev->id, 1)) { + if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_ID, &dev->id, 1)) { debug("Sensor not found"); return false; } @@ -165,15 +184,15 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) } // Soft reset. - if (write_register8(&dev->i2c_dev, BMP280_REG_RESET, BMP280_RESET_VALUE)) { + if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_RESET, BMP280_RESET_VALUE)) { debug("Failed resetting sensor"); return false; } // Wait until finished copying over the NVP data. while (1) { - uint8_t status; - if (!read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1) && (status & 1) == 0) + uint8_t status = 1; + if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1) || (status & 1) == 0) break; } @@ -189,7 +208,7 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) uint8_t config = (params->standby << 5) | (params->filter << 2); debug("Writing config reg=%x", config); - if (write_register8(&dev->i2c_dev, BMP280_REG_CONFIG, config)) { + if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CONFIG, config)) { debug("Failed configuring sensor"); return false; } @@ -206,14 +225,14 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) // Write crtl hum reg first, only active after write to BMP280_REG_CTRL. uint8_t ctrl_hum = params->oversampling_humidity; debug("Writing ctrl hum reg=%x", ctrl_hum); - if (write_register8(&dev->i2c_dev, BMP280_REG_CTRL_HUM, ctrl_hum)) { + if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CTRL_HUM, ctrl_hum)) { debug("Failed controlling sensor"); return false; } } debug("Writing ctrl reg=%x", ctrl); - if (write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { + if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { debug("Failed controlling sensor"); return false; } @@ -224,12 +243,12 @@ bool bmp280_init(bmp280_t *dev, bmp280_params_t *params) bool bmp280_force_measurement(bmp280_t *dev) { uint8_t ctrl; - if (read_data(&dev->i2c_dev, BMP280_REG_CTRL, &ctrl, 1)) + if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_CTRL, &ctrl, 1)) return false; ctrl &= ~0b11; // clear two lower bits ctrl |= BMP280_MODE_FORCED; debug("Writing ctrl reg=%x", ctrl); - if (write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { + if (ESP_OK != write_register8(&dev->i2c_dev, BMP280_REG_CTRL, ctrl)) { debug("Failed starting forced mode"); return false; } @@ -239,7 +258,7 @@ bool bmp280_force_measurement(bmp280_t *dev) bool bmp280_is_measuring(bmp280_t *dev) { uint8_t status; - if (read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1)) + if (ESP_OK != read_data(&dev->i2c_dev, BMP280_REG_STATUS, &status, 1)) return false; if (status & (1 << 3)) { debug("Status: measuring"); @@ -341,7 +360,7 @@ bool bmp280_read_fixed(bmp280_t *dev, int32_t *temperature, // Need to read in one sequence to ensure they match. size_t size = humidity ? 8 : 6; - if (read_data(&dev->i2c_dev, 0xf7, data, size)) { + if (ESP_OK != read_data(&dev->i2c_dev, 0xf7, data, size)) { debug("Failed reading"); return false; } diff --git a/components-todo/bmp280/bmp280.h b/components/bmp280/bmp280.h similarity index 70% rename from components-todo/bmp280/bmp280.h rename to components/bmp280/bmp280.h index 39805fc..f91789d 100644 --- a/components-todo/bmp280/bmp280.h +++ b/components/bmp280/bmp280.h @@ -26,7 +26,7 @@ #include #include -#include "i2c/i2c.h" +#include #ifdef __cplusplus extern "C" { @@ -37,6 +37,8 @@ extern "C" { */ // #define BMP280_DEBUG +#define BMP280_I2C_TIMEOUT_MS 1000 + /** * BMP280 or BME280 address is 0x77 if SDO pin is high, and is 0x76 if * SDO pin is low. @@ -53,43 +55,43 @@ extern "C" { * Normal - Continues measurement. */ typedef enum { - BMP280_MODE_SLEEP = 0, - BMP280_MODE_FORCED = 1, - BMP280_MODE_NORMAL = 3 + 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_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_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_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; /** @@ -97,39 +99,43 @@ typedef enum { * 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_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 { + uint8_t addr; + i2c_port_t i2c_num; +} bmp280_i2c_dev_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; - - i2c_dev_t i2c_dev; /* I2C dev setting. */ - uint8_t id; /* Chip ID */ + 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; + + bmp280_i2c_dev_t i2c_dev; /* I2C dev setting. */ + uint8_t id; /* Chip ID */ } bmp280_t; /** diff --git a/components-todo/bmp280/component.mk b/components/bmp280/component.mk similarity index 100% rename from components-todo/bmp280/component.mk rename to components/bmp280/component.mk diff --git a/main/meteo_task.c b/main/meteo_task.c index 32c36f5..3c5709b 100644 --- a/main/meteo_task.c +++ b/main/meteo_task.c @@ -11,7 +11,9 @@ #include "ds18b20.h" #include "dht.h" #include "driver/gpio.h" +#include "driver/i2c.h" #include "circbuf.h" +#include "bmp280.h" static volatile uint32_t timestamp = 0; @@ -41,7 +43,7 @@ void hw_timer_callback1s(void *arg) if (cbuf_full(&rps_cb)) { cbuf_pop_back(&rps_cb, NULL); } - cbuf_push(&rps_cb, (void*) &cycle_count); + cbuf_push(&rps_cb, (void *) &cycle_count); cycle_count = 0; calculate_wind(); @@ -57,7 +59,7 @@ void calculate_wind() uint32_t tenmin_sum = 0; uint32_t numsecs = cbuf_count(&rps_cb); uint16_t threesec1 = 0, threesec2 = 0; - for(size_t i = 0; i < numsecs; i++) { + for (size_t i = 0; i < numsecs; i++) { uint16_t *slot = cbuf_ptr_nth(&rps_cb, i); if (!slot) { continue; @@ -71,19 +73,19 @@ void calculate_wind() threesec1 = threesec2; threesec2 = slotval; - float gust_avg = (float)gust_sum * (float)20.0f; + float gust_avg = (float) gust_sum * (float) 20.0f; if (gust_avg > max_gust) { max_gust = gust_avg; } } rpm_gust = max_gust; - rpm_average = ((float)tenmin_sum / (float)numsecs) * 60.0f; + rpm_average = ((float) tenmin_sum / (float) numsecs) * 60.0f; } -void meteo_task(void* pvParameters) +void meteo_task(void *pvParameters) { - cbuf_init(&rps_cb, (void*)history, RPS_BUFFER_LEN, 2); // uint16 fields + cbuf_init(&rps_cb, (void *) history, RPS_BUFFER_LEN, 2); // uint16 fields // Try to unfuck GPIOs PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); @@ -92,8 +94,8 @@ void meteo_task(void* pvParameters) PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); // start timer used for timebase - hw_timer_init(hw_timer_callback1s, NULL); - hw_timer_alarm_us(1000000, true); // 1s timer + ESP_ERROR_CHECK(hw_timer_init(hw_timer_callback1s, NULL)); + ESP_ERROR_CHECK(hw_timer_alarm_us(1000000, true)); // 1s timer gpio_config_t io_conf; io_conf.intr_type = GPIO_INTR_POSEDGE; @@ -101,21 +103,63 @@ void meteo_task(void* pvParameters) io_conf.pin_bit_mask = 1 << 14; io_conf.pull_down_en = 1; io_conf.pull_up_en = 0; - gpio_config(&io_conf); - gpio_install_isr_service(0); - gpio_isr_handler_add(14, gpio_isr_handler, NULL); - - float dht_hum, dht_temp, ds_temp; + ESP_ERROR_CHECK(gpio_config(&io_conf)); + ESP_ERROR_CHECK(gpio_install_isr_service(0)); + ESP_ERROR_CHECK(gpio_isr_handler_add(14, gpio_isr_handler, NULL)); + + /* I2C driver & peri setup */ + int i2c_master_port = I2C_NUM_0; + i2c_config_t conf; + conf.mode = I2C_MODE_MASTER; + conf.sda_io_num = 4; + conf.sda_pullup_en = 1; + conf.scl_io_num = 5; + conf.scl_pullup_en = 1; + conf.clk_stretch_tick = 300; // 300 ticks, Clock stretch is about 210us, you can make changes according to the actual situation. + ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, conf.mode)); + ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf)); + + + bmp280_params_t bmp_conf; + bmp280_init_default_params(&bmp_conf); + + bmp280_t bmp_dev = { + .i2c_dev = { + .addr = BMP280_I2C_ADDRESS_0, + .i2c_num = I2C_NUM_0, + } + }; + bmp280_init(&bmp_dev, &bmp_conf); + + vTaskDelay(pdMS_TO_TICKS(500)); + + float dht_hum, dht_temp, ds_temp, bmp_temp, bmp_hum, bmp_press; while (1) { + dht_hum = 0; + dht_temp = 0; + ds_temp = 0; + bmp_temp = 0; + bmp_press = 0; + // this works ... ds_temp = ds18b20_measure_and_read(0, DS18B20_ANY); + if (ds_temp != ds_temp) { + printf("DS failed\n"); + } if (!dht_read_float_data(DHT_TYPE_DHT22, 12, &dht_hum, &dht_temp)) { dht_hum = dht_temp = NAN; + printf("DHT failed\n"); + } + + if(!bmp280_read_float(&bmp_dev, &bmp_temp, &bmp_press, &bmp_hum)) { + printf("BMP failed\n"); } - printf("Dallas: %.2f °C, DHT %.2f °C, %.1f %%r.H, HALL avg %.1f RPM, gust %.1f RPM\n", - ds_temp, dht_temp, dht_hum, rpm_average, rpm_gust); + printf("Dallas: %.2f °C, ** DHT %.2f °C, %.1f %%r.H, ** WIND avg %.1f, gust %.1f RPM, ** BMP %.2f °C, %f Pa \n", + ds_temp, dht_temp, dht_hum, + rpm_average, rpm_gust, + bmp_temp, bmp_press); vTaskDelay(pdMS_TO_TICKS(500)); }