Skip to content

Commit

Permalink
Add tagged types for BME280 sensors
Browse files Browse the repository at this point in the history
to allow a user to declare several sensor objects and
process them in a uniform way.
  • Loading branch information
reznikmm committed Dec 16, 2023
1 parent 87bb251 commit 49eb4e1
Show file tree
Hide file tree
Showing 16 changed files with 1,341 additions and 323 deletions.
93 changes: 93 additions & 0 deletions components/src/environment/bme280/bme280-generic_sensor.ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
------------------------------------------------------------------------------
-- --
-- Copyright (C) 2023, AdaCore --
-- --
-- Redistribution and use in source and binary forms, with or without --
-- modification, are permitted provided that the following conditions are --
-- met: --
-- 1. Redistributions of source code must retain the above copyright --
-- notice, this list of conditions and the following disclaimer. --
-- 2. Redistributions in binary form must reproduce the above copyright --
-- notice, this list of conditions and the following disclaimer in --
-- the documentation and/or other materials provided with the --
-- distribution. --
-- 3. Neither the name of the copyright holder nor the names of its --
-- contributors may be used to endorse or promote products derived --
-- from this software without specific prior written permission. --
-- --
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
-- --
------------------------------------------------------------------------------

-- This generic package contains shared code independent of the sensor
-- connection method. Following the Singleton pattern, it is convenient
-- when using only one sensor is required.

with HAL.Time;

generic
with procedure Read
(Data : out HAL.UInt8_Array;
Success : out Boolean);
-- Read the values from the BME280 chip registers into Data.
-- Each element in the Data corresponds to a specific register address
-- in the chip, so Data'Range determines the range of registers to read.
-- The value read from register X will be stored in Data(X), so
-- Data'Range should be of the Register_Address subtype.

with procedure Write
(Address : Register_Address;
Data : HAL.UInt8;
Success : out Boolean);
-- Write the value to the BME280 chip register with given Address.

package BME280.Generic_Sensor is

