Skip to content

Commit

Permalink
furi_hal_rtc: expose calendaring as functions
Browse files Browse the repository at this point in the history
  • Loading branch information
micolous committed May 29, 2023
1 parent a7e00a1 commit 47c3097
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 23 deletions.
6 changes: 4 additions & 2 deletions firmware/targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,27.0,,
Version,+,27.1,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down Expand Up @@ -1313,6 +1313,8 @@ Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime*
Function,-,furi_hal_rtc_deinit_early,void,
Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode,
Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime*
Function,+,furi_hal_rtc_get_days_per_month,uint8_t,"_Bool, uint8_t"
Function,+,furi_hal_rtc_get_days_per_year,uint16_t,uint16_t
Function,+,furi_hal_rtc_get_fault_data,uint32_t,
Function,+,furi_hal_rtc_get_heap_track_mode,FuriHalRtcHeapTrackMode,
Function,+,furi_hal_rtc_get_locale_dateformat,FuriHalRtcLocaleDateFormat,
Expand All @@ -1325,6 +1327,7 @@ Function,+,furi_hal_rtc_get_timestamp,uint32_t,
Function,-,furi_hal_rtc_init,void,
Function,-,furi_hal_rtc_init_early,void,
Function,+,furi_hal_rtc_is_flag_set,_Bool,FuriHalRtcFlag
Function,+,furi_hal_rtc_is_leap_year,_Bool,uint16_t
Function,+,furi_hal_rtc_reset_flag,void,FuriHalRtcFlag
Function,+,furi_hal_rtc_set_boot_mode,void,FuriHalRtcBootMode
Function,+,furi_hal_rtc_set_datetime,void,FuriHalRtcDateTime*
Expand Down Expand Up @@ -3085,7 +3088,6 @@ Variable,+,furi_hal_i2c_bus_external,FuriHalI2cBus,
Variable,+,furi_hal_i2c_bus_power,FuriHalI2cBus,
Variable,+,furi_hal_i2c_handle_external,FuriHalI2cBusHandle,
Variable,+,furi_hal_i2c_handle_power,FuriHalI2cBusHandle,
Variable,+,furi_hal_rtc_days_per_month,const uint8_t[2][12],
Variable,+,furi_hal_sd_spi_handle,FuriHalSpiBusHandle*,
Variable,+,furi_hal_spi_bus_d,FuriHalSpiBus,
Variable,+,furi_hal_spi_bus_handle_display,FuriHalSpiBusHandle,
Expand Down
28 changes: 23 additions & 5 deletions firmware/targets/f7/furi_hal/furi_hal_rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ typedef struct {

_Static_assert(sizeof(SystemReg) == 4, "SystemReg size mismatch");

const uint8_t furi_hal_rtc_days_per_month[2][FURI_HAL_RTC_MONTHS_COUNT] = {
#define FURI_HAL_RTC_SECONDS_PER_MINUTE 60
#define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60)
#define FURI_HAL_RTC_SECONDS_PER_DAY (FURI_HAL_RTC_SECONDS_PER_HOUR * 24)
#define FURI_HAL_RTC_MONTHS_COUNT 12
#define FURI_HAL_RTC_EPOCH_START_YEAR 1970

static const uint8_t furi_hal_rtc_days_per_month[2][FURI_HAL_RTC_MONTHS_COUNT] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};

Expand Down Expand Up @@ -387,7 +393,7 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) {
uint8_t leap_years = 0;

for(uint16_t y = FURI_HAL_RTC_EPOCH_START_YEAR; y < datetime->year; y++) {
if(FURI_HAL_RTC_IS_LEAP_YEAR(y)) {
if(furi_hal_rtc_is_leap_year(y)) {
leap_years++;
} else {
years++;
Expand All @@ -398,10 +404,10 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) {
((years * furi_hal_rtc_days_per_year[0]) + (leap_years * furi_hal_rtc_days_per_year[1])) *
FURI_HAL_RTC_SECONDS_PER_DAY;

uint8_t year_index = (FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year)) ? 1 : 0;
bool leap_year = furi_hal_rtc_is_leap_year(datetime->year);

for(uint8_t m = 0; m < (datetime->month - 1); m++) {
timestamp += furi_hal_rtc_days_per_month[year_index][m] * FURI_HAL_RTC_SECONDS_PER_DAY;
for(uint8_t m = 1; m < datetime->month; m++) {
timestamp += furi_hal_rtc_get_days_per_month(leap_year, m) * FURI_HAL_RTC_SECONDS_PER_DAY;
}

timestamp += (datetime->day - 1) * FURI_HAL_RTC_SECONDS_PER_DAY;
Expand All @@ -411,3 +417,15 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) {

return timestamp;
}

uint16_t furi_hal_rtc_get_days_per_year(uint16_t year) {
return furi_hal_rtc_days_per_year[furi_hal_rtc_is_leap_year(year) ? 1 : 0];
}

bool furi_hal_rtc_is_leap_year(uint16_t year) {
return (((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0);
}

uint8_t furi_hal_rtc_get_days_per_month(bool leap_year, uint8_t month) {
return furi_hal_rtc_days_per_month[leap_year ? 1 : 0][month - 1];
}
35 changes: 24 additions & 11 deletions firmware/targets/furi_hal_include/furi_hal_rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,6 @@
extern "C" {
#endif

#define FURI_HAL_RTC_SECONDS_PER_MINUTE 60
#define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60)
#define FURI_HAL_RTC_SECONDS_PER_DAY (FURI_HAL_RTC_SECONDS_PER_HOUR * 24)
#define FURI_HAL_RTC_EPOCH_START_YEAR 1970
#define FURI_HAL_RTC_IS_LEAP_YEAR(year) \
((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0))

#define FURI_HAL_RTC_MONTHS_COUNT 12

extern const uint8_t furi_hal_rtc_days_per_month[2][FURI_HAL_RTC_MONTHS_COUNT];

typedef struct {
// Time
uint8_t hour; /**< Hour in 24H format: 0-23 */
Expand Down Expand Up @@ -266,6 +255,30 @@ uint32_t furi_hal_rtc_get_timestamp();
*/
uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime);

/** Gets the number of days in the year according to the Gregorian calendar.
*
* @param year Input year.
*
* @return number of days in `year`.
*/
uint16_t furi_hal_rtc_get_days_per_year(uint16_t year);

/** Check if a year a leap year in the Gregorian calendar.
*
* @param year Input year.
*
* @return true if `year` is a leap year.
*/
bool furi_hal_rtc_is_leap_year(uint16_t year);

/** Get the number of days in the month.
*
* @param leap_year true to calculate based on leap years
* @param month month to check, where 1 = January
* @return the number of days in the month
*/
uint8_t furi_hal_rtc_get_days_per_month(bool leap_year, uint8_t month);

#ifdef __cplusplus
}
#endif
9 changes: 4 additions & 5 deletions lib/nfc/parsers/opal.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void opal_date_time_to_furi(uint16_t days, uint16_t minutes, FuriHalRtcDateTime*
if(!out) return;
uint16_t diy;
out->year = 1980;
out->month = 0;
out->month = 1;
// 1980-01-01 is a Tuesday
out->weekday = ((days + 1) % 7) + 1;
out->hour = minutes / 60;
Expand All @@ -73,7 +73,7 @@ void opal_date_time_to_furi(uint16_t days, uint16_t minutes, FuriHalRtcDateTime*

// What year is it?
for(;;) {
diy = (FURI_HAL_RTC_IS_LEAP_YEAR(out->year) ? 366 : 365);
diy = furi_hal_rtc_get_days_per_year(out->year);
if(days < diy) break;
days -= diy;
out->year++;
Expand All @@ -82,16 +82,15 @@ void opal_date_time_to_furi(uint16_t days, uint16_t minutes, FuriHalRtcDateTime*
// 1-index the day of the year
days++;
// What month is it?
uint8_t is_leap = diy - 365;
bool is_leap = furi_hal_rtc_is_leap_year(out->year);

for(;;) {
uint8_t dim = furi_hal_rtc_days_per_month[is_leap][out->month];
uint8_t dim = furi_hal_rtc_get_days_per_month(is_leap, out->month);
if(days <= dim) break;
days -= dim;
out->month++;
}

out->month++;
out->day = days;
}

Expand Down

0 comments on commit 47c3097

Please sign in to comment.