From dcc8edd1e5d53799a9e6ae4a202a62323bd9f20c Mon Sep 17 00:00:00 2001 From: Hendrik van Essen Date: Fri, 27 Aug 2021 14:14:26 +0200 Subject: [PATCH] tests/driver_mfrc522: add test for mfrc522 driver --- tests/driver_mfrc522/Makefile | 9 + tests/driver_mfrc522/Makefile.ci | 11 ++ tests/driver_mfrc522/README.md | 20 ++ tests/driver_mfrc522/main.c | 302 +++++++++++++++++++++++++++++++ 4 files changed, 342 insertions(+) create mode 100644 tests/driver_mfrc522/Makefile create mode 100644 tests/driver_mfrc522/Makefile.ci create mode 100644 tests/driver_mfrc522/README.md create mode 100644 tests/driver_mfrc522/main.c diff --git a/tests/driver_mfrc522/Makefile b/tests/driver_mfrc522/Makefile new file mode 100644 index 0000000000..69bf31588a --- /dev/null +++ b/tests/driver_mfrc522/Makefile @@ -0,0 +1,9 @@ +include ../Makefile.tests_common + +USEMODULE += mfrc522 + +USEMODULE += ztimer +USEMODULE += ztimer_msec +USEMODULE += shell + +include $(RIOTBASE)/Makefile.include diff --git a/tests/driver_mfrc522/Makefile.ci b/tests/driver_mfrc522/Makefile.ci new file mode 100644 index 0000000000..c9ac296b6c --- /dev/null +++ b/tests/driver_mfrc522/Makefile.ci @@ -0,0 +1,11 @@ +BOARD_INSUFFICIENT_MEMORY := \ + arduino-duemilanove \ + arduino-leonardo \ + arduino-nano \ + arduino-uno \ + atmega328p \ + atmega328p-xplained-mini \ + nucleo-l011k4 \ + samd10-xmini \ + stm32f030f4-demo \ + # diff --git a/tests/driver_mfrc522/README.md b/tests/driver_mfrc522/README.md new file mode 100644 index 0000000000..3045d7e1a2 --- /dev/null +++ b/tests/driver_mfrc522/README.md @@ -0,0 +1,20 @@ +# MFRC522 RFID Card Reader + +## Overview + +This test application demonstrates the usage of the MFRC522 driver interface +and can be used to test a MFRC522 RFID card reader with shell commands. + +## Usage + +The following shell commands are available: +* **reset** Reset the device. +* **antenna_on** Turn the antenna on. +* **antenna_off** Turn the antenna off. +* **set_antenna_gain** Set antenna gain. +* **get_antenna_gain** Get antenna gain. +* **firmware_version** Print the firmware version. +* **picc_dump** Dumps debug info about a scanned PICC. +* **scan_uid** Scan repeatedly until a PICC's UID is scanned. +* **set_uid** Set the UID of a scanned PICC. +* **self_test** Run the self test. diff --git a/tests/driver_mfrc522/main.c b/tests/driver_mfrc522/main.c new file mode 100644 index 0000000000..0c888514dd --- /dev/null +++ b/tests/driver_mfrc522/main.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2021 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @brief Test application for the MFRC522 controller + * @author Hendrik van Essen + * @file + * + */ + +#include +#include +#include + +#include "ztimer.h" +#include "shell.h" + +#include "mfrc522.h" +#include "mfrc522_params.h" + +static mfrc522_t mfrc522_dev; + +/* Stores scanned ID read from RFID Module */ +static uint8_t read_card[4]; + +int get_uid(mfrc522_uid_t *uid, bool stop_read) +{ + int rc = 0; + + /* Getting ready for Reading PICCs + * If a new PICC placed to RFID reader continue + */ + if (!(rc = mfrc522_picc_is_new_card_present(&mfrc522_dev))) { + puts("No card detected ..."); + return 0; + } + + puts("Card detected. Read card serial ..."); + + /* Since a PICC placed get Serial and continue */ + rc = mfrc522_picc_read_card_serial(&mfrc522_dev, uid); + if (rc != 0) { + return 0; + } + + printf("Scanned PICC's UID: "); + for (uint8_t i = 0; i < uid->size; i++) { + read_card[i] = uid->uid_byte[i]; + printf("%x", read_card[i]); + } + printf("\n"); + + /* Stop reading */ + if (stop_read) { + mfrc522_picc_halt_a(&mfrc522_dev); + } + + return 1; +} + +int scan_uid(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mfrc522_uid_t uid; + uint8_t success_read; + + int i = 0; + do { + if (i >= 1) { + printf("Repeat scan (%d/20) ...\n", i + 1); + } + success_read = get_uid(&uid, true); + ztimer_sleep(ZTIMER_MSEC, 500); + i++; + } while (!success_read && i < 20); + + return 0; +} + +int self_test(int argc, char **argv) +{ + (void)argc; + (void)argv; + + bool success = mfrc522_pcd_perform_self_test(&mfrc522_dev); + + success ? printf("SUCCESS\n") : printf("FAILED\n"); + + /* After self-test the device is unusable => repeat the initialization routine */ + int rc = 0; + if ((rc = mfrc522_pcd_init(&mfrc522_dev, &mfrc522_params[0])) != 0) { + printf("Initialization failed! rc = %d", rc); + return 1; + } + + return 0; +} + +int reset(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mfrc522_pcd_reset(&mfrc522_dev); + + return 0; +} + +int antenna_on(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mfrc522_pcd_antenna_on(&mfrc522_dev); + + return 0; +} + +int antenna_off(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mfrc522_pcd_antenna_off(&mfrc522_dev); + + return 0; +} + +int set_antenna_gain(int argc, char **argv) +{ + (void)argc; + (void)argv; + + if (argc != 2) { + puts("usage: set_antenna_gain "); + puts(" 0: 18db, 1: 23db, 2: 33db, 3: 38db, 4: 43db, 5: 48db"); + return 1; + } + else { + uint8_t input = atoi(argv[1]); + mfrc522_pcd_rx_gain_t gain; + + switch (input) { + case 0: + gain = MFRC522_RXGAIN_18_DB; + break; + case 1: + gain = MFRC522_RXGAIN_23_DB; + break; + case 2: + gain = MFRC522_RXGAIN_33_DB; + break; + case 3: + gain = MFRC522_RXGAIN_38_DB; + break; + case 4: + gain = MFRC522_RXGAIN_43_DB; + break; + case 5: + gain = MFRC522_RXGAIN_48_DB; + break; + default: + puts("gain needs to be one of [0-5]"); + puts("0: 18db, 1: 23db, 2: 33db, 3: 38db, 4: 43db, 5: 48db"); + return 1; + } + + mfrc522_pcd_set_antenna_gain(&mfrc522_dev, gain); + } + + return 0; +} + +int get_antenna_gain(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mfrc522_pcd_rx_gain_t gain = mfrc522_pcd_get_antenna_gain(&mfrc522_dev); + + switch (gain) { + case MFRC522_RXGAIN_18_DB: + /* fall-through */ + case MFRC522_RXGAIN_18_DB_2: + printf("gain = MFRC522_RXGAIN_18_DB\n"); + break; + case MFRC522_RXGAIN_23_DB: + /* fall-through */ + case MFRC522_RXGAIN_23_DB_2: + printf("gain = MFRC522_RXGAIN_23_DB\n"); + break; + case MFRC522_RXGAIN_33_DB: + printf("gain = MFRC522_RXGAIN_33_DB\n"); + break; + case MFRC522_RXGAIN_38_DB: + printf("gain = MFRC522_RXGAIN_38_DB\n"); + break; + case MFRC522_RXGAIN_43_DB: + printf("gain = MFRC522_RXGAIN_43_DB\n"); + break; + case MFRC522_RXGAIN_48_DB: + printf("gain = MFRC522_RXGAIN_48_DB\n"); + break; + default: + printf("gain = UNKNOWN\n"); + break; + } + + return 0; +} + +int firmware_version(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mfrc522_pcd_dump_version_to_serial(&mfrc522_dev); + + return 0; +} + +int picc_dump(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mfrc522_uid_t uid; + if (get_uid(&uid, false) != 1) { + return 1; + } + + mfrc522_picc_dump_to_serial(&mfrc522_dev, &uid); + + return 0; +} + +int set_uid(int argc, char **argv) +{ + (void)argc; + (void)argv; + + if (argc != 5) { + puts("usage: set_uid "); + puts(" as hex value (e.g. 0xA9 or A9)"); + return 1; + } + else { + mfrc522_uid_t uid; + if (get_uid(&uid, false) != 1) { + return 1; + } + + uint8_t byte_1 = (uint8_t)strtol(argv[1], NULL, 16); + uint8_t byte_2 = (uint8_t)strtol(argv[2], NULL, 16); + uint8_t byte_3 = (uint8_t)strtol(argv[3], NULL, 16); + uint8_t byte_4 = (uint8_t)strtol(argv[4], NULL, 16); + + uint8_t uid_buf[4] = { byte_1, byte_2, byte_3, byte_4 }; + + int status = mfrc522_mifare_set_uid(&mfrc522_dev, &uid, uid_buf, 4); + printf("status = %d\n", status); + } + + return 0; +} + +static const shell_command_t shell_commands[] = { + { "reset", "Reset the device.", reset }, + { "antenna_on", "Turn the antenna on.", antenna_on }, + { "antenna_off", "Turn the antenna off.", antenna_off }, + { "set_antenna_gain", "Set antenna gain.", set_antenna_gain }, + { "get_antenna_gain", "Get antenna gain.", get_antenna_gain }, + { "firmware_version", "Print the firmware version.", firmware_version }, + { "picc_dump", "Dumps debug info about a scanned PICC.", picc_dump }, + { "scan_uid", "Scan repeatedly until a PICC's UID is scanned.", scan_uid }, + { "set_uid", "Set the UID of a scanned PICC.", set_uid }, + { "self_test", "Run the self test.", self_test }, + { NULL, NULL, NULL } +}; + +int main(void) +{ + int rc = 0; + + if ((rc = mfrc522_pcd_init(&mfrc522_dev, &mfrc522_params[0])) != 0) { + printf("Initialization failed! rc = %d", rc); + return 1; + } + + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE); + + return 0; +}