/* * SPDX-License-Identifier: AGPL-3.0-only * Copyright (c) Camden Dixie O'Brien */ #include "alarm_store.h" #include "fatal.h" #include "esp_log.h" #include "esp_partition.h" #include "system_utils.h" #include #define TAG "Alarm store" Alarm alarms[CONFIG_MAX_ALARMS]; static const esp_partition_t *partition; static unsigned erase_size(void) { unsigned sector_count = sizeof(alarms) / partition->erase_size; if (sizeof(alarms) % partition->erase_size != 0) ++sector_count; return partition->erase_size * sector_count; } static void load() { const esp_err_t error = esp_partition_read(partition, 0, alarms, sizeof(alarms)); if (error != ESP_OK) { ESP_LOGE(TAG, "Error reading from alarms partition: %02x", error); FATAL(); } unsigned count = 0; for (unsigned i = 0; i < CONFIG_MAX_ALARMS; ++i) { if (alarms[i].set) ++count; } ESP_LOGI(TAG, "Loaded %u alarms from storage", count); } void alarm_store_init() { partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_UNDEFINED, "alarms"); if (partition == NULL) { ESP_LOGE(TAG, "Unable to find alarms partition"); FATAL(); } if (is_first_boot()) { ESP_LOGI(TAG, "Zeroing alarm store"); memset(alarms, 0, sizeof(alarms)); alarm_store_save(); } else { load(); } } void alarm_store_save() { esp_err_t error; error = esp_partition_erase_range(partition, 0, erase_size()); if (error != ESP_OK) { ESP_LOGE(TAG, "Error erasing alarm storage: %02x", error); return; } error = esp_partition_write(partition, 0, alarms, sizeof(alarms)); if (error != ESP_OK) ESP_LOGE(TAG, "Error writing alarm storage: %02x", error); }