From d2875fc77370509248b638b54969f5ed625d8cac Mon Sep 17 00:00:00 2001 From: Lorenzo Miori Date: Thu, 27 Sep 2012 11:56:03 +0200 Subject: This patch adds RDS capability to Samsung YP-R0 target. Uses register polling method to decide when it's time to decode RDS packets. Change-Id: I1d3cc995ea3350ec7b101438b8f2027130d4a4c9 Reviewed-on: http://gerrit.rockbox.org/320 Reviewed-by: Lorenzo Miori Tested-by: Lorenzo Miori Reviewed-by: Thomas Martitz Tested-by: Thomas Martitz --- firmware/export/config/samsungypr0.h | 13 ++----- firmware/target/hosted/ypr0/radio-ypr0.c | 61 +++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 12 deletions(-) (limited to 'firmware') diff --git a/firmware/export/config/samsungypr0.h b/firmware/export/config/samsungypr0.h index e97dabcfb2..debe9a3f80 100644 --- a/firmware/export/config/samsungypr0.h +++ b/firmware/export/config/samsungypr0.h @@ -18,9 +18,6 @@ /*TODO: implement USB data transfer management -> see safe mode script and think a way to implemtent it in the code */ #define USB_NONE -/* There is only USB charging */ -//#define HAVE_USB_POWER - /* define this if you have a bitmap LCD display */ #define HAVE_LCD_BITMAP @@ -28,7 +25,6 @@ #define HAVE_LCD_COLOR /* define this if the LCD needs to be shutdown */ -/* TODO: Our framebuffer must be closed... */ #define HAVE_LCD_SHUTDOWN /* define this if you want album art for this target */ @@ -84,7 +80,6 @@ /* The number of bytes reserved for loadable plugins */ #define PLUGIN_BUFFER_SIZE 0x100000 -/* We can do AB-repeat -> we use User key, our hotkey */ #define AB_REPEAT_ENABLE #define ACTION_WPSAB_SINGLE ACTION_WPS_HOTKEY @@ -93,10 +88,9 @@ /* R0 KeyPad configuration for plugins */ #define CONFIG_KEYPAD SAMSUNG_YPR0_PAD -/* It's better to close /dev/r0Btn at shutdown */ #define BUTTON_DRIVER_CLOSE -/* The YPR0 has a as3534 codec and we use that to control the volume */ +/* The YPR0 has a as3534 codec */ #define HAVE_AS3514 #define HAVE_AS3543 @@ -105,10 +99,7 @@ #define CONFIG_TUNER SI4700 #define HAVE_TUNER_PWR_CTRL -/* TODO: next step: enable RDS #define HAVE_RDS_CAP -#define RDS_ISR_PROCESSING -*/ /* Define this for FM radio input available */ #define HAVE_FMRADIO_IN @@ -154,5 +145,5 @@ /* Max IMX37 Cpu Frequency */ /* #define CPUFREQ_MAX CPU_FREQ */ -/* TODO: my idea is to create a folder in the cramfs [/.rockbox], mounting it by the starter script as the current working directory, so no issues of any type keeping the rockbox folder as in all other players */ +/* This folder resides in the ReadOnly CRAMFS. It is binded to /mnt/media0/.rockbox */ #define BOOTDIR "/.rockbox" diff --git a/firmware/target/hosted/ypr0/radio-ypr0.c b/firmware/target/hosted/ypr0/radio-ypr0.c index c3597bd18c..14d56826c1 100644 --- a/firmware/target/hosted/ypr0/radio-ypr0.c +++ b/firmware/target/hosted/ypr0/radio-ypr0.c @@ -25,8 +25,12 @@ #include #include "stdint.h" #include "string.h" +#include "kernel.h" #include "radio-ypr0.h" +#include "rds.h" +#include "si4700.h" +#include "power.h" static int radio_dev = -1; @@ -63,4 +67,59 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) (void)address; sSi4709_i2c_t r = { .size = count, .buf = buf }; return ioctl(radio_dev, IOCTL_SI4709_I2C_READ, &r); -} \ No newline at end of file +} + +#ifdef HAVE_RDS_CAP + +/* Register we are going to poll */ +#define STATUSRSSI 0xA +#define STATUSRSSI_RDSR (0x1 << 15) + +/* Low-level RDS Support */ +static struct event_queue rds_queue; +static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; +static uint16_t rds_data[4]; + +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 ? 1 : TIMEOUT_BLOCK; + break; + case SYS_TIMEOUT: + /* Captures RDS data and processes it */ + if ((si4709_read_reg(STATUSRSSI) & STATUSRSSI_RDSR) >> 8) { + if (si4700_rds_read_raw(rds_data) && rds_process(rds_data)) + si4700_rds_set_event(); + } + 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)); + rds_init(); +} +#endif /* HAVE_RDS_CAP */ -- cgit v1.2.3