diff options
Diffstat (limited to 'firmware/drivers/tuner')
-rw-r--r-- | firmware/drivers/tuner/si4700.c | 55 |
1 files changed, 55 insertions, 0 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) | ||
609 | static struct event_queue rds_queue; | ||
610 | static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; | ||
611 | |||
612 | enum { | ||
613 | Q_POWERUP, | ||
614 | }; | ||
615 | |||
616 | static 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 */ | ||
638 | void si4700_rds_powerup(bool on) | ||
639 | { | ||
640 | queue_post(&rds_queue, Q_POWERUP, on); | ||
641 | } | ||
642 | |||
643 | /* One-time RDS init at startup */ | ||
644 | void 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 | ||