Skip to content

Commit

Permalink
power_controller: read gpio pins from device tree
Browse files Browse the repository at this point in the history
This commit is part of the effort to move configuration of hardware more
closely to the linux platform
  • Loading branch information
svenrademakers committed Feb 15, 2024
1 parent 08d5093 commit fe54604
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/app/bmc_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ impl BmcApplication {
debug!("node activated bits updated:{:#06b}.", new_state);

let led = new_state != 0;
self.power_controller.power_led(led).await?;
if let Err(e) = self.power_controller.power_led(led).await {
log::warn!("power LED error: {}", e);
}

// also update the actual power state accordingly
self.power_controller
Expand Down
8 changes: 4 additions & 4 deletions src/authentication/authentication_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use humantime::format_duration;
use std::str::Utf8Error;
use std::{fmt::Display, str::Utf8Error};
use thiserror::Error;
use tokio::time::Instant;

Expand Down Expand Up @@ -92,8 +92,8 @@ impl SchemedAuthError {
}
}

impl ToString for SchemedAuthError {
fn to_string(&self) -> String {
self.1.to_string()
impl Display for SchemedAuthError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.1)
}
}
5 changes: 0 additions & 5 deletions src/hal/gpio_definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ pub const NODE2_USBOTG_DEV: u32 = 6;
pub const NODE3_USBOTG_DEV: u32 = 10;
pub const NODE4_USBOTG_DEV: u32 = 14;

pub const PORT1_EN: u32 = 0;
pub const PORT2_EN: u32 = 4;
pub const PORT3_EN: u32 = 8;
pub const PORT4_EN: u32 = 12;

pub const PORT1_RPIBOOT: u32 = 3;
pub const PORT2_RPIBOOT: u32 = 7;
pub const PORT3_RPIBOOT: u32 = 11;
Expand Down
9 changes: 9 additions & 0 deletions src/hal/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::HashMap;
const NODE_COUNT: u8 = 4;

/// small helper macro which handles the code duplication of declaring gpio lines.
Expand Down Expand Up @@ -56,3 +57,11 @@ pub fn bit_iterator(nodes_state: u8, nodes_mask: u8) -> impl Iterator<Item = (us
(mask != 0).then_some((n as usize, state))
})
}

pub fn load_lines(chip: &gpiod::Chip) -> HashMap<String, gpiod::LineId> {
HashMap::from_iter((0..chip.num_lines()).filter_map(|i| {
chip.line_info(i)
.ok()
.map(|info| (info.name, i as gpiod::LineId))
}))
}
32 changes: 28 additions & 4 deletions src/hal/power_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,22 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use super::{gpio_definitions::*, helpers::bit_iterator, NodeId};
use super::{
helpers::{bit_iterator, load_lines},
NodeId,
};
use crate::gpio_output_array;
use anyhow::Context;
use gpiod::{Chip, Lines, Output};
use log::{debug, trace};
use std::time::Duration;
use tokio::time::sleep;

const PORT1_EN: &str = "node1-en";
const PORT2_EN: &str = "node2-en";
const PORT3_EN: &str = "node3-en";
const PORT4_EN: &str = "node4-en";

// This structure is a thin layer that abstracts away the interaction details
// with Linux's power subsystem.
pub struct PowerController {
Expand All @@ -28,7 +36,21 @@ pub struct PowerController {
impl PowerController {
pub fn new() -> anyhow::Result<Self> {
let chip1 = Chip::new("/dev/gpiochip1").context("gpiod chip1")?;
let enable = gpio_output_array!(chip1, PORT1_EN, PORT2_EN, PORT3_EN, PORT4_EN);
let lines = load_lines(&chip1);
let port1 = *lines
.get(PORT1_EN)
.ok_or(anyhow::anyhow!("cannot find PORT1_EN"))?;
let port2 = *lines
.get(PORT2_EN)
.ok_or(anyhow::anyhow!("cannot find PORT2_EN"))?;
let port3 = *lines
.get(PORT3_EN)
.ok_or(anyhow::anyhow!("cannot find PORT3_EN"))?;
let port4 = *lines
.get(PORT4_EN)
.ok_or(anyhow::anyhow!("cannot find PORT4_EN"))?;

let enable = gpio_output_array!(chip1, port1, port2, port3, port4);

Ok(PowerController { enable })
}
Expand Down Expand Up @@ -71,9 +93,11 @@ impl PowerController {
Ok(())
}

pub async fn power_led(&self, on: bool) -> std::io::Result<()> {
pub async fn power_led(&self, on: bool) -> anyhow::Result<()> {
const SYS_LED: &str = "/sys/class/leds/fp:sys/brightness";
tokio::fs::write(SYS_LED, if on { "1" } else { "0" }).await
tokio::fs::write(SYS_LED, if on { "1" } else { "0" })
.await
.context(SYS_LED)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/serial_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn serial_config(cfg: &mut web::ServiceConfig) {

#[post("/serial/status")]
async fn serial_status(serials: web::Data<SerialConnections>) -> impl Responder {
serde_json::to_string(&serials.get_state()).map_or_else(|e| e.to_string(), |s| s)
serde_json::to_string(&serials.get_state()).unwrap_or_else(|e| e.to_string())
}

pub async fn legacy_serial_set_handler(
Expand Down

0 comments on commit fe54604

Please sign in to comment.