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 #ifndef CLOCK_H
#define CLOCK_H #define CLOCK_H
#define F_CPU 16000000 #define F_CPU 8000000
#include <util/delay.h> #include <util/delay.h>

View File

@ -38,7 +38,7 @@
</dependencies> </dependencies>
</framework-data> </framework-data>
</AsfFrameworkConfig> </AsfFrameworkConfig>
<avrtool>com.atmel.avrdbg.tool.simulator</avrtool> <avrtool>com.atmel.avrdbg.tool.stk500</avrtool>
<avrtoolserialnumber /> <avrtoolserialnumber />
<avrdeviceexpectedsignature>0x1E950F</avrdeviceexpectedsignature> <avrdeviceexpectedsignature>0x1E950F</avrdeviceexpectedsignature>
<custom> <custom>
@ -53,7 +53,7 @@
</ToolNumber> </ToolNumber>
<ToolName>Custom Programming Tool</ToolName> <ToolName>Custom Programming Tool</ToolName>
</custom> </custom>
<avrtoolinterface /> <avrtoolinterface>ISP</avrtoolinterface>
<com_atmel_avrdbg_tool_simulator> <com_atmel_avrdbg_tool_simulator>
<ToolOptions xmlns=""> <ToolOptions xmlns="">
<InterfaceProperties> <InterfaceProperties>
@ -66,11 +66,26 @@
</ToolNumber> </ToolNumber>
<ToolName xmlns="">Simulator</ToolName> <ToolName xmlns="">Simulator</ToolName>
</com_atmel_avrdbg_tool_simulator> </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>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<ToolchainSettings> <ToolchainSettings>
<AvrGccCpp> <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.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
@ -78,26 +93,38 @@
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures> <avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned> <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> <avrgcc.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues> </ListValues>
</avrgcc.compiler.directories.IncludePaths> </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.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum> <avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings> <avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned> <avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
<avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcccpp.compiler.general.ChangeDefaultBitFieldUnsigned> <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> <avrgcccpp.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues> </ListValues>
</avrgcccpp.compiler.directories.IncludePaths> </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.PackStructureMembers>True</avrgcccpp.compiler.optimization.PackStructureMembers>
<avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum> <avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcccpp.compiler.optimization.AllocateBytesNeededForEnum>
<avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings> <avrgcccpp.compiler.warnings.AllWarnings>True</avrgcccpp.compiler.warnings.AllWarnings>
<avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic> <avrgcccpp.compiler.warnings.Pedantic>True</avrgcccpp.compiler.warnings.Pedantic>
<avrgcccpp.compiler.miscellaneous.OtherFlags>-Wextra -std=c++11</avrgcccpp.compiler.miscellaneous.OtherFlags> <avrgcccpp.compiler.miscellaneous.OtherFlags>-Wextra -std=c++14</avrgcccpp.compiler.miscellaneous.OtherFlags>
<avrgcccpp.linker.libraries.Libraries> <avrgcccpp.linker.libraries.Libraries>
<ListValues> <ListValues>
<Value>libm</Value> <Value>libm</Value>
@ -105,29 +132,17 @@
</avrgcccpp.linker.libraries.Libraries> </avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths> <avrgcccpp.assembler.general.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues> </ListValues>
</avrgcccpp.assembler.general.IncludePaths> </avrgcccpp.assembler.general.IncludePaths>
<avrgcc.compiler.symbols.DefSymbols> </AvrGccCpp>
<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>
</ToolchainSettings> </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>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<ToolchainSettings> <ToolchainSettings>
<AvrGccCpp> <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.hex>True</avrgcc.common.outputfiles.hex>
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss> <avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep> <avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
@ -142,7 +157,7 @@
</avrgcc.compiler.symbols.DefSymbols> </avrgcc.compiler.symbols.DefSymbols>
<avrgcc.compiler.directories.IncludePaths> <avrgcc.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues> </ListValues>
</avrgcc.compiler.directories.IncludePaths> </avrgcc.compiler.directories.IncludePaths>
<avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level> <avrgcc.compiler.optimization.level>Optimize (-O1)</avrgcc.compiler.optimization.level>
@ -159,7 +174,7 @@
</avrgcccpp.compiler.symbols.DefSymbols> </avrgcccpp.compiler.symbols.DefSymbols>
<avrgcccpp.compiler.directories.IncludePaths> <avrgcccpp.compiler.directories.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues> </ListValues>
</avrgcccpp.compiler.directories.IncludePaths> </avrgcccpp.compiler.directories.IncludePaths>
<avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level> <avrgcccpp.compiler.optimization.level>Optimize (-O1)</avrgcccpp.compiler.optimization.level>
@ -176,13 +191,13 @@
</avrgcccpp.linker.libraries.Libraries> </avrgcccpp.linker.libraries.Libraries>
<avrgcccpp.assembler.general.IncludePaths> <avrgcccpp.assembler.general.IncludePaths>
<ListValues> <ListValues>
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.132\include</Value> <Value>%24(PackRepoDir)\Atmel\ATmega_DFP\1.2.193\include</Value>
</ListValues> </ListValues>
</avrgcccpp.assembler.general.IncludePaths> </avrgcccpp.assembler.general.IncludePaths>
<avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel> <avrgcccpp.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcccpp.assembler.debugging.DebugLevel>
</AvrGccCpp> </AvrGccCpp>
</ToolchainSettings> </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>
<ItemGroup> <ItemGroup>
<Compile Include="bootloader.h"> <Compile Include="bootloader.h">

