blob: 3bedcfbf7f3686c19debd4d33827a91e275fd872 [file] [edit]
/* Copyright 2023 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <stdlib.h>
#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/shell/shell.h>
#include <zephyr/drivers/usb/usb_dc.h>
#include "view.h"
#include "meas.h"
#include "model.h"
#include "mask.h"
static int cmd_meas_cc2(const struct shell *shell, size_t argc, char **argv)
{
int32_t out;
if (argc == 2 && *argv[1] == 'c') {
meas_vcon_c(&out);
shell_print(shell, "current of cc2: %i", out);
} else {
meas_cc2_v(&out);
shell_print(shell, "voltage of cc2: %i", out);
}
return 0;
}
static int cmd_meas_vb(const struct shell *shell, size_t argc, char **argv)
{
int32_t out;
if (argc == 2 && *argv[1] == 'c') {
meas_vbus_c(&out);
shell_print(shell, "current of vbus: %i", out);
} else {
meas_vbus_v(&out);
shell_print(shell, "voltage of vbus: %i", out);
}
return 0;
}
static int cmd_meas_cc1(const struct shell *shell, size_t argc, char **argv)
{
int32_t out;
meas_cc1_v(&out);
shell_print(shell, "voltage of cc1: %i", out);
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(sub_meas, SHELL_CMD(cc1, NULL, "Print cc1 voltage.", cmd_meas_cc1),
SHELL_CMD(cc2, NULL, "Print cc2 voltage or current.", cmd_meas_cc2),
SHELL_CMD(vb, NULL, "Print vbus voltage or current.", cmd_meas_vb),
SHELL_SUBCMD_SET_END);
SHELL_CMD_REGISTER(meas, &sub_meas, "Reads current or voltage of the selected line", NULL);
static int cmd_version(const struct shell *shell, size_t argc, char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
shell_print(shell, "Twinkie version 2.2.2");
return 0;
}
SHELL_CMD_REGISTER(version, NULL, "Show Twinkie version", cmd_version);
static int cmd_reset(const struct shell *shell, size_t argc, char **argv)
{
start_snooper(false);
reset_snooper();
usb_dc_reset();
start_snooper(true);
return 0;
}
SHELL_CMD_REGISTER(reset, NULL, "Resets the Twinkie device", cmd_reset);
static int cmd_snoop(const struct shell *shell, size_t argc, char **argv)
{
if (argc >= 2) {
switch (*argv[1]) {
case '0':
view_set_snoop(0);
break;
case '1':
view_set_snoop(CC1_CHANNEL_BIT);
break;
case '2':
view_set_snoop(CC2_CHANNEL_BIT);
break;
case '3':
view_set_snoop(CC1_CHANNEL_BIT | CC2_CHANNEL_BIT);
}
}
return 0;
}
SHELL_CMD_REGISTER(snoop, NULL, "Sets the snoop CC line, 0 for neither, 3 for both", cmd_snoop);
static int cmd_start(const struct shell *shell, size_t argc, char **argv)
{
start_snooper(true);
return 0;
}
SHELL_CMD_REGISTER(start, NULL, "Start snooper", cmd_start);
static int cmd_stop(const struct shell *shell, size_t argc, char **argv)
{
usb_dc_reset();
start_snooper(false);
return 0;
}
SHELL_CMD_REGISTER(stop, NULL, "Stop snooper", cmd_stop);
static int cmd_role(const struct shell *shell, size_t argc, char **argv, void *data)
{
snooper_mask_t pull_mask = (uint32_t)data;
set_role(pull_mask);
return 0;
}
SHELL_SUBCMD_DICT_SET_CREATE(role_options, cmd_role, (sink, SINK_BIT, "sink"),
(source, 0, "source"));
SHELL_CMD_REGISTER(role, &role_options, "Sets role as sink or source", cmd_role);
static int cmd_cc1_pull(const struct shell *shell, size_t argc, char **argv, void *data)
{
snooper_mask_t pull_mask = (uint32_t)data;
set_role(pull_mask & CC1_CHANNEL_BIT);
return 0;
}
static int cmd_cc2_pull(const struct shell *shell, size_t argc, char **argv, void *data)
{
snooper_mask_t pull_mask = (uint32_t)data;
set_role(pull_mask & CC2_CHANNEL_BIT);
return 0;
}
SHELL_SUBCMD_DICT_SET_CREATE(cc1_options, cmd_cc1_pull, (rd, 0, "resistor disconnected"),
(ru, 1, "default resistor"), (r1, 2, "1.5A resistor"),
(r3, 3, "3A resistor"));
SHELL_SUBCMD_DICT_SET_CREATE(cc2_options, cmd_cc2_pull, (rd, 0, "resistor disconnected"),
(ru, 1, "default resistor"), (r1, 2, "1.5A resistor"),
(r3, 3, "3A resistor"));
SHELL_STATIC_SUBCMD_SET_CREATE(
sub_rpull, SHELL_CMD(cc1, &cc1_options, "Sets pull resistor on cc1", cmd_cc1_pull),
SHELL_CMD(cc2, &cc2_options, "Sets pull resistor on cc2", cmd_cc2_pull),
SHELL_SUBCMD_SET_END);
SHELL_CMD_REGISTER(rpull, &sub_rpull, "Place pull resistor", NULL);
static int cmd_output(const struct shell *shell, size_t argc, char **argv, void *data)
{
bool p = (int)data;
set_empty_print(p);
return 0;
}
SHELL_SUBCMD_DICT_SET_CREATE(output_options, cmd_output, (cont, true, "continuous output"),
(pd_only, false, "output only on receiving pd messages"));
SHELL_CMD_REGISTER(output, &output_options,
"Sets console output as continuous or only on receiving PD messages",
cmd_output);
static int cmd_auto_stop(const struct shell *shell, size_t argc, char **argv, void *data)
{
bool p = (bool)data;
set_auto_stop(p);
return 0;
}
SHELL_SUBCMD_DICT_SET_CREATE(cmd_auto_stop_options, cmd_auto_stop,
(on, true, "twinkie turns off when no reciever is connected"),
(off, false,
"twinkie continues sending even when there is no response "
"from host (WARNING: may cause data corruption or desync)"));
SHELL_CMD_REGISTER(auto_stop, &cmd_auto_stop_options,
"Sets to automatically turn off when no valid receiver is connected",
cmd_auto_stop);
static int cmd_sleep_time(const struct shell *shell, size_t argc, char **argv, void *data)
{
if (argc == 2) {
set_sleep_time(atoi(argv[1]));
shell_print(shell, "%d", atoi(argv[1]));
}
return 0;
}
SHELL_CMD_REGISTER(sleep_time, NULL,
"Sets console output as continuous or only on receiving PD messages",
cmd_sleep_time);
static int cmd_status(const struct shell *shell, size_t argc, char **argv)
{
char p[50];
print_status(p, 0);
shell_print(shell, "%s", p);
print_status(p, 1);
shell_print(shell, "%s", p);
return 0;
}
SHELL_CMD_REGISTER(status, NULL, "Print the twinkie status", cmd_status);