@@ -232,6 +232,49 @@ public interface IFocasClient : IDisposable
|
||||
int depth, CancellationToken cancellationToken)
|
||||
=> Task.FromResult<IReadOnlyList<FocasAlarmHistoryEntry>>(Array.Empty<FocasAlarmHistoryEntry>());
|
||||
|
||||
/// <summary>
|
||||
/// Write a contiguous range of PMC bytes in a single wire call (FOCAS
|
||||
/// <c>pmc_wrpmcrng</c>) for the given <paramref name="letter"/> starting at
|
||||
/// <paramref name="startByte"/>, copying every byte from <paramref name="bytes"/>.
|
||||
/// Plan PR F4-c (issue #270). The wire call is byte-addressed; bit-level writes
|
||||
/// are handled upstream by the <see cref="WritePmcBitAsync"/> read-modify-write
|
||||
/// wrapper which performs <c>pmc_rdpmcrng</c> + bit mask + this method on a
|
||||
/// per-byte semaphore (so two concurrent bit writes against the same byte don't
|
||||
/// lose one another's update).
|
||||
/// <para>Default impl returns <see cref="FocasStatusMapper.BadNotSupported"/> so
|
||||
/// transport variants that haven't yet routed the write keep compiling — those
|
||||
/// variants surface BadNotSupported on PMC writes until the wire client is
|
||||
/// extended.</para>
|
||||
/// </summary>
|
||||
Task<uint> WritePmcRangeAsync(
|
||||
string letter, int pathId, int startByte, byte[] bytes, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(FocasStatusMapper.BadNotSupported);
|
||||
|
||||
/// <summary>
|
||||
/// Read-modify-write one bit within a PMC byte (Plan PR F4-c, issue #270). The
|
||||
/// wire call <c>pmc_wrpmcrng</c> is byte-addressed, so the driver reads the
|
||||
/// parent byte first, masks the target bit, then writes the byte back. Default
|
||||
/// impl uses <see cref="ReadPmcRangeAsync"/> + <see cref="WritePmcRangeAsync"/>
|
||||
/// so transport variants get correct RMW semantics for free; the FWLIB-backed
|
||||
/// client overrides this with a per-byte semaphore so two concurrent bit writes
|
||||
/// against the same byte serialise.
|
||||
/// </summary>
|
||||
async Task<uint> WritePmcBitAsync(
|
||||
string letter, int pathId, int byteAddress, int bitIndex, bool newValue,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (bitIndex is < 0 or > 7) return FocasStatusMapper.BadOutOfRange;
|
||||
var (buf, status) = await ReadPmcRangeAsync(letter, pathId, byteAddress, 1, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
if (status != FocasStatusMapper.Good || buf is null || buf.Length < 1) return status;
|
||||
var current = buf[0];
|
||||
var updated = newValue
|
||||
? (byte)(current | (1 << bitIndex))
|
||||
: (byte)(current & ~(1 << bitIndex));
|
||||
return await WritePmcRangeAsync(letter, pathId, byteAddress, new[] { updated }, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a contiguous range of PMC bytes in a single wire call (FOCAS
|
||||
/// <c>pmc_rdpmcrng</c> with byte data type) for the given <paramref name="letter"/>
|
||||
|
||||
Reference in New Issue
Block a user