Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_Baro/AP_Baro_BMP581.cpp
Views: 1798
/*1This program is free software: you can redistribute it and/or modify2it under the terms of the GNU General Public License as published by3the Free Software Foundation, either version 3 of the License, or4(at your option) any later version.56This program is distributed in the hope that it will be useful,7but WITHOUT ANY WARRANTY; without even the implied warranty of8MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9GNU General Public License for more details.1011You should have received a copy of the GNU General Public License12along with this program. If not, see <http://www.gnu.org/licenses/>.13*/14#include "AP_Baro_BMP581.h"1516#if AP_BARO_BMP581_ENABLED1718#include <utility>19#include <AP_Math/AP_Math.h>2021extern const AP_HAL::HAL &hal;2223#define BMP581_ID 0x502425#define BMP581_REG_CHIP_ID 0x0126#define BMP581_REG_REV_ID 0x0227#define BMP581_REG_CHIP_STATUS 0x1128#define BMP581_REG_DRIVE_CONFIG 0x1329#define BMP581_REG_INT_CONFIG 0x1430#define BMP581_REG_INT_SOURCE 0x1531#define BMP581_REG_FIFO_CONFIG 0x1632#define BMP581_REG_FIFO_COUNT 0x1733#define BMP581_REG_FIFO_SEL 0x1834#define BMP581_REG_TEMP_DATA_XLSB 0x1D35#define BMP581_REG_TEMP_DATA_LSB 0x1E36#define BMP581_REG_TEMP_DATA_MSB 0x1F37#define BMP581_REG_PRESS_DATA_XLSB 0x2038#define BMP581_REG_PRESS_DATA_LSB 0x2139#define BMP581_REG_PRESS_DATA_MSB 0x2240#define BMP581_REG_INT_STATUS 0x2741#define BMP581_REG_STATUS 0x2842#define BMP581_REG_FIFO_DATA 0x2943#define BMP581_REG_NVM_ADDR 0x2B44#define BMP581_REG_NVM_DATA_LSB 0x2C45#define BMP581_REG_NVM_DATA_MSB 0x2D46#define BMP581_REG_DSP_CONFIG 0x3047#define BMP581_REG_DSP_IIR 0x3148#define BMP581_REG_OOR_THR_P_LSB 0x3249#define BMP581_REG_OOR_THR_P_MSB 0x3350#define BMP581_REG_OOR_RANGE 0x3451#define BMP581_REG_OOR_CONFIG 0x3552#define BMP581_REG_OSR_CONFIG 0x3653#define BMP581_REG_ODR_CONFIG 0x3754#define BMP581_REG_OSR_EFF 0x3855#define BMP581_REG_CMD 0x7E5657AP_Baro_BMP581::AP_Baro_BMP581(AP_Baro &baro, AP_HAL::OwnPtr<AP_HAL::Device> dev)58: AP_Baro_Backend(baro)59, _dev(std::move(dev))60{61}6263AP_Baro_Backend *AP_Baro_BMP581::probe(AP_Baro &baro,64AP_HAL::OwnPtr<AP_HAL::Device> dev)65{66if (!dev) {67return nullptr;68}6970AP_Baro_BMP581 *sensor = NEW_NOTHROW AP_Baro_BMP581(baro, std::move(dev));71if (!sensor || !sensor->init()) {72delete sensor;73return nullptr;74}75return sensor;76}7778bool AP_Baro_BMP581::init()79{80if (!_dev) {81return false;82}8384WITH_SEMAPHORE(_dev->get_semaphore());8586_dev->set_speed(AP_HAL::Device::SPEED_HIGH);8788uint8_t whoami;8990// setup to allow reads on SPI91if (_dev->bus_type() == AP_HAL::Device::BUS_TYPE_SPI) {92_dev->set_read_flag(0x80);9394if (!_dev->read_registers(BMP581_REG_CHIP_ID, &whoami, 1)) {95return false;96}97}9899if (!_dev->read_registers(BMP581_REG_CHIP_ID, &whoami, 1)) {100return false;101}102103switch (whoami) {104case BMP581_ID:105_dev->set_device_type(DEVTYPE_BARO_BMP581);106break;107default:108return false;109}110111uint8_t status;112if (!_dev->read_registers(BMP581_REG_STATUS, &status, 1)) {113return false;114}115116if ((status & 0b10) == 0 || (status & 0b100) == 1) {117return false;118}119120uint8_t int_status;121if (!_dev->read_registers(BMP581_REG_INT_STATUS, &int_status, 1)) {122return false;123}124125if ((int_status & 0x10) == 0) {126return false;127}128129_dev->setup_checked_registers(4);130131// Standby mode132_dev->write_register(BMP581_REG_ODR_CONFIG, 0, true);133134// Press EN | osr_p 64X | osr_t 4X135_dev->write_register(BMP581_REG_OSR_CONFIG, 0b01110010, true);136137// ORD 50Hz | Normal Mode138_dev->write_register(BMP581_REG_ODR_CONFIG, 0b0111101, true);139140instance = _frontend.register_sensor();141142set_bus_id(instance, _dev->get_bus_id());143144// request 50Hz update145_dev->register_periodic_callback(20 * AP_USEC_PER_MSEC, FUNCTOR_BIND_MEMBER(&AP_Baro_BMP581::timer, void));146147return true;148}149150// acumulate a new sensor reading151void AP_Baro_BMP581::timer(void)152{153uint8_t buf[6];154155if (!_dev->read_registers(BMP581_REG_TEMP_DATA_XLSB, buf, sizeof(buf))) {156return;157}158159WITH_SEMAPHORE(_sem);160161if (buf[0] != 0x7f || buf[1] != 0x7f || buf[2] != 0x7f) {162// we have temperature data163temperature = (float)((int32_t)(((uint32_t)buf[2] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[0] << 8)) >> 8) * (1.0f / 65536.0f);164}165166if (buf[3] != 0x7f || buf[4] != 0x7f || buf[5] != 0x7f) {167// we have pressure data168pressure_sum += (float)(((uint32_t)buf[5] << 16) | ((uint32_t)buf[4] << 8) | (uint32_t)buf[3]) * (1.0f / 64.0f);169pressure_count++;170}171172_dev->check_next_register();173}174175// transfer data to the frontend176void AP_Baro_BMP581::update(void)177{178WITH_SEMAPHORE(_sem);179180if (pressure_count == 0) {181return;182}183184_copy_to_frontend(instance,185pressure_sum/pressure_count,186temperature);187188pressure_sum = 0;189pressure_count = 0;190}191192#endif // AP_BARO_BMP581_ENABLED193194195