blob: d8f1a6cd21c1c2f7e4325a2f3f1fa45940d3ccd0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, 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.
*/
#include "os/mynewt.h"
#if MYNEWT_VAL(DRV2605_CLI)
#include <string.h>
#include <errno.h>
#include "console/console.h"
#include "shell/shell.h"
#include "drv2605_priv.h"
#include "drv2605/drv2605.h"
#include "sensor/sensor.h"
#include "parse/parse.h"
static int drv2605_shell_cmd(int argc, char **argv);
static struct shell_cmd drv2605_shell_cmd_struct = {
.sc_cmd = "drv2605",
.sc_cmd_func = drv2605_shell_cmd
};
static int
drv2605_shell_err_too_many_args(char *cmd_name)
{
console_printf("Error: too many arguments for command \"%s\"\n",
cmd_name);
return EINVAL;
}
static int
drv2605_shell_err_too_few_args(char *cmd_name)
{
console_printf("Error: too few arguments for command \"%s\"\n",
cmd_name);
return EINVAL;
}
static int
drv2605_shell_err_unknown_arg(char *cmd_name)
{
console_printf("Error: unknown argument \"%s\"\n",
cmd_name);
return EINVAL;
}
static int
drv2605_shell_err_invalid_arg(char *cmd_name)
{
console_printf("Error: invalid argument \"%s\"\n",
cmd_name);
return EINVAL;
}
static int
drv2605_shell_help(void)
{
console_printf("%s cmd [flags...]\n", drv2605_shell_cmd_struct.sc_cmd);
console_printf("cmd:\n");
console_printf("\tchip_id\n");
console_printf("\tload_cal [brake_factor loop_gain lra_sample_time lra_blanking_time lra_idiss_time auto_cal_time lra_zc_det_time]\n");
console_printf("\tload_rom [up to 8 uint8_t]\n");
console_printf("\top_mode [reset | rom | pwm | analog | rtp | diag | cal]\n");
console_printf("\tpower_mode [deep | standby | active]\n");
console_printf("\ttrigger\n");
console_printf("\tpeek [reg]\n");
console_printf("\tpoke [reg value]\n");
console_printf("\tdump_cal\n");
console_printf("\tdump_all\n");
return 0;
}
static int
drv2605_shell_cmd_load_rom(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
uint8_t waveform[8] = {0};
uint8_t len = argc-2;
uint8_t i;
struct sensor_itf *itf;
if (argc > 10) {
return drv2605_shell_err_too_many_args(argv[1]);
} else if (argc < 3) {
return drv2605_shell_err_too_few_args(argv[1]);
}
for (i = 0; i<len;i++) {
waveform[i] = parse_ll_bounds(argv[i+2], 0, 255, &rc);
if (rc != 0) {
goto err;
}
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
rc = drv2605_load_rom(itf, waveform, len);
if (rc) {
console_printf("load failed %d\n", rc);
}else{
console_printf("load succeeded\n");
}
return 0;
err:
return rc;
}
static int
drv2605_shell_cmd_trigger_rom(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
struct sensor_itf *itf;
if (argc > 3) {
return drv2605_shell_err_too_many_args(argv[1]);
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
rc = drv2605_trigger_rom(itf);
if (rc) {
console_printf("trigger failed %d\n", rc);
}else{
console_printf("trigger succeeded\n");
}
return rc;
}
static int
drv2605_shell_cmd_get_chip_id(int argc, char **argv, struct drv2605 *drv2605)
{
uint8_t id;
int rc;
struct sensor_itf *itf;
if (argc > 3) {
return drv2605_shell_err_too_many_args(argv[1]);
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
/* Display the chip id */
if (argc == 2) {
rc = drv2605_get_chip_id(itf, &id);
if (rc) {
console_printf("chipid failed %d\n", rc);
}else{
console_printf("0x%02X\n", id);
}
}
return 0;
}
static int
drv2605_shell_cmd_dump_cal(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
uint8_t tmp[3];
struct sensor_itf *itf;
if (argc > 3) {
return drv2605_shell_err_too_many_args(argv[1]);
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
rc = drv2605_readlen(itf, DRV2605_AUTO_CALIBRATION_COMPENSATION_RESULT_ADDR, &tmp[0], sizeof(tmp));
if (rc) {
console_printf("dump failed %d\n", rc);
goto err;
}
console_printf("\nDRV2605_CALIBRATED_COMP: 0x%02X\nDRV2605_CALIBRATED_BEMF: 0x%02X\nDRV2605_CALIBRATED_BEMF_GAIN: %0d\n", tmp[0], tmp[1], tmp[2] & 0x03);
return 0;
err:
return rc;
}
static int
drv2605_shell_cmd_peek(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
uint8_t value;
uint8_t reg;
struct sensor_itf *itf;
if (argc > 3) {
return drv2605_shell_err_too_many_args(argv[1]);
} else if (argc < 3) {
return drv2605_shell_err_too_few_args(argv[1]);
}
reg = parse_ll_bounds(argv[2], 0, 34, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
rc = drv2605_read8(itf, reg, &value);
if (rc) {
console_printf("peek failed %d\n", rc);
}else{
console_printf("value: 0x%02X\n", value);
}
return 0;
}
static int
drv2605_shell_cmd_poke(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
uint8_t reg;
uint8_t value;
struct sensor_itf *itf;
if (argc > 4) {
return drv2605_shell_err_too_many_args(argv[1]);
} else if (argc < 4) {
return drv2605_shell_err_too_few_args(argv[1]);
}
reg = parse_ll_bounds(argv[2], 0, 34, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
value = parse_ll_bounds(argv[3], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[3]);
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
rc = drv2605_write8(itf, reg, value);
if (rc) {
console_printf("poke failed %d\n", rc);
}else{
console_printf("wrote: 0x%02X to 0x%02X\n", value, reg);
}
return 0;
}
static int
drv2605_shell_cmd_dump_all(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
uint8_t value;
int i;
struct sensor_itf *itf;
if (argc > 3) {
return drv2605_shell_err_too_many_args(argv[1]);
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
for (i=0; i<=34; i++){
rc = drv2605_read8(itf, i, &value);
if (rc) {
console_printf("dump failed %d\n", rc);
goto err;
}else{
console_printf("reg 0x:%02X = 0x%02X\n", i, value);
}
}
return 0;
err:
return rc;
}
static int
drv2605_shell_load_cal(int argc, char **argv, struct drv2605_cal *cal)
{
int rc;
cal->brake_factor = parse_ll_bounds(argv[2], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
cal->loop_gain = parse_ll_bounds(argv[3], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
cal->lra_sample_time = parse_ll_bounds(argv[4], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
cal->lra_blanking_time = parse_ll_bounds(argv[5], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
cal->lra_idiss_time = parse_ll_bounds(argv[6], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
cal->auto_cal_time = parse_ll_bounds(argv[7], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
cal->lra_zc_det_time = parse_ll_bounds(argv[8], 0, 255, &rc);
if (rc != 0) {
return drv2605_shell_err_invalid_arg(argv[2]);
}
return 0;
}
static int
drv2605_shell_cmd_load_cal(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
if(argc == 2) {
return drv2605_default_cal(&drv2605->cfg.cal);
}else if (argc > 9) {
return drv2605_shell_err_too_many_args(argv[1]);
} else if (argc < 9) {
return drv2605_shell_err_too_few_args(argv[1]);
}
rc = drv2605_shell_load_cal(argc, argv, &drv2605->cfg.cal);
if (rc) {
console_printf("load_cal failed %d\n", rc);
goto err;
}else{
console_printf("load_cal succeeded\n");
}
return 0;
err:
return rc;
}
static int
drv2605_shell_cmd_power_mode(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
enum drv2605_power_mode mode;
struct sensor_itf *itf;
if(strcmp(argv[2],"off") == 0) {
mode = DRV2605_POWER_OFF;
}else if(strcmp(argv[2],"standby") == 0) {
mode = DRV2605_POWER_STANDBY;
}else if(strcmp(argv[2],"active") == 0) {
mode = DRV2605_POWER_ACTIVE;
}else {
return drv2605_shell_err_unknown_arg(argv[2]);
}
itf = SENSOR_GET_ITF(&(drv2605->sensor));
rc = drv2605_set_power_mode(itf, mode);
if (rc) {
console_printf("power_mode failed %d\n", rc);
goto err;
}else{
console_printf("power_mode succeeded\n");
}
return 0;
err:
return rc;
}
static int
drv2605_shell_cmd_op_mode(int argc, char **argv, struct drv2605 *drv2605)
{
int rc;
if(strcmp(argv[2],"rom") == 0) {
drv2605->cfg.op_mode = DRV2605_OP_ROM;
}else if(strcmp(argv[2],"reset") == 0) {
drv2605->cfg.op_mode = DRV2605_OP_RESET;
}else if(strcmp(argv[2],"pwm") == 0) {
drv2605->cfg.op_mode = DRV2605_OP_PWM;
}else if(strcmp(argv[2],"analog") == 0) {
drv2605->cfg.op_mode = DRV2605_OP_ANALOG;
}else if(strcmp(argv[2],"rtp") == 0) {
drv2605->cfg.op_mode = DRV2605_OP_RTP;
}else if(strcmp(argv[2],"diag") == 0) {
drv2605->cfg.op_mode = DRV2605_OP_DIAGNOSTIC;
}else if(strcmp(argv[2],"cal") == 0) {
drv2605->cfg.op_mode = DRV2605_OP_CALIBRATION;
}else {
return drv2605_shell_err_unknown_arg(argv[2]);
}
rc = drv2605_config(drv2605, &drv2605->cfg);
if (rc) {
console_printf("op_mode failed %d\n", rc);
goto err;
}else{
console_printf("op_mode succeeded\n");
}
return 0;
err:
return rc;
}
static int
drv2605_shell_cmd(int argc, char **argv)
{
struct os_dev * dev;
struct drv2605 * drv2605;
dev = os_dev_open("drv2605_0", OS_TIMEOUT_NEVER, NULL);
if (dev == NULL) {
console_printf("failed to open drv2605_0 device\n");
return ENODEV;
}
drv2605 = (struct drv2605 *)dev;
if (argc == 1) {
return drv2605_shell_help();
}
if (argc > 1 && strcmp(argv[1], "load_cal") == 0) {
return drv2605_shell_cmd_load_cal(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "dump_cal") == 0) {
return drv2605_shell_cmd_dump_cal(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "dump_all") == 0) {
return drv2605_shell_cmd_dump_all(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "chip_id") == 0) {
return drv2605_shell_cmd_get_chip_id(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "op_mode") == 0) {
return drv2605_shell_cmd_op_mode(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "power_mode") == 0) {
return drv2605_shell_cmd_power_mode(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "load_rom") == 0) {
return drv2605_shell_cmd_load_rom(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "trigger") == 0) {
return drv2605_shell_cmd_trigger_rom(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "peek") == 0) {
return drv2605_shell_cmd_peek(argc, argv, drv2605);
}
if (argc > 1 && strcmp(argv[1], "poke") == 0) {
return drv2605_shell_cmd_poke(argc, argv, drv2605);
}
return drv2605_shell_err_unknown_arg(argv[1]);
}
int
drv2605_shell_init(void)
{
int rc;
rc = shell_cmd_register(&drv2605_shell_cmd_struct);
SYSINIT_PANIC_ASSERT(rc == 0);
return rc;
}
#endif