Skip to content

Commit

Permalink
Added HwClock::RtcSetAlarm and HwClock::RtcGetAlarm
Browse files Browse the repository at this point in the history
  • Loading branch information
vanvught committed Apr 4, 2024
1 parent 82f1d71 commit 1f3d876
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 15 deletions.
2 changes: 2 additions & 0 deletions lib-hal/Rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ ifneq ($(MAKE_FLAGS),)
ifneq (,$(findstring DISABLE_INTERNAL_RTC,$(MAKE_FLAGS)))
EXTRA_SRCDIR+=rtc/i2c
endif
EXTRA_INCLUDES+=../lib-properties/include
endif

ifneq (,$(findstring DEBUG_I2C,$(MAKE_FLAGS)))
Expand All @@ -51,4 +52,5 @@ else
EXTRA_SRCDIR+=console/i2c console/null console/uart0
EXTRA_SRCDIR+=posix
EXTRA_SRCDIR+=rtc rtc/i2c
EXTRA_INCLUDES+=../lib-properties/include
endif
8 changes: 4 additions & 4 deletions lib-hal/include/hwclock.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ class HwClock {
return RtcGetAlarm(pTime);
}
void AlarmEnable(const bool bEnable) {
RtcAlarmEnable(bEnable);
m_bRtcAlarmEnabled = bEnable;
}
bool AlarmIsEnabled() const {
return m_bRtcAlarmEnabled;
}

