summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/ypr0
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/hosted/ypr0')
-rw-r--r--firmware/target/hosted/ypr0/radio-ypr0.c61
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
31static int radio_dev = -1; 35static 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 */
79static struct event_queue rds_queue;
80static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)];
81static uint16_t rds_data[4];
82
83enum {
84 Q_POWERUP,
85};
86
87static 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 */
112void si4700_rds_powerup(bool on)
113{
114 queue_post(&rds_queue, Q_POWERUP, on);
115}
116
117/* One-time RDS init at startup */
118void 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 */