diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/rds.c | 21 | ||||
-rw-r--r-- | firmware/drivers/tuner/si4700.c | 27 | ||||
-rw-r--r-- | firmware/export/config.h | 2 | ||||
-rw-r--r-- | firmware/export/config/gigabeats.h | 3 | ||||
-rw-r--r-- | firmware/export/si4700.h | 8 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c | 49 |
6 files changed, 16 insertions, 94 deletions
diff --git a/firmware/drivers/rds.c b/firmware/drivers/rds.c index 0b9b227563..2d8466ae36 100644 --- a/firmware/drivers/rds.c +++ b/firmware/drivers/rds.c | |||
@@ -72,15 +72,6 @@ static int rt_data_idx; /* rt_data[0 or 1] */ | |||
72 | #define RT_DATA_INC(x) rt_data[rt_data_idx ^= (x)] | 72 | #define RT_DATA_INC(x) rt_data[rt_data_idx ^= (x)] |
73 | #endif /* (CONFIG_RDS & RDS_CFG_PROCESS) */ | 73 | #endif /* (CONFIG_RDS & RDS_CFG_PROCESS) */ |
74 | 74 | ||
75 | #if (CONFIG_RDS & RDS_CFG_ISR) | ||
76 | /* Functions are called in ISR context */ | ||
77 | #define rds_disable_irq_save() disable_irq_save() | ||
78 | #define rds_restore_irq(old) restore_irq(old) | ||
79 | #else /* !(CONFIG_RDS & RDS_CFG_ISR) */ | ||
80 | #define rds_disable_irq_save() 0 | ||
81 | #define rds_restore_irq(old) ((void)(old)) | ||
82 | #endif /* (CONFIG_RDS & RDS_CFG_ISR) */ | ||
83 | |||
84 | /* RDS code table G0 to UTF-8 translation */ | 75 | /* RDS code table G0 to UTF-8 translation */ |
85 | static const uint16_t rds_tbl_g0[0x100-0x20] = | 76 | static const uint16_t rds_tbl_g0[0x100-0x20] = |
86 | { | 77 | { |
@@ -195,8 +186,6 @@ static void register_activity(void) | |||
195 | /* resets the rds parser */ | 186 | /* resets the rds parser */ |
196 | void rds_reset(void) | 187 | void rds_reset(void) |
197 | { | 188 | { |
198 | int oldlevel = rds_disable_irq_save(); | ||
199 | |||
200 | /* reset general info */ | 189 | /* reset general info */ |
201 | pi_code = 0; | 190 | pi_code = 0; |
202 | ct_data = 0; | 191 | ct_data = 0; |
@@ -210,8 +199,6 @@ void rds_reset(void) | |||
210 | ps_segment = 0; | 199 | ps_segment = 0; |
211 | rt_segment = 0; | 200 | rt_segment = 0; |
212 | #endif /* (CONFIG_RDS & RDS_CFG_PROCESS) */ | 201 | #endif /* (CONFIG_RDS & RDS_CFG_PROCESS) */ |
213 | |||
214 | rds_restore_irq(oldlevel); | ||
215 | } | 202 | } |
216 | 203 | ||
217 | /* initialises the rds parser */ | 204 | /* initialises the rds parser */ |
@@ -223,8 +210,6 @@ void rds_init(void) | |||
223 | /* sync RDS state */ | 210 | /* sync RDS state */ |
224 | void rds_sync(void) | 211 | void rds_sync(void) |
225 | { | 212 | { |
226 | int oldlevel = rds_disable_irq_save(); | ||
227 | |||
228 | if (rds_active) { | 213 | if (rds_active) { |
229 | if (TIMED_OUT(rds_timeout)) { | 214 | if (TIMED_OUT(rds_timeout)) { |
230 | rds_reset(); | 215 | rds_reset(); |
@@ -238,8 +223,6 @@ void rds_sync(void) | |||
238 | } | 223 | } |
239 | } | 224 | } |
240 | } | 225 | } |
241 | |||
242 | rds_restore_irq(oldlevel); | ||
243 | } | 226 | } |
244 | 227 | ||
245 | #if (CONFIG_RDS & RDS_CFG_PROCESS) | 228 | #if (CONFIG_RDS & RDS_CFG_PROCESS) |
@@ -458,8 +441,6 @@ void rds_push_info(enum rds_info_id info_id, uintptr_t data, size_t size) | |||
458 | /* read fully-processed RDS data */ | 441 | /* read fully-processed RDS data */ |
459 | size_t rds_pull_info(enum rds_info_id info_id, uintptr_t data, size_t size) | 442 | size_t rds_pull_info(enum rds_info_id info_id, uintptr_t data, size_t size) |
460 | { | 443 | { |
461 | int oldlevel = rds_disable_irq_save(); | ||
462 | |||
463 | rds_sync(); | 444 | rds_sync(); |
464 | 445 | ||
465 | switch (info_id) { | 446 | switch (info_id) { |
@@ -490,7 +471,5 @@ size_t rds_pull_info(enum rds_info_id info_id, uintptr_t data, size_t size) | |||
490 | default: | 471 | default: |
491 | size = 0; | 472 | size = 0; |
492 | } | 473 | } |
493 | |||
494 | rds_restore_irq(oldlevel); | ||
495 | return size; | 474 | return size; |
496 | } | 475 | } |
diff --git a/firmware/drivers/tuner/si4700.c b/firmware/drivers/tuner/si4700.c index cce203fde9..7b54526f61 100644 --- a/firmware/drivers/tuner/si4700.c +++ b/firmware/drivers/tuner/si4700.c | |||
@@ -553,32 +553,6 @@ void si4700_dbg_info(struct si4700_dbg_info *nfo) | |||
553 | } | 553 | } |
554 | 554 | ||
555 | #ifdef HAVE_RDS_CAP | 555 | #ifdef HAVE_RDS_CAP |
556 | |||
557 | #if (CONFIG_RDS & RDS_CFG_ISR) | ||
558 | static unsigned char isr_regbuf[(RDSD - STATUSRSSI + 1) * 2]; | ||
559 | |||
560 | /* Called by RDS interrupt on target */ | ||
561 | void si4700_rds_interrupt(void) | ||
562 | { | ||
563 | si4700_rds_read_raw_async(isr_regbuf, sizeof (isr_regbuf)); | ||
564 | } | ||
565 | |||
566 | /* Handle RDS event from ISR */ | ||
567 | void si4700_rds_process(void) | ||
568 | { | ||
569 | uint16_t rds_data[4]; | ||
570 | int index = (RDSA - STATUSRSSI) * 2; | ||
571 | |||
572 | for (int i = 0; i < 4; i++) { | ||
573 | rds_data[i] = isr_regbuf[index] << 8 | isr_regbuf[index + 1]; | ||
574 | index += 2; | ||
575 | } | ||
576 | |||
577 | rds_process(rds_data); | ||
578 | } | ||
579 | |||
580 | #else /* !(CONFIG_RDS & RDS_CFG_ISR) */ | ||
581 | |||
582 | /* Handle RDS event from thread */ | 556 | /* Handle RDS event from thread */ |
583 | void si4700_rds_process(void) | 557 | void si4700_rds_process(void) |
584 | { | 558 | { |
@@ -603,7 +577,6 @@ void si4700_rds_process(void) | |||
603 | 577 | ||
604 | mutex_unlock(&fmr_mutex); | 578 | mutex_unlock(&fmr_mutex); |
605 | } | 579 | } |
606 | #endif /* (CONFIG_RDS & RDS_CFG_ISR) */ | ||
607 | 580 | ||
608 | #if (CONFIG_RDS & RDS_CFG_POLL) | 581 | #if (CONFIG_RDS & RDS_CFG_POLL) |
609 | static struct event_queue rds_queue; | 582 | static struct event_queue rds_queue; |
diff --git a/firmware/export/config.h b/firmware/export/config.h index 2ae7ef2c53..efd99569b6 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -728,7 +728,7 @@ Lyre prototype 1 */ | |||
728 | 728 | ||
729 | #ifdef HAVE_RDS_CAP | 729 | #ifdef HAVE_RDS_CAP |
730 | /* combinable bitflags */ | 730 | /* combinable bitflags */ |
731 | #define RDS_CFG_ISR 0x1 /* uses ISR to process packets */ | 731 | /* 0x01 can be reused, was RDS_CFG_ISR */ |
732 | #define RDS_CFG_PROCESS 0x2 /* uses raw packet processing */ | 732 | #define RDS_CFG_PROCESS 0x2 /* uses raw packet processing */ |
733 | #define RDS_CFG_PUSH 0x4 /* pushes processed information */ | 733 | #define RDS_CFG_PUSH 0x4 /* pushes processed information */ |
734 | #define RDS_CFG_POLL 0x8 /* tuner driver provides a polling function */ | 734 | #define RDS_CFG_POLL 0x8 /* tuner driver provides a polling function */ |
diff --git a/firmware/export/config/gigabeats.h b/firmware/export/config/gigabeats.h index 8d82b44065..edf76d0e98 100644 --- a/firmware/export/config/gigabeats.h +++ b/firmware/export/config/gigabeats.h | |||
@@ -121,7 +121,6 @@ | |||
121 | /* Define this if you have a SI4700 fm radio tuner */ | 121 | /* Define this if you have a SI4700 fm radio tuner */ |
122 | #define CONFIG_TUNER SI4700 | 122 | #define CONFIG_TUNER SI4700 |
123 | #define HAVE_RDS_CAP | 123 | #define HAVE_RDS_CAP |
124 | #define CONFIG_RDS (RDS_CFG_ISR | RDS_CFG_PROCESS) | ||
125 | 124 | ||
126 | /* define this if you can flip your LCD */ | 125 | /* define this if you can flip your LCD */ |
127 | #define HAVE_LCD_FLIP | 126 | #define HAVE_LCD_FLIP |
@@ -164,7 +163,7 @@ | |||
164 | #define GPIO_EVENT_MASK (USE_GPIO1_EVENTS) | 163 | #define GPIO_EVENT_MASK (USE_GPIO1_EVENTS) |
165 | 164 | ||
166 | /* Define this if target has an additional number of threads specific to it */ | 165 | /* Define this if target has an additional number of threads specific to it */ |
167 | #define TARGET_EXTRA_THREADS 1 | 166 | #define TARGET_EXTRA_THREADS 2 /* one is for RDS */ |
168 | 167 | ||
169 | /* Type of mobile power - check this out */ | 168 | /* Type of mobile power - check this out */ |
170 | #define BATTERY_CAPACITY_DEFAULT 700 /* default battery capacity */ | 169 | #define BATTERY_CAPACITY_DEFAULT 700 /* default battery capacity */ |
diff --git a/firmware/export/si4700.h b/firmware/export/si4700.h index 033b435f2a..cf9e0f077b 100644 --- a/firmware/export/si4700.h +++ b/firmware/export/si4700.h | |||
@@ -49,15 +49,7 @@ void si4700_rds_init(void) INIT_ATTR; | |||
49 | /* Radio is fully powered up or about to be powered down */ | 49 | /* Radio is fully powered up or about to be powered down */ |
50 | void si4700_rds_powerup(bool on); | 50 | void si4700_rds_powerup(bool on); |
51 | 51 | ||
52 | #if (CONFIG_RDS & RDS_CFG_ISR) | ||
53 | /* Read raw RDS info for processing - asynchronously */ | ||
54 | void si4700_rds_read_raw_async(unsigned char *buf, int count); /* implemented by target */ | ||
55 | void si4700_rds_interrupt(void); | ||
56 | #endif /* (CONFIG_RDS & RDS_CFG_ISR) */ | ||
57 | |||
58 | /* Read raw RDS info for processing. | 52 | /* Read raw RDS info for processing. |
59 | * - If RDS_CFG_ISR is set, the tuner driver will call si4700_rds_read_raw_async() which should | ||
60 | * perform an asynchronous read and call this function when the data has been read. | ||
61 | * - If RDS_CFG_POLL is set, this function will read status and RDS data and process it if a new | 53 | * - If RDS_CFG_POLL is set, this function will read status and RDS data and process it if a new |
62 | * packet is available. | 54 | * packet is available. |
63 | * - Otherwise this function will read a RDS packet and process it under the assumption that it is | 55 | * - Otherwise this function will read a RDS packet and process it under the assumption that it is |
diff --git a/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c index 5b0c71110d..c84f1cf41c 100644 --- a/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c | |||
@@ -125,53 +125,30 @@ bool si4700_st(void) | |||
125 | return (GPIO1_DR & (1 << 28)) >> 28; | 125 | return (GPIO1_DR & (1 << 28)) >> 28; |
126 | } | 126 | } |
127 | 127 | ||
128 | |||
129 | /* Low-level RDS Support */ | 128 | /* Low-level RDS Support */ |
130 | static bool int_restore; | 129 | static struct semaphore rds_sema; |
131 | 130 | static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)]; | |
132 | /* Called after I2C read cycle completes */ | ||
133 | static void si4700_rds_read_raw_async_callback(struct i2c_transfer_desc *xfer) | ||
134 | { | ||
135 | if (xfer->rxcount == 0) | ||
136 | si4700_rds_process(); | ||
137 | /* else read didn't finish */ | ||
138 | |||
139 | if (int_restore) | ||
140 | gpio_int_enable(SI4700_EVENT_ID); | ||
141 | } | ||
142 | |||
143 | /* Called to read registers from ISR context */ | ||
144 | void si4700_rds_read_raw_async(unsigned char *buf, int count) | ||
145 | { | ||
146 | /* transfer descriptor for RDS async operations */ | ||
147 | static struct i2c_transfer_desc xfer = { .node = &si4700_i2c_node }; | ||
148 | |||
149 | xfer.txdata = NULL; | ||
150 | xfer.txcount = 0; | ||
151 | xfer.rxdata = buf; | ||
152 | xfer.rxcount = count; | ||
153 | xfer.callback = si4700_rds_read_raw_async_callback; | ||
154 | xfer.next = NULL; | ||
155 | |||
156 | i2c_transfer(&xfer); | ||
157 | } | ||
158 | 131 | ||
159 | /* RDS GPIO interrupt handler - start RDS data read */ | 132 | /* RDS GPIO interrupt handler - start RDS data read */ |
160 | void INT_SI4700_RDS(void) | 133 | void INT_SI4700_RDS(void) |
161 | { | 134 | { |
162 | /* mask and clear the interrupt until we're done */ | ||
163 | gpio_int_disable(SI4700_EVENT_ID); | ||
164 | gpio_int_clear(SI4700_EVENT_ID); | 135 | gpio_int_clear(SI4700_EVENT_ID); |
136 | semaphore_release(&rds_sema); | ||
137 | } | ||
165 | 138 | ||
166 | /* tell radio driver about it */ | 139 | /* Captures RDS data and processes it */ |
167 | si4700_rds_interrupt(); | 140 | static void NORETURN_ATTR rds_thread(void) |
141 | { | ||
142 | while (true) { | ||
143 | semaphore_wait(&rds_sema, TIMEOUT_BLOCK); | ||
144 | si4700_rds_process(); | ||
145 | } | ||
168 | } | 146 | } |
169 | 147 | ||
170 | /* Called with on=true after full radio power up, and with on=false before | 148 | /* Called with on=true after full radio power up, and with on=false before |
171 | powering down */ | 149 | powering down */ |
172 | void si4700_rds_powerup(bool on) | 150 | void si4700_rds_powerup(bool on) |
173 | { | 151 | { |
174 | int_restore = on; | ||
175 | gpio_int_disable(SI4700_EVENT_ID); | 152 | gpio_int_disable(SI4700_EVENT_ID); |
176 | gpio_int_clear(SI4700_EVENT_ID); | 153 | gpio_int_clear(SI4700_EVENT_ID); |
177 | gpio_enable_event(SI4700_EVENT_ID, on); | 154 | gpio_enable_event(SI4700_EVENT_ID, on); |
@@ -180,5 +157,7 @@ void si4700_rds_powerup(bool on) | |||
180 | /* One-time RDS init at startup */ | 157 | /* One-time RDS init at startup */ |
181 | void si4700_rds_init(void) | 158 | void si4700_rds_init(void) |
182 | { | 159 | { |
183 | /* nothing to do */ | 160 | semaphore_init(&rds_sema, 1, 0); |
161 | create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds" | ||
162 | IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); | ||
184 | } | 163 | } |