I am wondering whether all the necessary addon functionality is there, or whether something was overlooked. N.b there is only 1 alarm exposed. The 2nd in hardware is reserved for internal purposes.
Thanx for looking.
class RTClock {
public:
enum RTCAlarmMatch
{
MATCH_OFF, // Never
MATCH_SS, // Every Minute
MATCH_MMSS, // Every Hour
MATCH_HHMMSS, // Every Day
MATCH_DDHHMMSS, // Every Month
MATCH_MMDDHHMMSS, // Every Year
MATCH_YYMMDDHHMMSS, // Once, on a specific date and a specific time
};
RTClock();
void begin(bool resetTime = false);
void enableAlarm(RTCAlarmMatch match);
void disableAlarm();
void attachInterrupt(void(*callback)(void));
void detachInterrupt();
void standbyMode();
// Get Functions
uint8_t getSeconds();
uint8_t getMinutes();
uint8_t getHours();
uint8_t getDay();
uint8_t getMonth();
uint8_t getYear();
uint8_t getAlarmSeconds();
uint8_t getAlarmMinutes();
uint8_t getAlarmHours();
uint8_t getAlarmDay();
uint8_t getAlarmMonth();
uint8_t getAlarmYear();
// Set Functions
void setSeconds(uint8_t seconds);
void setMinutes(uint8_t minutes);
void setHours(uint8_t hours);
void setTime(uint8_t hours, uint8_t minutes, uint8_t seconds);
void setDay(uint8_t day);
void setMonth(uint8_t month);
void setYear(uint8_t year);
void setDate(uint8_t day, uint8_t month, uint8_t year);
void setAlarmSeconds(uint8_t seconds);
void setAlarmMinutes(uint8_t minutes);
void setAlarmHours(uint8_t hours);
void setAlarmTime(uint8_t hours, uint8_t minutes, uint8_t seconds);
void setAlarmDay(uint8_t day);
void setAlarmMonth(uint8_t month);
void setAlarmYear(uint8_t year);
void setAlarmDate(uint8_t day, uint8_t month, uint8_t year);
// Epoch Functions
uint32_t getEpoch();
uint32_t getY2kEpoch();
void setEpoch(uint32_t ts);
void setY2kEpoch(uint32_t ts);
// EXTENSTION: subsecond handling for timer synchronisation
uint32_t getSubSeconds();
void shiftSubSeconds(int32_t micros);
// EXTENSTION: clock calibration [-511..512]
int32_t getCalibration();
void setCalibration(int32_t calibration);
// EXTENSTION: periodic wakeup
void wakeup(uint32_t millis, void(*callback)(void));
};
extern RTClock RTC;
Why would you not expose the second Alarm ?
On F1, if I remember, there is only 1, but on F4, I’ve implemented the lib with both available.
Why would you not expose the second Alarm ?
On F1, if I remember, there is only 1, but on F4, I’ve implemented the lib with both available.
Overview of the STM32 advanced RTC
AN3371
8/42
Doc ID 018624 Rev 2
1.2 RTC alarms
1.2.1
RTC Alarm configuration
STM32 RTC embeds two alarms, Alarm A and Alarm B, which are similar. An alarm can be
generated at a given time or/and date programmed by the user.
The STM32 RTC provides a rich combination of alarms settings, and offers many features to
make it easy to configure and display these alarms settings.
I cannot find anything specific to the F10x that says there is only one, however you may well be correct.On the other hand, even if the STM documentation claims only one for the F10x, this may be marketing spec rather than anything to do with the silicon, and the 2nd alarm may actually work any way.
For the F4xx, the document STM32F4xxx-RM0090-DM00031020.pdf (chap.26) is showing that there are 2 Alarms, A and B, and also WakeUp timer, which I’ve implemented in RTClock for F4 as setPeriodicWakeup() awhile ago.
EDIT : Also, on a side note, the RTC of F1 is “epoch” based while the F4 is BCD based.
For the F4xx, the document STM32F4xxx-RM0090-DM00031020.pdf (chap.26) is showing that there are 2 Alarms, A and B, and also WakeUp timer, which I’ve implemented in RTClock for F4 as setPeriodicWakeup() awhile ago.
EDIT : Also, on a side note, the RTC of F1 is “epoch” based while the F4 is BCD based.
For the F4xx, the document STM32F4xxx-RM0090-DM00031020.pdf (chap.26) is showing that there are 2 Alarms, A and B, and also WakeUp timer, which I’ve implemented in RTClock for F4 as setPeriodicWakeup() awhile ago.
EDIT : Also, on a side note, the RTC of F1 is “epoch” based while the F4 is BCD based.
The API is compatible with RTCZero (the code on github has a “RTCZero.h” wrapper). Couple of caveats. The wakeup timer is not exposed. This is reserved for “STM32.sleep(timeout)” and “STM32.deepsleep(timeout)”. The 2nd alarm for L0 and L4 is not exposed at the moment to support a future “RTCAlarm” class.
Some notes. RTC.getCalibration/setCalibration allows to speed-up/slow-down the clock. One uses RTC.pinMode(OUTPUT_1HZ) for example to output a 1Hz signal on PC13 which can be compared to a more precise reference clock. RTC.adjustTicks() can be used together with RTC.pinMode(INPUT_SYNC) to aligned the RTC with an external clock. Say one connects the PPS of a GPS to PC13, and uses RTC.onSync(). Each time there is a rising edge on PPS, the onSync() callback will be called, and with RTC.getSyncTicks() the offset (or adjustment factor) can be determinted. The sync facility itself can be used also to measure the exact time of an external event, say a button press (which is the default for Dragonfly).
N.b that “ticks” are similar to “subseconds” in the STM documentation, except that they are always scaled to [0..32767].
Thanx for looking.
class RTCClass {
public:
enum AlarmMatch: uint8_t {
MATCH_ANY = 0, // Every Second
MATCH_SS = 1, // Every Minute
MATCH_MMSS = 3, // Every Hour
MATCH_HHMMSS = 7, // Every Day
MATCH_DHHMMSS = 15, // Every Month
MATCH_MMDDHHMMSS = 31, // Every Year
MATCH_YYMMDDHHMMSS = 64 // Once, on a specific date and a specific time
};
enum PinMode: uint8_t {
NONE = 0,
INPUT_SYNC = 1,
OUTPUT_512HZ = 2,
OUTPUT_1HZ = 3,
};
void enableAlarm(AlarmMatch match);
void disableAlarm();
void attachInterrupt(void(*callback)(void));
void detachInterrupt();
// Get Functions
uint8_t getSeconds();
uint8_t getMinutes();
uint8_t getHours();
uint8_t getDay();
uint8_t getMonth();
uint8_t getYear();
uint8_t getAlarmSeconds();
uint8_t getAlarmMinutes();
uint8_t getAlarmHours();
uint8_t getAlarmDay();
uint8_t getAlarmMonth();
uint8_t getAlarmYear();
// Set Functions
void setSeconds(uint8_t seconds);
void setMinutes(uint8_t minutes);
void setHours(uint8_t hours);
void setTime(uint8_t hours, uint8_t minutes, uint8_t seconds);
void setDay(uint8_t day);
void setMonth(uint8_t month);
void setYear(uint8_t year);
void setDate(uint8_t day, uint8_t month, uint8_t year);
void setAlarmSeconds(uint8_t seconds);
void setAlarmMinutes(uint8_t minutes);
void setAlarmHours(uint8_t hours);
void setAlarmTime(uint8_t hours, uint8_t minutes, uint8_t seconds);
void setAlarmDay(uint8_t day);
void setAlarmMonth(uint8_t month);
void setAlarmYear(uint8_t year);
void setAlarmDate(uint8_t day, uint8_t month, uint8_t year);
// Epoch Functions
uint32_t getEpoch();
uint32_t getY2kEpoch();
void setEpoch(uint32_t ts);
void setY2kEpoch(uint32_t ts);
// STM32L4 EXTENSION: atomic set time/date
void setCalendar(uint8_t hours, uint8_t minutes, uint8_t seconds, uint8_t day, uint8_t month, uint8_t year);
// STM32L4 EXTENSION: ticks [0..32767] uint16_t getTicks();
// STM32L4 EXTENSION: clock calibration [-511..512]
int32_t getCalibration();
void setCalibration(int32_t calibration);
// STM32L4 EXTENSION: clock fine tuning [-32767..32768] void adjustTicks(int32_t ticks);
// STM32L4 EXTENSION: external sync pulse
bool syncOccured();
uint16_t getSyncTicks();
uint8_t getSyncSeconds();
uint8_t getSyncMinutes();
uint8_t getSyncHours();
uint8_t getSyncDay();
uint8_t getSyncMonth();
void onSync(void(*callback)(void));
// STM32L4 EXTENSION: PC13 control
void pinMode(PinMode mode);
};
extern RTCClass RTC;
I guess you supply power to vbat, to keep the rtc powered when the rest of the MCU is unpowered?
How much voltage? 1.5? 3v?
And im assuming there isnt already a functioning library?
Hence this thread? ![]()
I guess a little guide would be useful… or if you know of any documentation I can read even better ![]()
Sorry for the dumb post, im fairly tired and backs in pain………… (crippled)
I’m personally using a SuperCapacitor instead of a battery.
The library on github is working fine.
Does the built in rtc work off unix time? So you can derive a date from the number? Or is it simple 24 hour clock and nothing else?
i see the gettime function seems to be call to check the time. But I dont see any get date or anything else…
Does the built in rtc work off unix time? So you can derive a date from the number? Or is it simple 24 hour clock and nothing else?
i see the gettime function seems to be call to check the time. But I dont see any get date or anything else…
Having search for “RTC STM32L4” and reading the thread.
I’m wondering why the link is for F1
https://github.com/rogerclarkmelbourne/ … es/RTClock
And I is see no L4 section at all at the basic link, only F1/F3/F4.
https://github.com/rogerclarkmelbourne/Arduino_STM32
Does anyone know where I can find the L4 libraries..
Best regards,
Frank
[GrumpyOldPizza – Sun Oct 23, 2016 2:01 pm] –
Ok, finally got around implementing all of this for the STM32L4 core. Could somebody review && || provide feedback whether I got the API and functionality correct ?
[…] Some notes. RTC.getCalibration/setCalibration allows to speed-up/slow-down the clock. One uses RTC.pinMode(OUTPUT_1HZ) for example to output a 1Hz signal on PC13 which can be compared to a more precise reference clock. RTC.adjustTicks() can be used together with RTC.pinMode(INPUT_SYNC) to aligned the RTC with an external clock. Say one connects the PPS of a GPS to PC13, and uses RTC.onSync(). Each time there is a rising edge on PPS, the onSync() callback will be called, and with RTC.getSyncTicks() the offset (or adjustment factor) can be determinted. The sync facility itself can be used also to measure the exact time of an external event, say a button press (which is the default for Dragonfly).
I’m just curious about the sync method. I admit I haven’t yet looked at the F4 calibration circuit to see if there are any major differences from the F1. But on the F1, it takes more than one second to obtain a measurement equal to the register calibration steps, it takes at least 32 seconds. What I did is sample the 32kHz ticks twice, at least 32 seconds apart. That is because N pulses are removed in one 32S interval. Then some math to scale it to calibration steps. Is that close to what you are doing with the sync method in your RTC library?
Also have you considered the possibly intermittent nature of the incoming sync? For example, a device might only get PPS when it is near a window and it would be desirable to automatically retain the resulting cal, and continue to operate normally, even if the whole thing is moved to a place were GPS is dark.
Or, if the device lacks GPS hardware, and it is applied to external terminals for the purpose of an initial or a periodic calibration.
[electrobling – Mon Apr 09, 2018 6:00 pm] –[GrumpyOldPizza – Sun Oct 23, 2016 2:01 pm] –
Ok, finally got around implementing all of this for the STM32L4 core. Could somebody review && || provide feedback whether I got the API and functionality correct ?
[…] Some notes. RTC.getCalibration/setCalibration allows to speed-up/slow-down the clock. One uses RTC.pinMode(OUTPUT_1HZ) for example to output a 1Hz signal on PC13 which can be compared to a more precise reference clock. RTC.adjustTicks() can be used together with RTC.pinMode(INPUT_SYNC) to aligned the RTC with an external clock. Say one connects the PPS of a GPS to PC13, and uses RTC.onSync(). Each time there is a rising edge on PPS, the onSync() callback will be called, and with RTC.getSyncTicks() the offset (or adjustment factor) can be determinted. The sync facility itself can be used also to measure the exact time of an external event, say a button press (which is the default for Dragonfly).I’m just curious about the sync method. I admit I haven’t yet looked at the F4 calibration circuit to see if there are any major differences from the F1. But on the F1, it takes more than one second to obtain a measurement equal to the register calibration steps, it takes at least 32 seconds. What I did is sample the 32kHz ticks twice, at least 32 seconds apart. That is because N pulses are removed in one 32S interval. Then some math to scale it to calibration steps. Is that close to what you are doing with the sync method in your RTC library?
Also have you considered the possibly intermittent nature of the incoming sync? For example, a device might only get PPS when it is near a window and it would be desirable to automatically retain the resulting cal, and continue to operate normally, even if the whole thing is moved to a place were GPS is dark.
Or, if the device lacks GPS hardware, and it is applied to external terminals for the purpose of an initial or a periodic calibration.
A loaded topic. I am starting to use a slightly different technique now, mainly because the SYNC input might not be always available. The idea in general is to qualify the PPS input with a valid fix. I.e. it’s only armed after a valid fix (or sequence thereof). If you have a valid fix, then you have everything down to the second essentially. So you need to align the subsecond as a first step. With a PPS interrupt that is half way easy. If the getSubSeconds() read back is say between 1 and 16383, then you need to subtract from the subseconds, i.e. RTC.adjustSubSeconds(-offset). If your subseconds are between 16384 and 32767, then you need to add to the subseconds. Obviously you want to apply a filter, so that the steps close to the right alignment are smaller than the ones from far out.
If you have 2 back to back PPS measurements you also can derive from the uncompensated subseconds the period, and hence do fine calibration. Again, the issue is jitter, which requires a filter.
Have only really looked into that with regards to a GNSS …
Indeed, when I experimented with some GPS modules, they sometimes provided PPS pulses before a fix and I wasn’t too sure about that. I implemented a gate based on the NMEA sentences, as you suggested, to wait until the fix to sample it. But this time around, I’ve been lazy and wait 5 minutes after the light starts flashing (serial not connected). I also check for missing pulses. If one is missed, I stop the calibration and start all over.
I have some F4 boards on order, they have an onboard battery circuit so I may get a chance to try out whatever you come up with.


