Skip to content
Snippets Groups Projects
rtc.c 1.3 KiB
Newer Older
#include "epicardium.h"
#include "modules/log.h"
#include "api/interrupt-sender.h"

#include "FreeRTOS.h"
#include "task.h"

#include "rtc.h"

#include <stdint.h>

uint32_t epic_rtc_get_seconds(void)
{
	uint32_t sec, subsec;

	/*
	 * TODO:  Find out what causes the weird behavior of this function.  The
	 *        time needed for this call seems to depend on the frequency at
	 *        which it is called.
	 */
	while (RTC_GetTime(&sec, &subsec) == E_BUSY) {
		vTaskDelay(pdMS_TO_TICKS(4));
	}

	return sec;
void epic_rtc_set_milliseconds(uint64_t milliseconds)
{
	uint32_t sec, subsec;

	sec    = milliseconds / 1000;
	subsec = (milliseconds % 1000);
	subsec *= 4096;
	subsec /= 1000;

	while (RTC_Init(MXC_RTC, sec, subsec, NULL) == E_BUSY)
		;
	while (RTC_EnableRTCE(MXC_RTC) == E_BUSY)
		;
}

void RTC_IRQHandler(void)
{
	int flags = RTC_GetFlags();

	if (flags & MXC_F_RTC_CTRL_ALDF) {
		RTC_ClearFlags(MXC_F_RTC_CTRL_ALDF);
		api_interrupt_trigger(EPIC_INT_RTC_ALARM);
	} else {
		LOG_WARN("rtc", "Unknown IRQ caught!");
		/* Disable IRQ so it does not retrigger */
		NVIC_DisableIRQ(RTC_IRQn);
	}
}

int epic_rtc_schedule_alarm(uint32_t timestamp)
{
	int res;

	NVIC_EnableIRQ(RTC_IRQn);

	while ((res = RTC_SetTimeofdayAlarm(MXC_RTC, timestamp)) == E_BUSY)
		;

	if (res != E_SUCCESS) {
		return -EINVAL;
	}

	return 0;
}