Renamed rtc tm and implemented DST

This commit is contained in:
BlackMark 2017-12-16 19:48:54 +01:00
parent b658ebac97
commit 9c9164c447
5 changed files with 210 additions and 107 deletions

View File

@ -7,7 +7,7 @@
#ifndef CLOCK_H
#define CLOCK_H
#define F_CPU 16000000
#define F_CPU 8000000
#include <util/delay.h>

View File

@ -38,7 +38,7 @@
</dependencies>
</framework-data>
</AsfFrameworkConfig>
<avrtool>com.atmel.avrdbg.tool.simulator</avrtool>
<avrtool>com.atmel.avrdbg.tool.stk500</avrtool>
<avrtoolserialnumber />
<avrdeviceexpectedsignature>0x1E950F</avrdeviceexpectedsignature>
<custom>
@ -53,7 +53,7 @@
</ToolNumber>
<ToolName>Custom Programming Tool</ToolName>
</custom>
<avrtoolinterface />
<avrtoolinterface>ISP</avrtoolinterface>
<com_atmel_avrdbg_tool_simulator>
<ToolOptions xmlns="">
<InterfaceProperties>
@ -66,68 +66,83 @@
</ToolNumber>
<ToolName xmlns="">Simulator</ToolName>
</com_atmel_avrdbg_tool_simulator>
<ResetRule>0</ResetRule>
<EraseKey />
<com_atmel_avrdbg_tool_stk500>
<ToolOptions>
<InterfaceProperties>
<IspClock>125000</IspClock>
</InterfaceProperties>
<InterfaceName>ISP</InterfaceName>
</ToolOptions>
<ToolType>com.atmel.avrdbg.tool.stk500</ToolType>
<ToolNumber>
</ToolNumber>
<ToolName>STK500</ToolName>
</com_atmel_avrdbg_tool_stk500>
<avrtoolinterfaceclock>125000</avrtoolinterfaceclock>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-Wextra -std=c++11</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
</AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcc.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>
<avrgcccpp.compiler.symbols.DefSymbols>
<ListValues>
<Value>NDEBUG</Value>
</ListValues>
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize for size (-Os)</avrgcccpp.compiler.optimization.level>
<avrgcccpp.compiler.optimization.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-Wextra -std=c++14</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.libraries.Libraries>
<ListValues>
<Value>libm</Value>
</ListValues>
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
</AvrGccCpp>
</ToolchainSettings>
<PreBuildEvent>echo "C:\avrdude-6.2\avrdude.exe" -v -p$(avrdevice) %%* -Uflash:w:"$(OutputDirectory)\$(Name).hex":i &gt; "$(MSBuildProjectDirectory)\avrdude.bat"</PreBuildEvent>
<PreBuildEvent>echo "C:\bin\avrdude-6.3\avrdude.exe" -v -p$(avrdevice) %%* -Uflash:w:"$(OutputDirectory)\$(Name).hex":i &gt; "$(MSBuildProjectDirectory)\avrdude.bat"</PreBuildEvent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings>
<AvrGccCpp>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\gcc\dev\atmega328p"</avrgcc.common.Device>
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
@ -142,7 +157,7 @@
</avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues>
</avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
@ -159,7 +174,7 @@
</avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues>
</avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level>
@ -176,13 +191,13 @@
</avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths>
<ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value>
<Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues>
</avrgcccpp.assembler.general.IncludePaths>
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
</AvrGccCpp>
</ToolchainSettings>
<PreBuildEvent>echo "C:\avrdude-6.2\avrdude.exe" -v -p$(avrdevice) %%* -Uflash:w:"$(OutputDirectory)\$(Name).hex":i &gt; "$(MSBuildProjectDirectory)\avrdude.bat"</PreBuildEvent>
<PreBuildEvent>echo "C:\bin\avrdude-6.3\avrdude.exe" -v -p$(avrdevice) %%* -Uflash:w:"$(OutputDirectory)\$(Name).hex":i &gt; "$(MSBuildProjectDirectory)\avrdude.bat"</PreBuildEvent>
</PropertyGroup>
<ItemGroup>
<Compile Include="bootloader.h">

