diff options
Diffstat (limited to 'firmware/target/hosted/ypr0/radio-ypr0.c')
-rw-r--r-- | firmware/target/hosted/ypr0/radio-ypr0.c | 61 |
1 files changed, 60 insertions, 1 deletions
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 @@ | |||
25 | #include <sys/ioctl.h> | 25 | #include <sys/ioctl.h> |
26 | #include "stdint.h" | 26 | #include "stdint.h" |
27 | #include "string.h" | 27 | #include "string.h" |
28 | #include "kernel.h" | ||
28 | 29 | ||
29 | #include "radio-ypr0.h" | 30 | #include "radio-ypr0.h" |
31 | #include "rds.h" | ||
32 | #include "si4700.h" | ||
33 | #include "power.h" | ||
30 | 34 | ||
31 | static int radio_dev = -1; | 35 | static int radio_dev = -1; |
32 | 36 | ||
@@ -63,4 +67,59 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) | |||
63 | (void)address; | 67 | (void)address; |
64 | sSi4709_i2c_t r = { .size = count, .buf = buf }; | 68 | sSi4709_i2c_t r = { .size = count, .buf = buf }; |
65 | return ioctl(radio_dev, IOCTL_SI4709_I2C_READ, &r); | 69 | return ioctl(radio_dev, IOCTL_SI4709_I2C_READ, &r); |
66 | } \ No newline at end of file | 70 | } |
71 | |||
72 | #ifdef HAVE_RDS_CAP | ||
73 | |||
74 | /* Register we are going to poll */ | ||
75 | #define STATUSRSSI 0xA | ||
76 | #define STATUSRSSI_RDSR (0x1 << 15) | ||
77 | |||
78 | /* Low-level RDS Support */ | ||
79 | static struct event_queue rds_queue; | ||
80 | static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; | ||
81 | static uint16_t rds_data[4]; | ||
82 | |||
83 | enum { | ||
84 | Q_POWERUP, | ||
85 | }; | ||
86 | |||
87 | static void NORETURN_ATTR rds_thread(void) | ||
88 | { | ||
89 | /* start up frozen */ | ||
90 | int timeout = TIMEOUT_BLOCK; | ||
91 | struct queue_event ev; | ||
92 | |||
93 | while (true) { | ||
94 | queue_wait_w_tmo(&rds_queue, &ev, timeout); | ||
95 | switch (ev.id) { | ||
96 | case Q_POWERUP: | ||
97 | /* power up: timeout after 1 tick, else block indefinitely */ | ||
98 | timeout = ev.data ? 1 : TIMEOUT_BLOCK; | ||
99 | break; | ||
100 | case SYS_TIMEOUT: | ||
101 | /* Captures RDS data and processes it */ | ||
102 | if ((si4709_read_reg(STATUSRSSI) & STATUSRSSI_RDSR) >> 8) { | ||
103 | if (si4700_rds_read_raw(rds_data) && rds_process(rds_data)) | ||
104 | si4700_rds_set_event(); | ||
105 | } | ||
106 | break; | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /* true after full radio power up, and false before powering down */ | ||
112 | void si4700_rds_powerup(bool on) | ||
113 | { | ||
114 | queue_post(&rds_queue, Q_POWERUP, on); | ||
115 | } | ||
116 | |||
117 | /* One-time RDS init at startup */ | ||
118 | void si4700_rds_init(void) | ||
119 | { | ||
120 | queue_init(&rds_queue, false); | ||
121 | create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds" | ||
122 | IF_PRIO(, PRIORITY_PLAYBACK) IF_COP(, CPU)); | ||
123 | rds_init(); | ||
124 | } | ||
125 | #endif /* HAVE_RDS_CAP */ | ||