diff --git a/flash.sh b/flash.sh index eec3a2b..a1b569c 100755 --- a/flash.sh +++ b/flash.sh @@ -2,7 +2,7 @@ idf.py build mkdir build/encrypted -espsecure.py encrypt_flash_data --aes_xts --keyfile flash_key.bin --address 0x8000 --output build/encrypted/parttab.bin build/partition_table/partition-table.bin -espsecure.py encrypt_flash_data --aes_xts --keyfile flash_key.bin --address 0x10000 --output build/encrypted/app.bin build/undef_rfid.bin +espsecure.py encrypt_flash_data --aes_xts --keyfile keys/flash.bin --address 0x8000 --output build/encrypted/parttab.bin build/partition_table/partition-table.bin +espsecure.py encrypt_flash_data --aes_xts --keyfile keys/flash.bin --address 0x10000 --output build/encrypted/app.bin build/undef_rfid.bin esptool.py -b 3000000 write_flash --force 0x8000 build/encrypted/parttab.bin 0x10000 build/encrypted/app.bin idf.py monitor diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 7a5bc4b..759ec49 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ idf_component_register( - SRCS "http.c" "pn532.c" "main.c" "auth.c" "http.c" + SRCS "led_task.c" "http.c" "pn532.c" "main.c" "auth.c" INCLUDE_DIRS "include/" EMBED_TXTFILES "tg_api_root.pem") diff --git a/main/auth.c b/main/auth.c index df33e5a..c074c05 100644 --- a/main/auth.c +++ b/main/auth.c @@ -14,6 +14,7 @@ #include "common.h" #include "auth.h" #include "http.h" +#include "led_task.h" #define TAG "auth" @@ -264,9 +265,11 @@ void auth_task(void* _arg) { xQueueSend(http_queue, &msg, portMAX_DELAY); // open door + led_set_status(led_status_granted); gpio_set_level(DOOR_RELAY, 1); vTaskDelay(OPEN_DOOR_FOR); gpio_set_level(DOOR_RELAY, 0); + led_set_status(led_status_idle); } else if(err == ESP_ERR_NVS_NOT_FOUND) { // unknown credential: send notifications http_message_t msg = { @@ -274,6 +277,10 @@ void auth_task(void* _arg) { }; strcpy(msg.username, credential); xQueueSend(http_queue, &msg, portMAX_DELAY); + + led_set_status(led_status_refused); + vTaskDelay(1000 / portTICK_PERIOD_MS); + led_set_status(led_status_idle); } else { ESP_ERROR_CHECK(err); } diff --git a/main/include/config.h b/main/include/config.h index 1695e92..8a9bff4 100644 --- a/main/include/config.h +++ b/main/include/config.h @@ -11,6 +11,7 @@ #define PN532_MOSI 6 #define PN532_SS 7 #define PN532_RST 9 // note: RSTPD_N, not RSTO +#define LED_PIN 8 #define DOOR_RELAY 10 #define SCAN_TIMEOUT (5LL * 1000 * 1000) // uS diff --git a/main/include/led_task.h b/main/include/led_task.h new file mode 100644 index 0000000..74527cc --- /dev/null +++ b/main/include/led_task.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include + +#define LED_Q_SIZE 4 +#define LED_PATTERN_LEN 4 +extern QueueHandle_t led_queue; + +#define LED_COLOR_HEX(hex) ((rgb_t){ .r = ((hex) >> 16) & 0xff, .g = ((hex) >> 8) & 0xff, .b = (hex) & 0xff }) + +typedef enum { + led_status_error = 0, + led_status_wait, + led_status_idle, + led_status_granted, + led_status_refused, +} led_status_t; + +typedef struct { + rgb_t color; + uint32_t time_ms; + bool final; +} led_pattern_step_t; + +void led_task(void* param); +void led_init(void); +void led_set_status(led_status_t status); diff --git a/main/led_task.c b/main/led_task.c new file mode 100644 index 0000000..c5cb3a1 --- /dev/null +++ b/main/led_task.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "led_task.h" +#include "config.h" + +#define TAG "led_task" + +static const led_pattern_step_t _led_patterns[][LED_PATTERN_LEN] = { + /* error */ { + { LED_COLOR_HEX(0xff0000), 500, 0 }, + { LED_COLOR_HEX(0), 500, 1 } + }, + /* wait */ { + { LED_COLOR_HEX(0xffff00), 10000, 1 } + }, + /* idle */ { + { LED_COLOR_HEX(0x00ffff), 20, 0 }, + { LED_COLOR_HEX(0), 1980, 1 } + }, + /* granted */ { + { LED_COLOR_HEX(0x00ff00), 10000, 1} + }, + /* refused */ { + { LED_COLOR_HEX(0xff0000), 10000, 1} + }, +}; + +QueueHandle_t led_queue; + +void led_task(void* _arg) { + // initialize LED strip + led_strip_t strip = { + .type = LED_STRIP_WS2812, + .brightness = 255, + .length = 1, + .gpio = LED_PIN, + .channel = RMT_CHANNEL_0, + }; + ESP_ERROR_CHECK(led_strip_init(&strip)); + + // sequencer state + led_status_t status = led_status_wait; + int step_idx = -1; + time_t step_started = 0; + + while(1) { + // get new status if available + if(xQueueReceive(led_queue, &status, 10 / portTICK_PERIOD_MS)) { + step_idx = -1; + ESP_LOGD(TAG, "new status: %d", status); + } + + // refresh led according to next step + #define step _led_patterns[status][step_idx] + if(step_idx < 0 || esp_timer_get_time() - step_started >= step.time_ms * 1000) { + step_idx = (step_idx < 0 || step.final) ? 0 : (step_idx + 1); + led_strip_set_pixel(&strip, 0, step.color); + led_strip_flush(&strip); + step_started = esp_timer_get_time(); + } + #undef step + } +} + +void led_init(void) { + led_queue = xQueueCreate(LED_Q_SIZE, sizeof(led_status_t)); + led_strip_install(); +} + +void led_set_status(led_status_t status) { + xQueueSend(led_queue, &status, 0); +} diff --git a/main/main.c b/main/main.c index e8d1b0f..dbf1bb2 100644 --- a/main/main.c +++ b/main/main.c @@ -17,6 +17,7 @@ #include "secrets.h" #include "config.h" #include "http.h" +#include "led_task.h" // declarations void app_main(void); @@ -59,10 +60,12 @@ void nfc_task(void* _arg){ while(1) { // (re-)init if(esp_timer_get_time() - last_restart >= NFC_REINIT_PERIOD) { + led_set_status(led_status_wait); ESP_LOGD(TAG, "initializing PN532"); pn532_begin(&nfc); uint32_t version = pn532_getFirmwareVersion(&nfc); if (!version) { + led_set_status(led_status_error); ESP_LOGE(TAG, "failed to communicate with PN532. retrying in 5s"); vTaskDelay(5000 / portTICK_PERIOD_MS); continue; @@ -71,6 +74,7 @@ void nfc_task(void* _arg){ ESP_LOGD(TAG, "firmware ver. %d.%d", (version >> 16) & 0xFF, (version >> 8) & 0xFF); pn532_SAMConfig(&nfc); last_restart = esp_timer_get_time(); + led_set_status(led_status_idle); } // scan card @@ -153,9 +157,11 @@ void app_main(void) { // start tasks auth_init(); http_init(); + led_init(); xTaskCreate(&nfc_task, "nfc", 2048, NULL, 4, NULL); xTaskCreate(&auth_task, "auth", 2048, NULL, 4, NULL); xTaskCreate(&http_task, "http", 4096, NULL, 4, NULL); + xTaskCreate(&led_task, "led", 2048, NULL, 4, NULL); // print RSSI every minute while(1) { diff --git a/sdkconfig b/sdkconfig index cdc7296..98409c7 100644 --- a/sdkconfig +++ b/sdkconfig @@ -1143,16 +1143,14 @@ CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS=y # # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -CONFIG_LOG_DEFAULT_LEVEL_WARN=y +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set # CONFIG_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=2 +CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set # CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=2 +CONFIG_LOG_MAXIMUM_LEVEL=4 # CONFIG_LOG_MASTER_LEVEL is not set CONFIG_LOG_COLORS=y # CONFIG_LOG_TIMESTAMP_SOURCE_RTOS is not set