summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/as3525/fmradio-i2c-as3525.c59
-rw-r--r--firmware/target/arm/as3525/system-as3525.c4
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c56
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c9
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/gpio-target.h10
5 files changed, 135 insertions, 3 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
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index 7e2e480eda..965030ecc3 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -155,6 +155,10 @@ void INT_GPIOA(void)
155 void button_gpioa_isr(void); 155 void button_gpioa_isr(void);
156 button_gpioa_isr(); 156 button_gpioa_isr();
157#endif 157#endif
158#ifdef HAVE_RDS_CAP
159 void tuner_isr(void);
160 tuner_isr();
161#endif
158} 162}
159 163
160void irq_handler(void) 164void irq_handler(void)
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 39a2cdab04..e0457e367a 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
@@ -23,8 +23,12 @@
23#include "system.h" 23#include "system.h"
24#include "mc13783.h" 24#include "mc13783.h"
25#include "iomuxc-imx31.h" 25#include "iomuxc-imx31.h"
26#include "gpio-imx31.h"
26#include "i2c-imx31.h" 27#include "i2c-imx31.h"
27#include "fmradio_i2c.h" 28#include "fmradio_i2c.h"
29#include "thread.h"
30#include "rds.h"
31#include "tuner.h"
28 32
29static struct i2c_node si4700_i2c_node = 33static struct i2c_node si4700_i2c_node =
30{ 34{
@@ -117,7 +121,57 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
117 return 0; 121 return 0;
118} 122}
119 123
120int si4700_st(void) 124bool si4700_st(void)
121{ 125{
122 return (GPIO1_DR & (1 << 28)) >> 28; 126 return (GPIO1_DR & (1 << 28)) >> 28;
123} 127}
128
129
130/* Low-level RDS Support */
131static struct semaphore rds_sema;
132static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)];
133
134/* RDS GPIO interrupt handler */
135void si4700_stc_rds_event(void)
136{
137 /* read and clear the interrupt */
138 SI4700_GPIO_STC_RDS_ISR = (1ul << SI4700_GPIO_STC_RDS_LINE);
139 semaphore_release(&rds_sema);
140}
141
142/* Called with on=true after full radio power up, and with on=false before
143 powering down */
144void si4700_rds_powerup(bool on)
145{
146 gpio_disable_event(SI4700_STC_RDS_EVENT_ID);
147
148 if (on)
149 {
150 SI4700_GPIO_STC_RDS_ISR = (1ul << SI4700_GPIO_STC_RDS_LINE);
151 gpio_enable_event(SI4700_STC_RDS_EVENT_ID);
152 }
153}
154
155/* Captures RDS data and processes it */
156/* Use of a thread here is likely temporary */
157static void NORETURN_ATTR rds_thread(void)
158{
159 uint16_t rds_data[4];
160
161 while (1)
162 {
163 semaphore_wait(&rds_sema, TIMEOUT_BLOCK);
164
165 if (si4700_rds_read_raw(rds_data) && rds_process(rds_data))
166 si4700_rds_set_event();
167 }
168}
169
170/* One-time RDS init at startup */
171void si4700_rds_init(void)
172{
173 semaphore_init(&rds_sema, 1, 0);
174 rds_init();
175 create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds"
176 IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU));
177}
diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c
index f4402d5617..e6bbb2345d 100644
--- a/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c
@@ -39,5 +39,12 @@ const struct gpio_event gpio1_events[] =
39 .mask = 1 << MC13783_GPIO_LINE, 39 .mask = 1 << MC13783_GPIO_LINE,
40 .sense = GPIO_SENSE_HIGH_LEVEL, 40 .sense = GPIO_SENSE_HIGH_LEVEL,
41 .callback = mc13783_event, 41 .callback = mc13783_event,
42 } 42 },
43 /* Generates a 5ms low pulse on the line - detect the falling edge */
44 [SI4700_STC_RDS_EVENT_ID] =
45 {
46 .mask = 1 << SI4700_GPIO_STC_RDS_LINE,
47 .sense = GPIO_SENSE_FALLING,
48 .callback = si4700_stc_rds_event,
49 },
43}; 50};
diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-target.h b/firmware/target/arm/imx31/gigabeat-s/gpio-target.h
index 2eea27c3be..4903d0f631 100644
--- a/firmware/target/arm/imx31/gigabeat-s/gpio-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/gpio-target.h
@@ -29,6 +29,12 @@
29#define MC13783_GPIO_ISR GPIO1_ISR 29#define MC13783_GPIO_ISR GPIO1_ISR
30#define MC13783_GPIO_LINE 31 30#define MC13783_GPIO_LINE 31
31 31
32/* SI4700 GPIO STC/RDS pin info for this target */
33#define SI4700_GPIO_STC_RDS_IMR GPIO1_IMR
34#define SI4700_GPIO_STC_RDS_NUM GPIO1_NUM
35#define SI4700_GPIO_STC_RDS_ISR GPIO1_ISR
36#define SI4700_GPIO_STC_RDS_LINE 27
37
32#define GPIO1_INT_PRIO INT_PRIO_DEFAULT 38#define GPIO1_INT_PRIO INT_PRIO_DEFAULT
33 39
34/* Declare event indexes in priority order in a packed array */ 40/* Declare event indexes in priority order in a packed array */
@@ -36,7 +42,8 @@ enum gpio_event_ids
36{ 42{
37 /* GPIO1 event IDs */ 43 /* GPIO1 event IDs */
38 MC13783_EVENT_ID = GPIO1_EVENT_FIRST, 44 MC13783_EVENT_ID = GPIO1_EVENT_FIRST,
39 GPIO1_NUM_EVENTS = 1, 45 SI4700_STC_RDS_EVENT_ID,
46 GPIO1_NUM_EVENTS = 2,
40 /* GPIO2 event IDs */ 47 /* GPIO2 event IDs */
41 /* none defined */ 48 /* none defined */
42 /* GPIO3 event IDs */ 49 /* GPIO3 event IDs */
@@ -44,5 +51,6 @@ enum gpio_event_ids
44}; 51};
45 52
46void mc13783_event(void); 53void mc13783_event(void);
54void si4700_stc_rds_event(void);
47 55
48#endif /* GPIO_TARGET_H */ 56#endif /* GPIO_TARGET_H */