View File

@ -1,11 +1,12 @@
/* /*
* Copyright (c) by BlackMark 2017 * Copyright (c) by BlackMark 2017
* Date 26/04/2017 * Date 16/12/2017
* Version 1.0 * Version 1.1
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "usart/usart.h" #include "usart/usart.h"
@ -14,6 +15,52 @@
#include "twi.h" #include "twi.h"
#include "rtc.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() void setup()
{ {
USART0 &cSerial = USART0::inst(); USART0 &cSerial = USART0::inst();
@ -29,17 +76,37 @@ void setup()
{ {
cSerial << "ERROR - No RTC detected!" << "\r\n"; cSerial << "ERROR - No RTC detected!" << "\r\n";
} }
set_zone( 1 * ONE_HOUR );
set_dst( eu_dst );
setSystemTime();
} }
void setTime() void setTime()
{ {
USART0 &cSerial = USART0::inst(); USART0 &cSerial = USART0::inst();
tm* tmTime = rtc_get_time(); rtc_tm* tmTime = rtc_get_time();
constexpr auto BUFFER_SIZE = 32; constexpr auto BUFFER_SIZE = 32;
char szBuffer[BUFFER_SIZE]; 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 << "Set time:" << "\r\n" << "Hour: ";
cSerial.receiveLine( szBuffer, BUFFER_SIZE, "\r" ); cSerial.receiveLine( szBuffer, BUFFER_SIZE, "\r" );
cSerial << szBuffer << "\r\n"; cSerial << szBuffer << "\r\n";
@ -56,13 +123,15 @@ void setTime()
tmTime->sec = atoi( szBuffer ); tmTime->sec = atoi( szBuffer );
rtc_set_time( tmTime ); rtc_set_time( tmTime );
setSystemTime();
} }
void setAlarm() void setAlarm()
{ {
USART0 &cSerial = USART0::inst(); USART0 &cSerial = USART0::inst();
tm* tmAlarm = rtc_get_alarm(); rtc_tm* tmAlarm = rtc_get_alarm();
constexpr auto BUFFER_SIZE = 32; constexpr auto BUFFER_SIZE = 32;
char szBuffer[BUFFER_SIZE]; char szBuffer[BUFFER_SIZE];
@ -85,6 +154,16 @@ void setAlarm()
rtc_set_alarm( tmAlarm ); 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() int main()
{ {
uint8_t ui8MCUSR = handleReset(); uint8_t ui8MCUSR = handleReset();
@ -101,24 +180,25 @@ int main()
setup(); setup();
uint8_t ui8Hour; tm sTime;
uint8_t ui8Minute;
uint8_t ui8Second;
char szBuffer[32]; constexpr auto BUFFER_SIZE = 32;
char szBuffer[BUFFER_SIZE];
while( true ) 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; system_tick();
ui8Minute = tmTime->min;
ui8Second = tmTime->sec;
sprintf( szBuffer, "%02d:%02d:%02d\r\n", ui8Hour, ui8Minute, ui8Second ); time_t timeNow = time( nullptr );
cSerial << "Time: " << szBuffer; tm *psLocalTime = localtime( &timeNow );
strftime( szBuffer, BUFFER_SIZE, "%F %T %z", psLocalTime );
cSerial << "Time: " << szBuffer << "\r\n";
if( rtc_check_alarm() ) if( rtc_check_alarm() )
{ {
@ -126,6 +206,8 @@ int main()
} }
} }
sTime = sTimeNow;
uint8_t ui8Cmd; uint8_t ui8Cmd;
if( cSerial.receiveByte( ui8Cmd ) ) if( cSerial.receiveByte( ui8Cmd ) )
@ -146,6 +228,10 @@ int main()
} }
else if( ui8Cmd == 'p' ) else if( ui8Cmd == 'p' )
{ {
uint8_t ui8Hour;
uint8_t ui8Minute;
uint8_t ui8Second;
rtc_get_alarm_s( &ui8Hour, &ui8Minute, &ui8Second ); rtc_get_alarm_s( &ui8Hour, &ui8Minute, &ui8Second );
sprintf( szBuffer, "Alarm set to: %02d:%02d:%02d", ui8Hour, ui8Minute, ui8Second ); sprintf( szBuffer, "Alarm set to: %02d:%02d:%02d", ui8Hour, ui8Minute, ui8Second );
cSerial << szBuffer << "\r\n"; cSerial << szBuffer << "\r\n";
@ -156,6 +242,8 @@ int main()
cSerial.transmitByte( ui8Cmd ); cSerial.transmitByte( ui8Cmd );
cSerial << "'" << "\r\n"; cSerial << "'" << "\r\n";
} }
setSystemTime();
} }
} }

View File

@ -79,7 +79,7 @@
#define CH_BIT 7 // clock halt bit #define CH_BIT 7 // clock halt bit
// statically allocated structure for time value // statically allocated structure for time value
struct tm _tm; struct rtc_tm _rtc_tm;
uint8_t dec2bcd(uint8_t d) 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_ds1307(void) { s_is_ds1307 = true; s_is_ds3231 = false; }
void rtc_set_ds3231(void) { s_is_ds1307 = false; s_is_ds3231 = true; } 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 rtc[9];
uint8_t century = 0; 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 // This starts the clock for a DS1307, and has no effect for a DS3231
rtc[0] &= ~(_BV(CH_BIT)); // clear bit rtc[0] &= ~(_BV(CH_BIT)); // clear bit
_tm.sec = bcd2dec(rtc[0]); _rtc_tm.sec = bcd2dec(rtc[0]);
_tm.min = bcd2dec(rtc[1]); _rtc_tm.min = bcd2dec(rtc[1]);
_tm.hour = bcd2dec(rtc[2]); _rtc_tm.hour = bcd2dec(rtc[2]);
_tm.mday = bcd2dec(rtc[4]); _rtc_tm.mday = bcd2dec(rtc[4]);
_tm.mon = bcd2dec(rtc[5] & 0x1F); // returns 1-12 _rtc_tm.mon = bcd2dec(rtc[5] & 0x1F); // returns 1-12
century = (rtc[5] & 0x80) >> 7; century = (rtc[5] & 0x80) >> 7;
_tm.year = century == 1 ? 2000 + bcd2dec(rtc[6]) : 1900 + bcd2dec(rtc[6]); // year 0-99 _rtc_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.wday = bcd2dec(rtc[3]); // returns 1-7
if (_tm.hour == 0) { if (_rtc_tm.hour == 0) {
_tm.twelveHour = 0; _rtc_tm.twelveHour = 0;
_tm.am = 1; _rtc_tm.am = 1;
} else if (_tm.hour < 12) { } else if (_rtc_tm.hour < 12) {
_tm.twelveHour = _tm.hour; _rtc_tm.twelveHour = _rtc_tm.hour;
_tm.am = 1; _rtc_tm.am = 1;
} else { } else {
_tm.twelveHour = _tm.hour - 12; _rtc_tm.twelveHour = _rtc_tm.hour - 12;
_tm.am = 0; _rtc_tm.am = 0;
} }
return &_tm; return &_rtc_tm;
} }
void rtc_get_time_s(uint8_t* hour, uint8_t* min, uint8_t* sec) 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 // 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_begin_transmission(RTC_ADDR);
twi_send_byte(0x0); 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; if (!tm_) return;
rtc_set_alarm_s(tm_->hour, tm_->min, tm_->sec); 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; uint8_t hour, min, sec;
rtc_get_alarm_s(&hour, &min, &sec); rtc_get_alarm_s(&hour, &min, &sec);
_tm.hour = hour; _rtc_tm.hour = hour;
_tm.min = min; _rtc_tm.min = min;
_tm.sec = sec; _rtc_tm.sec = sec;
return &_tm; return &_rtc_tm;
} }
bool rtc_check_alarm(void) 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) * 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 sec; // 0 to 59
int min; // 0 to 59 int min; // 0 to 59
int hour; // 0 to 23 int hour; // 0 to 23
@ -53,7 +53,7 @@ struct tm {
}; };
// statically allocated // statically allocated
extern struct tm _tm; extern struct rtc_tm _rtc_tm;
// Initialize the RTC and autodetect type (DS1307 or DS3231) // Initialize the RTC and autodetect type (DS1307 or DS3231)
void rtc_init(void); void rtc_init(void);
@ -67,11 +67,11 @@ void rtc_set_ds3231(void);
// Get/set time // Get/set time
// Gets the time: Supports both 24-hour and 12-hour mode // 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 // Gets the time: 24-hour mode only
void rtc_get_time_s(uint8_t* hour, uint8_t* min, uint8_t* sec); 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 // 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 // Sets the time: Supports 12-hour mode only
void rtc_set_time_s(uint8_t hour, uint8_t min, uint8_t sec); 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 // Alarm functionality
void rtc_reset_alarm(void); 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); 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); void rtc_get_alarm_s(uint8_t* hour, uint8_t* min, uint8_t* sec);
bool rtc_check_alarm(void); bool rtc_check_alarm(void);