I am really digging this GIGA and its dual cores, the display, wow...so much new stuff to figure out.
Soldered a CR2032 to the VRTC pin which supplies Vbat on the chip and but if I get this right this only works if RTC is clocked by external oscillator (LSE). At present, if I get this right also, by default the RTC is clocked by its internal oscillator (LSI, at about 32kHz)? Would this explain the 1 sec gain/30 min? I found also about a 37 sec gain in time over a day maybe.
Can a guy get some beats off the MEMS oscillator for the RTC?
Thanks, Mark
Whoa, a 93-minute gain in time overnight.
Prolly better served mounting a sundial and LDRs to back of board and clock on the gnomon shadow.
But then useless at night.
I'm equally unimpressed by the GIGAs RTC and may have to pull my old external module out of retirement.
I lost about 12hrs overnight and when I tried to sync with ntp this morning it crashed:
Start NTP client
Send NTP req to: 192.168.1.7
No response to ntp
Send NTP req to: 192.168.1.2
++ MbedOS Error Info ++
Error Status: 0x80FF0100 Code: 256 Module: 255
Error Message: Fatal Run-time error
Location: 0x8094BDD
Error Value: 0x0
Current Thread: application_unnamed_thread Id: 0x24019E80 Entry: 0x8085E09 StackSize: 0x1000 StackMem: 0x24019ED0 SP: 0x2401ABBC
For more info, visit: mbedos-error
-- MbedOS Error Info --
Cannot initialize RTC with LSE
I had to disconnect and reconnect the coin and then ntp worked ok. Interesting the error message I got referred to LSE
UPDATE: In short, best I can figure out, NO.
That oscillator serves the Murata WiFi chip.
However, on PC14 and PC15 is connected a good old fashioned Citizen 32.768kHz crystal. And I do not have the slightest idea if the Arduino Giga core has set that as the crystal for the RTC.
My UNO-level aptitude tells me I need just get a DS3231 or a Chronodot and try figure out _REFIN and _SHIFTR, because hitting up NTP every 15 minutes is not very appealing.
Maybe some charitable soul could help enlighten a fella as to how to Serial.print out the contents of the RCC_BDCR register (0x070), particularly the bits 9:8, which are the RTCSEL bits. This as found in ST's RM0399, p. 458, here.
Hi @bambuino,
I appreciate your enthusiasm for the GIGA board and your efforts in exploring its features. I wanted to clarify that, in the current production version of GIGA, the external RTC Y1 oscillator is not available.
I apologize for any confusion, and I want to inform you that the product page documentation for GIGA has been updated to reflect this information accurately. You can refer to the updated schematics document for more details: GIGA Schematics.
If you have further questions or if there's anything else you'd like to explore on the GIGA board, feel free to ask.
Best regards,
I am very confused. From the updated schematic you provided, I now see that component Y2 (Citizen 32.768kHz crystal) has the red X's on lines to GND. However, from the block diagram and board outline in the datasheet, Y2 is there, and can confirm that the component is in fact mounted on the GIGA board.
So, can you explain the difference between what I seemingly see in front of my eyes, and what it is that you are telling me?
Really appreciate it. Thank you.
Hi @bambuino,
You are right, I have rectified my previous answer. What I am referring to is that the Y1 clock is not present, but as you rightly point out, Y2 is. I just wanted to let you know that we have updated the schematics with the current production version.
Sorry for the confusion caused in the previous message.
Gee, I wonder if uh...
My neighbor is a retired attorney. He must have been an awesome attorney, because when I ask him a direct question I always receive evasive and obfuscatory reponses.
@jorgetrujilloroman
Is the 32.768kHz crystal purportedly mounted across PC14 and PC15 on the GIGA R1 fully functional?
Thank you.
UPDATE:
Boy oh boy, I sure feel like a total dope. After previously having spent weeks and weeks on trying to figure out how to get the RTC to function properly, get it to run with some semblance of what a clock typically does. Granted, I am pretty much the noob with STM32, and this GIGA board is a big board with lots of stuff on it, I never took a close look a the board itself.
In my previous posts I posed questions for which I think I have the answer.
NO, the RTC on the GIGA R1 WiFi will not function properly -- EVER.
Let's take a close look at this board.
Notice something? That's right. Both the 32.768kHz and 16MHz oscillators are missing the load capacitors. The load capacitors for the RTC are spec'd in ST's App Note 2867.
There is an open ticket with Arduino on this matter. They offered to refund the cost of board. However, as seen below, I have more invested in this than just the cost of the board. And, by their offer, I am inclined to think that this is not just a one-off thing. Perhaps all the GIGA R1 WiFi's suffer this hardware bug?
So, now my question is...should I attempt to hand solder in the 1005 size caps? I thought of testing with some 12pF THTs, but even that sounds kinda messy, given my level of skill.
I would check off this topic as SOLVED, but is this really solved given the buggy board?
@bambuino the load capacitors are not mounted since the internal capacitance of the crystal is very similar to the requested load (from datasheet). However, probably due to a small variance in the various production batch, it looks like some recent boards are not driving the quartz correctly (the signal is very weak).
To fix this, you may try adding these lines to any sketch (no need to call any function, the constructor will just run before main()
class FixRTC {
public:
FixRTC() {
LL_RCC_LSE_Disable();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
LL_RCC_LSE_Enable();
}
};
FixRTC fixrtc __attribute__ ((init_priority (101)));
I can't test the stability over time at the moment but if you could run a test we can include the fix in the next version of the core (if it works, of course )
@facchinm Setting the RTC has not worked since the 4.0.8 core on my board, back in December 2023. Sketches attempted would be those found on the Cheat Sheet page, both manual and NTP/UDP examples, and those found elsewhere, such as Arduino GIGA R1 WiFi | DroneBot Workshop .
Should I roll back the board core to 4.0.8? As well the IDE has updated once or twice in the past couple months, should I roll that back as well?
A note on the NTP/UDP examples, connecting WiFi works, until setting the RTC would seemingly take place, after which board crashes with blinky red light crash code. All RTC code examples, where an attempt is made to update time with RTCset();
or setNtpTime();
, will crash the board since 4.0.8 core.
As I have the backup battery attached, no matter what code is running on the board, the RTC is still running in the background. At present it reports time on 24 Feb, so has accrued -5 day error since mid-December 2023.
Please advise.
EDITS below:
Above referenced 5-day error.
15:17:18.083 -> System Clock: 2023-02-24 16:28:33
15:17:19.106 -> System Clock: 2023-02-24 16:28:34
15:17:20.090 -> System Clock: 2023-02-24 16:28:35
/*
from: https://docs.arduino.cc/tutorials/giga-r1-wifi/cheat-sheet/#rtc-manual-example
accessed: 29 Feb 2024
*/
#include "mbed.h"
#include <mbed_mktime.h>
constexpr unsigned long printInterval { 1000 };
unsigned long printNow {};
class FixRTC {
public:
FixRTC() {
LL_RCC_LSE_Disable();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
LL_RCC_LSE_Enable();
}
};
FixRTC fixrtc __attribute__ ((init_priority (101)));
void setup() {
Serial.begin(9600);
RTCset();
}
void loop() {
if (millis() > printNow) {
Serial.print("System Clock: ");
Serial.println(getLocaltime());
printNow = millis() + printInterval;
}
}
void RTCset() // Set cpu RTC
{
tm t;
t.tm_sec = (0); // 0-59 // Attempting to set current time
t.tm_min = (29); // 0-59
t.tm_hour = (15); // 0-23
t.tm_mday = (29); // 1-31
t.tm_mon = (1); // 0-11 "0" = Jan, -1
t.tm_year = ((24)+100); // year since 1900, current year + 100 + 1900 = correct year
set_time(mktime(&t)); // set RTC clock
}
String getLocaltime()
{
char buffer[32];
tm t;
_rtc_localtime(time(NULL), &t, RTC_4_YEAR_LEAP_YEAR_SUPPORT);
strftime(buffer, 32, "%Y-%m-%d %k:%M:%S", &t);
return String(buffer);
}
I have rolled back to the 4.0.8 core and burned its bootloader to the GIGA R1 board. Things have improved, in that when I attempt RTCset();
or setNtpTime();
the board does not crash. Current time can be stored to the on-board RTC.
Referring to following sketch, where the RCC_BDCR is polled every so often:
/*
Udp NTP Client with Timezone Adjustment
Get the time from a Network Time Protocol (NTP) time server
Demonstrates use of UDP sendPacket and ReceivePacket
For more on NTP time servers and the messages needed to communicate with them,
see http://en.wikipedia.org/wiki/Network_Time_Protocol
created 4 Sep 2010
by Michael Margolis
modified 9 Apr 2012
by Tom Igoe
modified 28 Dec 2022
by Giampaolo Mancini
modified 29 Jan 2024
by Karl Söderby
This code is in the public domain.
*/
#include <WiFi.h>
#include <WiFiUdp.h>
#include <mbed_mktime.h>
#define VERBOSE 0
unsigned long millis();
unsigned long previousMillis = 0;
int timezone = -10; //this is GMT -1.
int status = WL_IDLE_STATUS;
char ssid[] = "nunya"; // your network SSID (name)
char pass[] = "biznez"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)
unsigned int localPort = 2390; // local port to listen for UDP packets
// IPAddress timeServer(162, 159, 200, 123); // pool.ntp.org NTP server
constexpr auto timeServer{ "pool.ntp.org" };
const int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
// A UDP instance to let us send and receive packets over UDP
WiFiUDP Udp;
constexpr unsigned long printInterval{ 1000 };
unsigned long printNow{};
class FixRTC {
public:
FixRTC() {
LL_RCC_LSE_Disable();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
LL_RCC_LSE_Enable();
//RCC->BDCR = (RCC->BDCR & ~(RCC_BDCR_LSEDRV_Msk)) | RCC_BDCR_LSEDRV_1;
}
};
FixRTC fixrtc __attribute__((init_priority(101)));
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println(RCC->BDCR, BIN);
// check for the WiFi module:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true)
;
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println("Connected to WiFi");
printWifiStatus();
setNtpTime();
}
void loop() {
if (millis() > printNow) {
Serial.print("System Clock: ");
Serial.println(getLocaltime());
printNow = millis() + printInterval;
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > 5000) {
previousMillis = currentMillis;
Serial.println(RCC->BDCR, BIN);
}
}
void setNtpTime() {
Udp.begin(localPort);
sendNTPpacket(timeServer);
delay(1000);
parseNtpPacket();
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(const char* address) {
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123); // NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
unsigned long parseNtpPacket() {
if (!Udp.parsePacket())
return 0;
Udp.read(packetBuffer, NTP_PACKET_SIZE);
const unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
const unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
const unsigned long secsSince1900 = highWord << 16 | lowWord;
constexpr unsigned long seventyYears = 2208988800UL;
const unsigned long epoch = secsSince1900 - seventyYears;
const unsigned long new_epoch = epoch + (3600 * timezone); //multiply the timezone with 3600 (1 hour)
set_time(new_epoch);
#if defined(VERBOSE)
Serial.print("Seconds since Jan 1 1900 = ");
Serial.println(secsSince1900);
// now convert NTP time into everyday time:
Serial.print("Unix time = ");
// print Unix time:
Serial.println(epoch);
// print the hour, minute and second:
Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT)
Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day)
Serial.print(':');
if (((epoch % 3600) / 60) < 10) {
// In the first 10 minutes of each hour, we'll want a leading '0'
Serial.print('0');
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ((epoch % 60) < 10) {
// In the first 10 seconds of each minute, we'll want a leading '0'
Serial.print('0');
}
Serial.println(epoch % 60); // print the second
#endif
return epoch;
}
String getLocaltime() {
char buffer[32];
tm t;
_rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
strftime(buffer, 32, "%Y-%m-%d %k:%M:%S", &t);
return String(buffer);
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
Uploading this sketch, Serial output is follows:
22:26:10.297 -> Connected to WiFi
22:26:10.297 -> SSID: nunya
22:26:10.297 -> IP Address: 192.168.1.111
22:26:10.345 -> signal strength (RSSI):-39 dBm
22:26:11.538 -> Seconds since Jan 1 1900 = 3918270370
22:26:11.538 -> Unix time = 1709281570
22:26:11.538 -> The UTC time is 8:26:10
22:26:11.538 -> System Clock: 2024-02-29 22:26:10
22:26:11.538 -> 1000000100011011
22:26:12.550 -> System Clock: 2024-02-29 22:26:11
22:26:13.552 -> System Clock: 2024-02-29 22:26:12
22:26:14.518 -> System Clock: 2024-02-29 22:26:13
22:26:15.545 -> System Clock: 2024-02-29 22:26:14
22:26:16.516 -> 1000000100011011
It appears that LSE is enabled and RDY, no flags on clock security, however the time is not maintained during power down or resets. There is a CR2032 battery mounted across VRTC pin, and it reads at 3.29V. Time reverts to that time last set.
Seeing the LSE as enabled is definitely an improvement as all previous experience has been with seeing the RTC defaulting to the LSI.
By commenting out the line setNtpTime();
, so that RTC will not look for a time update every time the board is reset, RTC time is set to 1/1/1970 after the upload.
22:30:55.284 -> Connected to WiFi
22:30:55.284 -> SSID: nunya
22:30:55.284 -> IP Address: 192.168.1.111
22:30:55.284 -> signal strength (RSSI):-38 dBm
22:30:55.330 -> System Clock: 1970-01-01 0:00:00
22:30:55.440 -> 1000000100011011
22:30:56.444 -> System Clock: 1970-01-01 0:00:01
Will roll the core up to 4.1.1 and run through this again see what happens.
Of note, having rolled back to 4.0.8 and burning that bootloader, I find that I now must double-tap RST to initiate upload.
Well, I must say that this GIGA R1 board can truly present some mysteries to me. Having rolled up to the 4.1.1 core and burned its bootloader in, not only am I back to where I left off with my current project, but have seemingly resolved, for the most part, issues with the STM32H7 on-board RTC.
It seems that upping the drive level for the crystal was the needed fix. In previous experiences with seeing the RTC default to LSI, it was readily apparent to see how off the RTC would get after just a few minutes. At present, with the LSE running, timing seems spot on for the past couple hours. So far, so good.
If I get this correctly, with the lowest drive level, which is the default after backup domain reset, the LSE was not detected, a flag or two was thrown, and the LSI became the clock source. I might try set drive level to medium high maybe later and see if everything still runs on time.
For the time being, I will monitor this GIGA display I have for any error in time-keeping.
None of this would have happened without the gracious assistance offered by @facchinm and @jorgetrujilloroman , and to you gentlemen I offer my sincerest gratitude.