4242#include < Wire.h>
4343#include " app_hal.h"
4444
45+ #include " tone.h"
46+
4547#include < lvgl.h>
4648#include " ui/ui.h"
4749
5961#define QMI8658C_I2C_FREQUENCY 40000 // Define I2C frequency as 80kHz (in Hz)
6062#endif
6163
64+ #ifdef ENABLE_RTC
65+ #include < RtcPCF8563.h>
66+ RtcPCF8563<TwoWire> Rtc (Wire);
67+ #endif
68+
6269#define FLASH FFat
6370#define F_NAME " FATFS"
6471#define buf_size 10
@@ -355,6 +362,71 @@ void set_pin_io(uint8_t pin_number, bool value)
355362}
356363#endif
357364
365+ #ifdef ENABLE_RTC
366+ bool wasError (const char *errorTopic = " " )
367+ {
368+ uint8_t error = Rtc.LastError ();
369+ if (error != 0 )
370+ {
371+ // we have a communications error
372+ // see https://www.arduino.cc/reference/en/language/functions/communication/wire/endtransmission/
373+ // for what the number means
374+ Serial.print (" [" );
375+ Serial.print (errorTopic);
376+ Serial.print (" ] WIRE communications error (" );
377+ Serial.print (error);
378+ Serial.print (" ) : " );
379+
380+ switch (error)
381+ {
382+ case Rtc_Wire_Error_None:
383+ Serial.println (" (none?!)" );
384+ break ;
385+ case Rtc_Wire_Error_TxBufferOverflow:
386+ Serial.println (" transmit buffer overflow" );
387+ break ;
388+ case Rtc_Wire_Error_NoAddressableDevice:
389+ Serial.println (" no device responded" );
390+ break ;
391+ case Rtc_Wire_Error_UnsupportedRequest:
392+ Serial.println (" device doesn't support request" );
393+ break ;
394+ case Rtc_Wire_Error_Unspecific:
395+ Serial.println (" unspecified error" );
396+ break ;
397+ case Rtc_Wire_Error_CommunicationTimeout:
398+ Serial.println (" communications timed out" );
399+ break ;
400+ }
401+ return true ;
402+ }
403+ return false ;
404+ }
405+ #endif
406+
407+
408+ void toneOut (int pitch, int duration)
409+ { // pitch in Hz, duration in ms
410+ #if defined(BUZZER) && (BUZZER != -1)
411+ int delayPeriod;
412+ long cycles, i;
413+
414+ pinMode (BUZZER, OUTPUT); // turn on output pin
415+ delayPeriod = (500000 / pitch) - 7 ; // calc 1/2 period in us -7 for overhead
416+ cycles = ((long )pitch * (long )duration) / 1000 ; // calc. number of cycles for loop
417+
418+ for (i = 0 ; i <= cycles; i++)
419+ { // play note for duration ms
420+ digitalWrite (BUZZER, HIGH);
421+ delayMicroseconds (delayPeriod);
422+ digitalWrite (BUZZER, LOW);
423+ delayMicroseconds (delayPeriod - 1 ); // - 1 to make up for digitaWrite overhead
424+ }
425+ pinMode (BUZZER, INPUT); // shut off pin to avoid noise from other operations
426+ #endif
427+ }
428+
429+
358430String heapUsage ()
359431{
360432 String usage;
@@ -504,6 +576,14 @@ void checkLocal()
504576 }
505577}
506578
579+ void screenBrightness (uint8_t value)
580+ {
581+ tft.setBrightness (value);
582+ #ifdef ELECROW_C3
583+ set_pin_io (2 , value > 0 ); // ELECROW C3, no brightness control
584+ #endif
585+ }
586+
507587String readFile (const char *path)
508588{
509589 String result;
@@ -897,6 +977,14 @@ void configCallback(Config config, uint32_t a, uint32_t b)
897977{
898978 switch (config)
899979 {
980+ case CF_TIME:
981+ // time has been synced from BLE
982+ #ifdef ENABLE_RTC
983+ // set the RTC time
984+ Rtc.SetDateTime (RtcDateTime (watch.getYear (), watch.getMonth () + 1 , watch.getDay (), watch.getHour (true ), watch.getMinute (), watch.getSecond ()));
985+
986+ #endif
987+ break ;
900988 case CF_RST:
901989
902990 Serial.println (" Reset request, formating storage" );
@@ -1104,7 +1192,7 @@ void onBrightnessChange(lv_event_t *e)
11041192 // Your code here
11051193 lv_obj_t *slider = lv_event_get_target (e);
11061194 int v = lv_slider_get_value (slider);
1107- tft. setBrightness (v);
1195+ screenBrightness (v);
11081196
11091197 prefs.putInt (" brightness" , v);
11101198}
@@ -1422,7 +1510,7 @@ void loadSplash()
14221510 int xOffset = 63 ;
14231511 int yOffset = 55 ;
14241512 tft.fillScreen (TFT_BLACK);
1425- tft. setBrightness (200 );
1513+ screenBrightness (200 );
14261514 for (int y = 0 ; y < h; y++)
14271515 {
14281516 for (int x = 0 ; x < w; x++)
@@ -1460,6 +1548,10 @@ void hal_setup()
14601548 tft.fillScreen (TFT_BLACK);
14611549 loadSplash ();
14621550
1551+ toneOut (TONE_EN * 2 , 170 );
1552+ toneOut (TONE_FS * 2 , 170 );
1553+ toneOut (TONE_GN * 2 , 170 );
1554+
14631555 Serial.println (heapUsage ());
14641556
14651557 lv_init ();
@@ -1566,7 +1658,7 @@ void hal_setup()
15661658 tm = 0 ;
15671659 }
15681660
1569- tft. setBrightness (br);
1661+ screenBrightness (br);
15701662
15711663 lv_dropdown_set_selected (ui_timeoutSelect, tm);
15721664 lv_slider_set_value (ui_brightnessSlider, br, LV_ANIM_OFF);
@@ -1615,6 +1707,28 @@ void hal_setup()
16151707
16161708#endif
16171709
1710+ #ifdef ENABLE_RTC
1711+ Rtc.Begin ();
1712+
1713+ if (!Rtc.GetIsRunning ())
1714+ {
1715+ uint8_t error = Rtc.LastError ();
1716+ if (error != 0 )
1717+ {
1718+ showError (" RTC" , " Error on RTC" );
1719+ }
1720+ Rtc.SetIsRunning (true );
1721+ }
1722+
1723+ RtcDateTime now = Rtc.GetDateTime ();
1724+
1725+ watch.setTime (now.Second (), now.Minute (), now.Hour (), now.Day (), now.Month (), now.Year ());
1726+
1727+ Rtc.StopAlarm ();
1728+ Rtc.StopTimer ();
1729+ Rtc.SetSquareWavePin (PCF8563SquareWavePinMode_None);
1730+ #endif
1731+
16181732 Timber.i (" Setup done" );
16191733 Timber.i (about);
16201734}
@@ -1685,7 +1799,7 @@ void hal_loop()
16851799 if (screenTimer.active )
16861800 {
16871801 uint8_t lvl = lv_slider_get_value (ui_brightnessSlider);
1688- tft. setBrightness (lvl);
1802+ screenBrightness (lvl);
16891803
16901804 if (screenTimer.duration < 0 )
16911805 {
@@ -1701,7 +1815,7 @@ void hal_loop()
17011815 Timber.w (" Screen timeout" );
17021816 screenTimer.active = false ;
17031817
1704- tft. setBrightness (0 );
1818+ screenBrightness (0 );
17051819 lv_disp_load_scr (ui_home);
17061820 }
17071821 }
@@ -1712,7 +1826,7 @@ void hal_loop()
17121826 {
17131827 if (start)
17141828 {
1715- tft. setBrightness (200 );
1829+ screenBrightness (200 );
17161830 tft.fillScreen (TFT_BLUE);
17171831
17181832 tft.drawRoundRect (70 , 120 , 100 , 20 , 5 , TFT_WHITE);
0 commit comments