function Check_Chip_Id (Expect : HAL.UInt8 := 16#60#) return Boolean;
-- Read the chip ID and check that it matches

procedure Reset
(Timer : not null HAL.Time.Any_Delays;
Success : out Boolean);
-- Issue a soft reset and wait until the chip is ready.

procedure Configure
(Standby : Standby_Duration := 1000.0;
Filter : IRR_Filter_Kind := Off;
SPI_3_Wire : Boolean := False;
Success : out Boolean);
-- Configure the sensor to use IRR filtering and/or SPI 3-wire mode

procedure Start
(Mode : Sensor_Mode := Normal;
Humidity : Oversampling_Kind := X1;
Pressure : Oversampling_Kind := X1;
Temperature : Oversampling_Kind := X1;
Success : out Boolean);
-- Change sensor mode. Mainly used to start one measurement or enable
-- perpetual cycling of measurements and inactive periods.

function Measuring return Boolean;
-- Check if a measurement is in progress

procedure Read_Measurement
(Value : out Measurement;
Success : out Boolean);
-- Read the raw measurement values from the sensor

procedure Read_Calibration
(Value : out Calibration_Constants;
Success : out Boolean);
-- Read the calibration constants from the sensor

end BME280.Generic_Sensor;
12 changes: 9 additions & 3 deletions components/src/environment/bme280/bme280-i2c.ads
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@
-- --
------------------------------------------------------------------------------

-- This package provides an easy way to setup BME280 connected via I2C.
-- This package offers a straightforward method for setting up the BME280
-- when connected via I2C, especially useful when the use of only one sensor
-- is required. If you need multiple sensors, it is preferable to use the
-- BME280.I2C_Sensors package, which provides the appropriate tagged type.

with HAL.I2C;

with BME280.Generic_Sensor;

generic
I2C_Port : not null HAL.I2C.Any_I2C_Port;
I2C_Address : HAL.UInt7 := 16#76#; -- The BME280 7-bit I2C address
Expand All @@ -44,9 +49,10 @@ package BME280.I2C is
-- Read registers starting from Data'First

procedure Write
(Data : HAL.UInt8_Array;
(Address : Register_Address;
Data : HAL.UInt8;
Success : out Boolean);
-- Write registers starting from Data'First
-- Write the value to the BME280 chip register with given Address.

package Sensor is new Generic_Sensor (Read, Write);

Expand Down
115 changes: 115 additions & 0 deletions components/src/environment/bme280/bme280-i2c_sensors.ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
------------------------------------------------------------------------------
-- --
-- Copyright (C) 2023, AdaCore --
-- --
-- Redistribution and use in source and binary forms, with or without --
-- modification, are permitted provided that the following conditions are --
-- met: --
-- 1. Redistributions of source code must retain the above copyright --
-- notice, this list of conditions and the following disclaimer. --
-- 2. Redistributions in binary form must reproduce the above copyright --
-- notice, this list of conditions and the following disclaimer in --
-- the documentation and/or other materials provided with the --
-- distribution. --
-- 3. Neither the name of the copyright holder nor the names of its --
-- contributors may be used to endorse or promote products derived --
-- from this software without specific prior written permission. --
-- --
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
-- --
------------------------------------------------------------------------------

-- This package provides a type representing the BME280 connected via the I2C
-- interface.

with HAL.I2C;
with HAL.Time;

with BME280.Sensors;

package BME280.I2C_Sensors is

Default_Address : constant HAL.UInt7 := 16#76#;
-- The typical BME280 7-bit I2C address

type BME280_I2C_Sensor
(I2C_Port : not null HAL.I2C.Any_I2C_Port;
I2C_Address : HAL.UInt7) is limited new BME280.Sensors.Sensor with
record
Calibration : Calibration_Constants;
end record;

overriding function Check_Chip_Id
(Self : BME280_I2C_Sensor;
Expect : HAL.UInt8 := 16#60#) return Boolean;
-- Read the chip ID and check that it matches

overriding procedure Reset
(Self : BME280_I2C_Sensor;
Timer : not null HAL.Time.Any_Delays;
Success : out Boolean);
-- Issue a soft reset and wait until the chip is ready.

overriding procedure Configure
(Self : BME280_I2C_Sensor;
Standby : Standby_Duration := 0.5;
Filter : IRR_Filter_Kind := Off;
SPI_3_Wire : Boolean := False;
Success : out Boolean);
-- Configure the sensor to use IRR filtering and/or SPI 3-wire mode

overriding procedure Start
(Self : BME280_I2C_Sensor;
Mode : Sensor_Mode := Normal;
Humidity : Oversampling_Kind := X1;
Pressure : Oversampling_Kind := X1;
Temperature : Oversampling_Kind := X1;
Success : out Boolean);
-- Change sensor mode. Mainly used to start one measurement or enable
-- perpetual cycling of measurements and inactive periods.

overriding function Measuring (Self : BME280_I2C_Sensor) return Boolean;
-- Check if a measurement is in progress

overriding procedure Read_Measurement
(Self : BME280_I2C_Sensor;
Value : out Measurement;
Success : out Boolean);
-- Read the raw measurement values from the sensor

overriding function Temperature
(Self : BME280_I2C_Sensor;
Value : Measurement) return Deci_Celsius is
(Temperature (Value, Self.Calibration));
-- Get the temperature from raw values in 0.1 Celsius

overriding function Humidity
(Self : BME280_I2C_Sensor;
Value : Measurement;
Temperature : Deci_Celsius) return Relative_Humidity is
(Humidity (Value, Temperature, Self.Calibration));
-- Get the humidity from raw values

overriding function Pressure
(Self : BME280_I2C_Sensor;
Value : Measurement;
Temperature : Deci_Celsius) return Pressure_Pa is
(Pressure (Value, Temperature, Self.Calibration));
-- Get the pressure from raw values

overriding procedure Read_Calibration
(Self : in out BME280_I2C_Sensor;
Success : out Boolean);
-- Read the calibration constants from the sensor

end BME280.I2C_Sensors;
98 changes: 98 additions & 0 deletions components/src/environment/bme280/bme280-sensors.ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
------------------------------------------------------------------------------
-- --
-- Copyright (C) 2023, AdaCore --
-- --
-- Redistribution and use in source and binary forms, with or without --
-- modification, are permitted provided that the following conditions are --
-- met: --
-- 1. Redistributions of source code must retain the above copyright --
-- notice, this list of conditions and the following disclaimer. --
-- 2. Redistributions in binary form must reproduce the above copyright --
-- notice, this list of conditions and the following disclaimer in --
-- the documentation and/or other materials provided with the --
-- distribution. --
-- 3. Neither the name of the copyright holder nor the names of its --
-- contributors may be used to endorse or promote products derived --
-- from this software without specific prior written permission. --
-- --
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT --
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR --
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT --
-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, --
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, --
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY --
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE --
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
-- --
------------------------------------------------------------------------------

with HAL.Time;

package BME280.Sensors is

type Sensor is limited interface;

function Check_Chip_Id
(Self : Sensor;
Expect : HAL.UInt8 := 16#60#) return Boolean is abstract;
-- Read the chip ID and check that it matches

procedure Reset
(Self : Sensor;
Timer : not null HAL.Time.Any_Delays;
Success : out Boolean) is abstract;
-- Issue a soft reset and wait until the chip is ready.

procedure Configure
(Self : Sensor;
Standby : Standby_Duration := 0.5;
Filter : IRR_Filter_Kind := Off;
SPI_3_Wire : Boolean := False;
Success : out Boolean) is abstract;
-- Configure the sensor to use IRR filtering and/or SPI 3-wire mode

procedure Start
(Self : Sensor;
Mode : Sensor_Mode := Normal;
Humidity : Oversampling_Kind := X1;
Pressure : Oversampling_Kind := X1;
Temperature : Oversampling_Kind := X1;
Success : out Boolean) is abstract;
-- Change sensor mode. Mainly used to start one measurement or enable
-- perpetual cycling of measurements and inactive periods.

function Measuring (Self : Sensor) return Boolean is abstract;
-- Check if a measurement is in progress

procedure Read_Measurement
(Self : Sensor;
Value : out Measurement;
Success : out Boolean) is abstract;
-- Read the raw measurement values from the sensor

function Temperature
(Self : Sensor;
Value : Measurement) return Deci_Celsius is abstract;
-- Get the temperature from raw values in 0.1 Celsius

function Humidity
(Self : Sensor;
Value : Measurement;
Temperature : Deci_Celsius) return Relative_Humidity is abstract;
-- Get the humidity from raw values

function Pressure
(Self : Sensor;
Value : Measurement;
Temperature : Deci_Celsius) return Pressure_Pa is abstract;
-- Get the pressure from raw values

procedure Read_Calibration
(Self : in out Sensor;
Success : out Boolean) is abstract;
-- Read the calibration constants from the sensor

end BME280.Sensors;
12 changes: 9 additions & 3 deletions components/src/environment/bme280/bme280-spi.ads
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@
-- --
------------------------------------------------------------------------------

-- This package provides an easy way to setup BME280 connected via SPI.
-- This package offers a straightforward method for setting up the BME280
-- when connected via SPI, especially useful when the use of only one sensor
-- is required. If you need multiple sensors, it is preferable to use the
-- BME280.SPI_Sensors package, which provides the appropriate tagged type.

with HAL.GPIO;
with HAL.SPI;

with BME280.Generic_Sensor;

generic
SPI_Port : not null HAL.SPI.Any_SPI_Port;
SPI_CS : not null HAL.GPIO.Any_GPIO_Point;
Expand All @@ -45,9 +50,10 @@ package BME280.SPI is
-- Read registers starting from Data'First

procedure Write
(Data : HAL.UInt8_Array;
(Address : Register_Address;
Data : HAL.UInt8;
Success : out Boolean);
-- Write registers starting from Data'First
-- Write the value to the BME280 chip register with given Address.

package Sensor is new Generic_Sensor (Read, Write);

Expand Down
Loading

0 comments on commit 49eb4e1

Please sign in to comment.