diff options
Diffstat (limited to 'firmware/drivers/tuner/si4700.c')
-rw-r--r-- | firmware/drivers/tuner/si4700.c | 84 |
1 files changed, 56 insertions, 28 deletions
diff --git a/firmware/drivers/tuner/si4700.c b/firmware/drivers/tuner/si4700.c index 88ff6c69f7..8b4d0a1b19 100644 --- a/firmware/drivers/tuner/si4700.c +++ b/firmware/drivers/tuner/si4700.c @@ -553,32 +553,6 @@ void si4700_dbg_info(struct si4700_dbg_info *nfo) } #ifdef HAVE_RDS_CAP - -#if (CONFIG_RDS & RDS_CFG_ISR) -static unsigned char isr_regbuf[(RDSD - STATUSRSSI + 1) * 2]; - -/* Called by RDS interrupt on target */ -void si4700_rds_interrupt(void) -{ - si4700_rds_read_raw_async(isr_regbuf, sizeof (isr_regbuf)); -} - -/* Handle RDS event from ISR */ -void si4700_rds_process(void) -{ - uint16_t rds_data[4]; - int index = (RDSA - STATUSRSSI) * 2; - - for (int i = 0; i < 4; i++) { - rds_data[i] = isr_regbuf[index] << 8 | isr_regbuf[index + 1]; - index += 2; - } - - rds_process(rds_data); -} - -#else /* !(CONFIG_RDS & RDS_CFG_ISR) */ - /* Handle RDS event from thread */ void si4700_rds_process(void) { @@ -586,13 +560,67 @@ void si4700_rds_process(void) if (tuner_powered()) { - si4700_read_reg(RDSD); + si4700_read(6); +#if (CONFIG_RDS & RDS_CFG_POLL) + /* we need to keep track of the ready bit because it stays set for 80ms + * and we must avoid processing it twice */ + + static bool old_rdsr = false; + bool rdsr = (cache[STATUSRSSI] & STATUSRSSI_RDSR); + if (rdsr && !old_rdsr) + rds_process(&cache[RDSA]); + old_rdsr = rdsr; +#else rds_process(&cache[RDSA]); +#endif /* !(CONFIG_RDS & RDS_CFG_POLL) */ } mutex_unlock(&fmr_mutex); } -#endif /* (CONFIG_RDS & RDS_CFG_ISR) */ + +#if (CONFIG_RDS & RDS_CFG_POLL) +static struct event_queue rds_queue; +static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; + +enum { + Q_POWERUP, +}; + +static void NORETURN_ATTR rds_thread(void) +{ + /* start up frozen */ + int timeout = TIMEOUT_BLOCK; + struct queue_event ev; + + while (true) { + queue_wait_w_tmo(&rds_queue, &ev, timeout); + switch (ev.id) { + case Q_POWERUP: + /* power up: timeout after 1 tick, else block indefinitely */ + timeout = ev.data ? CONFIG_RDS_POLL_TICKS : TIMEOUT_BLOCK; + break; + case SYS_TIMEOUT: + /* Captures RDS data and processes it */ + si4700_rds_process(); + break; + } + } +} + +/* true after full radio power up, and false before powering down */ +void si4700_rds_powerup(bool on) +{ + queue_post(&rds_queue, Q_POWERUP, on); +} + +/* One-time RDS init at startup */ +void si4700_rds_init(void) +{ + queue_init(&rds_queue, false); + create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds" + IF_PRIO(, PRIORITY_PLAYBACK) IF_COP(, CPU)); +} +#endif /* !(CONFIG_RDS & RDS_CFG_POLL) */ #endif /* HAVE_RDS_CAP */ |