forked from astlouys/Pico-Green-Clock
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPico-Green-Clock.c
18575 lines (14617 loc) · 665 KB
/
Pico-Green-Clock.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* ================================================================== *\
Pico-Clock-Green.c
St-Louys, Andre - February 2022
Revision 01-JUN-2023
Compiler: arm-none-eabi-gcc 7.3.1
Version 9.02
Raspberry Pi Pico firmware to drive the Waveshare Pico-Green-Clock.
From an original software version 1.00 by Waveshare
Released under 3-Clause BSD License.
NOTE:
THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
WITH CODING INFORMATION REGARDING THEIR PRODUCT IN ORDER FOR THEM TO SAVE
TIME. AS A RESULT, WAVESHARE OR THE AUTHOR SHALL NOT BE HELD LIABLE FOR ANY
DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. ALSO
NOTE THAT THE AUTHOR IS NOT A WAVESHARE EMPLOYEE.
REVISION HISTORY:
=================
04-FEB-2022 1.00 - Initial release from Waveshare.
10-FEB-2022 2.00 - Global code reformatting and rework.
- Fix a bug allowing "DayOfMonth" to be set to 0.
- Fix a bug allowing "DayOfMonth" to go higher than the maximum of 28, 29, 30 or 31 (dependingget_day_of_week of the month).
- Fix a bug and make sure the "count down" indicator is turned off when count-down timer reaches 00m00s.
- Fix a bug when the clock is set for 12-hours time display and is displaying 00h00 AM instead of 12h00 AM.
- Add a "test" section to put many chunks of code for testing and debugging purposes.
- Add "FRENCH" option so that the date can be displayed in the corresponding format (compile-time option).
(It will be easy to add other languages if the programmer makes a search for "ENGLISH" and / of "FRENCH" in the code...
...and assuming the characters required are standard ASCII characters, similar to English).
- Implement 5 X 7 character set with variable character width.
- Implement a reverse_bits() function allowing the bitmap of the 5 X 7 characters to be more intuitively defined.
- Add a generic "scroll_string()" function and a fill_display_buffer_5X7() function to easily handle 5 X 7 characters.
- Change the name of many functions to make them more representative of what they do.
- Make the scroll_string() function so that it can accept a string longer than what can be handled by the available
framebuffer. The function will wait until the framebuffer gets some free space to transfer next chunk of the string.
- Add a specific section at the top of source code to select many default clock options at compile time.
- Implement different tone types with different number of tones and duration for different events.
(Note: Tone frequency can't be changed since the oscillator is integrated in the clock active buzzer).
- Clock display will blink the two center dots according to the number of seconds passed since the last minute change.
- Add automatic handling of "Daylight Saving Time" for most northern hemisphere countries.
(Provision has been made to add different schemes of daylight saving time for other areas of the world).
- Add a new option for hourly chime. It may be On, Off, or "Day" (OI for "On, Intermittent"). If set to "Day",
chime will sound only during day hours, as defined between CHIME_TIME_ON and CHIME_TIME_OFF set during clock setup.
(They are 9h00 and 21h00 by default).
- Add handling of "Calendar events" that can be added by user at compile time. During the specified day of the year,
the string defined by the user will scroll on clock display twice an hour, at xxh05 and xxh35. Moreover, a special sound
will be heard when the message start scrolling during daytime as defined between CHIME_TIME_ON and CHIME_TIME_OFF.
- Add an option in the clock setup to configure the Chime Time On and Chime Time Off.
24-MAR-2022 3.00 - More code rework and optimisation.
- When powering up the clock, replace DST = 0xFF (hex value) by "DST = On" (and replace "DST = 0x00" by "DST = Off").
- Add logic for 2 different "repeat counts" for sounds, to add versatility and more possibilities for different sound codes.
- Day-of-month will change automatically if it becomes out-of-bound while setting up current month
(for example, day-of-month will change automatically from 31 to 28 while we change month from 3 (March) to 2 (February).
- Add suffix to day-of-month when scrolling the date in English (now "...March 31st...").
- The setting of Chime time On and Chime time Off now comply with 12 or 24-hours time format current clock setting.
- Fix a bug allowing Hourly Chime sound to be heard one hour later than the Chime time Off.
- Fix a bug allowing Hourly Chime to sound sometimes while doing clock setup.
- The setting of alarms now comply with 12 or 24-hours time format current clock setting.
- To help knowing which alarm is On (0 or 1), when Alarm 0 is On, Left Alarm LED is On in the
alarm indicator and when Alarm 1 is On, Right Alarm LED is On in the indicator.
NOTE: On power up, both alarms are set to OFF (this is also true in case of power failure), since there
is no backed-up RAM available in the RTC IC to save such variables in case of power failure.
- Change the logic so that each alarm (0 and 1) are now checked individually in the RTC IC.
- Add the logic for both alarms (0 and 1) to have a distinct (different) alarm sound.
- When setting up alarms, current alarm parameters saved in RTC IC are now proposed to user as default values.
Note: As mentioned above, alarm status (On or Off) is lost on power failure (and both alarms restart as Off),
but other alarm parameters (Hour, Minute, Day-of-week) are kept in RTC IC with battery back-up.
- Now blink the day-of-week while setting up day-of-week in alarm setup.
- Language selection is now a run-time option. English and French are the available languages for now.
- Hourly chime: add logic for "nighttime workers". If Chime time On is greater than Chime time Off
(as opposed to what we would normally expect), we assume that we want sounds to be heard during
nighttime and not heard during daytime. Hourly chime will then sounds after Chime time On (in the evening)
and before Chime time Off (in the morning).
- Add support for DHT22 (humidity and temperature sensor - compile time option). To implement this option, it must
be "#define" in the code, and a 3-wire cable must be installed between GPIO8, 3.3V and GND, and a DHT22
can be installed outdoor.
- Add Daily saving time as run-time parameter. User can select 0 (no support for DST) or 1 (North-America-like DST support).
- Add some of the changes already made by David Ruck (David is also on GitHub) to fine tune auto brightness.
- When time display format is H12 (12-hours format), do not print a leading 0 to Hour to comply with the standard.
04-APR-2022 4.00 - Some code optimization (there is much more to do !).
- Major cleanup in the "setup flags" to make it more straightforward to add options to the clock setup list of parameters.
- Transferred "Temperature unit" setup to the list of clock parameters setup.
- Transferred "Auto-brightness" setup to the list of clock parameters setup.
(NOTE: A copy of the "auto-brightness" function code has been left on the "bottom button quick press" for faster access if required).
- Implement new "Night light" feature: use the two white LEDs inside the clock as a night light. It can be
turned On, Off, Automatic or OI ("On, Intermittent" - see Hourly chime for explanation about "OI" setting).
- Since temperature unit setting has been transferred to the general clock setup, "Up" (middle) button quick press
will now display outside temperature and humidity (if user installed a DHT22).
- To be more deterministic, instead of scrolling the date every xxx minutes, scrolling will now occurs when reaching
an integer number of times the period specified. So, if we scroll the date every 5 minutes, scrolling will occur
at xh00, xh05, xh10, xh15 and so on. This way, we know how long we have to wait until next scroll.
- Add support for a remote control (see User guide for details). Infrared sensor (VS1838B-type) must be bought and installed
by user to enable this option.
- Time checking of calendar events has been changed from xxh05 and xxh35 to xxh14 and xxh44. Those values are unlikely to be a
multiple integer value of the time period to display date and then, those two actions (date display and calendar events) will
not interfere with one another.
- Implement many functions that are accessible only with remote control (see User guide for details):
- Emulate the three clock buttons on the remote control so that we can achieve a similar behavior remotely.
- Fix a bug in reading VSYS (power supply voltage).
- Add some pixel twinkling when software starts (just for fun...)
- Add column-by-column LED matrix test to make it easy to see if all LEDs work fine. Idem for all clock display indicators.
- Add firmware support for an optional passive piezo so that sound frequency may be changed / modulated by software.
PWM has been selected to drive the passive piezo. If we would use a completely "software" oscillator, we would
hear hiccups in the sound when the other ISR / callback functions run (this processing would interfere
with the regularity of the sound). Similar to the scroll queue, a sound queue (circular buffer) has been implemented
to handle the sounds of the passive piezo.
- Add the structure member "Jingle" to the calendar Event structure. If it is not "0", it identifies a jingle (quick music)
that will play when the calendar event is scrolled on the display. (For example, we could ask to play "Jingle bell",
along with the message "Merry Christmas" on December 25th. (NOTE: Passive piezo must have been bought and installed by user
to support this option).
- Add Pico internal temperature display (compliant to the temperature unit - C or F - that has been selected for other temperatures).
- Add programmable "silence period" to temporarily turn off hourly chime and calendar event sounds (available with remote control).
- Add "dice rolling" to randomly display 2 dice values (from 1 to 6) on display (available with remote control).
- Modify adc_read_light() function so that light value returned is intuitive: higher number means more light. Auto-brightness and
automatic night-light functions have been adapted accordingly.
19-JUN-2022 5.00 - Uncomment matrix_test() and pixel_twinkling() during power-up sequence that were left mistakenly commented-out in release 4.00.
- Add scrolling of firmware version number during power-up and in display function.
- Scroll Pico's "unique number" ("serial number") during power-up and in display function.
- When hour changes (from xh59 to xh00), date scrolling will now begin only 5 seconds later to let the time to look at the clock
display to see current time when we hear the hourly chime. This is true only from xh59 to xh00 and not for other integer number
of times the specified period (for example from xh04 to xh05 if date scrolling period is set to 5 minutes).
- Command "Display auto-bright" (with remote control generic display): logic has been fixed for French message.
- Modify the logic behind "automatic night light". There is now a "twilight" period during which the night light status does not
change. This is to prevent a period of "On/Off" toggling when light level is just around the value to change night light status.
- Modify the logic behind "clock auto-light" (or automatic brightness), so that clock display does not dim at all when ambient
light intensity is high enough.
- Also, slow down the frequency for reading ambient light (from one second to five seconds). Auto-brightness Will now take a few
seconds to react when changed with remote control.
- Adjust / change the ambient light levels for clock display dim intensities.
- Since the auto-brightness of the clock display has been fine-tuned, the default configuration when the clock is powered on
is now auto-brightness On.
- Add UART configuration to allow sending data to a VT101-type monitor connected to Pico's uart1.
>>> NOTE: be careful to adjust voltage logic levels before connecting an external monitor.
NOTE: see user guide on how to receive and display data from a Pico to a PC screen through USB port.
- Improve / optimize the logic of the sound circular buffer and sound related functions for passive buzzer.
- Add support for BME280 sensor (temperature, humidity and barometric pressure). The BME280 uses the same I2C channel as the
DS3231 real-time clock.
- Add calculation of approximate altitude based on barometric pressure. After a few tries, it has been commented out since it
changes with pressure variations and it appears to be not very accurate and / or useful.
- If a BME280 has been installed, scroll "device ID" and device "unique ID" on clock power-up.
- Rework algorithm of LED matrix automatic brightness. Add hysteresis and also more brightness levels.
25-AUG-2022 6.00 - Add Pico's flash memory read, write and erase functions.
- Add CRC16 function to calculate the cyclic redundancy checksum of an array of characters (using the 0x1021 polynom).
- Add algorithms to save Green Clock configuration to flash memory and restore it when required.
- Improve the "degree" symbol for Celsius and Fahrenheit. Thanks to Eric Escolano for proposing this improvement.
- Fix a few "compile bugs" when some options / features are turned Off (remote control, DHT22, BME280, etc...).
Thanks to "pjbroad" and "maxromanovsky" on GitHub for bringing this to my attention.
- Add a "QUICK_START" compile option to easily allow skipping parts of the power-up sequence if so desired.
- Change debug output from UART1 to UART0 for easier transfer to a PC through USB CDC interface.
- Add a system idle monitor to get an idea of the load on the microcontroller.
- Add a sound queue for the active buzzer (the one integrated with the Pico Green Clock).
- Adapt the sound callback function to support both the passive buzzer and the active buzzer.
- Implement 9 alarms since we can now save them to flash. Alarm algorithm has been completely reworked
- Optimize sound algorithm throughout the code by using the sound active queue.
- Tried to improve DHT22 algorithm by replacing the "polling" algorithm by an interrupt-driven function... without success. I'm
still getting more or less 75% read errors. Maybe the Pico is too busy with the callback functions to be able to properly
handle the DHT22. When I have some extra time, I may take a look with a logic analyzer to see what happens. Whatever the case,
I have 100% communications success (no error at all) with the BME280 device that I use (see User guide for more info).
31-OCT-2022 7.00 - Given all timing problems while trying to read datastream from DHT22, offload that function to Pico's second core (core 1).
- Implement two queues for inter-core communications since the SDK documentation recommends not using the fifos for this purpose if at all possible.
- Implement a new generic Daylight Saving Time algorithm covering most countries of the world.
- Add Universal Time Coordinate to the clock setup and to the flash configuration. It will be required when implementing time update / synchronization
via NTP and it also allows to properly handle Daylight Saving Time / Summer Time for those countries who change the time based on UTC.
- Add current DST status to flash memory to optimize DST algorithm.
- Change algorithm to find DayOfWeek that was sometimes returning an out-of-sync value.
13-JAN-2023 8.00 - Add "snowflakes" pixel animation (button "Play/Pause" on remote control).
- Optimize top indicators update function.
- Change clock display brightness configuration and algorithm so that it is now driven by a Pico's PWM signal.
- Add features and optimize sound queues handling.
- Add a command queue to prevent overrun while adding more and more processing in callback functions.
- Prevent a quick press on "set" (top) button to enter setup mode if data is currently scrolling on clock display.
- Rework / improve / optimize Daylight Saving Time / Summer Time algorithm.
- Make some cleanup and optimization on the analog-to-digital related functions.
- Debug hourly chime sometimes sounding at xxh01.
- Add automatic detection of CDC USB while in "DEVELOPER_VERSION".
- Add automatic detection of microcontroller (Pico or Pico W).
- Add a half-hour "light chime" (2 quick beeps).
- Add an option where hourly chime sounds a number of beeps being equal to current hour (2 o'clock = 2 beeps / 5 o'clock = 5 beeps, etc...)
- Cleanup and optimizations in PWM handling and integration of PWM for passive buzzer and clock display brightness.
- Modify checking of clock's flash configuration to prevent a glitch on clock display while disabling interrupts.
- Cleanup code for easier configuration and handling of temperature reading from either Pico, DS3231, DHT22 and / or BME280.
- Some general code cleanup and optimization.
19-JAN-2023 8.01 - Fix a bug with blinking days-of-week indicators in Alarm Setup.
- Add get_pico_unique_id() function and use it only once before flash operations to prevent potential problems.
21-JAN-2023 8.02 - Fix a bug with the logic behind "days-of-week". Two different logics were used throughout the code.
26-JAN-2023 9.00 - Change count-down timer alarm algorithm. Will now ring until reset by user or when reaching maximum ringing duration.
- Implement NTP (Network Time Protocol). Green Clock will now resync its time periodically from Internet. (Requires Pico W).
- Improve clock precision independantly of real-time IC by better synchronization of callback period time.
- Add a function to "set-and-save" Wi-Fi credentials to flash.
01-MAY-2023 9.01 - Restricted availability version to test German translation.
06-APR-2023 9.02 - Change "middle dots blinking" algorithm. Thanks to Frank Seidel for his suggestion and work on this feature.
- Add basic German language support. Thanks to Frank Seidel for his work and translation on this feature !
(Note: English is used if / when German translation is not available).
- Add functions to easily support and convert tm_time, human_time, unix_time.
- Fix a problem when initializing CYW43 with new SDK library.
- Increase string length for Calendar Events up to 50 characters.
- Begin implementation of "Reminders", giving even more flexibility than Calendar Events (to be completed).
- Fix dates encoded in CalendarEventsGeneric.cpp (example Calendar Events).
- Add Czech language support. Thanks to KaeroDot for the excellent work and translation on this feature !
\* ================================================================== */
/* ================================================================== *\
NOTE: Your comments - if they are constructive - are welcome:
Let me know which version of the firmware you are using, tell
me if you found bugs, what are the improvements you added /
integrated and / or what changes you would like to be done
to the firmware (however, I do not commit to make changes).
\* ================================================================== */
/* ================================================================== *\
Other features / options that could be added / implemented:
==================================================================
- Make more compile-time options available at run-time by making
the list of clock setup steps longer. Some options currently
"compile-time" only could be added to the list of "run-time" options
(for example: sound On/Off, scroll period, etc...).
- Use a PIO to support IR burst decoding and / or DHT22 data decoding.
- If a new version / update of the hardware is ever made, here are a
few suggestions for improvements:
> Make the plastic case deeper so that it is possible to add a
piggy-back module on top of the Pico (for example: ZigBee).
> Passive piezo to allow changing the frequency of the sound.
> Add a clear zone in the plastic case (similar to where is
located the photoresistor used for ambient light reading)
so that an IR sensor can be added internally (I had to put
my IR sensor externally).
> Remote control with buttons specifically configured for the
Green Clock.
> Replace the two unused white LEDs near the clock buttons by
infrared LEDs (installed through "holes" in the plastic case),
so that they can be used by software to emulate a "remote
control" to turn On or Off a radio, television, or other
equipment at a specific time (and / or date). Infrared protocol
analysis would need to be done "on the side", so that the
protocol can be reproduced on the Pico-Green-Clock.
NOTE: These two white LEDs are now used as "night light" on
the clock.
- NOTE: There is a new product from Waveshare that already provides
some of the improvements above: "Pico-RGB-Matrix-P3-64X32".
I will give it a try. So far, it seems to have more features
than the Green Clock:
- One external socket to put a Pico-compatible module.
- One IR sensor to receive commands from a remote (a small
remote control comes with it).
- Display is 64 X 32 pixels which allows much more data to
be displayed. Each 5X7 digit is physically smaller. However,
LEDs are crisp and bright. Not sure what the end result would
be as for the distance from which we can read it, compare to
the Green Clock.
You may want to check on my GitHub repository for an eventual
release of new firmware for the Pico-RGB-Matrix...
\* ================================================================== */
/* $TITLE=Clock configuration or options. */
/* $PAGE */
/* ================================================================== *\
===== CLOCK CONFIGURATION OR OPTIONS =====
SOME OF THESE ITEMS ARE ADJUSTABLE AT RUNTIME, OTHERS ARE NOT.
NOTE: Structure "CalendarEvent" should also be initialized
according to user needs. It is in the file:
"CalendarEventsGeneric.cpp".
\* ================================================================== */
/* Firmware version. */
#define FIRMWARE_VERSION "9.02" ///
/* Select the language for data display. */
#define DEFAULT_LANGUAGE ENGLISH // choices for now are FRENCH, ENGLISH and GERMAN.
/* While in development mode, we may want to disable NTP update, for example while testing Summer Time handling algorithm. */
// #define NTP_ENABLE /// WARNING: This #define is not supported for now. Use "#define PICO_W" below instead to enable NTP for now.
#define NETWORK_NAME "MyNetworkName" /// for those with a development environment, you can enter your SSID and password below, run the Firmware until the
#define NETWORK_PASSWORD "MyPassword" /// first date scrolling (credentials will be saved to flash), then erase the credentials and put comment on both lines.
/* If a Pico W is used, librairies for Wi-Fi and NTP synchronization will be merged in the executable. If PICO_W is not defined, NTP is automatically disabled. */
#define PICO_W ///
/* Flag to handle automatically the daylight saving time. List of countries are given in the User Guide. */
#define DST_COUNTRY DST_NORTH_AMERICA
/* Release or Developer Version: Make selective choices or options. */
#define RELEASE_VERSION ///
/* ----------------------------------------------------------------------------------------------------------------------- *\
Setup specific to RELEASE version.
\* ----------------------------------------------------------------------------------------------------------------------- */
#ifdef RELEASE_VERSION
#warning Built as RELEASE_VERSION
/* Specify the filename of calendar events to merge with this version of firmware. */
#define CALENDAR_FILENAME "CalendarEventsGeneric.cpp"
/* Specify the filename of reminders to merge with this version of firmware. */
#define REMINDER_FILENAME "RemindersGeneric.cpp"
#endif // RELEASE_VERSION
/* ----------------------------------------------------------------------------------------------------------------------- *\
End of setup specific to RELEASE version.
\* ----------------------------------------------------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------------------------------------------------------- *\
Setup specific to DEVELOPER version.
NOTE: Developer version requires a USB CDC communication to start. Refer to User Guide for details.
\* ----------------------------------------------------------------------------------------------------------------------- */
#ifndef RELEASE_VERSION
#define DEVELOPER_VERSION
#warning Built as DEVELOPER_VERSION
/* Specify the filename of calendar events to merge with this version of firmware. */
#define CALENDAR_FILENAME "CalendarEventsAndre.cpp"
/* Specify the filename of calendar events to merge with this version of firmware. */
#define REMINDER_FILENAME "RemindersAndre.cpp"
/* Conditional compile to allow a quicker power-up sequence by-passing some device tests. */
#define QUICK_START ///
#ifdef QUICK_START
#warning Built with QUICK_START
#endif // QUICK_START
/* If SOUND_DISABLED is commented out below, it allows turning Off <<< ABSOLUTELY ALL SOUNDS >>> from the Green Clock.
(For example, during development phase, if your wife is sleeping while you work late in the night as was my case - smile). */
// #define SOUND_DISABLED ///
#ifdef SOUND_DISABLED
#warning Built with SOUND DISABLED
#endif // SOUND_DISABLED
/* Flag to include test code in the executable (conditional compile). Tests can be run before falling in normal clock ("time display") mode.
Keeping the comment sign on the #define below will exclude test code and make the executable smaller. */
#define TEST_CODE
/* Loop at the beginning of the code until a USB CDC connection has been established. Quick beeps will be heard during waiting so that user
is aware of what's going on. */
#define USB_CONNECTION ///
#ifdef USB_CONNECTION
#warning Built with USB_CONNECTION
#endif // USB_CONNECTION
/* ---------------------------------------------------------------------------------- *\
Options that can be installed by user.
\* ---------------------------------------------------------------------------------- */
/* Support for an optional passive buzzer. This buzzer must be provided by user and is not included with the Green Clock.
It allows variable frequency sounds on the clock.
If you did install one, cut this block and paste is outside of the "#ifdef DEVELOPER_VERSION" and "#endif" to enable the "#define PASSIVE_PIEZO_SUPPORT". */
// #define PASSIVE_PIEZO_SUPPORT /// if a passive buzzer has been installed by user.
#ifdef PASSIVE_PIEZO_SUPPORT
#warning Built with PASSIVE_PIEZO support
#endif // PASSIVE_PIEZO_SUPPORT
/* Support of an optional (external) temperature and humidity sensor (DHT22) or temperature, humidity and atmospheric pressure sensor (BME280)
to read and display those parameters. The sensors must be bought and installed by user. They are not included with the Pico Green Clock.
If you did install one, cut this block and paste it outside of the "#ifdef DEVELOPER_VERSION" and "#endif" to enable the "#define DHT_SUPPORT and / or
"#define BME280_SUPPORT". */
#define DHT_SUPPORT /// if a DHT22 temperature and humidity sensor has been installed by user.
#ifdef DHT_SUPPORT
#warning Built with DHT22 support
#endif // DHT_SUPPORT
#define BME280_SUPPORT /// if a BME280 temperature, humidity and barometric pressure sensor has been installed by user.
#ifdef BME280_SUPPORT
#warning Built with BME280 support
#endif // BME280_SUPPORT
/* Support of an optional remote control to interact with the clock remotely, for example when the clock is installed
too high and is out of reach. There is no remote control provided with the clock. It must be bought by the user.
Current support is for a Memorex remote control, model MCR 5221 that I had readily available. If another brand of
remote control is to be used, user will have to decode its protocol and implement it in the Green Clock firmware.
(a file similar to "memorex.cpp" must be created to support the new remote control).
If you did install an infrared sensor, cut this block and paste it outside of the "#ifdef DEVELOPER_VERSION" and "#endif" to enable the "#define IR_SUPPORT".
You also need to replace the default "REMOTE_FILENAME" by the filename you created containing the infrared timing / codes corresponding to your remote control.
You may want to check the Pico-Remote-Analyzer utility in one of my repositories. */
#define IR_SUPPORT // if an infrared sensor (VS1838B-type) has been installed by the user and IR protocol of the remote control has been analyzed and implemented.
/* Specify the file containing the remote control protocol to be used. */
#define REMOTE_FILENAME "memorex.cpp"
/* Silence period request unit (in minutes). Needs remote control. */
#define SILENCE_PERIOD_UNIT 30
#ifdef IR_SUPPORT
#warning Built with INFRARED support
#endif // IR_SUPPORT
#endif // DEVELOPER_VERSION
/* ----------------------------------------------------------------------------------------------------------------------- *\
End of setup specific to DEVELOPER version
\* ----------------------------------------------------------------------------------------------------------------------- */
/* Determine if date scrolling will be enable by default when the clock starts. */
#define SCROLL_DEFAULT FLAG_ON // choices are FLAG_ON / FLAG_OFF
/* Scroll one dot to the left every such milliseconds (80 is a good start point. lower = faster). */
#define SCROLL_DOT_TIME 66 // this is a UINT8 (must be between 0 and 255).
/* Date, temperature and other options will scroll at this frequency
(in minutes - we must leave enough time for the previous scroll to complete). */
#define SCROLL_PERIOD_MINUTE 5
/* Default temperature unit to display on the clock. */
#define TEMPERATURE_DEFAULT CELSIUS // choices are CELSIUS and FAHRENHEIT.
/* Time will be displayed in 24-hours format by default. */
#define TIME_DISPLAY_DEFAULT H24 // choices are H12 and H24.
/* Exit setup mode after this period of inactivity (in seconds). (for "clock setup", "alarm setup" or "timer setup"). */
#define TIME_OUT_PERIOD 20
/* Maximum number of seconds an alarm will ring. It will be automatically shut Off after this period in seconds
if user has not pressed yet the "Set" (top) button. */
#define MAX_ALARM_RING_TIME 3600 // (in seconds) alarm will be automatically shut Off after ringing for one hour (3600 seconds).
/* Night light default values. "AUTO" is based on ambient light reading to turn night light On or Off. */
#define NIGHT_LIGHT_DEFAULT NIGHT_LIGHT_AUTO // choices are NIGHT_LIGHT_OFF / NIGHT_LIGHT_ON / NIGHT_LIGHT_NIGHT / NIGHT_LIGHT_AUTO
#define NIGHT_LIGHT_TIME_ON 21 // if "NIGHT_LIGHT_NIGHT", LEDs will turn On at this time (in the evening).
#define NIGHT_LIGHT_TIME_OFF 8 // if "NIGHT_LIGHT_NIGHT", LEDs will turn Off at this time (in the morning).
/* Hourly chime default values. */
#define CHIME_DEFAULT CHIME_DAY // choices are CHIME_OFF / CHIME_ON / CHIME_DAY
#define CHIME_TIME_ON 9 // if "CHIME_DAY", "hourly chime" and "calendar event" will sound beginning at this time (in the morning).
#define CHIME_TIME_OFF 21 // if "CHIME_DAY", "hourly chime" and "calendar event" will sound for the last time at this time (in the evening).
#define CHIME_HALF_HOUR FLAG_ON // if "FLAG_ON", will sound a "double-beep" on half-hour (every xxh30), compliant to chime settings above.
#define CHIME_HOUR_COUNT FLAG_OFF // if "FLAG_ON", hourly chime will beep a number of times equivalent to the hour value in 12-hour format.
#define CHIME_HOUR_COUNT_BEEP_DURATION 300 // duration of "hour count" beeps (in msec) when flag above is On.
/* NOTE: See also revision history above (or User guide) about "night time workers" support for hourly chime. */
/* For active buzzer integrated in Pico Green Clock. Number of "tones" for each "sound pack" (first level of repetition). */
#define TONE_CHIME_REPEAT1 2
#define TONE_EVENT_REPEAT1 5
#define TONE_KEYCLICK_REPEAT1 1
#define TONE_TIMER_REPEAT1 4
/* For active buzzer integrated in Pico Green Clock.
Number of times the "sound pack" above will repeat itself for each tone type (second level of repetition).
for example, if TONE_CHIME_REPEAT_1 is set to 3 and TONE_CHIME_REPEAT_2 is set to 2, we will hear:
beep-beep-beep..........beep-beep-beep (three beeps, twice). */
#define TONE_CHIME_REPEAT2 3
#define TONE_EVENT_REPEAT2 3
#define TONE_KEYCLICK_REPEAT2 1
#define TONE_TIMER_REPEAT2 2
/* For active buzzer integrated in Pico Green Clock.
Time duration for different tone types (in milliseconds). This is the time of each sound inside one "sound pack".
will be rounded-up by the clock to the next 50 milliseconds multiple.
We can separate sounds - or group of sound - by adding a silence (for example: "sound_queue_active(50, SILENT);"). */
#define TONE_CHIME_DURATION 50 // when sounding an hourly chime.
#define TONE_EVENT_DURATION 200 // when scrolling a calendar event.
#define TONE_KEYCLICK_DURATION 50 // when pressing a button ("keyclick").
#define TONE_TIMER_DURATION 100 // when count-down timer reaches 00m00s.
/* ================================================================== *\
===== END OF CLOCK CONFIGURATION OR OPTIONS =====
\* ================================================================== */
/* $TITLE=Definitions and include files. */
/* $PAGE */
/* ------------------------------------------------------------------ *\
Definitions and include files
(in alphabetical order)
\* ------------------------------------------------------------------ */
/* Miscellaneous defines. */
#define ALARM_PERIOD 5 // alarm ringer restart every x seconds (part of the whole "nine alarms algorithm").
#define CELSIUS 0x00
#define CHIME_DAY 0x02 // hourly chime is ON during defined daily hours (between CHIME_TIME_ON and CHIME_TIME_OFF).
#define CHIME_OFF 0x00 // hourly chime is OFF.
#define CHIME_ON 0x01 // hourly chime is ON.
#define COUNT_DOWN_DELAY 7 // number of seconds between each count-down alarm sound burst.
#define CRC16_POLYNOM 0x1021 // different polynom values are used by different authorities. (0x8005, 0x1021, 0x1DCF, 0x755B, 0x5935, 0x3D65, 0x8BB7, 0x0589, 0xC867, 0xA02B, 0x2F15, 0x6815, 0xC599, 0x202D, 0x0805, 0x1CF5)
#define DEFAULT_YEAR_CENTILE 20 // to be used as a default before flash configuration is read (to be displayed in debug log).
#define DELTA_TIME 60000000ll
#define DISPLAY_BUFFER_SIZE 248 // size of framebuffer.
#define EVENT_MINUTE1 14 // (Must be between 0 and 57) Calendar Events will checked when minutes reach this number (should preferably be selected out of peak periods).
#define EVENT_MINUTE2 44 // (Must be between 0 and 57) Calendar Events will checked when minutes reach this number (should preferably be selected out of peak periods).
#define FAHRENHEIT !CELSIUS // temperature unit to display.
#define FALSE 0x00
#define FLAG_OFF 0x00 // flag is OFF.
#define FLAG_ON 0x01 // flag is ON.
#define FLAG_POLL 0x02
#define FLAG_WAIT 0x03 // special flag asking passive sound queue to wait for active sound queue to complete.
#define FLASH_CONFIG_OFFSET 0x1FF000 // offset in the Pico's 2 MB where to save data. Starting at 2.00MB - 4096 bytes (very end of flash).
#define H12 FLAG_OFF // 12-hours time format.
#define H24 FLAG_ON // 24-hours time format.
#define MAX_ACTIVE_SOUND_QUEUE 100 // maximum number of "sounds" in the active buzzer sound queue.
#define MAX_ALARMS 9 // total number of alarms available.
#define MAX_LIGHT_SLOTS 24 // number of slots for ambient light level hysteresis.
#define MAX_COMMAND_QUEUE 25 // maximim number of active commands in command queue.
#define MAX_CORE_QUEUE 25 // maximum number of active commands in each circular buffers for inter-core communication (core0-to-core1 and core1-to-core0).
#define MAX_COUNT_DOWN_ALARM_DURATION 30 // maximum period of time (in minutes) during which count-down alarm will ring if not reset by user (quick press on "Set" button).
#define MAX_DHT_READINGS 100 // maximum number of "logic level changes" while reading DHT22 data stream.
#define MAX_EVENTS 50 // maximum number of "calendar events" that can be programmed in the source code.
#define MAX_IR_READINGS 500 // maximum number of "logic level changes" while receiving data from IR remote control.
#define MAX_PASSIVE_SOUND_QUEUE 500 // maximum number of "sounds" in the passive buzzer sound queue.
#define MAX_REMINDERS1 50 // maximum number of "reminders" of type 1 that can be defined.
#define MAX_SCROLL_QUEUE 75 // maximum number of messages in the scroll buffer queue (big enough to cover MAX_EVENTS defined for the same day + a few extra date scrolls).
#define NIGHT_LIGHT_AUTO 0x03 // night light will turn On when ambient light is low enough
#define NIGHT_LIGHT_NIGHT 0x02 // night light On between NightLightTimeOn and NightLightTimeOff.
#define NIGHT_LIGHT_OFF 0x00 // night light always Off.
#define NIGHT_LIGHT_ON 0x01 // night light always On.
#define TIMER_COUNT_DOWN 0x01 // timer mode is "Count Down".
#define TIMER_COUNT_UP 0x02 // timer mode is "Count Up".
#define TIMER_OFF 0x00 // timer is currently OFF.
#define TRUE 0x01
#define TYPE_PICO 0x01 // microcontroller is a Pico
#define TYPE_PICO_W 0x02 // microcontroller is a Pico W
/* DayOfWeek definitions. */
#define ALL 0x00 // All days
#define SUN 0x01 // Sunday
#define MON 0x02 // Monday
#define TUE 0x03 // Tuesday
#define WED 0x04 // Wednesday
#define THU 0x05 // Thursday
#define FRI 0x06 // Friday
#define SAT 0x07 // Saturday
/* Month definitions. */
#define JAN 1 // January
#define FEB 2 // February
#define MAR 3 // March
#define APR 4 // April
#define MAY 5 // May
#define JUN 6 // June
#define JUL 7 // July
#define AUG 8 // August
#define SEP 9 // September
#define OCT 10 // October
#define NOV 11 // November
#define DEC 12 // December
/* Language and locals used. */
#define LANGUAGE_LO_LIMIT 0x00
#define ENGLISH 0x01
#define FRENCH 0x02
#define GERMAN 0x03
#define CZECH 0x04
#define SPANISH 0x05 // just a placeholder for now. Spanish is not implemented yet.
#define LANGUAGE_HI_LIMIT 0x05
/* List of commands to be processed by command queue handler (while in the "main()" thread context). */
#define COMMAND_PLAY_JINGLE 0x01
/* Inter-core commands / messages. */
/* For target: core 0. */
#define CORE0_DHT_ERROR 0x01
#define CORE0_DHT_READ_COMPLETED 0x02
/* For target: core 1. */
#define CORE1_READ_DHT 0x01
/* "Display modes" used with remote control while in "Generic display mode". */
#define DISPLAY_LO_LIMIT 0x00
#define DISPLAY_TIME 0x01
#define DISPLAY_DATE 0x02
#define DISPLAY_DST 0x03
#define DISPLAY_BEEP 0x04
#define DISPLAY_SCROLLING 0x05
#define DISPLAY_TEMP_UNIT 0x06
#define DISPLAY_LANGUAGE 0x07
#define DISPLAY_TIME_FORMAT 0x08
#define DISPLAY_HOURLY_CHIME 0x09
#define DISPLAY_NIGHT_LIGHT 0x0A
#define DISPLAY_DIM 0x0B
#define DISPLAY_HI_LIMIT 0x0C
/* DST_COUNTRY valid choices (see details in User Guide). */
// #define DST_DEBUG /// this define to be used only for intensive DST debugging purposes.
#define DST_LO_LIMIT 0 // this specific define only to make the logic easier in the code.
#define DST_NONE 0 // there is no "Daylight Saving Time" in user's country.
#define DST_AUSTRALIA 1 // daylight saving time for most of Australia.
#define DST_AUSTRALIA_HOWE 2 // daylight saving time for Australia - Lord Howe Island.
#define DST_CHILE 3 // daylight saving time for Chile.
#define DST_CUBA 4 // daylight saving time for Cuba.
#define DST_EUROPE 5 // daylight saving time for European Union.
#define DST_ISRAEL 6 // daylight saving time for Israel.
#define DST_LEBANON 7 // daylight saving time for Lebanon.
#define DST_MOLDOVA 8 // daylight saving time for Moldova.
#define DST_NEW_ZEALAND 9 // daylight saving time for New Zealand.
#define DST_NORTH_AMERICA 10 // daylight saving time for most of Canada and United States.
#define DST_PALESTINE 11 // daylight saving time for Palestine.
#define DST_PARAGUAY 12 // daylight saving time for Paraguay.IR_DISPLAY_GENERIC
#define DST_HI_LIMIT 13 // to make the logic easier in the firmware.
/* List or commands available with remote control. */
#ifdef IR_SUPPORT
#define IR_LO_LIMIT 0x00
#define IR_BUTTON_TOP_QUICK 0x01
#define IR_BUTTON_TOP_LONG 0x02
#define IR_BUTTON_MIDDLE_QUICK 0x03
#define IR_BUTTON_MIDDLE_LONG 0x04
#define IR_BUTTON_BOTTOM_QUICK 0x05
#define IR_BUTTON_BOTTOM_LONG 0x06
#define IR_DICE_ROLLING 0x07
#define IR_DISPLAY_AMBIENT_LIGHT 0x08
#define IR_DISPLAY_EVENTS_THIS_WEEK 0x09
#define IR_DISPLAY_EVENTS_TODAY 0x0A
#define IR_DISPLAY_GENERIC 0x0B
#define IR_DISPLAY_OUTSIDE_TEMP 0x0C
#define IR_DISPLAY_SECOND 0x0D
#define IR_FULL_TEST 0x0E
#define IR_IDLE_TIME 0x0F
#define IR_POWER_ON_OFF 0x10
#define IR_SILENCE_PERIOD 0x11
#define IR_HI_LIMIT 0x12
#endif
/* Clock mode definitions. */
#define MODE_LO_LIMIT 0x00
#define MODE_UNDEFINED 0x00 // mode is currently undefined.
#define MODE_ALARM_SETUP 0x01 // user is setting up one or more alarms.
#define MODE_CLOCK_SETUP 0x02 // user is setting up clock parameters.
#define MODE_DISPLAY 0x03 // generic display mode used with IR remote control.
#define MODE_POWER_UP 0x04 // clock has just been powered-up.
#define MODE_SCROLLING 0x05 // clock is scrolling data on the display.
#define MODE_SHOW_TIME 0x06 // clock is displaying time ("normal" mode).
#define MODE_SHOW_VOLTAGE 0x07 // clock is displaying power supply voltage.
#define MODE_TEST 0x08 // clock is in test mode (to disable automatic clock behaviors on the display).
#define MODE_TIMER_SETUP 0x09 // user is setting up a timer.
#define MODE_HI_LIMIT 0x10
/* PWM - "Pulse Wide Modulation" is currently used to control sound on passive buzzer and clock display brightness. */
#define PWM_LO_LIMIT 0x00
#define PWM_SOUND 0x00
#define PWM_BRIGHTNESS 0x01
#define PWM_HI_LIMIT 0x02
/* Alarm setup steps definitions. */
#define SETUP_ALARM_LO_LIMIT 0x00
#define SETUP_ALARM_NUMBER 0x01
#define SETUP_ALARM_ON_OFF 0x02
#define SETUP_ALARM_HOUR 0x03
#define SETUP_ALARM_MINUTE 0x04
#define SETUP_ALARM_DAY 0x05
#define SETUP_ALARM_HI_LIMIT 0x06
/* NOTE: Clock setup step definitions are kept as variables and can be seen in the variables section below. */
/* Setup source definitions. */
#define SETUP_SOURCE_NONE 0x00
#define SETUP_SOURCE_ALARM 0x01
#define SETUP_SOURCE_CLOCK 0x02
#define SETUP_SOURCE_TIMER 0x03
/* Timer setup steps definitions. */
#define SETUP_TIMER_LO_LIMIT 0x00
#define SETUP_TIMER_UP_DOWN 0x01
#define SETUP_TIMER_MINUTE 0x02
#define SETUP_TIMER_SECOND 0x03
#define SETUP_TIMER_READY 0x04
#define SETUP_TIMER_HI_LIMIT 0x05
/* Tags that can be used in process_scroll() function. */
#define TAG_AMBIENT_LIGHT 0xFF // tag used to scroll current ambient light information.
#define TAG_BME280_DEVICE_ID 0xFE // tag used to scroll the BME280 device id (should be 0x60 for a "real" BME280).
#define TAG_BME280_TEMP 0xFD // tag used to display temperature, relative humidity and atmospheric pressure read from an optional BME280 sensor.
#define TAG_WIFI_CREDENTIALS 0xFC
#define TAG_DATE 0xFB // tag used to scroll current date, temperature and power supply voltage.
#define TAG_DEBUG 0xFA // tag used to scroll variables for debug purposes, while in main() context.
#define TAG_DHT22_TEMP 0xF9 // tag used to display temperature read from an optional DHT22 temperature and humidity sensor.
#define TAG_DS3231_TEMP 0xF8 // tag used to display ambient temperature read from DS3231 real-time IC in the Green Clock.
#define TAG_DST 0xF7 // tag used to scroll daylight saving time ("DST") information and status on clock display.
#define TAG_FIRMWARE_VERSION 0xF6 // tag used to display Pico Green Clock firmware version.
#define TAG_IDLE_MONITOR 0xF5 // tag used to scroll current System Idle Monitor on clock display.
#define TAG_INFO 0xF4 // tag used to display information while in "main()" context.
#define TAG_NTP_ERRORS 0xF3 // tag used to scroll cumulative number of errors in NTP requests.
#define TAG_NTP_STATUS 0xF2 // tag used to scroll cumulative number of errors in NTP requests.
#define TAG_PICO_TEMP 0xF1 // tag used to display Pico internal temperature.
#define TAG_PICO_TYPE 0xF0 // tag used to display the type of microcontroller installed (Pico or Pico W).
#define TAG_PICO_UNIQUE_ID 0xEF // tag used to display Pico (flash) unique ID.
#define TAG_QUEUE 0xEE // tag used to display "Head", "Tail", and "Tag" of currently used scroll queue (for debugging purposes).
#define TAG_TIMEZONE 0xED // tag used to display Universal Coordinated Time information.
#define TAG_VOLTAGE 0xEC // tag used to display power supply voltage.
#define SILENT 0
#define WAIT_4_ACTIVE 0xFFFF // request passive sound queue to wait for active sound queue to complete.
/* Music tones definitions. */
#ifdef PASSIVE_PIEZO_SUPPORT
#define DO_a 262
#define DO_DIESE_a 277
#define RE_a 294
#define RE_DIESE_a 311
#define MI_a 330
#define FA_a 349
#define FA_DIESE_a 370
#define SOL_a 392
#define SOL_DIESE_a 415
#define LA_a 440
#define LA_DIESE_a 466
#define SI_a 494
#define DO_b 523
#define DO_DIESE_b 554
#define RE_b 587
#define RE_DIESE_b 622
#define MI_b 659
#define FA_b 699
#define FA_DIESE_b 740
#define SOL_b 784
#define SOL_DIESE_b 831
#define LA_b 880
#define LA_DIESE_b 932
#define SI_b 988
#define DO_c 1047
#define DO_DIESE_c 1109
#define RE_c 1175
#define RE_DIESE_c 1245
#define MI_c 1319
#define FA_c 1397
#define FA_DIESE_c 1480
#define SOL_c 1568
#define SOL_DIESE_c 1661
#define LA_c 1760
#define LA_DIESE_c 1865
#define SI_c 1976
/* Jingle definitions. */
#define JINGLE_LO_LIMIT 0x00
#define JINGLE_BIRTHDAY 0x01
#define JINGLE_ENCOUNTER 0x02
#define JINGLE_FETE 0x03
#define JINGLE_RACING 0x04
#define JINGLE_HI_LIMIT 0x05
#else
/* Jingle definitions. Placeholder only if not using a passive piezo. */
#define JINGLE_LO_LIMIT 0x00
#define JINGLE_BIRTHDAY 0x00
#define JINGLE_ENCOUNTER 0x00
#define JINGLE_FETE 0x00
#define JINGLE_RACING 0x00
#define JINGLE_HI_LIMIT 0x00
#endif
/* Include files. */
#include "bitmap.h"
#include "ctype.h"
#include "debug.h"
#include "Ds3231.h"
#include "errno.h"
#include "fcntl.h"
#include "hardware/adc.h"
#include "hardware/clocks.h"
#include "hardware/flash.h"
#include "hardware/gpio.h"
#include "hardware/i2c.h"
#include "hardware/irq.h"
#include "hardware/pwm.h"
#include "hardware/watchdog.h"
#include "hardware/sync.h"
#include "hardware/uart.h"
#include "math.h"
#include "pico/multicore.h"
#include "pico/platform.h"
#include "pico/sync.h"
#include "pico/unique_id.h"
#include "stdarg.h"
#include "stdint.h"
#include "stdio.h"
#include "stdlib.h"
#ifdef PICO_W
#include "picow_ntp_client.h"
#endif // PICO_W
typedef unsigned int UINT; // processor-optimized.
typedef uint8_t UINT8;
typedef uint16_t UINT16;
typedef uint32_t UINT32;
typedef uint64_t UINT64;
typedef unsigned char UCHAR;
/* Clock setup step definitions. */
/* They are not categorized as #define since there is a difference in the
order to handle day-of-month setting and month setting between French and
English and it appears to be the easiest way to handle this difference.
"HI_LIMIT" remains a "#define" since it is used as an initialization
parameter for a vector. */
#define SETUP_CLOCK_LO_LIMIT 0x00
UINT8 SETUP_NONE = 0x00;
UINT8 SETUP_HOUR = 0x01;
UINT8 SETUP_MINUTE = 0x02;
UINT8 SETUP_MONTH = 0x03;
UINT8 SETUP_DAY_OF_MONTH = 0x04;
UINT8 SETUP_YEAR = 0x05;
UINT8 SETUP_DST = 0x06;
UINT8 SETUP_UTC = 0x07;
UINT8 SETUP_KEYCLICK = 0x08;
UINT8 SETUP_SCROLLING = 0x09;
UINT8 SETUP_TEMP_UNIT = 0x0A;
UINT8 SETUP_LANGUAGE = 0x0B;
UINT8 SETUP_TIME_FORMAT = 0x0C;
UINT8 SETUP_HOURLY_CHIME = 0x0D;
UINT8 SETUP_CHIME_TIME_ON = 0x0E;
UINT8 SETUP_CHIME_TIME_OFF = 0x0F;
UINT8 SETUP_NIGHT_LIGHT = 0x10;
UINT8 SETUP_NIGHT_LIGHT_TIME_ON = 0x11;
UINT8 SETUP_NIGHT_LIGHT_TIME_OFF = 0x12;
UINT8 SETUP_AUTO_BRIGHT = 0x13;
#define SETUP_CLOCK_HI_LIMIT 0x14
/* $TITLE=Calendar events. */
/* $PAGE */
/* ------------------------------------------------------------------ *\
Calendar events have been implemented to be configurable
by the user. However, they must be configured at compile time
(they can't be configured once the clock is running).
As a user may intuitively guess, the parameters are:
1) Day of month (1 to 31).
2) Month (English 3-letters: JAN / FEB / MAR / APR / etc...)
3) Jingle ID (Jingle number to play while scrolling this calendar event, 0 = none) (require passive buzzer to be installed by user).
4) Text to scroll on clock display (between "double-quotes" in the code)
(The text is limited to 40 characters. It takes a relatively long time to read 40 characters of text on the clock scrolling display !)
NOTE: Calendar events are verified twice an hour, at xxh14 and xxh44. The text configured will be scrolled on
the clock display if the clock is in its "normal" time display mode (that is, the text will not scroll if user is in a setup operation).
Also, the tone will sound (according to TONE_EVENT_xxx settings) during the 24 hours define by the date of the calendar event, and in
compliance with the CHIME_xxx settings. Outside hours define by CHIME_xxx settings, the text will scroll on the display, but there will be no sound.
NOTE: See also the "nighttime workers" information in User Guide.
NOTE: No validation is done on the date. If an invalid date is set, the event will never be scrolled.
Also if, for example, 29-FEB is set, the event will be scrolled only every 4 years.
\* ------------------------------------------------------------------ */
/* Calendar events definition. */
struct event
{
UINT64 Day;
UINT8 Month;
UINT16 Jingle;
UCHAR Description[51];
};
/* Events to scroll on clock display at specific dates. Must be setup by user. Some examples are already defined. */
#include CALENDAR_FILENAME
/* Alarm definitions. */
struct alarm
{
UINT8 FlagStatus;
UINT8 Second;
UINT8 Minute;
UINT8 Hour;
UINT8 Day;
UCHAR Text[40];
};
/* Command definitions for command queue. */
struct command
{
UINT16 Command;
UINT16 Parameter;
};
/* Summer Time / Winter Time parameters definitions. */
struct dst_parameters
{
UINT8 StartMonth;
UINT8 StartDayOfWeek;
int8_t StartDayOfMonthLow;
int8_t StartDayOfMonthHigh;
UINT8 StartHour;
UINT16 StartDayOfYear;
UINT8 EndMonth;
UINT8 EndDayOfWeek;
int8_t EndDayOfMonthLow;
int8_t EndDayOfMonthHigh;
UINT8 EndHour;
UINT16 EndDayOfYear;
UINT8 ShiftMinutes;
};
/* Structure to contain time stamp under "human" format instead of "tm" standard. */
struct human_time
{
UINT16 Hour;
UINT16 Minute;
UINT16 Second;
UINT16 DayOfMonth;
UINT16 Month;
UINT16 Year;
UINT16 DayOfWeek;
UINT16 DayOfYear;
UINT8 FlagDst;
};
/* NTP data structure. */
struct ntp_data
{
/* Time-related data. */
UINT8 CurrentDayOfWeek;
UINT8 CurrentDayOfMonth;
UINT8 CurrentMonth;
UINT16 CurrentYear;
UINT8 CurrentYearLowPart;
UINT8 CurrentHour;
UINT8 CurrentMinute;
UINT8 CurrentSecond;
/* Generic data. */
time_t Epoch;
UINT8 FlagNTPResync; // flag set to On if there is a specific reason to request an NTP update without delay.
UINT8 FlagNTPSuccess; // flag indicating that NTP date and time request has succeeded.
UINT64 NTPDelta;
UINT32 NTPErrors; // cumulative number of errors while trying to re-sync with NTP.
UINT64 NTPGetTime;
UINT64 NTPLastUpdate;
UINT32 NTPReadCycles; // total number of re-sync cycles through NTP.
}NTPData;
/* Clock display pixel definitions. */
struct pixel
{
UINT8 DisplayBuffer;
UINT8 BitNumber;
};
/* Pulse Wide Modulation (PWM) parameters definitions. */
struct pwm
{
UINT8 Channel;
UINT32 Clock;
float ClockDivider;
UINT8 DutyCycle;
UINT32 Frequency;
UINT8 Gpio;
UINT16 Level;
UINT8 OnOff;
UINT8 Slice;
UINT16 Wrap;
};
/* Type 1 Reminders. */
struct reminder1
{
struct human_time StartPeriod;
UINT64 StartPeriodEpoch;
struct human_time EndPeriod;
UINT64 EndPeriodEpoch;
struct human_time FirstRing;
UINT64 FirstRingEpoch;
UINT64 RingDuration;