26
26
#include " mbed.h"
27
27
#include " rtc_api.h"
28
28
29
-
30
29
using namespace utest ::v1;
31
30
32
31
static const uint32_t WAIT_TIME = 4 ;
33
32
static const uint32_t WAIT_TOLERANCE = 1 ;
34
33
34
+ #define US_PER_SEC 1000000
35
+ #define ACCURACY_FACTOR 10
35
36
36
- void rtc_init_test ()
37
+ static const uint32_t DELAY_4S = 4 ;
38
+ static const uint32_t DELAY_10S = 10 ;
39
+ static const uint32_t RTC_TOLERANCE = 1 ;
40
+ static const uint32_t TOLERANCE_ACCURACY_US = (DELAY_10S * US_PER_SEC / ACCURACY_FACTOR);
41
+
42
+ #if DEVICE_LOWPOWERTIMER
43
+ volatile bool expired;
44
+
45
+ void callback (void )
37
46
{
38
- for (int i = 0 ; i < 10 ; i++) {
39
- rtc_init ();
40
- }
47
+ expired = true ;
41
48
}
42
49
43
- void rtc_sleep_test ()
50
+ /* Auxiliary function to test if RTC continue counting in
51
+ * sleep and deep-sleep modes. */
52
+ void rtc_sleep_test_support (bool deepsleep_mode)
44
53
{
54
+ LowPowerTimeout timeout;
45
55
const uint32_t start = 100 ;
56
+ expired = false ;
57
+
58
+ /*
59
+ * Since deepsleep() may shut down the UART peripheral, we wait for 10ms
60
+ * to allow for hardware serial buffers to completely flush.
61
+ * This should be replaced with a better function that checks if the
62
+ * hardware buffers are empty. However, such an API does not exist now,
63
+ * so we'll use the wait_ms() function for now.
64
+ */
65
+ wait_ms (10 );
66
+
46
67
rtc_init ();
47
68
69
+ if (deepsleep_mode == false ) {
70
+ sleep_manager_lock_deep_sleep ();
71
+ }
72
+
48
73
rtc_write (start);
49
- wait (WAIT_TIME);
74
+
75
+ timeout.attach (callback, DELAY_4S);
76
+
77
+ TEST_ASSERT (sleep_manager_can_deep_sleep () == deepsleep_mode);
78
+
79
+ while (!expired) sleep ();
80
+
50
81
const uint32_t stop = rtc_read ();
51
82
83
+ TEST_ASSERT_UINT32_WITHIN (RTC_TOLERANCE, DELAY_4S, stop - start);
84
+
85
+ timeout.detach ();
86
+
87
+ if (deepsleep_mode == false ) {
88
+ sleep_manager_unlock_deep_sleep ();
89
+ }
90
+
52
91
rtc_free ();
92
+ }
93
+ #endif
53
94
54
- TEST_ASSERT_UINT32_WITHIN (WAIT_TOLERANCE, WAIT_TIME, stop - start);
95
+ /* Test that ::rtc_init can be called multiple times. */
96
+ void rtc_init_test ()
97
+ {
98
+ for (int i = 0 ; i < 10 ; i++) {
99
+ rtc_init ();
100
+ }
101
+
102
+ rtc_free ();
55
103
}
56
104
105
+ #if DEVICE_LOWPOWERTIMER
106
+ /* * Test that the RTC keeps counting in the various sleep modes. */
107
+
108
+ void rtc_sleep_test ()
109
+ {
110
+ /* Test sleep mode. */
111
+ rtc_sleep_test_support (false );
112
+
113
+ /* Test deep-sleep mode. */
114
+ rtc_sleep_test_support (true );
115
+ }
116
+ #endif
117
+
118
+ /* Test that the RTC keeps counting even after ::rtc_free has been called. */
57
119
void rtc_persist_test ()
58
120
{
59
121
const uint32_t start = 100 ;
@@ -72,6 +134,7 @@ void rtc_persist_test()
72
134
TEST_ASSERT_UINT32_WITHIN (WAIT_TOLERANCE, WAIT_TIME, stop - start);
73
135
}
74
136
137
+ /* Test time does not glitch backwards due to an incorrectly implemented ripple counter driver. */
75
138
void rtc_glitch_test ()
76
139
{
77
140
const uint32_t start = 0xffffe ;
@@ -88,12 +151,14 @@ void rtc_glitch_test()
88
151
rtc_free ();
89
152
}
90
153
154
+ /* Test that the RTC correctly handles different time values. */
91
155
void rtc_range_test ()
92
156
{
93
157
static const uint32_t starts[] = {
94
- 0x00000000 ,
95
- 0xEFFFFFFF ,
96
- 0x00001000 ,
158
+ 0x00000000 ,
159
+ 0xEFFFFFFF ,
160
+ 0x00001000 ,
161
+ 0x00010000 ,
97
162
};
98
163
99
164
rtc_init ();
@@ -107,21 +172,83 @@ void rtc_range_test()
107
172
rtc_free ();
108
173
}
109
174
175
+ /* Test that the RTC accuracy is at least 10%. */
176
+ void rtc_accuracy_test ()
177
+ {
178
+ Timer timer1;
179
+
180
+ const uint32_t start = 100 ;
181
+ rtc_init ();
182
+ rtc_write (start);
183
+
184
+ timer1.start ();
185
+ while (rtc_read () < (start + DELAY_10S)) {
186
+ /* Just wait. */
187
+ }
188
+ timer1.stop ();
189
+
190
+ /* RTC accuracy is at least 10%. */
191
+ TEST_ASSERT_INT32_WITHIN (TOLERANCE_ACCURACY_US, DELAY_10S * US_PER_SEC, timer1.read_us ());
192
+ }
193
+
194
+ /* Test that ::rtc_write/::rtc_read functions provides availability to set/get RTC time. */
195
+ void rtc_write_read_test ()
196
+ {
197
+ static const uint32_t rtc_init_val = 100 ;
198
+
199
+ rtc_init ();
200
+
201
+ for (int i = 0 ; i < 3 ; i++) {
202
+ const uint32_t init_val = (rtc_init_val + i * rtc_init_val);
203
+
204
+ core_util_critical_section_enter ();
205
+
206
+ rtc_write (init_val);
207
+ const uint32_t read_val = rtc_read ();
208
+
209
+ core_util_critical_section_exit ();
210
+
211
+ /* No tolerance is provided since we should have 1 second to
212
+ * execute this case after the RTC time is set.
213
+ */
214
+ TEST_ASSERT_EQUAL_UINT32 (init_val, read_val);
215
+ }
216
+
217
+ rtc_free ();
218
+ }
219
+
220
+ /* Test that ::is_enabled function returns 1 if the RTC is counting and the time has been set, 0 otherwise. */
221
+ void rtc_enabled_test ()
222
+ {
223
+ rtc_init ();
224
+ TEST_ASSERT_EQUAL_INT (0 , rtc_isenabled ());
225
+ rtc_write (0 );
226
+ TEST_ASSERT_EQUAL_INT (1 , rtc_isenabled ());
227
+ rtc_free ();
228
+ }
229
+
110
230
Case cases[] = {
111
231
Case (" RTC - init" , rtc_init_test),
232
+ #if DEVICE_LOWPOWERTIMER
112
233
Case (" RTC - sleep" , rtc_sleep_test),
234
+ #endif
113
235
Case (" RTC - persist" , rtc_persist_test),
114
236
Case (" RTC - glitch" , rtc_glitch_test),
115
237
Case (" RTC - range" , rtc_range_test),
238
+ Case (" RTC - accuracy" , rtc_accuracy_test),
239
+ Case (" RTC - write/read" , rtc_write_read_test),
240
+ Case (" RTC - enabled" , rtc_enabled_test),
116
241
};
117
242
118
- utest::v1::status_t greentea_test_setup (const size_t number_of_cases) {
243
+ utest::v1::status_t greentea_test_setup (const size_t number_of_cases)
244
+ {
119
245
GREENTEA_SETUP (30 , " default_auto" );
120
246
return greentea_test_setup_handler (number_of_cases);
121
247
}
122
248
123
249
Specification specification (greentea_test_setup, cases, greentea_test_teardown_handler);
124
250
125
- int main () {
251
+ int main ()
252
+ {
126
253
Harness::run (specification);
127
254
}
0 commit comments