mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #14751 from benpicco/tests/periph_gpio-auto_test
tests/periph_gpio: add automatic GPIO test cmd
This commit is contained in:
commit
5f9718525b
@ -262,6 +262,10 @@ void gpio_irq_enable(gpio_t pin)
|
||||
const uint8_t pin_num = _pin_num(pin);
|
||||
const uint8_t pin_bit = 1<<pin_num;
|
||||
|
||||
/* clear stale interrupt */
|
||||
ROM_GPIOPinIntClear(port_addr, pin_bit);
|
||||
|
||||
/* enable interrupt */
|
||||
HWREG(im_reg_addr) |= pin_bit;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#define BENCH_RUNS_DEFAULT (1000UL * 100)
|
||||
#define IRQ_TIMEOUT_US (1000UL)
|
||||
|
||||
#ifdef MODULE_PERIPH_GPIO_IRQ
|
||||
static void cb(void *arg)
|
||||
@ -246,6 +247,135 @@ static int cmd_toggle(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MODULE_PERIPH_GPIO_IRQ
|
||||
static void _test_cb(void *ctx)
|
||||
{
|
||||
mutex_unlock(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cmd_auto_test(int argc, char **argv)
|
||||
{
|
||||
if (argc < 5) {
|
||||
printf("usage: %s <port> <pin> <port> <pin>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
gpio_t pin_in = GPIO_PIN(atoi(argv[1]), atoi(argv[2]));
|
||||
gpio_t pin_out = GPIO_PIN(atoi(argv[3]), atoi(argv[4]));
|
||||
|
||||
puts("[START]");
|
||||
|
||||
if (gpio_init(pin_in, GPIO_IN)) {
|
||||
printf("Error to initialize GPIO_PIN(%s, %s)\n", argv[1], argv[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (gpio_init(pin_out, GPIO_OUT)) {
|
||||
printf("Error to initialize GPIO_PIN(%s, %s)\n", argv[3], argv[4]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* test set HIGH */
|
||||
gpio_set(pin_out);
|
||||
|
||||
if (gpio_read(pin_in) == 0) {
|
||||
puts("gpio_set() or gpio_read() or failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* test set LOW */
|
||||
gpio_clear(pin_out);
|
||||
|
||||
if (gpio_read(pin_in) != 0) {
|
||||
puts("gpio_clear() or gpio_read() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef MODULE_PERIPH_GPIO_IRQ
|
||||
mutex_t lock = MUTEX_INIT_LOCKED;
|
||||
|
||||
/* test rising interrupt */
|
||||
if (gpio_init_int(pin_in, GPIO_IN, GPIO_RISING, _test_cb, &lock)) {
|
||||
puts("setting rising interrupt failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio_set(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US)) {
|
||||
puts("rising interrupt timeout");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio_clear(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US) == 0) {
|
||||
puts("interrupt falsely generated on falling edge");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* test falling interrupt */
|
||||
if (gpio_init_int(pin_in, GPIO_IN, GPIO_FALLING, _test_cb, &lock)) {
|
||||
puts("setting falling interrupt failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio_set(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US) == 0) {
|
||||
puts("interrupt falsely generated on rising edge");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio_clear(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US)) {
|
||||
puts("rising interrupt timeout");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* test IRQ disable */
|
||||
gpio_irq_disable(pin_in);
|
||||
|
||||
gpio_set(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US) == 0) {
|
||||
puts("interrupt falsely generated on rising edge while disabled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio_clear(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US) == 0) {
|
||||
puts("interrupt falsely generated while disabled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* test IRQ enable */
|
||||
|
||||
gpio_irq_enable(pin_in);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US) == 0) {
|
||||
puts("interrupt falsely generated after being re-enabled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio_set(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US) == 0) {
|
||||
puts("interrupt falsely generated on rising edge after re-enabled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpio_clear(pin_out);
|
||||
if (xtimer_mutex_lock_timeout(&lock, IRQ_TIMEOUT_US)) {
|
||||
puts("interrupt not re-enabled");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* disable IRQ to avoid further interrupts */
|
||||
gpio_irq_disable(pin_in);
|
||||
|
||||
#endif
|
||||
|
||||
puts("[SUCCESS]");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bench(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
@ -285,6 +415,7 @@ static const shell_command_t shell_commands[] = {
|
||||
{ "set", "set pin to HIGH", cmd_set },
|
||||
{ "clear", "set pin to LOW", cmd_clear },
|
||||
{ "toggle", "toggle pin", cmd_toggle },
|
||||
{ "auto_test", "Run a series of automatic tests on two connected GPIOs", cmd_auto_test },
|
||||
{ "bench", "run a set of predefined benchmarks", bench },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user