Files @ 2e9e37796ebc
Branch filter:

Location: FeatherHAB/wsprhab/src/rtc.c - annotation

Ethan Zonca
Switch to newlib nano. Untested on actual hardware. Saves flash/ram.
bb703e19f242
bb703e19f242
bb703e19f242
bb703e19f242
bb703e19f242
bb703e19f242
af5348c12bda
bb703e19f242
bb703e19f242
c396707da341
c396707da341
c396707da341
c396707da341
c396707da341
c396707da341
c396707da341
c396707da341
c396707da341
bb703e19f242
bb703e19f242
bb703e19f242
af6b7df096c5
af5348c12bda
af5348c12bda
af5348c12bda
af5348c12bda
af5348c12bda
af5348c12bda
bb703e19f242
bb703e19f242
bb703e19f242
bb703e19f242
bb703e19f242
ddbcfaffc98a
bb703e19f242
bb703e19f242
30ab6b66325f
30ab6b66325f
30ab6b66325f
bb703e19f242
af5348c12bda
af5348c12bda
30ab6b66325f
30ab6b66325f
7f3f8f2d539f
7f3f8f2d539f
30ab6b66325f
af5348c12bda
30ab6b66325f
ddbcfaffc98a
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
bb703e19f242
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
bb703e19f242
30ab6b66325f
30ab6b66325f
af5348c12bda
af5348c12bda
bb703e19f242
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
bb703e19f242
ddbcfaffc98a
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
30ab6b66325f
ddbcfaffc98a
30ab6b66325f
af5348c12bda
f2f8cb2bebfa
30ab6b66325f
af5348c12bda
30ab6b66325f
af5348c12bda
30ab6b66325f
30ab6b66325f
30ab6b66325f
bb703e19f242
30ab6b66325f
30ab6b66325f
af5348c12bda
af5348c12bda
af5348c12bda
af5348c12bda
bb703e19f242
ddbcfaffc98a
c396707da341
f2f8cb2bebfa
c396707da341
f2f8cb2bebfa
f2f8cb2bebfa
f2f8cb2bebfa
f2f8cb2bebfa
f2f8cb2bebfa
f2f8cb2bebfa
c396707da341
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
c396707da341
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
7f3f8f2d539f
c396707da341
c396707da341
c396707da341
c396707da341
f2f8cb2bebfa
c396707da341
c396707da341
ddbcfaffc98a
ddbcfaffc98a
ddbcfaffc98a
ddbcfaffc98a
ddbcfaffc98a
c396707da341
c396707da341
ddbcfaffc98a
ddbcfaffc98a
ddbcfaffc98a
ddbcfaffc98a
ddbcfaffc98a
ddbcfaffc98a
//
// RTC: configure real-time clock
//

#include "stm32f0xx_hal.h"
#include "rtc.h"
#include "gpio.h"


static RTC_HandleTypeDef hrtc;
static volatile uint32_t seconds_ctr = 0;


void rtc_incseconds(void)
{
	//HAL_GPIO_TogglePin(LED_BLUE);
	seconds_ctr += 1;
}

static void Error_Handler(void)
{
	volatile uint8_t crap = 1;

	for(uint16_t i=0; i<300; i++)
	{
		HAL_GPIO_TogglePin(LED_BLUE);
		HAL_Delay(100);
	}
}

