blob: 5dc39f7c7d6d2b732e13138e532711be0f93e98b [file]
// Licensed under the Apache-2.0 license
// SPDX-License-Identifier: Apache-2.0
use openprot_hal_blocking::gpio_port::GpioErrorKind;
use super::hal_impl::SgpiomBankPort;
/// Concrete SGPIOM controller owning up to `N` child bank ports (US-01, US-05).
///
/// Each slot is `Option<SgpiomBankPort>` so that absent banks (disabled in
/// Devicetree) are represented safely without crashing callers (US-07).
/// Operations on one bank do not affect any other bank.
pub struct SgpiomController<const N: usize> {
banks: [Option<SgpiomBankPort>; N],
}
impl<const N: usize> SgpiomController<N> {
/// Construct from an array of optional bank instances.
pub fn new(banks: [Option<SgpiomBankPort>; N]) -> Self {
Self { banks }
}
/// Return the total number of bank slots (present or absent).
pub fn num_banks(&self) -> usize {
N
}
/// Obtain a mutable reference to the bank at `index`.
///
/// Returns `Err(GpioErrorKind::InvalidPort)` when the index is out of range
/// or the bank slot is absent.
pub fn bank(&mut self, index: usize) -> Result<&mut SgpiomBankPort, GpioErrorKind> {
self.banks
.get_mut(index)
.and_then(Option::as_mut)
.ok_or(GpioErrorKind::InvalidPort)
}
/// Return `None` when the bank is absent; never errors.
/// Prefer this for optional-bank patterns (US-07).
pub fn bank_opt(&mut self, index: usize) -> Option<&mut SgpiomBankPort> {
self.banks.get_mut(index)?.as_mut()
}
}