blob: f56a84c5c88af4456608eb573bcb71411733c1ed [file]
// Copyright 2022 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.
// Package hpsutil contains functionality used by the HPS tast tests.
package hpsutil
import (
"context"
"time"
"chromiumos/tast/errors"
"chromiumos/tast/ssh"
"chromiumos/tast/testing"
)
// HasHpsContext is an interface for fixture values that contain a HpsContext instance. It allows
// retrieval of the underlying HpsContext object.
type HasHpsContext interface {
HpsContext(ctx context.Context, outDir string) *HpsContext
}
// HpsContext stores common information passed around when calling hps tool and flashing the devboards.
type HpsContext struct {
Ctx context.Context
// Script to power-cycle p2 devboard.
p2PowerCycleFilename string
// Used as prefix for command logs.
CmdNum int
deviceType DeviceType
// String passed to the `hps` tool.
Device string
// Directory where the test results are stored.
OutDir string
// Ignore HPS error register errors when set to false.
FailOnHPSErrorRegister bool
DutConn *ssh.Conn
}
// NewHpsContext creates new HpsContext.
func NewHpsContext(ctx context.Context, p2PowerCycleFilename string, deviceType DeviceType, outDir string, dutConn *ssh.Conn) (*HpsContext, error) {
var device string
switch deviceType {
case DeviceTypeDevboard:
device = devboardDevice
case DeviceTypeBuiltin:
device = builtinDevice
default:
return nil, errors.New("Unhandled deviceType")
}
return &HpsContext{
Ctx: ctx,
p2PowerCycleFilename: p2PowerCycleFilename,
CmdNum: 1,
deviceType: deviceType,
Device: device,
OutDir: outDir,
FailOnHPSErrorRegister: true,
DutConn: dutConn,
}, nil
}
// HpsContext returns the HpsContext instance.
// It implements the HasChrome interface.
func (hctx *HpsContext) HpsContext(ctx context.Context, outDir string) *HpsContext {
return &HpsContext{
Ctx: ctx,
p2PowerCycleFilename: hctx.p2PowerCycleFilename,
CmdNum: 1,
deviceType: hctx.deviceType,
Device: hctx.Device,
OutDir: outDir,
FailOnHPSErrorRegister: true,
}
}
// PowerCycle power-cycles the HPS, and makes sure it's usable afterwards.
func (hctx *HpsContext) PowerCycle() error {
switch hctx.deviceType {
case DeviceTypeDevboard:
if err := RunWithLog(hctx, hctx.OutDir, "proto2-power-cycle", &hctx.CmdNum,
"python", hctx.p2PowerCycleFilename); err != nil {
return err
}
if err := testing.Sleep(hctx.Ctx, firmwareVerificationDelay); err != nil {
return errors.Wrap(err, "sleep failed")
}
if err := unbindUsbHid(hctx); err != nil {
return err
}
case DeviceTypeBuiltin:
// TODO(mblsha): Rely on hpsd to flash the firmware after http://b/202680181 is fixed.
// This might fail if the hpsd wasn't running, ignore this error.
RunWithLog(hctx, hctx.OutDir, "stop_hpsd", &hctx.CmdNum, "stop", "hpsd")
outDir := hctx.OutDir
cmdNum := &hctx.CmdNum
if err := RunWithLog(hctx, outDir, "gpio_0", cmdNum, "gpioset", "0", "327=0"); err != nil {
return err
}
// If the power is off for two short a time, the MCU won't have properly lost power and weird stuff can happen.
if err := testing.Sleep(hctx.Ctx, time.Second*1); err != nil {
return errors.Wrap(err, "sleep failed")
}
if err := RunWithLog(hctx, outDir, "gpio_1", cmdNum, "gpioset", "0", "327=1"); err != nil {
return err
}
if err := testing.Sleep(hctx.Ctx, firmwareVerificationDelay); err != nil {
return errors.Wrap(err, "sleep failed")
}
if err := RunBuiltinI2CDetect(hctx); err != nil {
return err
}
default:
return errors.New("Unhandled deviceType")
}
return nil
}