@@ -445,6 +445,42 @@ internal sealed class FwlibFocasClient : IFocasClient
|
||||
return (value, FocasStatusMapper.Good);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Range read for the PMC coalescer (issue #266). FWLIB's <c>pmc_rdpmcrng</c>
|
||||
/// payload is capped at 40 bytes (the IODBPMC.Data union width), so requested
|
||||
/// ranges larger than that are chunked into 32-byte sub-calls internally —
|
||||
/// callers still see one logical range, which matches the
|
||||
/// <see cref="Wire.FocasPmcCoalescer"/>'s "one wire call per group" semantics.
|
||||
/// </summary>
|
||||
public Task<(byte[]? buffer, uint status)> ReadPmcRangeAsync(
|
||||
string letter, int pathId, int startByte, int byteCount, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!_connected) return Task.FromResult<(byte[]?, uint)>((null, FocasStatusMapper.BadCommunicationError));
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (byteCount <= 0) return Task.FromResult<(byte[]?, uint)>((Array.Empty<byte>(), FocasStatusMapper.Good));
|
||||
|
||||
var addrType = FocasPmcAddrType.FromLetter(letter)
|
||||
?? throw new InvalidOperationException($"Unknown PMC letter '{letter}'.");
|
||||
var result = new byte[byteCount];
|
||||
const int chunkBytes = 32;
|
||||
var offset = 0;
|
||||
while (offset < byteCount)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var thisChunk = Math.Min(chunkBytes, byteCount - offset);
|
||||
var buf = new FwlibNative.IODBPMC { Data = new byte[40] };
|
||||
var ret = FwlibNative.PmcRdPmcRng(
|
||||
_handle, addrType, FocasPmcDataType.Byte,
|
||||
(ushort)(startByte + offset),
|
||||
(ushort)(startByte + offset + thisChunk - 1),
|
||||
(ushort)(8 + thisChunk), ref buf);
|
||||
if (ret != 0) return Task.FromResult<(byte[]?, uint)>((null, FocasStatusMapper.MapFocasReturn(ret)));
|
||||
Array.Copy(buf.Data, 0, result, offset, thisChunk);
|
||||
offset += thisChunk;
|
||||
}
|
||||
return Task.FromResult<(byte[]?, uint)>((result, FocasStatusMapper.Good));
|
||||
}
|
||||
|
||||
private uint WritePmc(FocasAddress address, FocasDataType type, object? value)
|
||||
{
|
||||
var addrType = FocasPmcAddrType.FromLetter(address.PmcLetter ?? "") ?? (short)0;
|
||||
|
||||
Reference in New Issue
Block a user