Skip to content

Conversation

@Fleker
Copy link
Contributor

@Fleker Fleker commented May 22, 2021

Start work on a template that will create extensions of RegisterDevice for use w/ I2C peripherals.

Fleker added 5 commits May 22, 2021 15:36
C++ source and header files
Test with BMP180 and Example peripherals
C++ source and header files
Test with BMP180 and Example peripherals
@Fleker
Copy link
Contributor Author

Fleker commented May 22, 2021

See RegisterDevice API and Getting Started

@Fleker
Copy link
Contributor Author

Fleker commented Jun 4, 2021

  • Use .cc over .cpp
  • WriteRegister8 cmd has no semicolon
  • Add #include "BMP180.h" at top
  • Address, Initiator -> pw::i2c::...
  • Result -> pw::Result and Status -> pw::Status
  • docs.rst file
  • BUILD.gn generation

@Fleker
Copy link
Contributor Author

Fleker commented Jun 4, 2021

BUILD.gn (see also sample)

# ...

import("//build_overrides/pigweed.gni")

import("$dir_pw_build/target_types.gni")
import("$dir_pw_chrono/backend.gni")
import("$dir_pw_docgen/docs.gni")
import("$dir_pw_unit_test/test.gni")

pw_source_set("bmp180") {
  public = [ "BMP180.h" ]
  sources = [ "BMP180.cc" ]
  deps = [
    "$dir_pw_bytes",
    "$dir_pw_chrono:system_clock",
    "$dir_pw_i2c:address",
    "$dir_pw_i2c:device",
    "$dir_pw_i2c:initiator",
    "$dir_pw_result",
    "$dir_pw_status",
  ]
}

pw_test_group("tests") {
  tests = [
    ":bmp180_test",
  ]
}

pw_test("bmp180_test") {
  sources = [ "bmp180_test.cc" ]
  deps = [ ":bmp180" ]
}

pw_doc_group("docs") {
  sources = [ "docs.rst" ]
}

BMP180_test.cc

// Copyright 2021 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include <array>
#include <chrono>
#include <span>

#include "gtest/gtest.h"
// #include "pw_bytes/array.h"
// #include "pw_bytes/span.h"
// #include "pw_i2c/address.h"

using namespace std::literals::chrono_literals;

namespace pw::i2c {
namespace {

TEST(Transaction, Read) {
  EXPECT_EQ(1, 1);
}

}  // namespace
}  // namespace pw::i2c

BMP180.cc

/*
* Copyright (C) 2020 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Auto-generated file for BMP180 v0.1.0.
* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2
* Class for BMP180
* Bosch Digital Temperature / Pressure Sensor
*/

#include "BMP180.h"


#define DEVICE_ADDRESS 119

#define REGISTER_CONTROL 244
#define REGISTER_PRESSURECALAC1 170
#define REGISTER_PRESSURECALAC2 172
#define REGISTER_PRESSURECALVB1 182
#define REGISTER_PRESSURECALVB2 184
#define REGISTER_RESULT 246
#define REGISTER_TEMPCAL3 174
#define REGISTER_TEMPCAL4 176
#define REGISTER_TEMPCAL5 178
#define REGISTER_TEMPCAL6 180
#define REGISTER_TEMPCALMC 188
#define REGISTER_TEMPCALMD 190

BMP180::BMP180(pw::i2c::Initiator& initiator):
    RegisterDevice(initiator, pw::i2c::Address(119),
          std::endian::big,
          pw::i2c::RegisterAddressSize::k1Byte) {}

pw::Status BMP180::writeControl(uint8_t data) {
  // Hard-coded timeout of 1s.
  return WriteRegister8(REGISTER_CONTROL, data, std::chrono::seconds(1));
}

