From 014df46e2e881d15e4fcefa4667fa23f858cd0d4 Mon Sep 17 00:00:00 2001 From: Semjon Kerner Date: Tue, 6 Mar 2018 12:01:55 +0100 Subject: [PATCH] tests/periph_pwm: add shellcommands for more detailed testing --- tests/periph_pwm/Makefile | 1 + tests/periph_pwm/main.c | 205 +++++++++++++++++++++++++++++++++++--- 2 files changed, 191 insertions(+), 15 deletions(-) diff --git a/tests/periph_pwm/Makefile b/tests/periph_pwm/Makefile index 2617987c5b..ab079f2f72 100644 --- a/tests/periph_pwm/Makefile +++ b/tests/periph_pwm/Makefile @@ -4,5 +4,6 @@ include ../Makefile.tests_common FEATURES_REQUIRED = periph_pwm USEMODULE += xtimer +USEMODULE += shell include $(RIOTBASE)/Makefile.include diff --git a/tests/periph_pwm/main.c b/tests/periph_pwm/main.c index d61925f257..04162d84ab 100644 --- a/tests/periph_pwm/main.c +++ b/tests/periph_pwm/main.c @@ -20,42 +20,140 @@ * every 1s on every channel. * * @author Hauke Petersen + * @author Semjon Kerner * * @} */ #include +#include +#include +#include #include "xtimer.h" +#include "shell.h" #include "timex.h" #include "periph/pwm.h" -#define INTERVAL (10LU * US_PER_MS) /* 10 ms */ -#define STEP (10) +#define OSC_INTERVAL (10LU * US_PER_MS) /* 10 ms */ +#define OSC_STEP (10) +#define OSC_MODE PWM_LEFT +#define OSC_FREQU (1000U) +#define OSC_STEPS (1000U) +#define PWR_SLEEP (1U) -#define MODE PWM_LEFT -#define FREQU (1000U) -#define STEPS (1000U) +static uint32_t initiated; - -int main(void) +static unsigned _get_dev(const char *dev_str) { + unsigned dev = (unsigned)atoi(dev_str); + if (dev >= PWM_NUMOF) { + printf("Error: device PWM_DEV(%u) is unknown\n", dev); + return UINT_MAX; + } + return dev; +} + +static int _init(int argc, char** argv) +{ + if (argc != 5) { + printf("usage: %s \n", argv[0]); + printf("\tdev: device by number between 0 and %u\n", PWM_NUMOF - 1); + puts("\tmode:\n"); + puts("\t\t0: left aligned\n"); + puts("\t\t1: right aligned\n"); + puts("\t\t2: center aligned\n"); + puts("\tfrequency: desired frequency in Hz\n"); + printf("\tresolution: number between 2 and %" PRIu16 "\n", UINT16_MAX); + return 1; + } + + unsigned dev = _get_dev(argv[1]); + if (dev == UINT_MAX) { + return 1; + } + + pwm_mode_t pwm_mode; + switch(atoi(argv[2])) { + case(0): + pwm_mode = PWM_LEFT; + break; + case(1): + pwm_mode = PWM_RIGHT; + break; + case(2): + pwm_mode = PWM_CENTER; + break; + default: + printf("Error: mode %d is not supported.\n", atoi(argv[2])); + return 1; + } + + uint32_t pwm_freq = pwm_init(PWM_DEV(dev), pwm_mode, + (uint32_t)atoi(argv[3]), + (uint16_t)atoi(argv[4])); + if (pwm_freq != 0) { + printf("The pwm frequency is set to %" PRIu32 "\n", pwm_freq); + initiated |= (1 << dev); + return 0; + } + + puts("Error: device is not initiated"); + return 1; +} + +static int _set(int argc, char**argv) +{ + if (argc != 4) { + printf("usage: %s \n", argv[0]); + printf("\tdev: device by number between 0 and %d\n", PWM_NUMOF - 1); + puts("\tch: channel of device\n"); + puts("\tval: duty cycle\n"); + return 1; + } + + unsigned dev = _get_dev(argv[1]); + if (dev == UINT_MAX) { + return 1; + } + + if ((initiated & (1 << dev)) == 0) { + puts("Error: pwm is not initiated.\n"); + puts("Execute init function first.\n"); + return 1; + } + + uint8_t chan = (uint8_t)atoi(argv[2]); + if (chan >= pwm_channels(PWM_DEV(dev))) { + printf("Error: channel %d is unknown.\n", chan); + return 1; + } + + pwm_set(PWM_DEV(dev), chan, (uint16_t)atoi(argv[3])); + return 0; +} + +static int _oscillate(int argc, char** argv) +{ + (void)argc; + (void)argv; + int state = 0; - int step = STEP; + int step = OSC_STEP; xtimer_ticks32_t last_wakeup = xtimer_now(); puts("\nRIOT PWM test"); - puts("Connect an LED or scope to PWM pins to see something\n"); + puts("Connect an LED or scope to PWM pins to see something.\n"); - printf("Available PWM devices: %i\n", PWM_NUMOF); + printf("Available PWM device between 0 and %d\n", PWM_NUMOF - 1); for (unsigned i = 0; i < PWM_NUMOF; i++) { - uint32_t real_f = pwm_init(PWM_DEV(i), MODE, FREQU, STEPS); + uint32_t real_f = pwm_init(PWM_DEV(i), OSC_MODE, OSC_FREQU, OSC_STEPS); if (real_f == 0) { - printf("Error initializing PWM_%u\n", i); + printf("Error: initializing PWM_%u.\n", i); return 1; } else { - printf("Initialized PWM_%u @ %" PRIu32 "Hz\n", i, real_f); + printf("Initialized PWM_%u @ %" PRIu32 "Hz.\n", i, real_f); } } @@ -68,12 +166,89 @@ int main(void) } state += step; - if (state <= 0 || state >= (int)STEPS) { + if (state <= 0 || state >= (int)OSC_STEPS) { step = -step; } - xtimer_periodic_wakeup(&last_wakeup, INTERVAL); + xtimer_periodic_wakeup(&last_wakeup, OSC_INTERVAL); } return 0; } + +static int _power(int argc, char** argv) +{ + if (argc != 3) { + printf("usage: %s \n", argv[0]); + printf("\tdev: device by number between 0 and %d\n", PWM_NUMOF - 1); + puts("\tstate:\n"); + puts("\t\t0: power off\n"); + puts("\t\t1: power on\n"); + return 1; + } + + unsigned dev = _get_dev(argv[1]); + if (dev == UINT_MAX) { + return 1; + } + + switch (atoi(argv[2])) { + case (0): + puts("Powering down PWM device.\n"); + pwm_poweroff(PWM_DEV(dev)); + break; + case (1): + puts("Powering up PWM device.\n"); + pwm_poweron(PWM_DEV(dev)); + break; + default: + puts("Error: power state not available.\n"); + return 1; + } + return 0; +} + +static int _power_test(int argc, char** argv) +{ + if (argc != 2) { + printf("usage: %s \n", argv[0]); + printf("\tdev: device by number between 0 and %d\n", PWM_NUMOF - 1); + return 1; + } + + unsigned dev = _get_dev(argv[1]); + if (dev == UINT_MAX) { + return 1; + } + + printf("Powering down PWM device and sleeping for %u second(s)...\n", + PWR_SLEEP); + pwm_poweroff(PWM_DEV(dev)); + + xtimer_sleep(PWR_SLEEP); + + puts("Powering up PWM device.\n"); + pwm_poweron(PWM_DEV(dev)); + + return 0; +} + +static const shell_command_t shell_commands[] = { + { "init", "initial pwm configuration", _init }, + { "set", "set pwm duty cycle", _set }, + { "power", "set pwm power", _power }, + { "powertest", "test power on/off functions", _power_test }, + { "osci", "blocking, default oscillation test", _oscillate }, + { NULL, NULL, NULL } +}; + +int main(void) +{ + puts("PWM peripheral driver test\n"); + initiated = 0; + + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + + return 0; +}