diff options
Diffstat (limited to 'firmware/target/arm/as3525/fmradio-i2c-as3525.c')
-rw-r--r-- | firmware/target/arm/as3525/fmradio-i2c-as3525.c | 59 |
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 */ | ||
189 | static struct semaphore rds_sema; | ||
190 | static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)]; | ||
191 | |||
192 | /* RDS GPIO interrupt handler */ | ||
193 | void 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 */ | ||
203 | static 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 */ | ||
217 | void 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 */ | ||
232 | void 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 | |||