View File

@ -1,11 +1,12 @@
/*
* Copyright (c) by BlackMark 2017
* Date 26/04/2017
* Version 1.0
* Date 16/12/2017
* Version 1.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <avr/interrupt.h>
#include "usart/usart.h"
@ -14,6 +15,52 @@
#include "twi.h"
#include "rtc.h"
// DST magic by Edgar Bonet
int eu_dst( const time_t *timer, int32_t *z )
{
static_cast<void>( z );
uint32_t t = *timer;
if( static_cast<uint8_t>( t >> 24 ) >= 194 )
t -= 3029443200U;
t = ( t + 655513200 ) / 604800 * 28;
if( static_cast<uint16_t>( t % 1461 ) < 856 )
return ONE_HOUR;
else
return 0;
}
tm getTime()
{
tm sTime;
rtc_tm* ptmTime = rtc_get_time();
sTime.tm_sec = ptmTime->sec;
sTime.tm_min = ptmTime->min;
sTime.tm_hour = ptmTime->hour;
sTime.tm_mday = ptmTime->mday;
sTime.tm_mon = ptmTime->mon - 1;
sTime.tm_year = ptmTime->year - 1900;
sTime.tm_isdst = 0;
time_t timeNow = mk_gmtime( &sTime );
sTime.tm_isdst = eu_dst( &timeNow, nullptr );
mktime( &sTime );
return sTime;
}
void setSystemTime()
{
tm sTime = getTime();
set_system_time( mktime( &sTime ) );
}
void setup()
{
USART0 &cSerial = USART0::inst();
@ -29,17 +76,37 @@ void setup()
{
cSerial << "ERROR - No RTC detected!" << "\r\n";
}
set_zone( 1 * ONE_HOUR );
set_dst( eu_dst );
setSystemTime();
}
void setTime()
{
USART0 &cSerial = USART0::inst();
tm* tmTime = rtc_get_time();
rtc_tm* tmTime = rtc_get_time();
constexpr auto BUFFER_SIZE = 32;
char szBuffer[BUFFER_SIZE];
cSerial << "Set time:" << "\r\n" << "Year: ";
cSerial.receiveLine( szBuffer, BUFFER_SIZE, "\r" );
cSerial << szBuffer << "\r\n";
tmTime->year = atoi( szBuffer );
cSerial << "Set time:" << "\r\n" << "Month: ";
cSerial.receiveLine( szBuffer, BUFFER_SIZE, "\r" );
cSerial << szBuffer << "\r\n";
tmTime->mon = atoi( szBuffer );
cSerial << "Set time:" << "\r\n" << "Day: ";
cSerial.receiveLine( szBuffer, BUFFER_SIZE, "\r" );
cSerial << szBuffer << "\r\n";
tmTime->mday = atoi( szBuffer );
cSerial << "Set time:" << "\r\n" << "Hour: ";
cSerial.receiveLine( szBuffer, BUFFER_SIZE, "\r" );
cSerial << szBuffer << "\r\n";
@ -56,13 +123,15 @@ void setTime()
tmTime->sec = atoi( szBuffer );
rtc_set_time( tmTime );
setSystemTime();
}
void setAlarm()
{
USART0 &cSerial = USART0::inst();
tm* tmAlarm = rtc_get_alarm();
rtc_tm* tmAlarm = rtc_get_alarm();
constexpr auto BUFFER_SIZE = 32;
char szBuffer[BUFFER_SIZE];
@ -85,6 +154,16 @@ void setAlarm()
rtc_set_alarm( tmAlarm );
}
bool timeDiff( const tm &sTime1, const tm &sTime2 )
{
if( sTime1.tm_sec != sTime2.tm_sec || sTime1.tm_min != sTime2.tm_min || sTime1.tm_hour != sTime2.tm_hour )
return true;
if( sTime1.tm_mday != sTime2.tm_mday || sTime1.tm_mon != sTime2.tm_mon || sTime1.tm_year != sTime2.tm_year )
return true;
return false;
}
int main()
{
uint8_t ui8MCUSR = handleReset();
@ -101,24 +180,25 @@ int main()
setup();
uint8_t ui8Hour;
uint8_t ui8Minute;
uint8_t ui8Second;
char szBuffer[32];
tm sTime;
constexpr auto BUFFER_SIZE = 32;
char szBuffer[BUFFER_SIZE];
while( true )
{
tm* tmTime = rtc_get_time();
tm sTimeNow = getTime();
if( tmTime->hour != ui8Hour || tmTime->min != ui8Minute || tmTime->sec != ui8Second )
if( timeDiff( sTime, sTimeNow ) )
{
ui8Hour = tmTime->hour;
ui8Minute = tmTime->min;
ui8Second = tmTime->sec;
system_tick();
sprintf( szBuffer, "%02d:%02d:%02d\r\n", ui8Hour, ui8Minute, ui8Second );
cSerial << "Time: " << szBuffer;
time_t timeNow = time( nullptr );
tm *psLocalTime = localtime( &timeNow );
strftime( szBuffer, BUFFER_SIZE, "%F %T %z", psLocalTime );
cSerial << "Time: " << szBuffer << "\r\n";
if( rtc_check_alarm() )
{
@ -126,6 +206,8 @@ int main()
}
}
sTime = sTimeNow;
uint8_t ui8Cmd;
if( cSerial.receiveByte( ui8Cmd ) )
@ -146,6 +228,10 @@ int main()
}
else if( ui8Cmd == 'p' )
{
uint8_t ui8Hour;
uint8_t ui8Minute;
uint8_t ui8Second;
rtc_get_alarm_s( &ui8Hour, &ui8Minute, &ui8Second );
sprintf( szBuffer, "Alarm set to: %02d:%02d:%02d", ui8Hour, ui8Minute, ui8Second );
cSerial << szBuffer << "\r\n";
@ -156,6 +242,8 @@ int main()
cSerial.transmitByte( ui8Cmd );
cSerial << "'" << "\r\n";
}
setSystemTime();
}
}

View File

@ -79,7 +79,7 @@
#define CH_BIT 7 // clock halt bit
// statically allocated structure for time value
struct tm _tm;
struct rtc_tm _rtc_tm;
uint8_t dec2bcd(uint8_t d)
{
@ -146,7 +146,7 @@ bool rtc_is_ds3231(void) { return s_is_ds3231; }
void rtc_set_ds1307(void) { s_is_ds1307 = true; s_is_ds3231 = false; }
void rtc_set_ds3231(void) { s_is_ds1307 = false; s_is_ds3231 = true; }
struct tm* rtc_get_time(void)
struct rtc_tm* rtc_get_time(void)
{
uint8_t rtc[9];
uint8_t century = 0;
@ -169,27 +169,27 @@ struct tm* rtc_get_time(void)
// This starts the clock for a DS1307, and has no effect for a DS3231
rtc[0] &= ~(_BV(CH_BIT)); // clear bit
_tm.sec = bcd2dec(rtc[0]);
_tm.min = bcd2dec(rtc[1]);
_tm.hour = bcd2dec(rtc[2]);
_tm.mday = bcd2dec(rtc[4]);
_tm.mon = bcd2dec(rtc[5] & 0x1F); // returns 1-12
_rtc_tm.sec = bcd2dec(rtc[0]);
_rtc_tm.min = bcd2dec(rtc[1]);
_rtc_tm.hour = bcd2dec(rtc[2]);
_rtc_tm.mday = bcd2dec(rtc[4]);
_rtc_tm.mon = bcd2dec(rtc[5] & 0x1F); // returns 1-12
century = (rtc[5] & 0x80) >> 7;
_tm.year = century == 1 ? 2000 + bcd2dec(rtc[6]) : 1900 + bcd2dec(rtc[6]); // year 0-99
_tm.wday = bcd2dec(rtc[3]); // returns 1-7
_rtc_tm.year = century == 1 ? 2000 + bcd2dec(rtc[6]) : 1900 + bcd2dec(rtc[6]); // year 0-99
_rtc_tm.wday = bcd2dec(rtc[3]); // returns 1-7
if (_tm.hour == 0) {
_tm.twelveHour = 0;
_tm.am = 1;
} else if (_tm.hour < 12) {
_tm.twelveHour = _tm.hour;
_tm.am = 1;
if (_rtc_tm.hour == 0) {
_rtc_tm.twelveHour = 0;
_rtc_tm.am = 1;
} else if (_rtc_tm.hour < 12) {
_rtc_tm.twelveHour = _rtc_tm.hour;
_rtc_tm.am = 1;
} else {
_tm.twelveHour = _tm.hour - 12;
_tm.am = 0;
_rtc_tm.twelveHour = _rtc_tm.hour - 12;
_rtc_tm.am = 0;
}
return &_tm;
return &_rtc_tm;
}
void rtc_get_time_s(uint8_t* hour, uint8_t* min, uint8_t* sec)
@ -216,7 +216,7 @@ void rtc_get_time_s(uint8_t* hour, uint8_t* min, uint8_t* sec)
}
// fixme: support 12-hour mode for setting time
void rtc_set_time(struct tm* tm_)
void rtc_set_time(struct rtc_tm* tm_)
{
twi_begin_transmission(RTC_ADDR);
twi_send_byte(0x0);
@ -550,7 +550,7 @@ void rtc_set_alarm_s(uint8_t hour, uint8_t min, uint8_t sec)
}
}
void rtc_set_alarm(struct tm* tm_)
void rtc_set_alarm(struct rtc_tm* tm_)
{
if (!tm_) return;
rtc_set_alarm_s(tm_->hour, tm_->min, tm_->sec);
@ -570,15 +570,15 @@ void rtc_get_alarm_s(uint8_t* hour, uint8_t* min, uint8_t* sec)
}
}
struct tm* rtc_get_alarm(void)
struct rtc_tm* rtc_get_alarm(void)
{
uint8_t hour, min, sec;
rtc_get_alarm_s(&hour, &min, &sec);
_tm.hour = hour;
_tm.min = min;
_tm.sec = sec;
return &_tm;
_rtc_tm.hour = hour;
_rtc_tm.min = min;
_rtc_tm.sec = sec;
return &_rtc_tm;
}
bool rtc_check_alarm(void)

View File

@ -38,7 +38,7 @@
* and translation has to be done manually (you can call rtc_24h_to_12h to perform the calculation)
*
*/
struct tm {
struct rtc_tm {
int sec; // 0 to 59
int min; // 0 to 59
int hour; // 0 to 23
@ -53,7 +53,7 @@ struct tm {
};
// statically allocated
extern struct tm _tm;
extern struct rtc_tm _rtc_tm;
// Initialize the RTC and autodetect type (DS1307 or DS3231)
void rtc_init(void);
@ -67,11 +67,11 @@ void rtc_set_ds3231(void);
// Get/set time
// Gets the time: Supports both 24-hour and 12-hour mode
struct tm* rtc_get_time(void);
struct rtc_tm* rtc_get_time(void);
// Gets the time: 24-hour mode only
void rtc_get_time_s(uint8_t* hour, uint8_t* min, uint8_t* sec);
// Sets the time: Supports both 24-hour and 12-hour mode
void rtc_set_time(struct tm* tm_);
void rtc_set_time(struct rtc_tm* tm_);
// Sets the time: Supports 12-hour mode only
void rtc_set_time_s(uint8_t hour, uint8_t min, uint8_t sec);
@ -98,9 +98,9 @@ void rtc_osc32kHz_enable(bool enable);
// Alarm functionality
void rtc_reset_alarm(void);
void rtc_set_alarm(struct tm* tm_);
void rtc_set_alarm(struct rtc_tm* tm_);
void rtc_set_alarm_s(uint8_t hour, uint8_t min, uint8_t sec);
struct tm* rtc_get_alarm(void);
struct rtc_tm* rtc_get_alarm(void);
void rtc_get_alarm_s(uint8_t* hour, uint8_t* min, uint8_t* sec);
bool rtc_check_alarm(void);