summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/common/timefuncs.c45
-rw-r--r--firmware/drivers/rtc/rtc_mc13783.c13
-rw-r--r--firmware/export/config.h10
-rw-r--r--firmware/target/arm/as3525/ascodec-as3525.c35
-rw-r--r--firmware/target/arm/as3525/rtc-target.h27
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/mc13783-target.h4
-rw-r--r--firmware/target/arm/imx31/rtc-target.h27
7 files changed, 140 insertions, 21 deletions
diff --git a/firmware/common/timefuncs.c b/firmware/common/timefuncs.c
index c8819ea76e..50addad27a 100644
--- a/firmware/common/timefuncs.c
+++ b/firmware/common/timefuncs.c
@@ -24,13 +24,21 @@
24 24
25#include "kernel.h" 25#include "kernel.h"
26#include "rtc.h" 26#include "rtc.h"
27#ifdef HAVE_RTC_IRQ
28#include "rtc-target.h"
29#endif
27#include "timefuncs.h" 30#include "timefuncs.h"
28#include "debug.h" 31#include "debug.h"
29 32
30static struct tm tm; 33static struct tm tm;
31 34
32#if !CONFIG_RTC 35#if !CONFIG_RTC
33static void fill_default_tm(struct tm *tm) 36static inline bool rtc_dirty(void)
37{
38 return true;
39}
40
41static inline int rtc_read_datetime(struct tm *tm)
34{ 42{
35 tm->tm_sec = 0; 43 tm->tm_sec = 0;
36 tm->tm_min = 0; 44 tm->tm_min = 0;
@@ -38,9 +46,9 @@ static void fill_default_tm(struct tm *tm)
38 tm->tm_mday = 1; 46 tm->tm_mday = 1;
39 tm->tm_mon = 0; 47 tm->tm_mon = 0;
40 tm->tm_year = 70; 48 tm->tm_year = 70;
41 tm->tm_wday = 1; 49 tm->tm_wday = 4;
42 tm->tm_yday = 0; /* Not implemented for now */ 50 tm->tm_yday = 0;
43 tm->tm_isdst = -1; /* Not implemented for now */ 51 return 1;
44} 52}
45#endif /* !CONFIG_RTC */ 53#endif /* !CONFIG_RTC */
46 54
@@ -58,24 +66,37 @@ bool valid_time(const struct tm *tm)
58 else 66 else
59 return true; 67 return true;
60} 68}
61#endif /* CONFIG_RTC */
62 69
63struct tm *get_time(void) 70/* Don't read the RTC more than once per second
71 * returns true if the rtc needs to be read
72 * targets may override with their own implementation
73 */
74#ifndef HAVE_RTC_IRQ
75static inline bool rtc_dirty(void)
64{ 76{
65#if CONFIG_RTC
66 static long timeout = 0; 77 static long timeout = 0;
67 78
68 /* Don't read the RTC more than once per second */ 79 /* Don't read the RTC more than once per second */
69 if (TIME_AFTER(current_tick, timeout)) 80 if (TIME_AFTER(current_tick, timeout))
70 { 81 {
71 /* Once per second, 1/10th of a second off */ 82 /* Once per second, 1/5th of a second off */
72 timeout = HZ * (current_tick / HZ + 1) + HZ / 5; 83 timeout = current_tick / HZ * HZ + 6*HZ / 5;
84 return true;
85 }
86
87 return false;
88}
89#endif /* HAVE_RTC_IRQ */
90#endif /* CONFIG_RTC */
91
92struct tm *get_time(void)
93{
94 if (rtc_dirty())
95 {
73 rtc_read_datetime(&tm); 96 rtc_read_datetime(&tm);
74 tm.tm_isdst = -1; /* Not implemented for now */ 97 tm.tm_isdst = -1; /* Not implemented for now */
75 } 98 }
76#else /* No RTC */ 99
77 fill_default_tm(&tm);
78#endif /* RTC */
79 return &tm; 100 return &tm;
80} 101}
81 102
diff --git a/firmware/drivers/rtc/rtc_mc13783.c b/firmware/drivers/rtc/rtc_mc13783.c
index a1f78f738d..aedf5f6fa5 100644
--- a/firmware/drivers/rtc/rtc_mc13783.c
+++ b/firmware/drivers/rtc/rtc_mc13783.c
@@ -69,6 +69,7 @@ static const unsigned char rtc_registers[RTC_NUM_REGS_RD] =
69 69
70/* was it an alarm that triggered power on ? */ 70/* was it an alarm that triggered power on ? */
71static bool alarm_start = false; 71static bool alarm_start = false;
72static unsigned long rtc_is_dirty = 1; /* force a read right away */
72 73
73static const unsigned short month_table[13] = 74static const unsigned short month_table[13] =
74{ 75{
@@ -96,6 +97,16 @@ static bool read_time_and_day(uint32_t regs[RTC_NUM_REGS_RD])
96 return true; 97 return true;
97} 98}
98 99
100void MC13783_EVENT_CB_1HZ(void)
101{
102 rtc_is_dirty = 1;
103}
104
105bool rtc_mc13783_dirty(void)
106{
107 return bitclr32(&rtc_is_dirty, 1);
108}
109
99/** Public APIs **/ 110/** Public APIs **/
100void rtc_init(void) 111void rtc_init(void)
101{ 112{
@@ -105,6 +116,8 @@ void rtc_init(void)
105 alarm_start = true; 116 alarm_start = true;
106 mc13783_write(MC13783_INTERRUPT_STATUS1, MC13783_TODAI); 117 mc13783_write(MC13783_INTERRUPT_STATUS1, MC13783_TODAI);
107 } 118 }
119
120 mc13783_enable_event(MC13783_INT_ID_1HZ, true);
108} 121}
109 122
110int rtc_read_datetime(struct tm *tm) 123int rtc_read_datetime(struct tm *tm)
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 475bd573d4..a4f0ea94fd 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -742,6 +742,16 @@ Lyre prototype 1 */
742#endif /* CONFIG_RDS */ 742#endif /* CONFIG_RDS */
743#endif /* HAVE_RDS_CAP */ 743#endif /* HAVE_RDS_CAP */
744 744
745#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
746#if CONFIG_RTC == RTC_AS3514
747#if CONFIG_CPU == AS3525 || CONFIG_CPU == AS3525v2
748#define HAVE_RTC_IRQ
749#endif
750#elif CONFIG_RTC == RTC_MC13783
751#define HAVE_RTC_IRQ
752#endif
753#endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */
754
745#ifndef CONFIG_ORIENTATION 755#ifndef CONFIG_ORIENTATION
746#if LCD_HEIGHT > LCD_WIDTH 756#if LCD_HEIGHT > LCD_WIDTH
747#define CONFIG_ORIENTATION SCREEN_PORTRAIT 757#define CONFIG_ORIENTATION SCREEN_PORTRAIT
diff --git a/firmware/target/arm/as3525/ascodec-as3525.c b/firmware/target/arm/as3525/ascodec-as3525.c
index 1bd07c57b1..a8ad9706f8 100644
--- a/firmware/target/arm/as3525/ascodec-as3525.c
+++ b/firmware/target/arm/as3525/ascodec-as3525.c
@@ -131,6 +131,16 @@ static unsigned long ascodec_enrd0_shadow = 0;
131 131
132static void ascodec_wait_cb(struct ascodec_request *req); 132static void ascodec_wait_cb(struct ascodec_request *req);
133 133
134/* RTC interrupt and status
135 * Caution: To avoid an extra variable, IRQ_RTC is used as a flag for
136 * ascodec_enrd0_shadow, which conflicts with RVDD_WASLOW, but we're not using
137 * that right now */
138#if CONFIG_RTC
139#define IFRTC_IRQ_RTC IRQ_RTC
140#else /* !CONFIG_RTC */
141#define IFRTC_IRQ_RTC 0
142#endif /* CONFIG_RTC */
143
134/** --debugging help-- **/ 144/** --debugging help-- **/
135 145
136#ifdef DEBUG 146#ifdef DEBUG
@@ -149,7 +159,6 @@ static struct int_audio_counters {
149 159
150#define COUNT_INT(x) IFDEBUG((int_audio_counters.int_##x)++) 160#define COUNT_INT(x) IFDEBUG((int_audio_counters.int_##x)++)
151 161
152
153/** --stock request and callback functionality -- **/ 162/** --stock request and callback functionality -- **/
154 163
155/* init for common request data (call before submitting) */ 164/* init for common request data (call before submitting) */
@@ -510,13 +519,12 @@ static void ascodec_int_audio_cb(struct ascodec_request *req)
510 } 519 }
511 } 520 }
512 521
522#if CONFIG_RTC
513 if (data[2] & IRQ_RTC) { /* rtc irq */ 523 if (data[2] & IRQ_RTC) { /* rtc irq */
514 /* 524 ascodec_enrd0_shadow |= IRQ_RTC;
515 * Can be configured for once per second or once per minute,
516 * default is once per second
517 */
518 COUNT_INT(rtc); 525 COUNT_INT(rtc);
519 } 526 }
527#endif /* CONFIG_RTC */
520 528
521 if (data[2] & IRQ_ADC) { /* adc finished */ 529 if (data[2] & IRQ_ADC) { /* adc finished */
522 COUNT_INT(adc); 530 COUNT_INT(adc);
@@ -580,6 +588,14 @@ int ascodec_read_charger(void)
580} 588}
581#endif /* CONFIG_CHARGING */ 589#endif /* CONFIG_CHARGING */
582 590
591#if CONFIG_RTC
592/* read sticky rtc dirty status */
593bool ascodec_rtc_dirty(void)
594{
595 return bitclr32(&ascodec_enrd0_shadow, IRQ_RTC) & IRQ_RTC;
596}
597#endif /* CONFIG_RTC */
598
583/* 599/*
584 * NOTE: 600 * NOTE:
585 * After the conversion to interrupts, ascodec_(lock|unlock) are only used by 601 * After the conversion to interrupts, ascodec_(lock|unlock) are only used by
@@ -635,8 +651,9 @@ void ascodec_init(void)
635 VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO; 651 VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO;
636 VIC_INT_ENABLE = INTERRUPT_AUDIO; 652 VIC_INT_ENABLE = INTERRUPT_AUDIO;
637 653
638 /* detect if USB was connected at startup since there is no transition */ 654 /* detect if USB was connected at startup since there is no transition;
639 ascodec_enrd0_shadow = ascodec_read(AS3514_IRQ_ENRD0); 655 force an initial read of the clock (if CONFIG_RTC) */
656 ascodec_enrd0_shadow = ascodec_read(AS3514_IRQ_ENRD0) | IFRTC_IRQ_RTC;
640 if(ascodec_enrd0_shadow & USB_STATUS) 657 if(ascodec_enrd0_shadow & USB_STATUS)
641 usb_insert_int(); 658 usb_insert_int();
642 659
@@ -651,10 +668,10 @@ void ascodec_init(void)
651 /* XIRQ = IRQ, active low reset signal, 6mA push-pull output */ 668 /* XIRQ = IRQ, active low reset signal, 6mA push-pull output */
652 ascodec_write_pmu(0x1a, 3, (1<<2)|3); /* 1A-3 = Out_Cntr3 register */ 669 ascodec_write_pmu(0x1a, 3, (1<<2)|3); /* 1A-3 = Out_Cntr3 register */
653 /* Generate irq on (rtc,) adc change */ 670 /* Generate irq on (rtc,) adc change */
654 ascodec_write(AS3514_IRQ_ENRD2, /*IRQ_RTC |*/ IRQ_ADC); 671 ascodec_write(AS3514_IRQ_ENRD2, IFRTC_IRQ_RTC | IRQ_ADC);
655#else 672#else
656 /* Generate irq for push-pull, active high, irq on rtc+adc change */ 673 /* Generate irq for push-pull, active high, irq on rtc+adc change */
657 ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE | 674 ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE |
658 /*IRQ_RTC |*/ IRQ_ADC); 675 IFRTC_IRQ_RTC | IRQ_ADC);
659#endif 676#endif
660} 677}
diff --git a/firmware/target/arm/as3525/rtc-target.h b/firmware/target/arm/as3525/rtc-target.h
new file mode 100644
index 0000000000..900aa357d0
--- /dev/null
+++ b/firmware/target/arm/as3525/rtc-target.h
@@ -0,0 +1,27 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2017 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef RTC_TARGET_H
22#define RTC_TARGET_H
23
24bool ascodec_rtc_dirty(void);
25#define rtc_dirty ascodec_rtc_dirty
26
27#endif /* RTC_TARGET_H */
diff --git a/firmware/target/arm/imx31/gigabeat-s/mc13783-target.h b/firmware/target/arm/imx31/gigabeat-s/mc13783-target.h
index 179c65cad6..4bb148e36c 100644
--- a/firmware/target/arm/imx31/gigabeat-s/mc13783-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/mc13783-target.h
@@ -46,6 +46,10 @@ static struct spi_node mc13783_spi =
46MC13783_EVENT_VECTOR_TBL_START() 46MC13783_EVENT_VECTOR_TBL_START()
47 /* ADC conversion complete */ 47 /* ADC conversion complete */
48 MC13783_EVENT_VECTOR(ADCDONE, 0) 48 MC13783_EVENT_VECTOR(ADCDONE, 0)
49#if CONFIG_RTC
50 /* RTC tick */
51 MC13783_EVENT_VECTOR(1HZ, 0)
52#endif /* CONFIG_RTC */
49 /* Power button */ 53 /* Power button */
50 MC13783_EVENT_VECTOR(ONOFD1, MC13783_ONOFD1S) 54 MC13783_EVENT_VECTOR(ONOFD1, MC13783_ONOFD1S)
51 /* Main charger detection */ 55 /* Main charger detection */
diff --git a/firmware/target/arm/imx31/rtc-target.h b/firmware/target/arm/imx31/rtc-target.h
new file mode 100644
index 0000000000..b6dc46204d
--- /dev/null
+++ b/firmware/target/arm/imx31/rtc-target.h
@@ -0,0 +1,27 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2017 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef RTC_TARGET_H
22#define RTC_TARGET_H
23
24bool rtc_mc13783_dirty(void);
25#define rtc_dirty rtc_mc13783_dirty
26
27#endif /* RTC_TARGET_H */