1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 by Bertrik Sikken
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
35 #include "backlight.h"
36 #include "backlight-target.h"
42 #include "bitmaps/rockboxlogo.h"
45 #include "adc-target.h"
49 #include "i2c-s5l8700.h"
50 #include "dma-target.h"
56 #include "fmradio_i2c.h"
58 #include "nand-target.h"
60 #define LONG_DELAY 200000
61 #define SHORT_DELAY 50000
62 #define PAUSE_DELAY 50000
64 static inline void delay(unsigned int duration
)
66 volatile unsigned int i
;
67 for(i
=0;i
<duration
;i
++);
70 // forward declaration
71 static int rds_decode(int line
, struct si4700_dbg_info
*nfo
);
79 struct si4700_dbg_info si4700_info
;
80 int brightness
= DEFAULT_BRIGHTNESS_SETTING
;
82 unsigned int fm_frequency
= 100700000;
86 // enable all peripherals
89 // disable all interrupts
92 // start with all GPIOs as input
105 asm volatile("msr cpsr_c, #0x13\n\t"); // enable interrupts
110 lcd_bitmap(rockboxlogo
, 0, 160, BMPWIDTH_rockboxlogo
, BMPHEIGHT_rockboxlogo
);
119 button_init_device();
124 si4700_set(RADIO_SLEEP
, 0);
125 si4700_set(RADIO_MUTE
, 0);
126 si4700_set(RADIO_REGION
, 0);
127 si4700_set(RADIO_FREQUENCY
, fm_frequency
);
129 lcd_puts_scroll(0,0,"+++ this is a very very long line to test scrolling. ---");
131 // WM1800 codec configuration
132 wmcodec_write(0x0F, 0); // codec reset
133 wmcodec_write(0x19, 0xF0); // pwr mgmt1: VMID = 1, VREF, AINL, AINR
134 wmcodec_write(0x1A, 0x60); // pwr mgmt2: LOUT1, ROUT1
135 wmcodec_write(0x2F, 0x0C); // pwr mgmt3: LOMIX, ROMIX
136 wmcodec_write(0x02, audiovol
); // LOUT1VOL
137 wmcodec_write(0x03, audiovol
| (1 << 8)); // ROUT1VOL
138 wmcodec_write(0x22, (1 << 7) | (7 << 4)); // left out mix (1)
139 wmcodec_write(0x25, (1 << 7) | (7 << 4)); // right out mix (2)
142 PCON5
= (PCON5
& ~0x0000000F) | 0x00000001;
146 for (i
= 0; i
< 4; i
++) {
147 nand_ids
[i
] = nand_ll_read_id(i
);
154 #if 1 /* enable to see GPIOs */
155 snprintf(mystring
, 64, "%02X %02X %02X %02X %02X %02X %02X %02X",
156 PDAT0
, PDAT1
, PDAT2
, PDAT3
, PDAT4
, PDAT5
, PDAT6
, PDAT7
);
157 lcd_puts(0, line
++, mystring
);
160 #if 1 /* enable this to see info about the RTC */
161 rtc_read_datetime(&dt
);
162 snprintf(mystring
, 64, "RTC: %04d-%02d-%02d %02d:%02d:%02d",
163 dt
.tm_year
+ 1900, dt
.tm_mon
+1, dt
.tm_mday
,
164 dt
.tm_hour
, dt
.tm_min
, dt
.tm_sec
);
165 lcd_puts(0, line
++, mystring
);
168 #if 1 /* enable this to see radio debug info */
169 button
= button_read_device();
170 if (button
& BUTTON_RIGHT
) {
171 fm_frequency
+= 100000;
172 si4700_set(RADIO_FREQUENCY
, fm_frequency
);
174 if (button
& BUTTON_LEFT
) {
175 fm_frequency
-= 100000;
176 si4700_set(RADIO_FREQUENCY
, fm_frequency
);
178 snprintf(mystring
, 64, "FM frequency: %9d", fm_frequency
);
179 lcd_puts(0, line
++, mystring
);
181 si4700_dbg_info(&si4700_info
);
182 col
= snprintf(mystring
, 64, "FM: ");
183 for (i
= 0; i
< 16; i
++) {
184 col
+= snprintf(mystring
+ col
, 64, "%04X ", si4700_info
.regs
[i
]);
185 if (((i
+ 1) % 4) == 0) {
186 lcd_puts(0, line
++, mystring
);
190 line
= rds_decode(line
, &si4700_info
);
193 #if 1 /* volume control with up/down keys */
194 button
= button_read_device();
195 if (button
& BUTTON_UP
) {
196 if (audiovol
< 127) {
198 wmcodec_write(0x02, audiovol
);
199 wmcodec_write(0x03, (1 << 8) | audiovol
);
202 if (button
& BUTTON_DOWN
) {
205 wmcodec_write(0x02, audiovol
);
206 wmcodec_write(0x03, (1 << 8) | audiovol
);
209 snprintf(mystring
, 64, "volume %3d", audiovol
);
210 lcd_puts(0, line
++, mystring
);
213 #if 1 /* enable this to see ADC info */
214 snprintf(mystring
, 64, "ADC: %04X %04X %04X %04X",
215 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
);
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
);
226 snprintf(mystring
, 64, "%04X %04X %04X %04X", PHYCTRL
, PHYPWR
, URSTCON
, UCLKCON
);
227 lcd_puts(0, line
++, mystring
);
229 snprintf(mystring
, 64, "SCR %04X SSR %04X EIR %04X", USB_SCR
, USB_SSR
, USB_EIR
);
230 lcd_puts(0, line
++, mystring
);
232 snprintf(mystring
, 64, "FAR %04X FNR %04X EP0 %04X", USB_FAR
, USB_FNR
, USB_EP0SR
);
233 lcd_puts(0, line
++, mystring
);
236 #if 1 /* button lights controlled by keypad */
237 button
= button_read_device();
238 if (button
& (BUTTON_UP
| BUTTON_DOWN
| BUTTON_LEFT
| BUTTON_RIGHT
)) {
244 if (button
& (BUTTON_BACK
| BUTTON_MENU
)) {
250 if (button
& (BUTTON_SELECT
)) {
258 #if 1 /* backlight brightness controlled by up/down keys */
259 button
= button_read_device();
260 if (button
& BUTTON_MENU
) {
261 if (brightness
< MAX_BRIGHTNESS_SETTING
) {
263 _backlight_set_brightness(brightness
);
266 else if (button
& BUTTON_BACK
) {
267 if (brightness
> MIN_BRIGHTNESS_SETTING
) {
269 _backlight_set_brightness(brightness
);
272 snprintf(mystring
, 64, "brightness %3d", brightness
);
273 lcd_puts(0, line
++, mystring
);
276 #if 1 /* power off using power button */
277 button
= button_read_device();
278 if (button
& BUTTON_POWER
) {
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
);
289 #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
);
297 snprintf(mystring
, 64, "TIMER A:%08X B:%08X", TACNT
, TBCNT
);
298 lcd_puts(0, line
++, mystring
);
299 snprintf(mystring
, 64, "TIMER C:%08X D:%08X", TCCNT
, TDCNT
);
300 lcd_puts(0, line
++, mystring
);
308 static int rds_decode(int line
, struct si4700_dbg_info
*nfo
)
310 unsigned short rdsdata
[4];
311 unsigned int pi
, group
, tp
, pty
, segment
, abflag
;
312 static unsigned int af1
= 0, af2
= 0;
313 static unsigned int day
= 0, hour
= 0, minute
= 0;
314 static unsigned int abflag_prev
= -1;
315 static char mystring
[64];
321 rdsdata
[0] = nfo
->regs
[12];
322 rdsdata
[1] = nfo
->regs
[13];
323 rdsdata
[2] = nfo
->regs
[14];
324 rdsdata
[3] = nfo
->regs
[15];
327 group
= (rdsdata
[1] >> 11) & 0x1F;
328 tp
= (rdsdata
[1] >> 10) & 1;
329 pty
= (rdsdata
[1] >> 5) & 0x1F;
333 case 0: /* group 0A: basic info */
334 af1
= (rdsdata
[2] >> 8) & 0xFF;
335 af2
= (rdsdata
[2] >> 0) & 0xFF;
337 case 1: /* group 0B: basic info */
338 segment
= rdsdata
[1] & 3;
339 ps
[segment
* 2 + 0] = (rdsdata
[3] >> 8) & 0xFF;
340 ps
[segment
* 2 + 1] = (rdsdata
[3] >> 0) & 0xFF;
343 case 2: /* group 1A: programme item */
344 case 3: /* group 1B: programme item */
345 day
= (rdsdata
[3] >> 11) & 0x1F;
346 hour
= (rdsdata
[3] >> 6) & 0x1F;
347 minute
= (rdsdata
[3] >> 0) & 0x3F;
350 case 4: /* group 2A: radio text */
351 segment
= rdsdata
[1] & 0xF;
352 abflag
= (rdsdata
[1] >> 4) & 1;
353 if (abflag
!= abflag_prev
) {
355 abflag_prev
= abflag
;
357 rt
[segment
* 4 + 0] = (rdsdata
[2] >> 8) & 0xFF;
358 rt
[segment
* 4 + 1] = (rdsdata
[2] >> 0) & 0xFF;
359 rt
[segment
* 4 + 2] = (rdsdata
[3] >> 8) & 0xFF;
360 rt
[segment
* 4 + 3] = (rdsdata
[3] >> 0) & 0xFF;
363 case 5: /* group 2B: radio text */
364 segment
= rdsdata
[1] & 0xF;
365 abflag
= (rdsdata
[1] >> 4) & 1;
366 if (abflag
!= abflag_prev
) {
368 abflag_prev
= abflag
;
370 rt
[segment
* 2 + 0] = (rdsdata
[3] >> 8) & 0xFF;
371 rt
[segment
* 2 + 1] = (rdsdata
[3] >> 0) & 0xFF;
378 snprintf(mystring
, 64, "PI:%04X,TP:%d,PTY:%2d,AF:%02X/%02X", pi
, tp
, pty
, af1
, af2
);
379 lcd_puts(0, line
++, mystring
);
380 snprintf(mystring
, 64, "PS:%s,ITEM:%02d-%02d:%02d", ps
, day
, hour
, minute
);
381 lcd_puts(0, line
++, mystring
);
382 snprintf(mystring
, 64, "RT:%s", rt
);
383 lcd_puts(0, line
++, mystring
);