
#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

#include <zephyr/drivers/watchdog.h>
#include <zephyr/task_wdt/task_wdt.h>

#define MODULE watchdog
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);

/*******************************************************************************
 * Private Variables
 ******************************************************************************/
static const struct device *wdt = DEVICE_DT_GET(DT_NODELABEL(wdt0));

/*******************************************************************************
 * Private Functions
 ******************************************************************************/

static void task_watchdog_callback(int channel_id, void *user_data)
{
  __ASSERT(false, "Watchdog timeout in %s\n",
           k_thread_name_get((k_tid_t)user_data));
}

/*******************************************************************************
 * Public Functions
 ******************************************************************************/

int watchdog_init(void)
{
  int status;

  if (!device_is_ready(wdt) || wdt == NULL) {
    LOG_ERR("HW watchdog not ready");
    return -EIO;
  }

  // Init the task watchdog
  status = task_wdt_init(wdt);
  if (status != 0) {
    LOG_ERR("task wdt init failure: %d\n", status);
    return status;
  }

  return 0;
}

int watchdog_task_register(uint32_t reload)
{
  int id
      = task_wdt_add(reload, task_watchdog_callback, (void *)k_current_get());
  if (id == -ENOMEM) {
    LOG_ERR("Unable to register %s for monitoring",
            k_thread_name_get(k_current_get()));
  }

  return id;
}

int watchdog_task_deregister(int channelId)
{
  return task_wdt_delete(channelId);
}

int watchdog_feed(int channelId)
{
  return task_wdt_feed(channelId);
}