-
-
Notifications
You must be signed in to change notification settings - Fork 112
/
Copy pathHelpers.cs
100 lines (87 loc) · 3.88 KB
/
Helpers.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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Iot.Device.Mcp3428
{
internal static class Helpers
{
/// <summary>
/// Gets the voltage value corresponding to the least significant bit based on resolution.
/// </summary>
/// <param name="res">The resolution.</param>
/// <returns>System.Double.</returns>
/// <exception cref="ArgumentOutOfRangeException">res - null</exception>
public static double LSBValue(AdcResolution res) => res switch
{
AdcResolution.Bit12 => 1e-3,
AdcResolution.Bit14 => 250e-6,
AdcResolution.Bit16 => 62.5e-6,
_ => throw new ArgumentOutOfRangeException(nameof(res)),
};
/// <summary>
/// Gets the divisor to scale raw data based on resolution. = 1/LSB
/// </summary>
/// <param name="res">The resolution.</param>
/// <returns>System.UInt16.</returns>
/// <exception cref="ArgumentOutOfRangeException">res - null</exception>
public static ushort LsbDivisor(AdcResolution res) => res switch
{
AdcResolution.Bit12 => 1000,
AdcResolution.Bit14 => 4000,
AdcResolution.Bit16 => 16000,
_ => throw new ArgumentOutOfRangeException(nameof(res)),
};
/// <summary>
/// Determine device I2C address based on the configuration pin states. Based on documentation TABLE 5-3-
/// </summary>
/// <param name="adr0">The adr0 pin state</param>
/// <param name="adr1">The adr1 pin state</param>
/// <returns>System.Int32.</returns>
public static byte I2CAddressFromPins(PinState adr0, PinState adr1)
{
byte addr = 0b1101000; // Base value from doc
int idx = (byte)adr0 << 4 + (byte)adr1;
int value = idx switch
{
0 or 0x22 => 0,
0x02 => 1,
0x01 => 2,
0x10 => 4,
0x12 => 5,
0x11 => 6,
0x20 => 3,
0x21 => 7,
_ => throw new ArgumentException("Invalid combination"),
};
return addr += (byte)value;
}
public static byte SetChannelBits(byte configByte, int channel)
{
if (channel > 3 || channel < 0)
{
throw new ArgumentException("Channel numbers are only valid 0 to 3", nameof(channel));
}
return (byte)((configByte & ~Helpers.Masks.ChannelMask) | ((byte)channel << 5));
}
public static byte SetGainBits(byte configByte, AdcGain gain) => (byte)((configByte & ~Helpers.Masks.GainMask) | (byte)gain);
public static byte SetModeBit(byte configByte, AdcMode mode) => (byte)((configByte & ~Helpers.Masks.ModeMask) | (byte)mode);
public static byte SetReadyBit(byte configByte, bool ready) => (byte)(ready ? configByte & ~Helpers.Masks.ReadyMask : configByte | Helpers.Masks.ReadyMask);
public static byte SetResolutionBits(byte configByte, AdcResolution resolution) => (byte)((configByte & ~Helpers.Masks.ResolutionMask) | (byte)resolution);
public static int UpdateFrequency(AdcResolution res) => res switch
{
AdcResolution.Bit12 => 240,
AdcResolution.Bit14 => 60,
AdcResolution.Bit16 => 15,
_ => throw new ArgumentOutOfRangeException(nameof(res)),
};
// From datasheet 5.2
public static class Masks
{
public const byte ChannelMask = 0b01100000;
public const byte GainMask = 0b00000011;
public const byte ModeMask = 0b00010000;
public const byte ReadyMask = 0b10000000;
public const byte ResolutionMask = 0b00001100;
}
}
}