35 if (!
g.frequency.isUnspecified()) {
39 ? caps.clockless_frequency
55 fl::u32 effective_clock_hz, fl::u16 max_ticks,
57 if (window.isUnspecified()) {
61 if (effective_clock_hz == 0u) {
64 const fl::u64 kBillion = 1000000000ULL;
65 const fl::u64 lo_num =
static_cast<fl::u64
>(window.min_ns) * effective_clock_hz;
66 const fl::u64 hi_num =
static_cast<fl::u64
>(window.max_ns) * effective_clock_hz;
68 fl::u64 n_lo_64 = (lo_num + kBillion - 1ULL) / kBillion;
69 fl::u64 n_hi_64 = hi_num / kBillion;
73 if (n_lo_64 > n_hi_64) {
76 if (max_ticks != 0u && n_lo_64 >
static_cast<fl::u64
>(max_ticks)) {
87 if (cap.isUnspecified()) {
92 if (chip.t0h_window.isUnspecified() && chip.t0l_window.isUnspecified()
93 && chip.t1h_window.isUnspecified() && chip.t1l_window.isUnspecified()) {
96 fl::u16 d_lo = cap.min_divider == 0u ? 1u : cap.min_divider;
97 fl::u16 d_hi = cap.max_divider == 0u ? d_lo : cap.max_divider;
101 for (fl::u32 d = d_lo; d <= d_hi; ++d) {
105 fl::u32 effective_clock = cap.base_clock_hz /
static_cast<fl::u32
>(d);
106 if (effective_clock == 0u) {
109 if (
canHitPhase(effective_clock, cap.max_phase_ticks, chip.t0h_window) &&
110 canHitPhase(effective_clock, cap.max_phase_ticks, chip.t0l_window) &&
111 canHitPhase(effective_clock, cap.max_phase_ticks, chip.t1h_window) &&
112 canHitPhase(effective_clock, cap.max_phase_ticks, chip.t1l_window)) {
124 bool found_lo =
false;
137 return b.count() == (hi - lo + 1u);
153 if (
g.protocol != r.protocol) {
156 if (!
g.data_pins.acceptsAll(r.data_pins)) {
163 if (!
g.clock_pins.accepts(r.clock_pin)) {
173 fl::u32 requested_count = r.data_pins.count();
174 if (
g.max_concurrent != 0u && requested_count >
static_cast<fl::u32
>(
g.max_concurrent)) {
177 if (r.frequency_hz.has_value()) {
201 if (groups.empty()) {
205 if (request.data_pins.none()) {
213 const fl::u32 requested_count = request.data_pins.count();
214 if (caps.max_total_channels != 0u &&
215 requested_count >
static_cast<fl::u32
>(caps.max_total_channels)) {
220 for (fl::size i = 0; i < groups.size(); ++i) {
Free function that decides whether a ChannelRequest can be served by a driver's published capability ...
Declarative driver capabilities + channel-request types for the Channel Manager's predicate / depende...
HandleResult checkOneGroup(const DriverCapabilities &caps, const PinGroup &g, const ChannelRequest &r) FL_NO_EXCEPT
bool isContiguousBitset(const PinBitset &b) FL_NO_EXCEPT
bool isClocklessTimingCompatible(const ClocklessTimingCapability &cap, const ChipsetClocklessTiming &chip) FL_NO_EXCEPT
bool driverProtocolGate(const DriverCapabilities &caps, Protocol p) FL_NO_EXCEPT
FreqRange effectiveFrequencyRange(const DriverCapabilities &caps, const PinGroup &g) FL_NO_EXCEPT
fl::u8 strength(HandleResult r) FL_NO_EXCEPT
bool canHitPhase(fl::u32 effective_clock_hz, fl::u16 max_ticks, const NanosRange &window) FL_NO_EXCEPT
fl::bitset_fixed< kPinSetCapacity > PinBitset
HandleResult canMatch(const DriverCapabilities &caps, fl::span< const PinGroup > groups, const ChannelRequest &request) FL_NO_EXCEPT
Test a request (single-pin OR multi-pin ganged) against a driver's published capability data.
@ NoPinPair
clock pin not in the matching group's allowlist
@ NoProtocol
driver doesn't support the requested Protocol
@ NoPin
data pin not in any matching group's allowlist
@ NoCapacity
group full / driver-total cap reached
@ NoTiming
chipset tolerance windows can't be hit
@ NoFrequency
requested freq outside driver/group range
InputGamut g FL_NO_EXCEPT
@ Spi
Data + clock (APA102, SK9822, ...)
@ Clockless
Single data line + async timing (WS2812, SK6812, ...)
static constexpr fl::u32 kPinSetCapacity
Maximum pin number representable in a PinSet's bitset.
Base definition for an LED controller.
constexpr bool isUnspecified() const FL_NO_EXCEPT
constexpr bool contains(fl::u32 hz) const FL_NO_EXCEPT