summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/fmradio-i2c-as3525.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/as3525/fmradio-i2c-as3525.c')
-rw-r--r--firmware/target/arm/as3525/fmradio-i2c-as3525.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/firmware/target/arm/as3525/fmradio-i2c-as3525.c b/firmware/target/arm/as3525/fmradio-i2c-as3525.c
index 1dbf2fde24..3da42e31b2 100644
--- a/firmware/target/arm/as3525/fmradio-i2c-as3525.c
+++ b/firmware/target/arm/as3525/fmradio-i2c-as3525.c
@@ -27,10 +27,14 @@
27 I2C with a couple of GPIO pins. 27 I2C with a couple of GPIO pins.
28 */ 28 */
29 29
30#include "config.h"
30#include "as3525.h" 31#include "as3525.h"
31#include "system.h" 32#include "system.h"
33#include "tuner.h"
32#include "generic_i2c.h" 34#include "generic_i2c.h"
33#include "fmradio_i2c.h" 35#include "fmradio_i2c.h"
36#include "thread.h"
37#include "rds.h"
34 38
35#if defined(SANSA_CLIP) || defined(SANSA_C200V2) 39#if defined(SANSA_CLIP) || defined(SANSA_C200V2)
36#define I2C_SCL_GPIO(x) GPIOB_PIN(x) 40#define I2C_SCL_GPIO(x) GPIOB_PIN(x)
@@ -179,3 +183,58 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
179#endif 183#endif
180 return ret; 184 return ret;
181} 185}
186
187#ifdef HAVE_RDS_CAP
188/* Low-level RDS Support */
189static struct semaphore rds_sema;
190static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)];
191
192/* RDS GPIO interrupt handler */
193void tuner_isr(void)
194{
195 /* read and clear the interrupt */
196 if (GPIOA_MIS & (1<<4)) {
197 semaphore_release(&rds_sema);
198 }
199 GPIOA_IC = (1<<4);
200}
201
202/* Captures RDS data and processes it */
203static void NORETURN_ATTR rds_thread(void)
204{
205 uint16_t rds_data[4];
206
207 while (true) {
208 semaphore_wait(&rds_sema, TIMEOUT_BLOCK);
209 if (si4700_rds_read_raw(rds_data) && rds_process(rds_data)) {
210 si4700_rds_set_event();
211 }
212 }
213}
214
215/* Called with on=true after full radio power up, and with on=false before
216 powering down */
217void si4700_rds_powerup(bool on)
218{
219 GPIOA_IE &= ~(1<<4); /* disable GPIO interrupt */
220
221 if (on) {
222 GPIOA_DIR &= ~(1<<4); /* input */
223 GPIOA_IS &= ~(1<<4); /* edge detect */
224 GPIOA_IBE &= ~(1<<4); /* only one edge */
225 GPIOA_IEV &= ~(1<<4); /* falling edge */
226 GPIOA_IC = (1<<4); /* clear any pending interrupt */
227 GPIOA_IE |= (1<<4); /* enable GPIO interrupt */
228 }
229}
230
231/* One-time RDS init at startup */
232void si4700_rds_init(void)
233{
234 semaphore_init(&rds_sema, 1, 0);
235 rds_init();
236 create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds"
237 IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU));
238}
239#endif /* HAVE_RDS_CAP */
240