// Initialize RTC
void rtc_init(void)
{
	__HAL_RCC_RTC_ENABLE();

    
	RTC_TimeTypeDef sTime;
	RTC_DateTypeDef sDate;
	RTC_AlarmTypeDef sAlarm;

	HAL_PWR_EnableBkUpAccess();

	hrtc.Instance = RTC;
	hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
	hrtc.Init.AsynchPrediv = 127; // Note that both these dividers actually divide by their value + 1
	hrtc.Init.SynchPrediv = 311; // About 1Hz with 40kHz LSI
	hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
 	hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
	hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

	if (HAL_RTC_Init(&hrtc) != HAL_OK)
	{
		Error_Handler();
	}

	sTime.Hours = 0x0;
	sTime.Minutes = 0x0;
	sTime.Seconds = 0x0;
	sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sTime.StoreOperation = RTC_STOREOPERATION_RESET;
	if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
	{
		Error_Handler();
	}

	sDate.WeekDay = RTC_WEEKDAY_MONDAY;
	sDate.Month = RTC_MONTH_JANUARY;
	sDate.Date = 0x01;
	sDate.Year = 0x19;

	if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
	{
		Error_Handler();
	}


	/**Enable the Alarm A
	*/
	sAlarm.AlarmTime.Hours = 0x0;
	sAlarm.AlarmTime.Minutes = 0x0;
	sAlarm.AlarmTime.Seconds = 0x0;
	sAlarm.AlarmTime.SubSeconds = 0x0;
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;

	// Alarm will trigger on the Xth second of every minute
	sAlarm.AlarmMask = RTC_ALARMMASK_ALL; // Trigger every second for now
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_SS14; //RTC_ALARMSUBSECONDMASK_ALL;
	sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	sAlarm.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY;
	sAlarm.Alarm = RTC_ALARM_A;
	if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
	{
		Error_Handler();
	}

	HAL_NVIC_SetPriority(RTC_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(RTC_IRQn);

	HAL_RTC_WaitForSynchro(&hrtc);


}

static RTC_TimeTypeDef time_last = {0};

// Get the time from the RTC
RTC_TimeTypeDef* rtc_time(void)
{
	HAL_RTC_GetTime(&hrtc, &time_last, RTC_FORMAT_BCD);
	return &time_last;
}

// Calculate value in milliseconds from subseconds of the RTC
uint16_t __rtc_millis(uint32_t sub_seconds)
{
	// Subsecond counter counts down from SynchPrediv value to zero
	return (hrtc.Init.SynchPrediv - sub_seconds) * 999 / hrtc.Init.SynchPrediv; // 0 - 999 mS
}

#define JULIAN_DATE_BASE 2440588 // Unix epoch time in Julian calendar (UnixTime = 00:00:00 01.01.1970 => JDN = 2440588)

// Calculate timestamp in milliseconds since Unix epoch
uint64_t rtc_timestamp(void)
{
	RTC_TimeTypeDef time = {0};
	RTC_DateTypeDef date = {0};

	HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BCD);
	HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BCD);

	// Thanks to LonelyWolf: https://github.com/LonelyWolf/stm32/blob/master/stm32l-dosfs/RTC.c
	// Convert Date/Time structures to epoch time
	uint8_t  a;
	uint16_t y;
	uint8_t  m;
	uint64_t JDN;

	// These hardcore math's are taken from http://en.wikipedia.org/wiki/Julian_day

	// Calculate some coefficients
	a = (14 - date.Month) / 12;
	y = (date.Year + 2000) + 4800 - a; // years since 1 March, 4801 BC
	m = date.Month + (12 * a) - 3; // since 1 March, 4801 BC

	// Gregorian calendar date compute
	JDN  = date.Date;
	JDN += (153 * m + 2) / 5;
	JDN += 365 * y;
	JDN += y / 4;
	JDN += -y / 100;
	JDN += y / 400;
	JDN  = JDN - 32045;
	JDN  = JDN - JULIAN_DATE_BASE;    // Calculate from base date
	JDN *= 86400;                     // Days to seconds
	JDN += time.Hours * 3600;    // ... and today seconds
	JDN += time.Minutes * 60;
	JDN += time.Seconds;

	JDN *= 1000; // Prepare to add ms

	JDN += __rtc_millis(time.SubSeconds);

	return JDN;

}

uint32_t rtc_timestamp_seconds(void)
{
	return seconds_ctr;
}


// Calibrate the RTC somehow
void rtc_cal(void)
{
	// Do something with hrtc.Instance->CALR; // this has a plus and minus component, see refman
}


// RTC accessor
RTC_HandleTypeDef* rtc_gethandle(void)
{
	return &hrtc;
}