Skip to content

Commit 9032ab5

Browse files
authored
Added time and date tests/examples (#155)
1 parent 47739b3 commit 9032ab5

File tree

12 files changed

+1413
-0
lines changed

12 files changed

+1413
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
///////////////////////////////////////////////////////////////////////////////
2+
// time_esp32_sleep.ino
3+
//
4+
// Test RTC running while ESP32 is in deep sleep mode
5+
//
6+
// - Initially, the RTC is set to epoch time INIT_TIME
7+
// - After initialization (flag rtcSet stored in RTC RAM),
8+
// the time is read from RTC and printed
9+
//
10+
// created: 08/2025
11+
//
12+
//
13+
// MIT License
14+
//
15+
// Copyright (c) 2025 Matthias Prinke
16+
//
17+
// Permission is hereby granted, free of charge, to any person obtaining a copy
18+
// of this software and associated documentation files (the "Software"), to deal
19+
// in the Software without restriction, including without limitation the rights
20+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21+
// copies of the Software, and to permit persons to whom the Software is
22+
// furnished to do so, subject to the following conditions:
23+
//
24+
// The above copyright notice and this permission notice shall be included in all
25+
// copies or substantial portions of the Software.
26+
//
27+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33+
// SOFTWARE.
34+
//
35+
// History:
36+
//
37+
// 20250809 Created
38+
//
39+
///////////////////////////////////////////////////////////////////////////////
40+
41+
#include <Arduino.h>
42+
#include <time.h>
43+
44+
#define TZINFO "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00"
45+
46+
RTC_DATA_ATTR bool rtcSet = false;
47+
48+
// 2025-01-01 00:00:00 UTC
49+
const time_t INIT_TIME = 1735689600;
50+
51+
// Sleep time in seconds
52+
const unsigned int SLEEP_TIME = 30;
53+
54+
/*!
55+
* \brief Print local time and date
56+
*/
57+
void printTime(void)
58+
{
59+
time_t now_t = time(nullptr);
60+
if (now_t == -1)
61+
{
62+
Serial.println("Failed to obtain time");
63+
}
64+
65+
struct tm *tm_info = localtime(&now_t);
66+
67+
char buffer[20];
68+
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", tm_info);
69+
Serial.printf("Local time: %s\n\n", buffer);
70+
}
71+
72+
void setup()
73+
{
74+
Serial.begin(115200);
75+
76+
#ifndef ESP8266
77+
while (!Serial)
78+
; // wait for serial port to connect. Needed for native USB
79+
#endif
80+
81+
Serial.println("Test ESP32 RTC with deep sleep mode");
82+
83+
// Set timezone
84+
setenv("TZ", TZINFO, 1);
85+
tzset();
86+
87+
if (!rtcSet)
88+
{
89+
Serial.println("Initializing RTC");
90+
91+
// Set the internal RTC
92+
struct timeval tv = {INIT_TIME, 0}; // `t` is seconds, 0 is microseconds
93+
settimeofday(&tv, nullptr);
94+
95+
rtcSet = true;
96+
}
97+
printTime();
98+
Serial.println("Sleeping...");
99+
Serial.flush();
100+
esp_sleep_enable_timer_wakeup(SLEEP_TIME * 1000UL * 1000UL); // function uses uS
101+
esp_deep_sleep_start();
102+
}
103+
104+
void loop()
105+
{
106+
delay(100);
107+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
///////////////////////////////////////////////////////////////////////////////
2+
// logging.h
3+
//
4+
// Replacement for
5+
// https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-log.h
6+
// on RP2040
7+
//
8+
// - DEBUG_RP2040_PORT is set in Arduino IDE:
9+
// Tools->Debug port: "<Disabled>|<Serial>|<Serial1>|<Serial2>"
10+
// - CORE_DEBUG_LEVEL has to be set manually below
11+
//
12+
// created: 09/2023
13+
//
14+
//
15+
// MIT License
16+
//
17+
// Copyright (c) 2023 Matthias Prinke
18+
//
19+
// Permission is hereby granted, free of charge, to any person obtaining a copy
20+
// of this software and associated documentation files (the "Software"), to deal
21+
// in the Software without restriction, including without limitation the rights
22+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23+
// copies of the Software, and to permit persons to whom the Software is
24+
// furnished to do so, subject to the following conditions:
25+
//
26+
// The above copyright notice and this permission notice shall be included in all
27+
// copies or substantial portions of the Software.
28+
//
29+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35+
// SOFTWARE.
36+
//
37+
//
38+
// History:
39+
//
40+
// 20230927 Created from BresserWeatherSensorReceiver
41+
// 20231004 Added function names and line numbers to ESP8266/RP2040 debug logging
42+
// 20231005 Allowed re-definition of CORE_DEBUG_LEVEL and log_* macros
43+
//
44+
// ToDo:
45+
// -
46+
//
47+
///////////////////////////////////////////////////////////////////////////////
48+
49+
#ifndef LOGGING_H
50+
#define LOGGING_H
51+
52+
#if defined(ARDUINO_ARCH_RP2040)
53+
54+
#if defined(DEBUG_RP2040_PORT)
55+
#define DEBUG_PORT DEBUG_RP2040_PORT
56+
#endif
57+
58+
#define ARDUHAL_LOG_LEVEL_NONE 0
59+
#define ARDUHAL_LOG_LEVEL_ERROR 1
60+
#define ARDUHAL_LOG_LEVEL_WARN 2
61+
#define ARDUHAL_LOG_LEVEL_INFO 3
62+
#define ARDUHAL_LOG_LEVEL_DEBUG 4
63+
#define ARDUHAL_LOG_LEVEL_VERBOSE 5
64+
65+
// '#undef' allows to change a previous definition from WeatherSensor.h
66+
#undef log_e
67+
#undef log_w
68+
#undef log_i
69+
#undef log_d
70+
#undef log_v
71+
72+
// Set desired level here!
73+
#undef CORE_DEBUG_LEVEL
74+
#define CORE_DEBUG_LEVEL ARDUHAL_LOG_LEVEL_DEBUG
75+
76+
#if defined(DEBUG_PORT) && CORE_DEBUG_LEVEL > ARDUHAL_LOG_LEVEL_NONE
77+
#define log_e(...) { DEBUG_PORT.printf("%s(), l.%d: ", __func__, __LINE__); DEBUG_PORT.println(); }
78+
#else
79+
#define log_e(...) {}
80+
#endif
81+
#if defined(DEBUG_PORT) && CORE_DEBUG_LEVEL > ARDUHAL_LOG_LEVEL_ERROR
82+
#define log_w(...) { DEBUG_PORT.printf("%s(), l.%d: ", __func__, __LINE__); DEBUG_PORT.printf(__VA_ARGS__); DEBUG_PORT.println(); }
83+
#else
84+
#define log_w(...) {}
85+
#endif
86+
#if defined(DEBUG_PORT) && CORE_DEBUG_LEVEL > ARDUHAL_LOG_LEVEL_WARN
87+
#define log_i(...) { DEBUG_PORT.printf("%s(), l.%d: ", __func__, __LINE__); DEBUG_PORT.printf(__VA_ARGS__); DEBUG_PORT.println(); }
88+
#else
89+
#define log_i(...) {}
90+
#endif
91+
#if defined(DEBUG_PORT) && CORE_DEBUG_LEVEL > ARDUHAL_LOG_LEVEL_INFO
92+
#define log_d(...) { DEBUG_PORT.printf("%s(), l.%d: ", __func__, __LINE__); DEBUG_PORT.printf(__VA_ARGS__); DEBUG_PORT.println(); }
93+
#else
94+
#define log_d(...) {}
95+
#endif
96+
#if defined(DEBUG_PORT) && CORE_DEBUG_LEVEL > ARDUHAL_LOG_LEVEL_DEBUG
97+
#define log_v(...) { DEBUG_PORT.printf("%s(), l.%d: ", __func__, __LINE__); DEBUG_PORT.printf(__VA_ARGS__); DEBUG_PORT.println(); }
98+
#else
99+
#define log_v(...) {}
100+
#endif
101+
102+
#endif // defined(ARDUINO_ARCH_RP2040)
103+
#endif // LOGGING_H
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
#if defined(ARDUINO_ARCH_RP2040)
7+
8+
#ifndef _HARDWARE_ROSC_H_
9+
#define _HARDWARE_ROSC_H_
10+
11+
#include "pico.h"
12+
#include "hardware/structs/rosc.h"
13+
14+
#ifdef __cplusplus
15+
extern "C" {
16+
#endif
17+
18+
/** \file rosc.h
19+
* \defgroup hardware_rosc hardware_rosc
20+
*
21+
* Ring Oscillator (ROSC) API
22+
*
23+
* A Ring Oscillator is an on-chip oscillator that requires no external crystal. Instead, the output is generated from a series of
24+
* inverters that are chained together to create a feedback loop. RP2040 boots from the ring oscillator initially, meaning the
25+
* first stages of the bootrom, including booting from SPI flash, will be clocked by the ring oscillator. If your design has a
26+
* crystal oscillator, you’ll likely want to switch to this as your reference clock as soon as possible, because the frequency is
27+
* more accurate than the ring oscillator.
28+
*/
29+
30+
/*! \brief Set frequency of the Ring Oscillator
31+
* \ingroup hardware_rosc
32+
*
33+
* \param code The drive strengths. See the RP2040 datasheet for information on this value.
34+
*/
35+
void rosc_set_freq(uint32_t code);
36+
37+
/*! \brief Set range of the Ring Oscillator
38+
* \ingroup hardware_rosc
39+
*
40+
* Frequency range. Frequencies will vary with Process, Voltage & Temperature (PVT).
41+
* Clock output will not glitch when changing the range up one step at a time.
42+
*
43+
* \param range 0x01 Low, 0x02 Medium, 0x03 High, 0x04 Too High.
44+
*/
45+
void rosc_set_range(uint range);
46+
47+
/*! \brief Disable the Ring Oscillator
48+
* \ingroup hardware_rosc
49+
*
50+
*/
51+
void rosc_disable(void);
52+
53+
/*! \brief Enable the Ring Oscillator
54+
* \ingroup hardware_rosc
55+
*
56+
*/
57+
void rosc_enable(void);
58+
59+
/*! \brief Put Ring Oscillator in to dormant mode.
60+
* \ingroup hardware_rosc
61+
*
62+
* The ROSC supports a dormant mode,which stops oscillation until woken up up by an asynchronous interrupt.
63+
* This can either come from the RTC, being clocked by an external clock, or a GPIO pin going high or low.
64+
* If no IRQ is configured before going into dormant mode the ROSC will never restart.
65+
*
66+
* PLLs should be stopped before selecting dormant mode.
67+
*/
68+
void rosc_set_dormant(void);
69+
70+
// FIXME: Add doxygen
71+
72+
uint32_t next_rosc_code(uint32_t code);
73+
74+
uint rosc_find_freq(uint32_t low_mhz, uint32_t high_mhz);
75+
76+
void rosc_set_div(uint32_t div);
77+
78+
inline static void rosc_clear_bad_write(void) {
79+
hw_clear_bits(&rosc_hw->status, ROSC_STATUS_BADWRITE_BITS);
80+
}
81+
82+
inline static bool rosc_write_okay(void) {
83+
return !(rosc_hw->status & ROSC_STATUS_BADWRITE_BITS);
84+
}
85+
86+
inline static void rosc_write(io_rw_32 *addr, uint32_t value) {
87+
rosc_clear_bad_write();
88+
assert(rosc_write_okay());
89+
*addr = value;
90+
assert(rosc_write_okay());
91+
};
92+
93+
#ifdef __cplusplus
94+
}
95+
#endif
96+
97+
#endif
98+
#endif /* ARDUINO_ARCH_RP2040 */

0 commit comments

Comments
 (0)