blob: 927cd6e43a3ba57f85d812d4e7c1275a89dcffb7 [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"
Michael Sevakis4ea4cdf2014-08-08 02:28:11 -040033#include "../kernel-internal.h"
Bertrik Sikken2fb73842009-07-29 20:42:02 +000034#include "backlight.h"
35#include "backlight-target.h"
36#include "button.h"
37#include "panic.h"
38#include "power.h"
39#include "common.h"
40#include "usb.h"
41#include "bitmaps/rockboxlogo.h"
42
43#include "adc.h"
44#include "adc-target.h"
45
46#include "timer.h"
47
48#include "i2c-s5l8700.h"
49#include "dma-target.h"
50#include "pcm.h"
51#include "audiohw.h"
52#include "rtc.h"
53#include "tuner.h"
54#include "si4700.h"
55#include "fmradio_i2c.h"
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +000056#include "wmcodec.h"
Bertrik Sikken5aeaa842009-08-09 16:12:36 +000057#include "nand-target.h"
Bertrik Sikken2fb73842009-07-29 20:42:02 +000058
Bertrik Sikken2fb73842009-07-29 20:42:02 +000059#define LONG_DELAY 200000
60#define SHORT_DELAY 50000
61#define PAUSE_DELAY 50000
62
63static inline void delay(unsigned int duration)
64{
65 volatile unsigned int i;
66 for(i=0;i<duration;i++);
67}
68
69// forward declaration
70static int rds_decode(int line, struct si4700_dbg_info *nfo);
71
Bertrik Sikken2fb73842009-07-29 20:42:02 +000072void main(void)
73{
74 char mystring[64];
75 int line, col;
Bertrik Sikkena5248a22010-05-30 21:43:14 +000076 struct tm dt;
Bertrik Sikken2fb73842009-07-29 20:42:02 +000077 int i;
78 struct si4700_dbg_info si4700_info;
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +000079 int brightness = DEFAULT_BRIGHTNESS_SETTING;
Bertrik Sikkenee0ab032009-08-02 16:43:58 +000080 unsigned int button;
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +000081 unsigned int fm_frequency = 100700000;
82 int audiovol = 0x60;
Bertrik Sikken5aeaa842009-08-09 16:12:36 +000083 unsigned nand_ids[4];
Bertrik Sikken2fb73842009-07-29 20:42:02 +000084
Bertrik Sikken2fb73842009-07-29 20:42:02 +000085 // enable all peripherals
86 PWRCON = 0;
87
88 // disable all interrupts
89 INTMSK = 0;
90
91 // start with all GPIOs as input
92 PCON0 = 0;
93 PCON1 = 0;
94 PCON2 = 0;
95 PCON3 = 0;
96 PCON4 = 0;
97 PCON5 = 0;
98 PCON6 = 0;
99 PCON7 = 0;
100
101 system_init();
102 kernel_init();
103
104 asm volatile("msr cpsr_c, #0x13\n\t"); // enable interrupts
105
106 lcd_init();
107
108 lcd_clear_display();
109 lcd_bitmap(rockboxlogo, 0, 160, BMPWIDTH_rockboxlogo, BMPHEIGHT_rockboxlogo);
110 lcd_update();
111
112 power_init();
113
114 i2c_init();
115 fmradio_i2c_init();
116 adc_init();
117 _backlight_init();
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000118 button_init_device();
119
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000120 // FM power
121 si4700_init();
122 tuner_power(true);
123 si4700_set(RADIO_SLEEP, 0);
124 si4700_set(RADIO_MUTE, 0);
Bertrik Sikkena5248a22010-05-30 21:43:14 +0000125 si4700_set(RADIO_REGION, 0);
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000126 si4700_set(RADIO_FREQUENCY, fm_frequency);
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000127
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000128 lcd_puts_scroll(0,0,"+++ this is a very very long line to test scrolling. ---");
129
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000130 // WM1800 codec configuration
131 wmcodec_write(0x0F, 0); // codec reset
132 wmcodec_write(0x19, 0xF0); // pwr mgmt1: VMID = 1, VREF, AINL, AINR
133 wmcodec_write(0x1A, 0x60); // pwr mgmt2: LOUT1, ROUT1
134 wmcodec_write(0x2F, 0x0C); // pwr mgmt3: LOMIX, ROMIX
135 wmcodec_write(0x02, audiovol); // LOUT1VOL
136 wmcodec_write(0x03, audiovol | (1 << 8)); // ROUT1VOL
137 wmcodec_write(0x22, (1 << 7) | (7 << 4)); // left out mix (1)
138 wmcodec_write(0x25, (1 << 7) | (7 << 4)); // right out mix (2)
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000139
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000140 // enable audio
141 PCON5 = (PCON5 & ~0x0000000F) | 0x00000001;
142 PDAT5 |= 1;
143
Bertrik Sikken5aeaa842009-08-09 16:12:36 +0000144 nand_ll_init();
145 for (i = 0; i < 4; i++) {
146 nand_ids[i] = nand_ll_read_id(i);
147 }
148
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000149 while (true)
150 {
151 line = 1;
152
153#if 1 /* enable to see GPIOs */
Bertrik Sikkena5248a22010-05-30 21:43:14 +0000154 snprintf(mystring, 64, "%02X %02X %02X %02X %02X %02X %02X %02X",
155 PDAT0, PDAT1, PDAT2, PDAT3, PDAT4, PDAT5, PDAT6, PDAT7);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000156 lcd_puts(0, line++, mystring);
157#endif
158
159#if 1 /* enable this to see info about the RTC */
Bertrik Sikkena5248a22010-05-30 21:43:14 +0000160 rtc_read_datetime(&dt);
161 snprintf(mystring, 64, "RTC: %04d-%02d-%02d %02d:%02d:%02d",
162 dt.tm_year + 1900, dt.tm_mon+1, dt.tm_mday,
163 dt.tm_hour, dt.tm_min, dt.tm_sec);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000164 lcd_puts(0, line++, mystring);
165#endif
166
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000167#if 1 /* enable this to see radio debug info */
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000168 button = button_read_device();
169 if (button & BUTTON_RIGHT) {
170 fm_frequency += 100000;
171 si4700_set(RADIO_FREQUENCY, fm_frequency);
172 }
173 if (button & BUTTON_LEFT) {
174 fm_frequency -= 100000;
175 si4700_set(RADIO_FREQUENCY, fm_frequency);
176 }
177 snprintf(mystring, 64, "FM frequency: %9d", fm_frequency);
178 lcd_puts(0, line++, mystring);
179
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000180 si4700_dbg_info(&si4700_info);
181 col = snprintf(mystring, 64, "FM: ");
182 for (i = 0; i < 16; i++) {
183 col += snprintf(mystring + col, 64, "%04X ", si4700_info.regs[i]);
184 if (((i + 1) % 4) == 0) {
185 lcd_puts(0, line++, mystring);
186 col = 4;
187 }
188 }
189 line = rds_decode(line, &si4700_info);
190#endif
191
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000192#if 1 /* volume control with up/down keys */
193 button = button_read_device();
194 if (button & BUTTON_UP) {
195 if (audiovol < 127) {
196 audiovol++;
197 wmcodec_write(0x02, audiovol);
198 wmcodec_write(0x03, (1 << 8) | audiovol);
199 }
200 }
201 if (button & BUTTON_DOWN) {
202 if (audiovol > 0) {
203 audiovol--;
204 wmcodec_write(0x02, audiovol);
205 wmcodec_write(0x03, (1 << 8) | audiovol);
206 }
207 }
208 snprintf(mystring, 64, "volume %3d", audiovol);
209 lcd_puts(0, line++, mystring);
210#endif
211
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000212#if 1 /* enable this to see ADC info */
Bertrik Sikkena5248a22010-05-30 21:43:14 +0000213 snprintf(mystring, 64, "ADC: %04X %04X %04X %04X",
214 adc_read(0), adc_read(1), adc_read(2), adc_read(3));
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000215 lcd_puts(0, line++, mystring);
216 snprintf(mystring, 64, "ADC:USB %4d mV BAT %4d mV",
217 (adc_read(0) * 6000) >> 10, (adc_read(2) * 4650) >> 10);
218 lcd_puts(0, line++, mystring);
219#endif
220
221#if 1 /* enable this so see USB info */
222 snprintf(mystring, 64, "CLK %08X CLK2 %08X", CLKCON, CLKCON2);
223 lcd_puts(0, line++, mystring);
224
225 snprintf(mystring, 64, "%04X %04X %04X %04X", PHYCTRL, PHYPWR, URSTCON, UCLKCON);
226 lcd_puts(0, line++, mystring);
227
Bertrik Sikkenb68d7f52009-10-11 13:15:23 +0000228 snprintf(mystring, 64, "SCR %04X SSR %04X EIR %04X", USB_SCR, USB_SSR, USB_EIR);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000229 lcd_puts(0, line++, mystring);
230
Bertrik Sikkenb68d7f52009-10-11 13:15:23 +0000231 snprintf(mystring, 64, "FAR %04X FNR %04X EP0 %04X", USB_FAR, USB_FNR, USB_EP0SR);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000232 lcd_puts(0, line++, mystring);
233#endif
234
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000235#if 1 /* button lights controlled by keypad */
236 button = button_read_device();
237 if (button & (BUTTON_UP | BUTTON_DOWN | BUTTON_LEFT | BUTTON_RIGHT)) {
238 PDAT3 |= (1 << 3);
239 }
240 else {
241 PDAT3 &= ~(1 << 3);
242 }
243 if (button & (BUTTON_BACK | BUTTON_MENU)) {
244 PDAT3 |= (1 << 2);
245 }
246 else {
247 PDAT3 &= ~(1 << 2);
248 }
249 if (button & (BUTTON_SELECT)) {
250 PDAT4 |= (1 << 2);
251 }
252 else {
253 PDAT4 &= ~(1 << 2);
254 }
255#endif
256
257#if 1 /* backlight brightness controlled by up/down keys */
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000258 button = button_read_device();
259 if (button & BUTTON_MENU) {
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000260 if (brightness < MAX_BRIGHTNESS_SETTING) {
261 brightness++;
262 _backlight_set_brightness(brightness);
263 }
264 }
Bertrik Sikken0dc5cc82009-08-03 14:24:28 +0000265 else if (button & BUTTON_BACK) {
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000266 if (brightness > MIN_BRIGHTNESS_SETTING) {
267 brightness--;
268 _backlight_set_brightness(brightness);
269 }
270 }
Bertrik Sikkena5248a22010-05-30 21:43:14 +0000271 snprintf(mystring, 64, "brightness %3d", brightness);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000272 lcd_puts(0, line++, mystring);
273#endif
274
Bertrik Sikken4632fc02009-08-05 16:16:17 +0000275#if 1 /* power off using power button */
276 button = button_read_device();
277 if (button & BUTTON_POWER) {
278 power_off();
279 }
280#endif
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000281
282#if 1 /* button info */
283 snprintf(mystring, 64, "BUTTONS %08X, %s", button_read_device(),
284 headphones_inserted() ? "HP" : "hp");
285 lcd_puts(0, line++, mystring);
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000286#endif
287
Bertrik Sikken5aeaa842009-08-09 16:12:36 +0000288#if 1 /* NAND debug */
289 snprintf(mystring, 64, "NAND ID: %08X %08X", nand_ids[0], nand_ids[1]);
290 lcd_puts(0, line++, mystring);
291 snprintf(mystring, 64, "NAND ID: %08X %08X", nand_ids[2], nand_ids[3]);
292 lcd_puts(0, line++, mystring);
293#endif
294
Bertrik Sikkena5248a22010-05-30 21:43:14 +0000295#if 1
296 snprintf(mystring, 64, "TIMER A:%08X B:%08X", TACNT, TBCNT);
297 lcd_puts(0, line++, mystring);
298 snprintf(mystring, 64, "TIMER C:%08X D:%08X", TCCNT, TDCNT);
299 lcd_puts(0, line++, mystring);
300#endif
301
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000302 lcd_update();
Bertrik Sikkenee0ab032009-08-02 16:43:58 +0000303 }
Bertrik Sikken2fb73842009-07-29 20:42:02 +0000304}
305
306
307static int rds_decode(int line, struct si4700_dbg_info *nfo)
308{
309 unsigned short rdsdata[4];
310 unsigned int pi, group, tp, pty, segment, abflag;
311 static unsigned int af1 = 0, af2 = 0;
312 static unsigned int day = 0, hour = 0, minute = 0;
313 static unsigned int abflag_prev = -1;
314 static char mystring[64];
315
316 /* big RDS arrays */
317 static char ps[9];
318 static char rt[65];
319
320 rdsdata[0] = nfo->regs[12];
321 rdsdata[1] = nfo->regs[13];
322 rdsdata[2] = nfo->regs[14];
323 rdsdata[3] = nfo->regs[15];
324
325 pi = rdsdata[0];
326 group = (rdsdata[1] >> 11) & 0x1F;
327 tp = (rdsdata[1] >> 10) & 1;
328 pty = (rdsdata[1] >> 5) & 0x1F;
329
330 switch (group) {
331
332 case 0: /* group 0A: basic info */
333 af1 = (rdsdata[2] >> 8) & 0xFF;
334 af2 = (rdsdata[2] >> 0) & 0xFF;
335 /* fall through */
336 case 1: /* group 0B: basic info */
337 segment = rdsdata[1] & 3;
338 ps[segment * 2 + 0] = (rdsdata[3] >> 8) & 0xFF;
339 ps[segment * 2 + 1] = (rdsdata[3] >> 0) & 0xFF;
340 break;
341
342 case 2: /* group 1A: programme item */
343 case 3: /* group 1B: programme item */
344 day = (rdsdata[3] >> 11) & 0x1F;
345 hour = (rdsdata[3] >> 6) & 0x1F;
346 minute = (rdsdata[3] >> 0) & 0x3F;
347 break;
348
349 case 4: /* group 2A: radio text */
350 segment = rdsdata[1] & 0xF;
351 abflag = (rdsdata[1] >> 4) & 1;
352 if (abflag != abflag_prev) {
353 memset(rt, '.', 64);
354 abflag_prev = abflag;
355 }
356 rt[segment * 4 + 0] = (rdsdata[2] >> 8) & 0xFF;
357 rt[segment * 4 + 1] = (rdsdata[2] >> 0) & 0xFF;
358 rt[segment * 4 + 2] = (rdsdata[3] >> 8) & 0xFF;
359 rt[segment * 4 + 3] = (rdsdata[3] >> 0) & 0xFF;
360 break;
361
362 case 5: /* group 2B: radio text */
363 segment = rdsdata[1] & 0xF;
364 abflag = (rdsdata[1] >> 4) & 1;
365 if (abflag != abflag_prev) {
366 memset(rt, '.', 64);
367 abflag_prev = abflag;
368 }
369 rt[segment * 2 + 0] = (rdsdata[3] >> 8) & 0xFF;
370 rt[segment * 2 + 1] = (rdsdata[3] >> 0) & 0xFF;
371 break;
372
373 default:
374 break;
375 }
376
377 snprintf(mystring, 64, "PI:%04X,TP:%d,PTY:%2d,AF:%02X/%02X", pi, tp, pty, af1, af2);
378 lcd_puts(0, line++, mystring);
379 snprintf(mystring, 64, "PS:%s,ITEM:%02d-%02d:%02d", ps, day, hour, minute);
380 lcd_puts(0, line++, mystring);
381 snprintf(mystring, 64, "RT:%s", rt);
382 lcd_puts(0, line++, mystring);
383
384 return line;
385}
386
387