diff --git a/bdk/rtc/max77620-rtc.c b/bdk/rtc/max77620-rtc.c index 6f813c0d..369457ed 100644 --- a/bdk/rtc/max77620-rtc.c +++ b/bdk/rtc/max77620-rtc.c @@ -1,7 +1,7 @@ /* * PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC * - * Copyright (c) 2018-2022 CTCaer + * Copyright (c) 2018-2025 CTCaer * Copyright (c) 2019 shchmue * * This program is free software; you can redistribute it and/or modify it @@ -23,7 +23,8 @@ #include #include -int epoch_offset = 0; +bool auto_dst = false; +int epoch_offset = 0; void max77620_rtc_prep_read() { @@ -39,20 +40,24 @@ void max77620_rtc_get_time(rtc_time_t *time) // Get control reg config. val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_CONTROL_REG); - // TODO: Check for binary format also? + // TODO: Make also sure it's binary format? // Get time. - time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F; - time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F; - u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG); + time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F; + time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F; + u8 hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG) & 0x1F; time->hour = hour & 0x1F; - if (!(val & MAX77620_RTC_24H) && (hour & MAX77620_RTC_HOUR_PM_MASK)) - time->hour = (time->hour & 0xF) + 12; + if (!(val & MAX77620_RTC_24H)) + { + time->hour = hour & 0xF; + if (hour & MAX77620_RTC_HOUR_PM_MASK) + time->hour += 12; + } // Get day of week. 1: Monday to 7: Sunday. time->weekday = 0; - val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG); + val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG) & 0x7F; for (int i = 0; i < 8; i++) { time->weekday++; @@ -62,8 +67,9 @@ void max77620_rtc_get_time(rtc_time_t *time) } // Get date. - time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f; + time->day = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DAY_REG) & 0x1F; time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1; + time->month++; // Normally minus 1, but everything else expects 1 as January. time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000; } @@ -126,7 +132,7 @@ void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time) time->day = day; // Set weekday. - time->weekday = 0; //! TODO. + time->weekday = (day + 4) % 7; } u32 max77620_rtc_date_to_epoch(const rtc_time_t *time) @@ -162,10 +168,21 @@ void max77620_rtc_get_time_adjusted(rtc_time_t *time) if (epoch_offset) { u32 epoch = (u32)((s64)max77620_rtc_date_to_epoch(time) + epoch_offset); + + // Adjust for DST between 28 march and 28 october. Good enough to cover all years as week info is not valid. + u16 md = (time->month << 8) | time->day; + if (auto_dst && md >= 0x31C && md < 0xA1C) + epoch += 3600; + max77620_rtc_epoch_to_date(epoch, time); } } +void max77620_rtc_set_auto_dst(bool enable) +{ + auto_dst = enable; +} + void max77620_rtc_set_epoch_offset(int offset) { epoch_offset = offset; diff --git a/bdk/rtc/max77620-rtc.h b/bdk/rtc/max77620-rtc.h index b82c3e63..2de94bbc 100644 --- a/bdk/rtc/max77620-rtc.h +++ b/bdk/rtc/max77620-rtc.h @@ -46,7 +46,7 @@ #define MAX77620_RTC_WEEKDAY_REG 0x0A #define MAX77620_RTC_MONTH_REG 0x0B #define MAX77620_RTC_YEAR_REG 0x0C -#define MAX77620_RTC_DATE_REG 0x0D +#define MAX77620_RTC_DAY_REG 0x0D #define MAX77620_ALARM1_SEC_REG 0x0E #define MAX77620_ALARM1_MIN_REG 0x0F @@ -111,6 +111,7 @@ void max77620_rtc_prep_read(); void max77620_rtc_get_time(rtc_time_t *time); void max77620_rtc_get_time_adjusted(rtc_time_t *time); void max77620_rtc_set_epoch_offset(int offset); +void max77620_rtc_set_auto_dst(bool enable); void max77620_rtc_stop_alarm(); void max77620_rtc_epoch_to_date(u32 epoch, rtc_time_t *time); u32 max77620_rtc_date_to_epoch(const rtc_time_t *time);