Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rtc binary only mode subseconds param. expressed in milliseconds #101

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ _RTC hours mode (12 or 24)_

_RTC clock source_
* **`Source_Clock getClockSource(void)`** : get current clock source.
* **`void setClockSource(Source_Clock source)`** : this function must be called before `begin()`.
* **`void setClockSource(Source_Clock source, uint32_t predivA, uint32_t predivS)`** : set the clock source (`LSI_CLOCK`, `LSE_CLOCK` or `HSE_CLOCK`) and (a)synchronous prescaler values. This function must be called before `begin()`. Use `(PREDIVA_MAX + 1)` and `(PREDIVS_MAX +1)` to reset value and use computed ones. Those values have to match the following conditions: **_1Hz = RTC CLK source / ((predivA + 1) * (predivS + 1))_**

_RTC Asynchronous and Synchronous prescaler_
* **`void getPrediv(int8_t *predivA, int16_t *predivS)`** : get (a)synchronous prescaler values if set else computed ones for the current clock source.
* **`void setPrediv(int8_t predivA, int16_t predivS)`** : set (a)synchronous prescaler values. This function must be called before `begin()`. Use -1 to reset value and use computed ones. Those values have to match the following conditions: **_1Hz = RTC CLK source / ((predivA + 1) * (predivS + 1))_**
* **`void getPrediv(uint32_t *predivA, uint32_t *predivS)`** : get (a)synchronous prescaler values if set else computed ones for the current clock source.
* **`void setPrediv(uint32_t predivA, uint32_t predivS)`** : set (a)synchronous prescaler values. This function must be called before `begin()`. Use `(PREDIVA_MAX + 1)` and `(PREDIVS_MAX +1)` to reset value and use computed ones. Those values have to match the following conditions: **_1Hz = RTC CLK source / ((predivA + 1) * (predivS + 1))_**

_SubSeconds management_
* **`uint32_t getSubSeconds(void)`**
Expand Down
51 changes: 33 additions & 18 deletions examples/RTCReset/RTCReset.ino
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ typedef struct {
bool alarm_a;
} cb_data_t;

static cb_data_t atime = { 2222, true};
static cb_data_t atime = { 2222, true };
#ifdef RTC_ALARM_B
static cb_data_t btime = { 3333, false};
static cb_data_t btime = { 3333, false };
#endif
static byte seconds = 0;
static byte minutes = 0;
Expand All @@ -64,7 +64,7 @@ static uint8_t conv2d(const char* p) {
}