pw::Result<uint16_t> BMP180::readPressureCalAC1() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_PRESSURECALAC1, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readPressureCalAC2() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_PRESSURECALAC2, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readPressureCalVB1() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_PRESSURECALVB1, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readPressureCalVB2() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_PRESSURECALVB2, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readResult() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_RESULT, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readTempCal3() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_TEMPCAL3, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readTempCal4() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_TEMPCAL4, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readTempCal5() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_TEMPCAL5, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readTempCal6() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_TEMPCAL6, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readTempCalMC() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_TEMPCALMC, std::chrono::seconds(1));
}


pw::Result<uint16_t> BMP180::readTempCalMD() {
  // Hard-coded timeout of 1s.
  return ReadRegister16(REGISTER_TEMPCALMD, std::chrono::seconds(1));
}




float BMP180::pressureasMbars() {
    short ac1; // Variable declaration
    short ac2; // Variable declaration
    short ac3; // Variable declaration
    uint16_t ac4; // Variable declaration
    float b1; // Variable declaration
    float c3; // Variable declaration
    float c4; // Variable declaration
    float p0; // Variable declaration
    float p1; // Variable declaration
    float p2; // Variable declaration
    float pressure; // Variable declaration
    float rawComp; // Variable declaration
    float temperature; // Variable declaration
    short vb1; // Variable declaration
    short vb2; // Variable declaration
    float x; // Variable declaration
    float x1; // Variable declaration
    float x2; // Variable declaration
    float y; // Variable declaration
    float y0; // Variable declaration
    float y1; // Variable declaration
    float y2; // Variable declaration
    float z; // Variable declaration


    writeControl(52);
    pressure = readResult().value();
    temperature = temperatureasCelsius();
    pw::chrono::SystemClock::time_point before = pw::chrono::SystemClock::now();
    while (pw::chrono::SystemClock::now() - before < std::chrono::milliseconds(10)) {}
    rawComp = (temperature-25);
    ac1 = readPressureCalAC1().value();
    ac2 = readPressureCalAC2().value();
    x1 = (160*pow(2, -13)*ac2);
    vb2 = readPressureCalVB2().value();
    x2 = (pow(160, 2)*pow(2, -25)*vb2);
    x = ((x2*pow(rawComp, 2))+(x1*rawComp)+ac1);
    ac3 = readTempCal3().value();
    c3 = (160*pow(2, -15)*ac3);
    ac4 = readTempCal4().value();
    c4 = (pow(10, -3)*pow(2, -15)*ac4);
    vb1 = readPressureCalVB1().value();
    b1 = (pow(160, 2)*pow(2, -30)*vb1);
    y0 = (c4*pow(2, 15));
    y1 = (c4*c3);
    y2 = (c4*b1);
    y = ((y2*pow(rawComp, 2))+(y1*rawComp)+y0);
    z = ((pressure-x)/y);
    p0 = ((3791-8)/1600);
    p1 = (1-(7357*pow(2, -30)));
    p2 = (3038*100*pow(2, -36));
    pressure = ((p2*pow(z, 2))+(p1*z)+p0);



    return pressure;
}

float BMP180::temperatureasCelsius() {
    short rawComp; // Variable declaration
    short rawMc; // Variable declaration
    short rawMd; // Variable declaration
    float temperature; // Variable declaration
    uint16_t varAc5; // Variable declaration
    uint16_t varAc6; // Variable declaration
    float varC5; // Variable declaration
    float varMc; // Variable declaration
    float varMd; // Variable declaration


    writeControl(46);
    temperature = readResult().value();
    varAc5 = readTempCal5().value();
    varAc6 = readTempCal6().value();
    varC5 = ((pow(2, -15)/160)*varAc5);
    rawComp = (varC5*(temperature-varAc6));
    rawMc = readTempCalMC().value();
    varMc = ((pow(2, 11)/pow(160, 2))*rawMc);
    rawMd = readTempCalMD().value();
    varMd = (rawMd/160);
    temperature = (rawComp+(varMc/(rawComp+varMd)));


    return temperature;
}

