blob: 6d12f684fc1035e1e3402547b4acf127cc5afac1 [file] [log] [blame]
Bertrik Sikken2fb73842009-07-29 20:42:02 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 by Bertrik Sikken
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <stdarg.h>
25#include <string.h>
26
27#include "config.h"
28
29#include "inttypes.h"
30#include "cpu.h"
31#include "system.h"
32#include "lcd.h"
33#include "kernel.h"
34#include "thread.h"
35#include "backlight.h"
36#include "backlight-target.h"
37#include "button.h"
38#include "panic.h"
39#include "power.h"
40#include "common.h"
41#include "usb.h"
42#include "bitmaps/rockboxlogo.h"
43
44#include "adc.h"
45#include "adc-target.h"
46
47#include "timer.h"
48
49#include "i2c-s5l8700.h"
50#include "dma-target.h"
51#include "pcm.h"
52#include "audiohw.h"
53#include "rtc.h"
54#include "tuner.h"
55#include "si4700.h"
56#include "fmradio_i2c.h"
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +000057#include "wmcodec.h"
Bertrik Sikken5aeaa842009-08-09 16:12:36 +000058#include "nand-target.h"
Bertrik Sikken2fb73842009-07-29 20:42:02 +000059
60char version[] = APPSVERSION;
61#define LONG_DELAY 200000
62#define SHORT_DELAY 50000
63#define PAUSE_DELAY 50000
64
65static inline void delay(unsigned int duration)
66{
67 volatile unsigned int i;
68 for(i=0;i<duration;i++);
69}
70
71// forward declaration
72static int rds_decode(int line, struct si4700_dbg_info *nfo);
73
Bertrik Sikken2fb73842009-07-29 20:42:02 +000074void main(void)
75{
76 char mystring[64];
77 int line, col;
78 unsigned char read_data[16];
79 int i;
80 struct si4700_dbg_info si4700_info;
Bertrik Sikkenee0ab032009-08-02 16:43:58 +000081// unsigned int data;
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +000082 int brightness = DEFAULT_BRIGHTNESS_SETTING;
Bertrik Sikkenee0ab032009-08-02 16:43:58 +000083 unsigned int button;
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +000084 unsigned int fm_frequency = 100700000;
85 int audiovol = 0x60;
Bertrik Sikken5aeaa842009-08-09 16:12:36 +000086 unsigned nand_ids[4];
Bertrik Sikken2fb73842009-07-29 20:42:02 +000087
Bertrik Sikken2fb73842009-07-29 20:42:02 +000088 // enable all peripherals
89 PWRCON = 0;
90
91 // disable all interrupts
92 INTMSK = 0;
93
94 // start with all GPIOs as input
95 PCON0 = 0;
96 PCON1 = 0;
97 PCON2 = 0;
98 PCON3 = 0;
99 PCON4 = 0;
100 PCON5 = 0;
101 PCON6 = 0;
102 PCON7 = 0;
103
104 system_init();
105 kernel_init();
106
107 asm volatile("msr cpsr_c, #0x13\n\t"); // enable interrupts
108
109 lcd_init();
110
111 lcd_clear_display();
112 lcd_bitmap(rockboxlogo, 0, 160, BMPWIDTH_rockboxlogo, BMPHEIGHT_rockboxlogo);
113 lcd_update();
114
115 power_init();
116
117 i2c_init();
118 fmradio_i2c_init();
119 adc_init();
120 _backlight_init();
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000121 button_init_device();
122
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000123 // FM power
124 si4700_init();
125 tuner_power(true);
126 si4700_set(RADIO_SLEEP, 0);
127 si4700_set(RADIO_MUTE, 0);
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000128 si4700_set(RADIO_FREQUENCY, fm_frequency);
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000129
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000130 lcd_puts_scroll(0,0,"+++ this is a very very long line to test scrolling. ---");
131
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000132 // WM1800 codec configuration
133 wmcodec_write(0x0F, 0); // codec reset
134 wmcodec_write(0x19, 0xF0); // pwr mgmt1: VMID = 1, VREF, AINL, AINR
135 wmcodec_write(0x1A, 0x60); // pwr mgmt2: LOUT1, ROUT1
136 wmcodec_write(0x2F, 0x0C); // pwr mgmt3: LOMIX, ROMIX
137 wmcodec_write(0x02, audiovol); // LOUT1VOL
138 wmcodec_write(0x03, audiovol | (1 << 8)); // ROUT1VOL
139 wmcodec_write(0x22, (1 << 7) | (7 << 4)); // left out mix (1)
140 wmcodec_write(0x25, (1 << 7) | (7 << 4)); // right out mix (2)
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000141
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000142 // enable audio
143 PCON5 = (PCON5 & ~0x0000000F) | 0x00000001;
144 PDAT5 |= 1;
145
Bertrik Sikken5aeaa842009-08-09 16:12:36 +0000146 nand_ll_init();
147 for (i = 0; i < 4; i++) {
148 nand_ids[i] = nand_ll_read_id(i);
149 }
150
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000151 while (true)
152 {
153 line = 1;
154
155#if 1 /* enable to see GPIOs */
156 snprintf(mystring, 64, "%02X %02X %02X %02X %02X %02X %02X %02X", PDAT0, PDAT1, PDAT2, PDAT3, PDAT4, PDAT5, PDAT6, PDAT7);
157 lcd_puts(0, line++, mystring);
158#endif
159
160#if 1 /* enable this to see info about the RTC */
161 rtc_read_datetime(read_data);
162 snprintf(mystring, 64, "RTC:");
163 for (i = 0; i < 7; i++) {
164 snprintf(mystring + 2 * i + 4, 64, "%02X", read_data[i]);
165 }
166 lcd_puts(0, line++, mystring);
167#endif
168
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000169#if 1 /* enable this to see radio debug info */
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000170 button = button_read_device();
171 if (button & BUTTON_RIGHT) {
172 fm_frequency += 100000;
173 si4700_set(RADIO_FREQUENCY, fm_frequency);
174 }
175 if (button & BUTTON_LEFT) {
176 fm_frequency -= 100000;
177 si4700_set(RADIO_FREQUENCY, fm_frequency);
178 }
179 snprintf(mystring, 64, "FM frequency: %9d", fm_frequency);
180 lcd_puts(0, line++, mystring);
181
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000182 si4700_dbg_info(&si4700_info);
183 col = snprintf(mystring, 64, "FM: ");
184 for (i = 0; i < 16; i++) {
185 col += snprintf(mystring + col, 64, "%04X ", si4700_info.regs[i]);
186 if (((i + 1) % 4) == 0) {
187 lcd_puts(0, line++, mystring);
188 col = 4;
189 }
190 }
191 line = rds_decode(line, &si4700_info);
192#endif
193
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000194#if 1 /* volume control with up/down keys */
195 button = button_read_device();
196 if (button & BUTTON_UP) {
197 if (audiovol < 127) {
198 audiovol++;
199 wmcodec_write(0x02, audiovol);
200 wmcodec_write(0x03, (1 << 8) | audiovol);
201 }
202 }
203 if (button & BUTTON_DOWN) {
204 if (audiovol > 0) {
205 audiovol--;
206 wmcodec_write(0x02, audiovol);
207 wmcodec_write(0x03, (1 << 8) | audiovol);
208 }
209 }
210 snprintf(mystring, 64, "volume %3d", audiovol);
211 lcd_puts(0, line++, mystring);
212#endif
213
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000214#if 1 /* enable this to see ADC info */
215 snprintf(mystring, 64, "%04X %04X %04X %04X", adc_read(0), adc_read(1), adc_read(2), adc_read(3));
216 lcd_puts(0, line++, mystring);
217 snprintf(mystring, 64, "ADC:USB %4d mV BAT %4d mV",
218 (adc_read(0) * 6000) >> 10, (adc_read(2) * 4650) >> 10);
219 lcd_puts(0, line++, mystring);
220#endif
221
222#if 1 /* enable this so see USB info */
223 snprintf(mystring, 64, "CLK %08X CLK2 %08X", CLKCON, CLKCON2);
224 lcd_puts(0, line++, mystring);
225
226 snprintf(mystring, 64, "%04X %04X %04X %04X", PHYCTRL, PHYPWR, URSTCON, UCLKCON);
227 lcd_puts(0, line++, mystring);
228
229 snprintf(mystring, 64, "SCR %04X SSR %04X EIR %04X", SCR, SSR, EIR);
230 lcd_puts(0, line++, mystring);
231
232 snprintf(mystring, 64, "FAR %04X FNR %04X EP0 %04X", FAR, FNR, EP0SR);
233 lcd_puts(0, line++, mystring);
234#endif
235
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000236#if 1 /* button lights controlled by keypad */
237 button = button_read_device();
238 if (button & (BUTTON_UP | BUTTON_DOWN | BUTTON_LEFT | BUTTON_RIGHT)) {
239 PDAT3 |= (1 << 3);
240 }
241 else {
242 PDAT3 &= ~(1 << 3);
243 }
244 if (button & (BUTTON_BACK | BUTTON_MENU)) {
245 PDAT3 |= (1 << 2);
246 }
247 else {
248 PDAT3 &= ~(1 << 2);
249 }
250 if (button & (BUTTON_SELECT)) {
251 PDAT4 |= (1 << 2);
252 }
253 else {
254 PDAT4 &= ~(1 << 2);
255 }
256#endif
257
258#if 1 /* backlight brightness controlled by up/down keys */
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000259 button = button_read_device();
260 if (button & BUTTON_MENU) {
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000261 if (brightness < MAX_BRIGHTNESS_SETTING) {
262 brightness++;
263 _backlight_set_brightness(brightness);
264 }
265 }
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000266 else if (button & BUTTON_BACK) {
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000267 if (brightness > MIN_BRIGHTNESS_SETTING) {
268 brightness--;
269 _backlight_set_brightness(brightness);
270 }
271 }
272 snprintf(mystring, 64, "bright %3d", brightness);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000273 lcd_puts(0, line++, mystring);
274#endif
275
Bertrik Sikken4632fc02009-08-05 16:16:17 +0000276#if 1 /* power off using power button */
277 button = button_read_device();
278 if (button & BUTTON_POWER) {
279 power_off();
280 }
281#endif
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000282
283#if 1 /* button info */
284 snprintf(mystring, 64, "BUTTONS %08X, %s", button_read_device(),
285 headphones_inserted() ? "HP" : "hp");
286 lcd_puts(0, line++, mystring);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000287#endif
288
Bertrik Sikken5aeaa842009-08-09 16:12:36 +0000289#if 1 /* NAND debug */
290 snprintf(mystring, 64, "NAND ID: %08X %08X", nand_ids[0], nand_ids[1]);
291 lcd_puts(0, line++, mystring);
292 snprintf(mystring, 64, "NAND ID: %08X %08X", nand_ids[2], nand_ids[3]);
293 lcd_puts(0, line++, mystring);
294#endif
295
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000296 lcd_update();
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000297 }
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000298}
299
300
301static int rds_decode(int line, struct si4700_dbg_info *nfo)
302{
303 unsigned short rdsdata[4];
304 unsigned int pi, group, tp, pty, segment, abflag;
305 static unsigned int af1 = 0, af2 = 0;
306 static unsigned int day = 0, hour = 0, minute = 0;
307 static unsigned int abflag_prev = -1;
308 static char mystring[64];
309
310 /* big RDS arrays */
311 static char ps[9];
312 static char rt[65];
313
314 rdsdata[0] = nfo->regs[12];
315 rdsdata[1] = nfo->regs[13];
316 rdsdata[2] = nfo->regs[14];
317 rdsdata[3] = nfo->regs[15];
318
319 pi = rdsdata[0];
320 group = (rdsdata[1] >> 11) & 0x1F;
321 tp = (rdsdata[1] >> 10) & 1;
322 pty = (rdsdata[1] >> 5) & 0x1F;
323
324 switch (group) {
325
326 case 0: /* group 0A: basic info */
327 af1 = (rdsdata[2] >> 8) & 0xFF;
328 af2 = (rdsdata[2] >> 0) & 0xFF;
329 /* fall through */
330 case 1: /* group 0B: basic info */
331 segment = rdsdata[1] & 3;
332 ps[segment * 2 + 0] = (rdsdata[3] >> 8) & 0xFF;
333 ps[segment * 2 + 1] = (rdsdata[3] >> 0) & 0xFF;
334 break;
335
336 case 2: /* group 1A: programme item */
337 case 3: /* group 1B: programme item */
338 day = (rdsdata[3] >> 11) & 0x1F;
339 hour = (rdsdata[3] >> 6) & 0x1F;
340 minute = (rdsdata[3] >> 0) & 0x3F;
341 break;
342
343 case 4: /* group 2A: radio text */
344 segment = rdsdata[1] & 0xF;
345 abflag = (rdsdata[1] >> 4) & 1;
346 if (abflag != abflag_prev) {
347 memset(rt, '.', 64);
348 abflag_prev = abflag;
349 }
350 rt[segment * 4 + 0] = (rdsdata[2] >> 8) & 0xFF;
351 rt[segment * 4 + 1] = (rdsdata[2] >> 0) & 0xFF;
352 rt[segment * 4 + 2] = (rdsdata[3] >> 8) & 0xFF;
353 rt[segment * 4 + 3] = (rdsdata[3] >> 0) & 0xFF;
354 break;
355
356 case 5: /* group 2B: radio text */
357 segment = rdsdata[1] & 0xF;
358 abflag = (rdsdata[1] >> 4) & 1;
359 if (abflag != abflag_prev) {
360 memset(rt, '.', 64);
361 abflag_prev = abflag;
362 }
363 rt[segment * 2 + 0] = (rdsdata[3] >> 8) & 0xFF;
364 rt[segment * 2 + 1] = (rdsdata[3] >> 0) & 0xFF;
365 break;
366
367 default:
368 break;
369 }
370
371 snprintf(mystring, 64, "PI:%04X,TP:%d,PTY:%2d,AF:%02X/%02X", pi, tp, pty, af1, af2);
372 lcd_puts(0, line++, mystring);
373 snprintf(mystring, 64, "PS:%s,ITEM:%02d-%02d:%02d", ps, day, hour, minute);
374 lcd_puts(0, line++, mystring);
375 snprintf(mystring, 64, "RT:%s", rt);
376 lcd_puts(0, line++, mystring);
377
378 return line;
379}
380
381