blob: 68c876ec83195932f6fc6fec3827cc6cc3682d38 [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "hps/daemon/hps_daemon.h"
#include <stdint.h>
#include <string.h>
#include <base/check.h>
#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/logging.h>
#include <base/task/thread_pool/thread_pool_instance.h>
#include <brillo/flag_helper.h>
#include <brillo/syslog_logging.h>
#include "hps/hal/fake_dev.h"
#include "hps/hal/i2c.h"
#include "hps/hal/mcp.h"
#include "hps/hps_impl.h"
#include "hps/utils.h"
int main(int argc, char* argv[]) {
base::AtExitManager at_exit;
DEFINE_string(bus, "/dev/i2c-hps-controller", "I2C device");
DEFINE_string(hps_dev, "/dev/cros-hps", "HPS device");
DEFINE_uint32(addr, 0x30, "I2C address of module");
DEFINE_uint32(speed, 200, "I2C bus speed in KHz");
DEFINE_bool(mcp, false, "Use MCP2221A connection");
DEFINE_bool(test, false, "Use internal test fake");
DEFINE_bool(skipboot, false, "Skip boot sequence");
DEFINE_int64(version, -1, "Override MCU firmware file version");
DEFINE_string(mcu_fw_image, "", "MCU firmware file");
DEFINE_string(fpga_bitstream, "", "FPGA bitstream file");
DEFINE_string(fpga_app_image, "", "FPGA application file");
DEFINE_uint32(poll_timer_ms, 500,
"How frequently to poll HPS hardware for results (in ms).");
brillo::FlagHelper::Init(argc, argv, "hps_daemon - HPS services daemon");
// Always log to syslog and log to stderr if we are connected to a tty.
brillo::InitLog(brillo::kLogToSyslog | brillo::kLogToStderrIfTty);
uint32_t version;
if (FLAGS_version < 0) {
if (!hps::ReadVersionFromFile(base::FilePath(FLAGS_mcu_fw_image),
&version)) {
return 1;
}
} else {
version = base::checked_cast<uint32_t>(FLAGS_version);
}
// Determine the hardware connection.
std::unique_ptr<hps::DevInterface> dev;
uint8_t addr = base::checked_cast<uint8_t>(FLAGS_addr);
if (FLAGS_mcp) {
dev = hps::Mcp::Create(addr, FLAGS_speed);
} else if (FLAGS_test) {
// Initialise the fake device as already booted so that
// features can be enabled/disabled.
auto fake = std::make_unique<hps::FakeDev>();
fake->SkipBoot();
dev = std::move(fake);
} else {
dev = hps::I2CDev::Create(FLAGS_bus, addr, FLAGS_hps_dev);
}
CHECK(dev) << "Hardware device failed to initialise";
int exit_code =
hps::HpsDaemon(std::move(dev), FLAGS_poll_timer_ms, FLAGS_skipboot,
version, base::FilePath(FLAGS_mcu_fw_image),
base::FilePath(FLAGS_fpga_bitstream),
base::FilePath(FLAGS_fpga_app_image))
.Run();
LOG(INFO) << "HPS Service ended with exit_code=" << exit_code;
return exit_code;
}