BMP180.h

/*
* Copyright (C) 2020 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Auto-generated file for BMP180 v0.1.0.
* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2
* Class for BMP180
* Bosch Digital Temperature / Pressure Sensor

*/

#pragma once

#include <cmath>

#include "pw_bytes/byte_builder.h"
#include "pw_chrono/system_clock.h"
#include "pw_i2c/address.h"
#include "pw_i2c/device.h"
#include "pw_i2c/register_device.h"
#include "pw_i2c/initiator.h"
#include "pw_result/result.h"
#include "pw_status/status.h"

class BMP180 : pw::i2c::RegisterDevice {
    public:
        BMP180(pw::i2c::Initiator& initiator);


        /**
         * Stores the current measurement type.

         */
        pw::Status writeControl(uint8_t data);
        /**
         * Constant register for pressure measurement calibration.

         */
        pw::Result<uint16_t> readPressureCalAC1();


        /**
         * Constant register for pressure measurement calibration.

         */
        pw::Result<uint16_t> readPressureCalAC2();


        /**
         * Constant register for pressure measurement calibration.

         */
        pw::Result<uint16_t> readPressureCalVB1();


        /**
         * Constant register for pressure measurement calibration.

         */
        pw::Result<uint16_t> readPressureCalVB2();


        /**
         * Stores the most recent measurement result.

         */
        pw::Result<uint16_t> readResult();


        /**
         * Third constant register for temperature measurement calibration.

         */
        pw::Result<uint16_t> readTempCal3();


        /**
         * Fourth constant register for temperature measurement calibration.

         */
        pw::Result<uint16_t> readTempCal4();


        /**
         * Fifth constant register for temperature measurement calibration.

         */
        pw::Result<uint16_t> readTempCal5();


        /**
         * Sixth constant register for temperature measurement calibration.

         */
        pw::Result<uint16_t> readTempCal6();


        /**
         * Constant register for temperature measurement calibration.

         */
        pw::Result<uint16_t> readTempCalMC();


        /**
         * Constant register for temperature measurement calibration.

         */
        pw::Result<uint16_t> readTempCalMD();



        /**
         * Reads the pressure in absolute millibars,
         * not compensated for sea level.

         */
        float pressureasMbars();

        /**
         * Reads the temperature as a raw value or in Celsius.

         */
        float temperatureasCelsius();

};

This all builds, technically. But it gives an error at the very end, maybe because it's building on the host and not for a specific device.

20210604 18:09:31 ERR 
20210604 18:09:31 ERR Build error for //pw_chrono:system_clock.NO_BACKEND_SET(//targets/stm32f429i_disc1:stm32f429i_disc1_debug):
20210604 18:09:31 ERR 
20210604 18:09:31 ERR   Attempted to build the //pw_chrono:system_clock facade with no backend.
20210604 18:09:31 ERR   
20210604 18:09:31 ERR   If you are using this facade, ensure you have configured a backend 
20210604 18:09:31 ERR   properly. The build arg for the facade must be set to a valid 
20210604 18:09:31 ERR   backend in the toolchain. For example, you may need to add a line 
20210604 18:09:31 ERR   like the following to the toolchain's .gni file:
20210604 18:09:31 ERR   
20210604 18:09:31 ERR     pw_chrono_<FACADE_NAME>_BACKEND = "//path/to/the:backend"
20210604 18:09:31 ERR   
20210604 18:09:31 ERR   If you are NOT using this facade, this error may have been triggered 
20210604 18:09:31 ERR   by trying to build all targets.
20210604 18:09:31 ERR 
20210604 18:09:32 ERR Dependency path to this target:
20210604 18:09:32 ERR 
20210604 18:09:32 ERR   gn path out //:default "//pw_chrono:system_clock.NO_BACKEND_SET(//targets/stm32f429i_disc1:stm32f429i_disc1_debug)"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant