Livt packages
Livt.Usb
Version 0.0.5
USB 2.0 low/full-speed PHY, host transfers, device discovery, HID keyboard, and read-only mass storage for Livt.
Published files (57)
src/host/ControlTransfer.lvt
namespace Livt.Usb.Host
using Livt.Usb
/**
* Scheduled standard/class request helper borrowing a single-owner controller.
* Completion remains retained for the caller to inspect and release. No class policy.
*/
component ControlTransfer
{
// Borrowed transfer slot; caller serializes all uses with other transfers.
controller: IHostController
/**
* The controller outlives this helper and shares its clock/reset context.
*/
new(controller: IHostController)
{
this.controller = controller
}
/**
* Stages an eight-byte request and waits at most 500 frames for its completion.
* Supports IN data or no-data requests; OUT payload uses IHostController directly.
*/
public fn Run(address: int, packetSize: int, requestType: byte, request: byte,
value: int, index: int, length: int) bool
{
if (controller.GetState() != TransferState.Idle) { return false }
controller.TryClearStaging()
for (var position: byte = 0; position < 8; position++) {
var valueByte: byte
match position
{
0 =>
{
valueByte = requestType
}
1 =>
{
valueByte = request
}
2 =>
{
valueByte = (value & 255) as byte
}
3 =>
{
valueByte = ((value >> 8) & 255) as byte
}
4 =>
{
valueByte = (index & 255) as byte
}
5 =>
{
valueByte = ((index >> 8) & 255) as byte
}
6 =>
{
valueByte = (length & 255) as byte
}
_ =>
{
valueByte = ((length >> 8) & 255) as byte
}
}
if (!controller.TryStageSetup(valueByte)) { return false }
}
var direction = TransferDirection.HostToDevice
if (length != 0) { direction = TransferDirection.DeviceToHost }
if (controller.TrySubmit(address, 0, TransferKind.Control, direction, packetSize, length, 500, 0) != SubmissionResult.Accepted) { return false }
while (controller.GetState() == TransferState.Active) {}
return controller.GetResult() == TransferResult.Success
}
}