Files
battleship/src/main.c
T

142 lines
4.2 KiB
C

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include "driver/gpio.h"
#include "esp_chip_info.h"
#include "esp_err.h"
#include "esp_flash.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *const kLogTag = "bringup";
static const gpio_num_t kCandidateLedGpio = GPIO_NUM_8;
static const uint32_t kLedProbeCount = 10;
static const uint32_t kLedProbeIntervalMs = 500;
static const uint32_t kHealthIntervalMs = 30000;
static const uint32_t kStartupAttachmentDelayMs = 10000;
static const char *reset_reason_name(esp_reset_reason_t reason) {
switch (reason) {
case ESP_RST_UNKNOWN:
return "unknown";
case ESP_RST_POWERON:
return "power_on";
case ESP_RST_EXT:
return "external";
case ESP_RST_SW:
return "software";
case ESP_RST_PANIC:
return "panic";
case ESP_RST_INT_WDT:
return "interrupt_watchdog";
case ESP_RST_TASK_WDT:
return "task_watchdog";
case ESP_RST_WDT:
return "other_watchdog";
case ESP_RST_DEEPSLEEP:
return "deep_sleep";
case ESP_RST_BROWNOUT:
return "brownout";
case ESP_RST_SDIO:
return "sdio";
case ESP_RST_USB:
return "usb";
case ESP_RST_JTAG:
return "jtag";
case ESP_RST_EFUSE:
return "efuse";
case ESP_RST_PWR_GLITCH:
return "power_glitch";
case ESP_RST_CPU_LOCKUP:
return "cpu_lockup";
}
return "unrecognized";
}
static void log_heap(uint64_t uptime_ms) {
const size_t free_heap_bytes = esp_get_free_heap_size();
const size_t minimum_free_heap_bytes = esp_get_minimum_free_heap_size();
uint32_t flash_size_bytes = 0;
const esp_err_t flash_result = esp_flash_get_size(NULL, &flash_size_bytes);
if (flash_result == ESP_OK) {
ESP_LOGI(kLogTag,
"health uptime_ms=%" PRIu64 " reset_reason=%s flash_bytes=%" PRIu32
" free_heap_bytes=%u min_free_heap_bytes=%u",
uptime_ms,
reset_reason_name(esp_reset_reason()),
flash_size_bytes,
(unsigned int)free_heap_bytes,
(unsigned int)minimum_free_heap_bytes);
} else {
ESP_LOGE(kLogTag, "health flash_size_failed=%s", esp_err_to_name(flash_result));
}
}
static void probe_candidate_led(void) {
ESP_LOGI(kLogTag,
"led_probe gpio=%d transitions=%" PRIu32 " interval_ms=%" PRIu32 "; visually confirm the LED",
(int)kCandidateLedGpio,
kLedProbeCount,
kLedProbeIntervalMs);
esp_err_t result = gpio_reset_pin(kCandidateLedGpio);
if (result != ESP_OK) {
ESP_LOGW(kLogTag, "led_probe gpio_reset_pin failed: %s", esp_err_to_name(result));
return;
}
result = gpio_set_direction(kCandidateLedGpio, GPIO_MODE_OUTPUT);
if (result != ESP_OK) {
ESP_LOGW(kLogTag, "led_probe gpio_set_direction failed: %s", esp_err_to_name(result));
return;
}
for (uint32_t transition = 0; transition < kLedProbeCount; ++transition) {
gpio_set_level(kCandidateLedGpio, transition % 2U);
vTaskDelay(pdMS_TO_TICKS(kLedProbeIntervalMs));
}
gpio_set_level(kCandidateLedGpio, 0);
ESP_LOGI(kLogTag, "led_probe complete; USB serial remained available during probe");
}
static void log_startup(void) {
esp_chip_info_t chip_info = {0};
uint32_t flash_size_bytes = 0;
const esp_err_t flash_result = esp_flash_get_size(NULL, &flash_size_bytes);
esp_chip_info(&chip_info);
ESP_LOGI(kLogTag,
"startup reset_reason=%s chip_model=%d chip_revision=%d cores=%d features=0x%08" PRIx32,
reset_reason_name(esp_reset_reason()),
(int)chip_info.model,
chip_info.revision,
chip_info.cores,
chip_info.features);
if (flash_result == ESP_OK) {
ESP_LOGI(kLogTag, "startup flash_bytes=%" PRIu32, flash_size_bytes);
} else {
ESP_LOGE(kLogTag, "startup flash_size_failed=%s", esp_err_to_name(flash_result));
}
log_heap(0);
}
void app_main(void) {
vTaskDelay(pdMS_TO_TICKS(kStartupAttachmentDelayMs));
log_startup();
probe_candidate_led();
while (true) {
log_heap((uint64_t)(esp_timer_get_time() / 1000));
vTaskDelay(pdMS_TO_TICKS(kHealthIntervalMs));
}
}