// sample input: date = "Dec 26 2009", time = "12:34:56"
void initDateTime (void) {
void initDateTime(void) {
Serial.printf("Build date & time %s, %s\n", mydate, mytime);

year = conv2d(mydate + 9);
Expand All @@ -89,15 +89,15 @@ void initDateTime (void) {
seconds = conv2d(mytime + 6);
}

void setup()
{
void setup() {
pinMode(USER_BTN, INPUT_PULLUP);
int32_t default_state = digitalRead(USER_BTN);

Serial.begin(9600);
while (!Serial);
Serial.begin(115200);
while (!Serial)
;
// Wait user input to start
while (digitalRead(USER_BTN) == default_state);
while (digitalRead(USER_BTN) == default_state)
;
// Convenient function to init date and time variables
initDateTime();

Expand All @@ -110,7 +110,7 @@ void setup()
#ifdef RTC_ALARM_B
rtc.attachInterrupt(alarmMatch, &btime, STM32RTC::ALARM_B);
#endif
rtc.begin(); // Initialize RTC 24H format
rtc.begin(); // Initialize RTC 24H format
if (!rtc.isTimeSet()) {
Serial.printf("RTC time not set\n Set it.\n");
// Set the time
Expand All @@ -129,6 +129,10 @@ void setup()
} else {
// RTC already initialized
time_t epoc, alarm_epoc;
rtc.getTime(&hours, &minutes, &seconds, &subSeconds, &period);
year = rtc.getYear();
month = rtc.getMonth();
day = rtc.getDay();
if (rtc.isAlarmEnabled()) {
rtc.enableAlarm(rtc.MATCH_DHHMMSS);
alarm_epoc = rtc.getAlarmEpoch();
Expand Down Expand Up @@ -156,16 +160,28 @@ void setup()
#endif
Serial.printf("RTC time already set\n");
}
Serial.printf("Alarm A enable status: %s\n", (rtc.isAlarmEnabled(STM32RTC::ALARM_A)) ? "True" : "False");
// For STM32F1xx series, alarm is always disabled after a reset.
bool alarmA = rtc.isAlarmEnabled(STM32RTC::ALARM_A);
Serial.printf("Alarm A enable status: %s\n", (alarmA) ? "True" : "False");
if (!alarmA) {
rtc.setAlarmDay(day);
rtc.setAlarmTime(hours, minutes, seconds + 5, 567);
rtc.enableAlarm(rtc.MATCH_DHHMMSS);
}
#ifdef RTC_ALARM_B
Serial.printf("Alarm B enable status: %s\n", (rtc.isAlarmEnabled(STM32RTC::ALARM_B)) ? "True" : "False");
bool alarmB = rtc.isAlarmEnabled(STM32RTC::ALARM_B);
Serial.printf("Alarm B enable status: %s\n", (alarmB) ? "True" : "False");
if (!alarmB) {
rtc.setAlarmDay(day, STM32RTC::ALARM_B);
rtc.setAlarmTime(hours, minutes, seconds + 5, 567, STM32RTC::ALARM_B);
rtc.enableAlarm(rtc.MATCH_DHHMMSS, STM32RTC::ALARM_B);
}
#else
Serial.println("Alarm B not available.");
#endif
}

void loop()
{
void loop() {
rtc.getTime(&hours, &minutes, &seconds, &subSeconds, &period);
// Print current date & time
Serial.printf("\n%02d/%02d/%02d %02d:%02d:%02d.%03d\n", rtc.getDay(), rtc.getMonth(), rtc.getYear(), hours, minutes, seconds, subSeconds);
Expand All @@ -177,13 +193,12 @@ void loop()
delay(1000);
}

void alarmMatch(void *data)
{
void alarmMatch(void* data) {
time_t epoc;
uint32_t epoc_ms;
uint32_t sec = 0;
uint32_t _millis = 1000;
cb_data_t cbdata = {.next = 1000, .alarm_a = true};
cb_data_t cbdata = { .next = 1000, .alarm_a = true };
if (data != NULL) {
cbdata.next = ((cb_data_t*)data)->next;
cbdata.alarm_a = ((cb_data_t*)data)->alarm_a;
Expand All @@ -204,7 +219,7 @@ void alarmMatch(void *data)
// Update epoch_ms - might need to add a second to epoch
epoc_ms += _millis;
if (epoc_ms >= 1000) {
sec ++;
sec++;
epoc_ms -= 1000;
}
#endif
Expand Down
83 changes: 83 additions & 0 deletions examples/bin_onlyRTCAlarm/bin_onlyRTCAlarm.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
mode BINary only RTC alarm

This sketch shows how to configure the alarm A & B of the RTC in BIN mode

Creation 12 Dec 2017
by Wi6Labs
Modified 03 Jul 2020
by Frederic Pillon for STMicroelectronics
Modified 03 sept 2023
by Francois Ramu for STMicroelectronics

This example code is in the public domain.

https://github.com/stm32duino/STM32RTC
*/

#include <STM32RTC.h>

/* Get the rtc object */
STM32RTC& rtc = STM32RTC::getInstance();

uint32_t timeout;

void setup()
{
Serial.begin(115200);

// Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK.
rtc.setClockSource(STM32RTC::LSE_CLOCK);

/* Configure the RTC mode */
rtc.setBinaryMode(STM32RTC::MODE_BIN);

/* in BIN mode time and Date register are not used, only the subsecond register for milisseconds */
rtc.begin(true, STM32RTC::HOUR_24);

/* wait for a while */
delay(200);

/* subsecond expressed in milliseconds */
Serial.printf("Start at %d ms \r\n", rtc.getSubSeconds());

/* Attach the callback function before enabling Interrupt */
rtc.attachInterrupt(alarmAMatch);

/* Program the AlarmA in 12 seconds */
rtc.setAlarmTime(0, 0, 0, 12000);
rtc.enableAlarm(rtc.MATCH_SUBSEC);
Serial.printf("Set Alarm A in 12s (at %d ms)\r\n", rtc.getAlarmSubSeconds());

#ifdef RTC_ALARM_B
/* Program ALARM B in 400ms ms from now (keep timeout < 1000ms) */
timeout = rtc.getSubSeconds() + 400;

rtc.attachInterrupt(alarmBMatch, STM32RTC::ALARM_B);
rtc.setAlarmSubSeconds(timeout, STM32RTC::ALARM_B);
rtc.enableAlarm(rtc.MATCH_SUBSEC, STM32RTC::ALARM_B);
Serial.printf("Set Alarm B (in %d ms) at %d ms\r\n", 400,
rtc.getAlarmSubSeconds(STM32RTC::ALARM_B));
#endif

}

void loop()
{

}

void alarmAMatch(void *data)
{
UNUSED(data);
rtc.disableAlarm(STM32RTC::ALARM_A);
Serial.printf("Alarm A Match at %d ms \r\n", rtc.getSubSeconds());
}

void alarmBMatch(void *data)
{
UNUSED(data);
rtc.disableAlarm(STM32RTC::ALARM_B); /* Else it will trig again */
Serial.printf("Alarm B Match at %d ms\r\n", rtc.getSubSeconds());
}

99 changes: 99 additions & 0 deletions examples/mixRTCAlarm/mixRTCAlarm.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
mode Mix RTC alarm

This sketch shows how to configure the alarm A & B of the RTC in MIX mode

Creation 12 Dec 2017
by Wi6Labs
Modified 03 Jul 2020
by Frederic Pillon for STMicroelectronics
Modified 03 Jul 2023
by Francois Ramu for STMicroelectronics

This example code is in the public domain.

https://github.com/stm32duino/STM32RTC
*/

#include <STM32RTC.h>

/* Get the rtc object */
STM32RTC& rtc = STM32RTC::getInstance();

/* Change these values to set the current initial time */
const byte seconds = 06;
const byte minutes = 22;
const byte hours = 16;

/* Change these values to set the current initial date */
const byte day = 25;
const byte month = 6;
const byte year = 23;

uint32_t timeout;

void setup()
{
Serial.begin(115200);

// Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK.
rtc.setClockSource(STM32RTC::LSE_CLOCK);

/* Configure the RTC mode : STM32RTC::MODE_MIX or STM32RTC::MODE_BCD */
rtc.setBinaryMode(STM32RTC::MODE_MIX);

rtc.begin(true, STM32RTC::HOUR_24);

rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);

/* wait for a while */
delay(200);

Serial.printf("Start at %02d:%02d:%02d.%03d\r\n",
rtc.getHours(), rtc.getMinutes(), rtc.getSeconds(), rtc.getSubSeconds());

/* Attach the callback function before enabling Interrupt */
rtc.attachInterrupt(alarmAMatch);

/* Program the AlarmA in a 12 seconds */
rtc.setAlarmDay(day);
rtc.setAlarmTime(hours, minutes, seconds + 12);
rtc.enableAlarm(rtc.MATCH_DHHMMSS);
Serial.printf("Set Alarm A in 12s (at %02d:%02d:%02d)\r\n",
rtc.getAlarmHours(), rtc.getAlarmMinutes(), rtc.getAlarmSeconds());

#ifdef RTC_ALARM_B
/* Program ALARM B in 400ms ms from now (keep timeout < 1000ms) */
timeout = rtc.getSubSeconds() + 400;

rtc.attachInterrupt(alarmBMatch, STM32RTC::ALARM_B);
rtc.setAlarmSubSeconds(timeout, STM32RTC::ALARM_B);
rtc.enableAlarm(rtc.MATCH_SUBSEC, STM32RTC::ALARM_B);
Serial.printf("Set Alarm B (in %d ms) at %d ms\r\n", 400,
rtc.getAlarmSubSeconds(STM32RTC::ALARM_B));
#endif

}

void loop()
{

}

void alarmAMatch(void *data)
{
UNUSED(data);
rtc.disableAlarm(STM32RTC::ALARM_A);
Serial.printf("Alarm A Match at %02d:%02d:%02d\r\n",
rtc.getHours(), rtc.getMinutes(), rtc.getSeconds());
}

void alarmBMatch(void *data)
{
UNUSED(data);
rtc.disableAlarm(STM32RTC::ALARM_B); /* Else it will trig again */
Serial.printf("Alarm B Match at %d ms\r\n", rtc.getSubSeconds());
}


Loading
Loading