J1939Spn Class¶
Static helpers for extracting SAE J1939-71 SPN (Suspect Parameter Number) values from a PGN payload using configurable scale/offset (SRS FR-J1939-002).
Inheritance Object → J1939Spn
Remarks¶
SAE J1939-71 encodes each SPN as an integer field of 1..64 bits — unsigned, or two's
complement for a signed SLOT — at a fixed byte (and bit) offset inside its PGN payload, with
a linear transform to physical units: physical = raw * resolution + offset.
Not every bit pattern is a measurement. §5.1.1 reserves the top of each SPN's raw range for
indicators — "not available", "error", reserved and parameter-specific codes — so
Extract(ReadOnlySpan<byte>, int, int, int, double, double, bool) returns a
J1939SpnValue that reports which of the two it found, rather than a bare
Double that would turn a 16-bit 0xFFFF ("not available") into a
plausible-looking 8191.875 rpm. Classify(ulong, int, bool) exposes the range check on its own.
Byte order is little-endian, matching SAE J1939-71 §5.1.3. Bit fields that start at an offset within a byte are read across byte boundaries with the low bits coming from the low-indexed byte, in line with the standard.
Methods¶
J1939Spn.Classify(ulong, int, bool) Method¶
Classifies a raw SPN field against the SAE J1939-71 §5.1.1 indicator ranges, which occupy the top of every SPN's raw range and must not be scaled into physical values.
public static CanKit.Pro.J1939.J1939SpnValueKind Classify(ulong raw, int bitLength, bool isSigned=false);
Parameters¶
raw UInt64
The field's raw bits, right-aligned and zero-extended (as returned by ExtractRaw(ReadOnlySpan<byte>, int, int, int)) — for a signed SPN the two's-complement pattern, not the sign-extended number.
bitLength Int32
Field size in bits (1..64).
isSigned Boolean
Whether the SPN is a two's-complement signed parameter.
Returns¶
Exceptions¶
ArgumentOutOfRangeException
bitLength is outside
1..64.
Remarks¶
J1939-71 defines the ranges on the field's leading byte for parameters of one byte
or wider — unsigned 0xFB parameter-specific, 0xFC..0xFD reserved,
0xFE error, 0xFF not available — so a two-byte SPN is "not available" over
0xFF00..0xFFFF and a four-byte one over 0xFF000000..0xFFFFFFFF.
For a signed parameter the same codes sit at the top of the signed range, i.e. with the
sign bit clear: 0x7B, 0x7C..0x7D, 0x7E, 0x7F.
Sub-byte parameters carry the codes as individual values at the top of the field
("terminal codes"), matching the 4-bit and 2-bit tables in §5.1.1: 4 bits reads
0xB parameter-specific, 0xC..0xD reserved, 0xE error and
0xF not available; 2 bits reads 0b10 error and 0b11 not available.
The widths the standard does not tabulate keep that shape, scaled to the field top rather
than to a leading group: 5..7 bits take all five codes (5 bits: 27 parameter-specific,
28..29 reserved, 30 error, 31 not available), and 3 bits takes the two of the 2-bit table
(0b110 error, 0b111 not available). Above a byte, widths other than
8/16/32 use the leading byte like the tabulated ones. A 1-bit field has no room for an
indicator and is always Valid, as is a signed field
narrower than a byte — J1939-71 defines no indicator codes there, and inventing some would
report real measurements as missing.
The terminal reading for the untabulated sub-byte widths is taken from how real SPNs of
those widths are defined, not from the tables (issue #99). SPN 527 "Cruise Control
States" (CCVS1, PGN 65265) is a 3-bit field whose raw 4 and 5 are Resume and Set; the
leading-group reading this replaced reported them as errors. SPN 527 also defines raw 6
as a state (AccelOverride), which this reading reports as an error — a rule by
width cannot know a parameter's own table, and a caller that has it should decode such a
field from ExtractRaw(ReadOnlySpan<byte>, int, int, int) instead. Every width above is pinned by known-answer
tests so it cannot drift silently.
J1939Spn.Extract(ReadOnlySpan<byte>, int, int, double, double, bool) Method¶
Extracts an SPN and applies the linear transform
physical = raw * +
(SRS FR-J1939-002, SAE J1939-71 §5.1.3).
public static CanKit.Pro.J1939.J1939SpnValue Extract(System.ReadOnlySpan<byte> payload, int byteOffset, int bitLength, double resolution, double offset, bool isSigned=false);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
bitLength Int32
Number of bits (1..64).
resolution Double
Physical units per raw increment.
offset Double
Physical value at raw 0.
isSigned Boolean
Whether the SPN is a two's-complement signed parameter.
Returns¶
J1939SpnValue
A J1939SpnValue that is either a measurement or one of the J1939-71 §5.1.1
indicators. It is <b>not</b> a Double: a field reading 0xFFFF is
"not available", and reporting it as 8191.875 rpm was the defect this return type exists
to prevent.
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.Extract(ReadOnlySpan<byte>, int, int, int, double, double, bool) Method¶
Extracts an SPN and applies the linear transform
physical = raw * +
(SRS FR-J1939-002, SAE J1939-71 §5.1.3).
public static CanKit.Pro.J1939.J1939SpnValue Extract(System.ReadOnlySpan<byte> payload, int byteOffset, int startBit, int bitLength, double resolution, double offset, bool isSigned=false);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
startBit Int32
Zero-based bit index within byteOffset byte (0..7). 0 = least-significant bit of the byte, as in SAE J1939-71 §5.1.3.
bitLength Int32
Number of bits (1..64).
resolution Double
Physical units per raw increment.
offset Double
Physical value at raw 0.
isSigned Boolean
Whether the SPN is a two's-complement signed parameter.
Returns¶
J1939SpnValue
A J1939SpnValue that is either a measurement or one of the J1939-71 §5.1.1
indicators. It is <b>not</b> a Double: a field reading 0xFFFF is
"not available", and reporting it as 8191.875 rpm was the defect this return type exists
to prevent.
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.ExtractRaw(ReadOnlySpan<byte>, int, int, int) Method¶
Extracts an unsigned SPN raw value from payload at byteOffset starting at bit startBit (0..7) and spanning bitLength bits (1..64), little-endian.
public static ulong ExtractRaw(System.ReadOnlySpan<byte> payload, int byteOffset, int startBit, int bitLength);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
startBit Int32
Zero-based bit index within byteOffset byte (0..7). 0 = least-significant bit of the byte, as in SAE J1939-71 §5.1.3.
bitLength Int32
Number of bits (1..64).
Returns¶
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.ExtractRawSigned(ReadOnlySpan<byte>, int, int, int) Method¶
Extracts an unsigned SPN raw value from payload at byteOffset starting at bit startBit (0..7) and spanning bitLength bits (1..64), little-endian.
public static long ExtractRawSigned(System.ReadOnlySpan<byte> payload, int byteOffset, int startBit, int bitLength);
Parameters¶
payload ReadOnlySpan<Byte>
The PGN payload bytes.
byteOffset Int32
Zero-based byte position of the first bit.
startBit Int32
Zero-based bit index within byteOffset byte (0..7). 0 = least-significant bit of the byte, as in SAE J1939-71 §5.1.3.
bitLength Int32
Number of bits (1..64).
Returns¶
Exceptions¶
ArgumentOutOfRangeException
Any argument is out of range or the
requested field extends past payload.
J1939Spn.FromRaw(ulong, int, double, double, bool) Method¶
Applies the SAE J1939-71 §5.1.1 range check and, for a measurement, the linear transform
physical = raw * +
to an already-extracted raw field.
public static CanKit.Pro.J1939.J1939SpnValue FromRaw(ulong raw, int bitLength, double resolution, double offset, bool isSigned=false);
Parameters¶
raw UInt64
The field's raw bits, right-aligned and zero-extended.
bitLength Int32
Field size in bits (1..64).
resolution Double
Physical units per raw increment.
offset Double
Physical value at raw 0.
isSigned Boolean
Whether the SPN is a two's-complement signed parameter; when true the raw bits are sign-extended before scaling.
Returns¶
J1939Spn.WriteRaw(Span<byte>, int, int, int, ulong) Method¶
Encodes an SPN raw value back into a payload buffer, little-endian. Useful for tests and for round-tripping simulated PGN payloads.
public static void WriteRaw(System.Span<byte> payload, int byteOffset, int startBit, int bitLength, ulong rawValue);
Parameters¶
byteOffset Int32
startBit Int32
bitLength Int32
rawValue UInt64
Exceptions¶
ArgumentOutOfRangeException
The requested field extends past
payload.