forked from nanoframework/nanoFramework.IoT.Device
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Lps25h.cs
117 lines (100 loc) · 3.59 KB
/
Lps25h.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Buffers.Binary;
using System.Device.I2c;
using System.Device.Model;
using System.Diagnostics;
using UnitsNet;
namespace Iot.Device.Lps25h
{
/// <summary>
/// LPS25H - Piezoresistive pressure and thermometer sensor
/// </summary>
[Interface("LPS25H - Piezoresistive pressure and thermometer sensor")]
public class Lps25h : IDisposable
{
private const byte ReadMask = 0x80;
private I2cDevice _i2c;
/// <summary>
/// Lps25h - Pressure and temperature sensor
/// </summary>
public Lps25h(I2cDevice i2cDevice)
{
_i2c = i2cDevice ?? throw new ArgumentNullException(nameof(i2cDevice));
// Highest resolution for both pressure and temperature sensor
byte resolution = Read(Register.ResolutionMode);
resolution |= 0b1111;
WriteByte(Register.ResolutionMode, resolution);
byte control1orig = Read(Register.Control1);
// 7 - PD - power down control - 1 means active
// 6-4 - output data rate - 0b100 means 25Hz for both sensors
// 3 - interrupt circuit enable - 0 means disabled
// 2 - block data update - 1 means update when both MSB and LSB are read
// 1 - reset auto-zero - 0 means disable
// 0 - SPI mode - we don't care what value since we use I2c, leave at default (0)
byte control1 = 0b1100_0100;
WriteByte(Register.Control1, control1);
}
/// <summary>
/// Temperature
/// </summary>
[Telemetry]
public Temperature Temperature => Temperature.FromDegreesCelsius(42.5f + ReadInt16(Register.Temperature) / 480f);
/// <summary>
/// Pressure
/// </summary>
[Telemetry]
public Pressure Pressure => Pressure.FromHectopascals(ReadInt24(Register.Pressure) / 4096.0);
private static int ReadInt24LittleEndian(SpanByte buff)
{
Debug.Assert(buff.Length == 3, "Buffer must be 3 bytes long");
byte mostSignificantByte = buff[2];
SpanByte b = new byte[4]
{
buff[0],
buff[1],
mostSignificantByte,
(mostSignificantByte >> 7) != 0 ? (byte)0xff : (byte)0x00,
};
return BinaryPrimitives.ReadInt32LittleEndian(b);
}
private void WriteByte(Register register, byte data)
{
SpanByte buff = new byte[2]
{
(byte)register,
data
};
_i2c.Write(buff);
}
private int ReadInt24(Register register)
{
SpanByte val = new byte[3];
Read(register, val);
return ReadInt24LittleEndian(val);
}
private short ReadInt16(Register register)
{
SpanByte val = new byte[2];
Read(register, val);
return BinaryPrimitives.ReadInt16LittleEndian(val);
}
private void Read(Register register, SpanByte buffer)
{
_i2c.WriteByte((byte)((byte)register | ReadMask));
_i2c.Read(buffer);
}
private byte Read(Register register)
{
_i2c.WriteByte((byte)((byte)register | ReadMask));
return _i2c.ReadByte();
}
/// <inheritdoc/>
public void Dispose()
{
_i2c?.Dispose();
_i2c = null!;
}
}
}