summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/tuner/si4700.c55
-rw-r--r--firmware/export/config.h1
-rw-r--r--firmware/export/config/sansaclipplus.h6
-rw-r--r--firmware/export/si4700.h8
-rw-r--r--firmware/target/arm/as3525/fmradio-i2c-as3525.c6
-rw-r--r--firmware/target/arm/as3525/system-as3525.c2
6 files changed, 76 insertions, 2 deletions
diff --git a/firmware/drivers/tuner/si4700.c b/firmware/drivers/tuner/si4700.c
index 88ff6c69f7..57006b4e3c 100644
--- a/firmware/drivers/tuner/si4700.c
+++ b/firmware/drivers/tuner/si4700.c
@@ -587,12 +587,67 @@ void si4700_rds_process(void)
587 if (tuner_powered()) 587 if (tuner_powered())
588 { 588 {
589 si4700_read_reg(RDSD); 589 si4700_read_reg(RDSD);
590#if (CONFIG_RDS & RDS_CFG_POLL)
591 /* we need to keep track of the ready bit because it stays set for 80ms
592 * and we must avoid processing it twice */
593
594 static bool old_rdsr = false;
595 bool rdsr = (cache[STATUSRSSI] & STATUSRSSI_RDSR);
596 if (rdsr && !old_rdsr)
597 rds_process(&cache[RDSA]);
598 old_rdsr = rdsr;
599#else
590 rds_process(&cache[RDSA]); 600 rds_process(&cache[RDSA]);
601#endif /* !(CONFIG_RDS & RDS_CFG_POLL) */
591 } 602 }
592 603
593 mutex_unlock(&fmr_mutex); 604 mutex_unlock(&fmr_mutex);
594} 605}
595#endif /* (CONFIG_RDS & RDS_CFG_ISR) */ 606#endif /* (CONFIG_RDS & RDS_CFG_ISR) */
596 607
608#if (CONFIG_RDS & RDS_CFG_POLL)
609static struct event_queue rds_queue;
610static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)];
611
612enum {
613 Q_POWERUP,
614};
615
616static void NORETURN_ATTR rds_thread(void)
617{
618 /* start up frozen */
619 int timeout = TIMEOUT_BLOCK;
620 struct queue_event ev;
621
622 while (true) {
623 queue_wait_w_tmo(&rds_queue, &ev, timeout);
624 switch (ev.id) {
625 case Q_POWERUP:
626 /* power up: timeout after 1 tick, else block indefinitely */
627 timeout = ev.data ? CONFIG_RDS_POLL_TICKS : TIMEOUT_BLOCK;
628 break;
629 case SYS_TIMEOUT:;
630 /* Captures RDS data and processes it */
631 si4700_rds_process();
632 break;
633 }
634 }
635}
636
637/* true after full radio power up, and false before powering down */
638void si4700_rds_powerup(bool on)
639{
640 queue_post(&rds_queue, Q_POWERUP, on);
641}
642
643/* One-time RDS init at startup */
644void si4700_rds_init(void)
645{
646 queue_init(&rds_queue, false);
647 create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds"
648 IF_PRIO(, PRIORITY_PLAYBACK) IF_COP(, CPU));
649}
650#endif /* !(CONFIG_RDS & RDS_CFG_POLL) */
651
597#endif /* HAVE_RDS_CAP */ 652#endif /* HAVE_RDS_CAP */
598 653
diff --git a/firmware/export/config.h b/firmware/export/config.h
index e887796acc..52f647f2fa 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -718,6 +718,7 @@ Lyre prototype 1 */
718#define RDS_CFG_ISR 0x1 /* uses ISR to process packets */ 718#define RDS_CFG_ISR 0x1 /* uses ISR to process packets */
719#define RDS_CFG_PROCESS 0x2 /* uses raw packet processing */ 719#define RDS_CFG_PROCESS 0x2 /* uses raw packet processing */
720#define RDS_CFG_PUSH 0x4 /* pushes processed information */ 720#define RDS_CFG_PUSH 0x4 /* pushes processed information */
721#define RDS_CFG_POLL 0x8 /* tuner driver provides a polling function */
721#ifndef CONFIG_RDS 722#ifndef CONFIG_RDS
722#define CONFIG_RDS RDS_CFG_PROCESS /* thread processing+raw processing */ 723#define CONFIG_RDS RDS_CFG_PROCESS /* thread processing+raw processing */
723#endif /* CONFIG_RDS */ 724#endif /* CONFIG_RDS */
diff --git a/firmware/export/config/sansaclipplus.h b/firmware/export/config/sansaclipplus.h
index 3108bace61..e0df0c28c3 100644
--- a/firmware/export/config/sansaclipplus.h
+++ b/firmware/export/config/sansaclipplus.h
@@ -17,6 +17,9 @@
17 17
18#ifndef BOOTLOADER 18#ifndef BOOTLOADER
19#define HAVE_HOTSWAP 19#define HAVE_HOTSWAP
20#define HAVE_RDS_CAP
21#define CONFIG_RDS (RDS_CFG_POLL | RDS_CFG_PROCESS)
22#define CONFIG_RDS_POLL_TICKS 4
20#endif 23#endif
21 24
22#define HW_SAMPR_CAPS SAMPR_CAP_ALL_96 25#define HW_SAMPR_CAPS SAMPR_CAP_ALL_96
@@ -146,6 +149,9 @@
146/* define this if the flash memory uses the SecureDigital Memory Card protocol */ 149/* define this if the flash memory uses the SecureDigital Memory Card protocol */
147#define CONFIG_STORAGE STORAGE_SD 150#define CONFIG_STORAGE STORAGE_SD
148 151
152/* Define this if target has an additional number of threads specific to it */
153#define TARGET_EXTRA_THREADS 1 /* RDS thread */
154
149#define BATTERY_CAPACITY_DEFAULT 290 /* default battery capacity */ 155#define BATTERY_CAPACITY_DEFAULT 290 /* default battery capacity */
150#define BATTERY_CAPACITY_MIN 290 /* min. capacity selectable */ 156#define BATTERY_CAPACITY_MIN 290 /* min. capacity selectable */
151#define BATTERY_CAPACITY_MAX 290 /* max. capacity selectable */ 157#define BATTERY_CAPACITY_MAX 290 /* max. capacity selectable */
diff --git a/firmware/export/si4700.h b/firmware/export/si4700.h
index bd75bf0817..033b435f2a 100644
--- a/firmware/export/si4700.h
+++ b/firmware/export/si4700.h
@@ -55,7 +55,13 @@ void si4700_rds_read_raw_async(unsigned char *buf, int count); /* implemented by
55void si4700_rds_interrupt(void); 55void si4700_rds_interrupt(void);
56#endif /* (CONFIG_RDS & RDS_CFG_ISR) */ 56#endif /* (CONFIG_RDS & RDS_CFG_ISR) */
57 57
58/* Read raw RDS info for processing */ 58/* Read raw RDS info for processing.
59 * - If RDS_CFG_ISR is set, the tuner driver will call si4700_rds_read_raw_async() which should
60 * perform an asynchronous read and call this function when the data has been read.
61 * - If RDS_CFG_POLL is set, this function will read status and RDS data and process it if a new
62 * packet is available.
63 * - Otherwise this function will read a RDS packet and process it under the assumption that it is
64 * new. */
59void si4700_rds_process(void); 65void si4700_rds_process(void);
60 66
61#endif /* HAVE_RDS_CAP */ 67#endif /* HAVE_RDS_CAP */
diff --git a/firmware/target/arm/as3525/fmradio-i2c-as3525.c b/firmware/target/arm/as3525/fmradio-i2c-as3525.c
index 5b629f5ad4..7f6cb8366b 100644
--- a/firmware/target/arm/as3525/fmradio-i2c-as3525.c
+++ b/firmware/target/arm/as3525/fmradio-i2c-as3525.c
@@ -185,6 +185,11 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
185} 185}
186 186
187#ifdef HAVE_RDS_CAP 187#ifdef HAVE_RDS_CAP
188/* On the Sansa Clip Zip, the tuner interrupt line is routed to the SoC so we
189 * can use to detect when a RDS packet is ready. On the Clip+, we have to
190 * regularly poll. */
191
192#if !(CONFIG_RDS & RDS_CFG_POLL)
188/* Low-level RDS Support */ 193/* Low-level RDS Support */
189static struct semaphore rds_sema; 194static struct semaphore rds_sema;
190static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)]; 195static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)];
@@ -231,4 +236,5 @@ void si4700_rds_init(void)
231 create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds" 236 create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds"
232 IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); 237 IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU));
233} 238}
239#endif /* !(CONFIG_RDS & RDS_CFG_POLL) */
234#endif /* HAVE_RDS_CAP */ 240#endif /* HAVE_RDS_CAP */
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index 83ccb55f79..0450c8b410 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -180,7 +180,7 @@ void INT_GPIOA(void)
180 void button_gpioa_isr(void); 180 void button_gpioa_isr(void);
181 button_gpioa_isr(); 181 button_gpioa_isr();
182#endif 182#endif
183#ifdef HAVE_RDS_CAP 183#if defined(HAVE_RDS_CAP) && !(CONFIG_RDS & RDS_CFG_POLL)
184 void tuner_isr(void); 184 void tuner_isr(void);
185 tuner_isr(); 185 tuner_isr();
186#endif 186#endif