bool IsConnected() const {
Expand All @@ -83,9 +86,6 @@ class HwClock {
bool RtcGet(struct tm *pTime);
bool RtcSetAlarm(const struct tm *pTime);
bool RtcGetAlarm(struct tm *pTime);
void RtcAlarmEnable(const bool bEnable) {
m_bRtcAlarmEnabled = bEnable;
}
int MCP794xxAlarmWeekday(struct tm *pTime);
void PCF8563GetAlarmMode();
void PCF8563SetAlarmMode();
Expand Down
82 changes: 82 additions & 0 deletions lib-hal/rtc/gd32/hwclockrtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include <cstring>
#include <time.h>

#include "hwclock.h"

#include "hardware.h"
#include "gd32.h"

Expand Down Expand Up @@ -209,3 +211,83 @@ bool HwClock::RtcGet(struct tm *pTime) {

return true;
}

bool HwClock::RtcSetAlarm(const struct tm *pTime) {
DEBUG_ENTRY
assert(pTime != nullptr);

DEBUG_PRINTF("secs=%d, mins=%d, hours=%d, mday=%d, mon=%d, year=%d, wday=%d, enabled=%d",
pTime->tm_sec,
pTime->tm_min,
pTime->tm_hour,
pTime->tm_mday,
pTime->tm_mon,
pTime->tm_year,
pTime->tm_wday,
m_bRtcAlarmEnabled);

#if defined (GD32F4XX) || defined (GD32H7XX)
rtc_alarm_disable (RTC_ALARM0);
rtc_alarm_struct rtc_alarm;

rtc_alarm.alarm_mask = RTC_ALARM_ALL_MASK;
rtc_alarm.weekday_or_date = RTC_ALARM_DATE_SELECTED;
rtc_alarm.am_pm = 0;
rtc_alarm.alarm_day = DEC2BCD(pTime->tm_mday);
rtc_alarm.alarm_hour = DEC2BCD(pTime->tm_hour);
rtc_alarm.alarm_minute = DEC2BCD(pTime->tm_min);
rtc_alarm.alarm_second = DEC2BCD(pTime->tm_sec);

rtc_alarm_config(RTC_ALARM0, &rtc_alarm);

if (m_bRtcAlarmEnabled) {
rtc_interrupt_enable (RTC_INT_ALARM0);
rtc_alarm_enable(RTC_ALARM0);
} else {
rtc_alarm_disable(RTC_ALARM0);
rtc_interrupt_disable(RTC_INT_ALARM0);
}
#else
rtc_alarm_config(mktime(const_cast<struct tm *>(pTime)));
#endif

DEBUG_EXIT
return true;
}

bool HwClock::RtcGetAlarm(struct tm *pTime) {
DEBUG_ENTRY
assert(pTime != nullptr);

#if defined (GD32F4XX) || defined (GD32H7XX)
if (!RtcGet(pTime)) {
DEBUG_EXIT
return false;
}

rtc_alarm_struct rtc_alarm;
rtc_alarm_get(RTC_ALARM0, &rtc_alarm);

pTime->tm_sec= BCD2DEC(rtc_alarm.alarm_second);
pTime->tm_min = BCD2DEC(rtc_alarm.alarm_minute);
pTime->tm_hour = BCD2DEC(rtc_alarm.alarm_hour);
pTime->tm_mday = BCD2DEC(rtc_alarm.alarm_day);
#else
const auto nSeconds = static_cast<time_t>((RTC_ALRMH << 16U) | RTC_ALRML);
const auto *pTm = localtime(&nSeconds);
memcpy(pTime, pTm, sizeof(struct tm));
#endif

DEBUG_PRINTF("secs=%d, mins=%d, hours=%d, mday=%d, mon=%d, year=%d, wday=%d, enabled=%d",
pTime->tm_sec,
pTime->tm_min,
pTime->tm_hour,
pTime->tm_mday,
pTime->tm_mon,
pTime->tm_year,
pTime->tm_wday,
m_bRtcAlarmEnabled);

DEBUG_EXIT
return true;
}
34 changes: 23 additions & 11 deletions lib-hal/rtc/i2c/hwclockrtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file hwclockrtc.cpp
*
*/
/* Copyright (C) 2020-2023 by Arjan van Vught mailto:[email protected]
/* Copyright (C) 2020-2024 by Arjan van Vught mailto:[email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -342,13 +342,14 @@ bool HwClock::RtcSetAlarm(const struct tm *pTime) {
DEBUG_ENTRY
assert(pTime != nullptr);

DEBUG_PRINTF("sec=%d min=%d hour=%d wday=%d mday=%d mon=%d",
pTime->tm_sec,
pTime->tm_min,
pTime->tm_hour,
pTime->tm_wday,
pTime->tm_mday,
pTime->tm_mon);
DEBUG_PRINTF("secs=%d, mins=%d, hours=%d, mday=%d, mon=%d, year=%d, wday=%d",
pTime->tm_sec,
pTime->tm_min,
pTime->tm_hour,
pTime->tm_mday,
pTime->tm_mon,
pTime->tm_year,
pTime->tm_wday);

switch (m_Type) {
#if !defined (CONFIG_RTC_DISABLE_MCP7941X)
Expand Down Expand Up @@ -465,6 +466,11 @@ bool HwClock::RtcGetAlarm(struct tm *pTime) {
DEBUG_ENTRY
assert(pTime != nullptr);

if (!RtcGet(pTime)) {
DEBUG_EXIT
return false;
}

switch (m_Type) {
#if !defined (CONFIG_RTC_DISABLE_MCP7941X)
case Type::MCP7941X: {
Expand All @@ -483,9 +489,6 @@ bool HwClock::RtcGetAlarm(struct tm *pTime) {
pTime->tm_wday = BCD2DEC(registers[6] & 0x7) - 1;
pTime->tm_mday = BCD2DEC(registers[7] & 0x3f);
pTime->tm_mon = BCD2DEC(registers[8] & 0x1f) - 1;
pTime->tm_year = -1;
pTime->tm_yday = -1;
pTime->tm_isdst = -1;

m_bRtcAlarmEnabled = registers[0] & mcp7941x::bit::ALM0_EN;

Expand All @@ -500,6 +503,9 @@ bool HwClock::RtcGetAlarm(struct tm *pTime) {
(registers[6] & mcp7941x::bit::ALMX_POL),
(registers[6] & mcp7941x::bit::ALMX_IF),
(registers[6] & mcp7941x::bit::MSK_ALMX_MATCH) >> 4);

DEBUG_EXIT
return true;
}
break;
#endif
Expand Down Expand Up @@ -529,6 +535,9 @@ bool HwClock::RtcGetAlarm(struct tm *pTime) {
pTime->tm_mday,
m_bRtcAlarmEnabled,
m_bRtcAlarmPending);

DEBUG_EXIT
return true;
}

break;
Expand Down Expand Up @@ -565,6 +574,9 @@ bool HwClock::RtcGetAlarm(struct tm *pTime) {
pTime->tm_wday,
m_bRtcAlarmEnabled,
m_bRtcAlarmPending);

DEBUG_EXIT
return true;
}
break;
#endif
Expand Down
155 changes: 155 additions & 0 deletions lib-hal/rtc/json_rtc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/**
* @file json_rtc.cpp
*
*/
/* Copyright (C) 2024 by Arjan van Vught mailto:[email protected]
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#include <cstdio>
#include <cstdint>
#include <cstring>
#include <cassert>

#include "hwclock.h"

#include "debug.h"

// ISO 8601 format (YYYY-MM-DDTHH:MM:SS)

#include "readconfigfile.h"
#include "sscan.h"

static constexpr auto iso8601FormatSize = sizeof("YYYY-MM-DDTHH:MM:SS");
static char iso8601Format[iso8601FormatSize];

static void staticCallbackFunction([[maybe_unused]] void *p, const char *s) {
assert(p == nullptr);
assert(s != nullptr);

uint32_t nLength = iso8601FormatSize;

if (Sscan::Char(s, "alarm" , iso8601Format, nLength) == Sscan::OK) {
DEBUG_PUTS("alarm");
return;
}

char action[8];
nLength = sizeof(action) - 1;

if (Sscan::Char(s, "action" , action, nLength) == Sscan::OK) {
if (strncmp(action, "hctosys", nLength) == 0) {
HwClock::Get()->HcToSys();
return;
}

if (strncmp(action, "systohc", nLength) == 0) {
HwClock::Get()->SysToHc();
return;
}

return;
}

uint8_t nValue8;

if (Sscan::Uint8(s, "enable", nValue8) == Sscan::OK) {
HwClock::Get()->AlarmEnable(nValue8 != 0);
return;
}
}

namespace remoteconfig {
namespace rtc {
static int atoi(const char *pBuffer, uint32_t nSize) {
assert(pBuffer != nullptr);
assert(nSize <= 4);

const char *p = pBuffer;
int32_t res = 0;

for (; (nSize > 0) && (*p >= '0' && *p <= '9'); nSize--) {
res = res * 10 + *p - '0';
p++;
}

return res;
}

uint32_t json_get_rtc(char *pOutBuffer, const uint32_t nOutBufferSize) {
DEBUG_ENTRY

struct tm tm;

if (HwClock::Get()->Get(&tm)) {
auto nLength = static_cast<uint32_t>(snprintf(pOutBuffer, nOutBufferSize,
"{\"rtc\":\"%d-%.2d-%.2dT%.2d:%.2d:%.2d\",",
1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec));

if (HwClock::Get()->AlarmGet(&tm)) {
nLength += static_cast<uint32_t>(snprintf(&pOutBuffer[nLength], nOutBufferSize,
"\"alarm\":\"%d-%.2d-%.2dT%.2d:%.2d:%.2d\",",
1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec));

nLength += static_cast<uint32_t>(snprintf(&pOutBuffer[nLength], nOutBufferSize,
"\"enabled\":\"%d\"}", HwClock::Get()->AlarmIsEnabled()));

DEBUG_EXIT
return nLength;
} else {
pOutBuffer[nLength++] = '}';
}
}

DEBUG_EXIT
return 0;
}

void json_set_rtc(const char *pBuffer, const uint32_t nBufferSize) {
DEBUG_ENTRY
debug_dump(pBuffer, static_cast<uint16_t>(nBufferSize));

iso8601Format[0] = 0;

ReadConfigFile config(staticCallbackFunction, nullptr);
config.Read(pBuffer, nBufferSize);

debug_dump(iso8601Format, static_cast<uint16_t>(sizeof(iso8601Format)));

if (iso8601Format[0] != 0) {
struct tm tm;
tm.tm_year = atoi(&iso8601Format[0], 4) - 1900;
tm.tm_mon = atoi(&iso8601Format[5], 2) - 1;
tm.tm_mday = atoi(&iso8601Format[8], 2);
tm.tm_hour = atoi(&iso8601Format[11], 2);
tm.tm_min = atoi(&iso8601Format[14], 2);
tm.tm_sec = atoi(&iso8601Format[17], 2);
HwClock::Get()->AlarmSet(&tm);

DEBUG_EXIT
return;
}

DEBUG_EXIT
}
} // namespace rtc
} // namespace remoteconfig
Loading

0 comments on commit 1f3d876

Please sign in to comment.