From fc9695eb47732e1c189e2f033dbd55e5c346e8c4 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 30 Jan 2017 09:52:05 -0500 Subject: Improve radio RDS driver and framework * Remove unused bits like the radio event and simplify basic radio interface. It can be more self-contained with rds.h only required by radio and tuner code. * Add post-processing to text a-la Silicon Labs AN243. The chip's error correction can only do so much; additional checks are highly recommended. Simply testing for two identical messages in a row is extremely effective and I've never seen corrupted text since doing that, even with mediocre reception. Groups segments must arrive in order, not randomly; logic change only accepts them in order, starting at 0. Time readout was made a bit better but really we'd need to use verbose mode and ensure that no errors were seen during receiving of time and more checks would be need to have a stable PI. The text is the important bit anyway. * Time out of stale text. * Text is no longer updated until a complete group has been received, as is specified in the standard. Perhaps go back to scrolling text lines in the radio screen? * Add proper character conversion to UTF-8. Only the default G0 table for the moment. The other two could be added in. * Add variants "RDS_CFG_PROCESS" and "RDS_CFG_PUSH" to allow the option for processed RDS data to be pushed to the driver and still do proper post-processing (only text conversion for now for the latter). Change-Id: I4d83f8b2e89a209a5096d15ec266477318c66925 --- firmware/drivers/tuner/ipod_remote_tuner.c | 33 ++---------- firmware/drivers/tuner/si4700.c | 87 +++++++----------------------- 2 files changed, 23 insertions(+), 97 deletions(-) (limited to 'firmware/drivers/tuner') diff --git a/firmware/drivers/tuner/ipod_remote_tuner.c b/firmware/drivers/tuner/ipod_remote_tuner.c index 8b599cb79c..e283ddfb68 100644 --- a/firmware/drivers/tuner/ipod_remote_tuner.c +++ b/firmware/drivers/tuner/ipod_remote_tuner.c @@ -30,6 +30,7 @@ #include "adc.h" #include "settings.h" #include "power.h" +#include "rds.h" static unsigned char tuner_param = 0x00, old_tuner_param = 0xFF; /* temp var for tests to avoid looping execution in submenus settings*/ @@ -40,7 +41,6 @@ int radio_present = 0; static int tuner_frequency = 0; static int tuner_signal_power = 0; static bool radio_tuned = false; -static bool rds_event = false; static char rds_radioname[9]; static char rds_radioinfo[65]; @@ -90,6 +90,7 @@ static void rmt_tuner_sleep(int state) { if (state == 0) { + rds_init(); tuner_param = 0x00; old_tuner_param = 0xFF; mono_mode = -1; @@ -273,13 +274,12 @@ void rmt_tuner_rds_data(unsigned int len, const unsigned char *buf) { if (buf[2] == 0x1E) { - strlcpy(rds_radioname,buf+4,8); + rds_push_info(RDS_INFO_PS, (uintptr_t)(buf+4), 8); } else if(buf[2] == 0x04) { - strlcpy(rds_radioinfo,buf+4,len-4); + rds_push_info(RDS_INFO_RT, (uintptr_t)(buf+4), len-4); } - rds_event = true; } /* tuner abstraction layer: set something to the tuner */ @@ -421,31 +421,6 @@ int ipod_rmt_tuner_get(int setting) case RADIO_STEREO: val = true; break; - - case RADIO_EVENT: - if (rds_event) - { - val = 1; - rds_event = false; - } - break; } return val; } - -char* ipod_get_rds_info(int setting) -{ - char *text = NULL; - - switch(setting) - { - case RADIO_RDS_NAME: - text = rds_radioname; - break; - - case RADIO_RDS_TEXT: - text = rds_radioinfo; - break; - } - return text; -} diff --git a/firmware/drivers/tuner/si4700.c b/firmware/drivers/tuner/si4700.c index 90d8df27dc..c7d942f293 100644 --- a/firmware/drivers/tuner/si4700.c +++ b/firmware/drivers/tuner/si4700.c @@ -213,9 +213,6 @@ static bool tuner_present = false; static uint16_t cache[16]; static struct mutex fmr_mutex SHAREDBSS_ATTR; -#ifdef HAVE_RDS_CAP -static int rds_event = 0; -#endif /* reads registers from radio at offset 0x0A into cache */ static void si4700_read(int len) @@ -373,6 +370,7 @@ void si4700_init(void) si4700_sleep(1); #ifdef HAVE_RDS_CAP + rds_init(); si4700_rds_init(); #endif } @@ -528,21 +526,6 @@ int si4700_get(int setting) case RADIO_RSSI_MAX: val = RSSI_MAX; break; - -#ifdef HAVE_RDS_CAP - case RADIO_EVENT: - { - #ifdef RDS_ISR_PROCESSING - int oldlevel = disable_irq_save(); - #endif - val = rds_event; - rds_event = 0; - #ifdef RDS_ISR_PROCESSING - restore_irq(oldlevel); - #endif - break; - } -#endif } mutex_unlock(&fmr_mutex); @@ -567,77 +550,45 @@ void si4700_dbg_info(struct si4700_dbg_info *nfo) #ifdef HAVE_RDS_CAP -#ifdef RDS_ISR_PROCESSING -/* Read raw RDS info for processing - in ISR */ +#if (CONFIG_RDS & RDS_CFG_ISR) +static unsigned char isr_regbuf[(RDSD - STATUSRSSI + 1) * 2]; -/* Assumes regbuf is 32 bytes */ -void si4700_rds_read_raw_async(void) +/* Called by RDS interrupt on target */ +void si4700_rds_interrupt(void) { - si4700_read_raw_async((RDSD - STATUSRSSI + 1) * 2); + si4700_rds_read_raw_async(isr_regbuf, sizeof (isr_regbuf)); } -void si4700_rds_read_raw_async_complete(unsigned char *regbuf, - uint16_t data[4]) +/* Handle RDS event from ISR */ +void si4700_rds_process(void) { - const int index = (RDSA - STATUSRSSI) * 2; + uint16_t rds_data[4]; + int index = (RDSA - STATUSRSSI) * 2; for (int i = 0; i < 4; i++) { - data[i] = regbuf[index] << 8 | regbuf[index + 1]; - regbuf += 2; + rds_data[i] = isr_regbuf[index] << 8 | isr_regbuf[index + 1]; + index += 2; } -} -/* Set the event flag */ -void si4700_rds_set_event(void) -{ - rds_event = 1; + rds_process(rds_data); } -#else /* ndef RDS_ISR_PROCESSING */ -/* Read raw RDS info for processing */ -bool si4700_rds_read_raw(uint16_t data[4]) -{ - bool retval = false; +#else /* !(CONFIG_RDS & RDS_CFG_ISR) */ +/* Handle RDS event from thread */ +void si4700_rds_process(void) +{ mutex_lock(&fmr_mutex); if (tuner_powered()) { si4700_read_reg(RDSD); - memcpy(data, &cache[RDSA], 4 * sizeof (uint16_t)); - retval = true; + rds_process(&cache[RDSA]); } mutex_unlock(&fmr_mutex); - - return retval; -} - -/* Set the event flag */ -void si4700_rds_set_event(void) -{ - mutex_lock(&fmr_mutex); - rds_event = 1; - mutex_unlock(&fmr_mutex); } -#endif /* RDS_ISR_PROCESSING */ +#endif /* (CONFIG_RDS & RDS_CFG_ISR) */ -char * si4700_get_rds_info(int setting) -{ - char *text = NULL; - - switch(setting) - { - case RADIO_RDS_NAME: - text = rds_get_ps(); - break; - - case RADIO_RDS_TEXT: - text = rds_get_rt(); - break; - } - - return text; -} #endif /* HAVE_RDS_CAP */ -- cgit v1.2.3